summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAhmad Fatoum <ahmad@a3f.at>2021-01-31 21:18:42 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2021-02-08 10:57:05 +0100
commit01a55d345dbb8d861cda0d430d42c3bbbaff718a (patch)
treee22881f24ddb8ae83eb7211137ccb92ff331be44 /drivers
parent78dd61b47e5d93240b3d112c51fa3b1896c4f6e6 (diff)
downloadbarebox-01a55d345dbb8d861cda0d430d42c3bbbaff718a.tar.gz
barebox-01a55d345dbb8d861cda0d430d42c3bbbaff718a.tar.xz
sound: add basic synthesizers for PCM beeper use
For beeping on PCM sound cards, barebox will need to synthesize samples. Add basic sine and square wave synthesizers to achieve this. Client code can either call __synth_F to explicitly select synth F or synth_F, which depending on CONFIG_SYNTH_SQUARES may expand to either __synth_F or a gain-adjusted __synth_generate_square. The latter is mainly useful for slow systems that can't synthesize enough sine samples in a poller without impacting boot performance. Signed-off-by: Ahmad Fatoum <ahmad@a3f.at> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/sound/Kconfig13
-rw-r--r--drivers/sound/Makefile2
-rw-r--r--drivers/sound/synth.c43
3 files changed, 57 insertions, 1 deletions
diff --git a/drivers/sound/Kconfig b/drivers/sound/Kconfig
index cce5c760af..d9f63a5f3c 100644
--- a/drivers/sound/Kconfig
+++ b/drivers/sound/Kconfig
@@ -6,3 +6,16 @@ menuconfig SOUND
Say Y here for sound support. At the moment that's just beep tones.
Tones are played asynchronously in a poller. Check the beep command
for how to exercise the API.
+
+if SOUND
+
+config SYNTH_SQUARES
+ bool "Synthesize square waves only"
+ help
+ For beeping on PCM sound cards, barebox needs to synthesize samples,
+ which can take too much poller time for crisp playback and/or quick
+ booting. If your playback stutters, say Y here. This will have all
+ synthesizers output a gain-adjusted square wave instead, which is
+ less time-consuming to compute.
+
+endif
diff --git a/drivers/sound/Makefile b/drivers/sound/Makefile
index e343e0fa72..69873faab9 100644
--- a/drivers/sound/Makefile
+++ b/drivers/sound/Makefile
@@ -1,2 +1,2 @@
# SPDX-License-Identifier: GPL-2.0-only
-obj-y += core.o
+obj-y += core.o synth.o
diff --git a/drivers/sound/synth.c b/drivers/sound/synth.c
new file mode 100644
index 0000000000..c9de62b516
--- /dev/null
+++ b/drivers/sound/synth.c
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2012 Samsung Electronics, R. Chandrasekar <rcsekar@samsung.com>
+ * Copyright (C) 2021 Ahmad Fatoum
+ */
+
+#include <common.h>
+#include <linux/fixp-arith.h>
+#include <linux/math64.h>
+#include <sound.h>
+
+void __synth_sin(unsigned freq, s16 amplitude, s16 *stream,
+ unsigned sample_rate, unsigned nsamples)
+{
+ int64_t v = 0;
+ int i = 0;
+
+ for (i = 0; i < nsamples; i++) {
+ /* Assume RHS sign extension, true for GCC */
+ stream[i] = (fixp_sin32(div_s64(v * 360, sample_rate)) * (int64_t)amplitude) >> 31;
+ v += freq;
+ }
+}
+
+void __synth_square(unsigned freq, s16 amplitude, s16 *stream,
+ unsigned sample_rate, unsigned nsamples)
+{
+ unsigned period = freq ? sample_rate / freq : 0;
+ int half = period / 2;
+
+ while (nsamples) {
+ int i;
+
+ for (i = 0; nsamples && i < half; i++) {
+ nsamples--;
+ *stream++ = amplitude;
+ }
+ for (i = 0; nsamples && i < period - half; i++) {
+ nsamples--;
+ *stream++ = -amplitude;
+ }
+ }
+}