diff options
author | XANTRONIX Development | 2022-02-15 20:53:24 -0500 |
---|---|---|
committer | XANTRONIX Development | 2022-02-15 20:53:24 -0500 |
commit | e0fda7988c2cca763d92075a5d95f813a37b69f4 (patch) | |
tree | e547109adad66235581ec60ea5836ad6e75b6f95 /examples | |
parent | 1fe063a6d66048e6f95d1f60a7d7f837799cefe7 (diff) | |
download | xas-e0fda7988c2cca763d92075a5d95f813a37b69f4.tar.gz xas-e0fda7988c2cca763d92075a5d95f813a37b69f4.tar.bz2 xas-e0fda7988c2cca763d92075a5d95f813a37b69f4.zip |
It's surprising this stuff compiles, but fuck it
Diffstat (limited to 'examples')
-rw-r--r-- | examples/Makefile | 2 | ||||
-rw-r--r-- | examples/spatial.c | 166 |
2 files changed, 167 insertions, 1 deletions
diff --git a/examples/Makefile b/examples/Makefile index 537d103..5604297 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -7,7 +7,7 @@ INCLUDE_PATH = ../include CFLAGS += -I$(INCLUDE_PATH) LDFLAGS += -L../src -lxas -lm -EXAMPLES = test open say +EXAMPLES = test open say spatial all: $(EXAMPLES) diff --git a/examples/spatial.c b/examples/spatial.c new file mode 100644 index 0000000..9985ffe --- /dev/null +++ b/examples/spatial.c @@ -0,0 +1,166 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <sysexits.h> +#include <fcntl.h> +#include <math.h> + +#include <xas/spatial.h> +#include <xas/synth.h> +#include <xas/audio.h> +#include <xas/riff.h> + +#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; + 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->format.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) { + xas_spatial_scene *scene; + + xas_audio_stream *synth, + *output, + *wave; + + synth_sine sine_channels[2] = { + { SYNTH_STATUS_ON, 0.0f, 220 }, + { SYNTH_STATUS_ON, 0.0f, 420 }, + }; + + 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; + + xas_spatial_coord speakers[2] = { + { -0.09, 0.0, 0.0 }, + { 0.09, 0.0, 0.0 } + }; + + 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 ((synth = xas_synth_new((xas_synth_callback_sample)sine_sample, + (xas_synth_callback_cleanup)sine_cleanup, + format, + buffer_size, + &sine_channels[0])) == NULL) { + goto error_synth_new; + } + + if ((scene = xas_spatial_scene_new(format, + speakers[0], + speakers[1])) == NULL) { + goto error_spatial_scene_new; + } + + if ((output = xas_spatial_scene_new_stream(scene, + buffer_size)) == NULL) { + goto error_spatial_scene_new_stream; + } + + if (xas_spatial_scene_add_object(scene, + (xas_spatial_coord){ 0.0, 0.0, 20.0 }, + synth) == NULL) { + goto error_spatial_scene_add_object; + } + + for (i=0; i<duration_s; i++) { + void *buf; + ssize_t readlen; + + if ((readlen = xas_audio_stream_read(output, + &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_audio_stream_destroy(output); + xas_spatial_scene_destroy(scene); + xas_audio_stream_destroy(synth); + xas_audio_stream_destroy(wave); + + return EX_OK; + +error_audio_stream_read: +error_audio_stream_write: +error_spatial_scene_add_object: + xas_audio_stream_destroy(output); + +error_spatial_scene_new_stream: + xas_spatial_scene_destroy(scene); + +error_spatial_scene_new: + xas_audio_stream_destroy(synth); + +error_synth_new: + xas_audio_stream_destroy(wave); + +error_riff_new_file: + return EX_OSERR; +} |