#include #include #include #include #include #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; 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); } static int16_t sine_sample(xas_synth *synth, synth_sine *sine) { int16_t ret; if (sine->flags & SYNTH_STATUS_ON) { ret = (int16_t)roundf((INT16_MAX >> 2) * sinf(sine->phase)); sine->phase += (2.0f * M_PI) / (synth->sample_rate / sine->frequency); } else { ret = 0; } return ret; } static void sine_destroy(xas_synth *synth, synth_sine *sine) { return; } int main(int argc, char **argv) { xas_audio_stream *stream; xas_synth *synth; synth_sine sine = { .flags = SYNTH_STATUS_ON, .phase = 0.0f, .frequency = 220 }; size_t sample_rate = 44100, duration_s = 60; int i; if (argc != 2) { usage(argc, argv, "No output file provided"); } if ((stream = xas_riff_file_open(argv[1], 2, sample_rate, 1, O_WRONLY | O_CREAT | O_TRUNC)) == NULL) { goto error_riff_file_open; } if ((synth = xas_synth_new(sample_rate, (xas_synth_callback_sample)sine_sample, (xas_synth_callback_destroy)sine_destroy, &sine)) == NULL) { goto error_synth_new; } for (i=0; i < duration_s * sample_rate; i++) { int16_t samples[1] = { xas_synth_sample(synth) }; xas_audio_stream_write(stream, samples, 1); } xas_audio_stream_flush(stream); xas_audio_stream_destroy(stream); return EX_OK; error_synth_new: xas_audio_stream_destroy(stream); error_riff_file_open: return EX_OSERR; }