From ba025f66532913d20604e74ab7b4530d8b3caacf Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Wed, 2 Feb 2022 00:39:40 -0500 Subject: Add synths to examples/say.c --- examples/say.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 95 insertions(+), 16 deletions(-) (limited to 'examples') diff --git a/examples/say.c b/examples/say.c index 92d2b19..d72c7ff 100644 --- a/examples/say.c +++ b/examples/say.c @@ -9,8 +9,19 @@ #include #include #include +#include #include +#define SYNTH_STATUS_CLEAR 0 +#define SYNTH_STATUS_ON (1 << 0) + +typedef struct _synth_sine { + int flags; + float phase; + + size_t frequency; +} synth_sine; + static void usage(int argc, char **argv, const char *message, ...) { va_list args; @@ -28,31 +39,53 @@ static void usage(int argc, char **argv, const char *message, ...) { exit(EX_USAGE); } +static int16_t sine_sample(xas_synth *synth, synth_sine *sine) { + int16_t ret; + static float tau = 2.0f * M_PI; + + if (sine->flags & SYNTH_STATUS_ON) { + ret = (int16_t)roundf((INT16_MAX >> 2) * sinf(sine->phase)); + + sine->phase += tau / (synth->sample_rate / sine->frequency); + + if (sine->phase > tau) { + sine->phase -= tau; + } + } else { + ret = 0; + } + + return ret; +} + +static void sine_cleanup(xas_synth *synth, synth_sine *sine) { + return; +} + int main(int argc, char **argv) { + synth_sine sine_channels[2] = { + { SYNTH_STATUS_ON, 0.0f, 220 }, + { SYNTH_STATUS_ON, 0.0f, 420 }, + }; + xas_mixer *mixer; xas_audio_stream *input, + *synth_l, + *synth_r, *output; xas_vox *vox; - size_t sample_rate = 44100, - buffer_size = 4096, - duration_s = 60, + size_t sample_rate = 44100, + buffer_size = 735, + duration_frames = 3600, i; if (argc != 2) { usage(argc, argv, "No output file provided"); } - if ((output = xas_riff_new_file(argv[1], - XAS_AUDIO_STREAM_PCM_16_BIT, - sample_rate, - XAS_AUDIO_STREAM_STEREO, - O_WRONLY | O_CREAT | O_TRUNC)) == NULL) { - goto error_riff_new_file; - } - if ((vox = xas_vox_new("/usr/bin/text2wave", XAS_AUDIO_STREAM_PCM_16_BIT, sample_rate, @@ -61,10 +94,36 @@ int main(int argc, char **argv) { goto error_vox_new; } + if ((output = xas_riff_new_file(argv[1], + XAS_AUDIO_STREAM_PCM_16_BIT, + sample_rate, + XAS_AUDIO_STREAM_STEREO, + O_WRONLY | O_CREAT | O_TRUNC)) == NULL) { + goto error_riff_new_file; + } + if ((input = xas_vox_stream_new(vox)) == NULL) { goto error_vox_stream_new; } + if ((synth_l = xas_synth_new(XAS_AUDIO_STREAM_PCM_16_BIT, + sample_rate, + buffer_size, + (xas_synth_callback_sample)sine_sample, + (xas_synth_callback_cleanup)sine_cleanup, + &sine_channels[0])) == NULL) { + goto error_synth_new_l; + } + + if ((synth_r = xas_synth_new(XAS_AUDIO_STREAM_PCM_16_BIT, + sample_rate, + buffer_size, + (xas_synth_callback_sample)sine_sample, + (xas_synth_callback_cleanup)sine_cleanup, + &sine_channels[1])) == NULL) { + goto error_synth_new_r; + } + if ((mixer = xas_mixer_new(XAS_AUDIO_STREAM_PCM_16_BIT, sample_rate, XAS_AUDIO_STREAM_STEREO, @@ -72,13 +131,23 @@ int main(int argc, char **argv) { goto error_mixer_new; } - if (xas_mixer_input_add(mixer, input, 1.0, -1.0) == NULL) { + if (xas_mixer_input_add(mixer, input, 1.0, 0.0) == NULL) { + goto error_mixer_input_add; + } + + if (xas_mixer_input_add(mixer, synth_l, 0.5, -1.0) == NULL) { + goto error_mixer_input_add; + } + + if (xas_mixer_input_add(mixer, synth_r, 0.5, 1.0) == NULL) { goto error_mixer_input_add; } xas_vox_say(vox, "I want to eat your soul. You don't understand. I really want to eat your soul.\n"); - for (i=0; i