diff options
author | Ahmad Fatoum <ahmad@a3f.at> | 2021-01-31 21:18:42 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2021-02-08 10:57:05 +0100 |
commit | 01a55d345dbb8d861cda0d430d42c3bbbaff718a (patch) | |
tree | e22881f24ddb8ae83eb7211137ccb92ff331be44 /drivers | |
parent | 78dd61b47e5d93240b3d112c51fa3b1896c4f6e6 (diff) | |
download | barebox-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/Kconfig | 13 | ||||
-rw-r--r-- | drivers/sound/Makefile | 2 | ||||
-rw-r--r-- | drivers/sound/synth.c | 43 |
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; + } + } +} |