#include #include #include #include #include #include #include #include #include #include #include static void usage(int argc, char **argv, const char *message, ...) { va_list args; va_start(args, message); if (message) { vfprintf(stderr, message, args); fputc('\n', stderr); } va_end(args); fprintf(stderr, "usage: %s output.wav\n", argv[0]); exit(EX_USAGE); } int main(int argc, char **argv) { xas_mixer *mixer; xas_audio_stream *synth_l, *synth_r, *wave; xas_synth *sine_l, *sine_r; xas_audio_format format = { .channels = XAS_AUDIO_STEREO, .sample_size = XAS_AUDIO_PCM_16_BIT, .sample_rate = 44100 }; size_t buffer_size = 4096, duration_s = 60, i; if (argc != 2) { usage(argc, argv, "No output file provided"); } if ((wave = xas_riff_new_file(argv[1], format, O_WRONLY | O_CREAT | O_TRUNC)) == NULL) { goto error_riff_new_file; } if ((sine_l = xas_synth_new(format, buffer_size, XAS_SYNTH_SINE)) == NULL) { goto error_synth_new_l; } if ((synth_l = xas_synth_new_stream(sine_l)) == NULL) { goto error_synth_new_stream_l; } if ((sine_r = xas_synth_new(format, buffer_size, XAS_SYNTH_SINE)) == NULL) { goto error_synth_new_r; } if ((synth_r = xas_synth_new_stream(sine_r)) == NULL) { goto error_synth_new_stream_r; } if ((mixer = xas_mixer_new(format, buffer_size)) == NULL) { goto error_mixer_new; } if (xas_mixer_input_add(mixer, synth_l, 0.3, -1.0) == NULL) { goto error_mixer_input_add; } if (xas_mixer_input_add(mixer, synth_r, 0.3, 1.0) == NULL) { goto error_mixer_input_add; } xas_synth_set_frequency(sine_l, 2600); xas_synth_start(sine_l); xas_synth_set_frequency(sine_r, 420); xas_synth_start(sine_r); for (i=0; ioutput, &buf, buffer_size)) < 0) { goto error_audio_stream_read; } if (xas_audio_stream_write(wave, buf, readlen) < 0) { goto error_audio_stream_write; } } xas_audio_stream_flush(wave); xas_mixer_destroy(mixer); xas_audio_stream_destroy(synth_r); xas_synth_destroy(sine_r); xas_audio_stream_destroy(synth_l); xas_synth_destroy(sine_l); xas_audio_stream_destroy(wave); return EX_OK; error_audio_stream_write: error_audio_stream_read: error_mixer_input_add: xas_mixer_destroy(mixer); error_mixer_new: xas_audio_stream_destroy(synth_r); error_synth_new_stream_r: xas_synth_destroy(sine_r); error_synth_new_r: xas_audio_stream_destroy(synth_l); error_synth_new_stream_l: xas_synth_destroy(sine_l); error_synth_new_l: xas_audio_stream_destroy(wave); error_riff_new_file: return EX_OSERR; }