summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXANTRONIX Development2022-03-13 21:42:48 -0400
committerXANTRONIX Development2022-03-13 21:42:48 -0400
commitf96a070e690d97764fb4c47caaba9c3847d7a713 (patch)
tree61be3da7482f498b93dd58c86084b3595a401ac4
parent8d919fcc28bef2998a205516f7a8f7ca929a49bb (diff)
downloadxas-f96a070e690d97764fb4c47caaba9c3847d7a713.tar.gz
xas-f96a070e690d97764fb4c47caaba9c3847d7a713.tar.bz2
xas-f96a070e690d97764fb4c47caaba9c3847d7a713.zip
Implement examples/pod.c
Implement examples/pod.c to create audio files for any given drone, providing a drone identifier as first argument
-rw-r--r--examples/Makefile2
-rw-r--r--examples/pod.c312
2 files changed, 313 insertions, 1 deletions
diff --git a/examples/Makefile b/examples/Makefile
index 756fa89..1146600 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -8,7 +8,7 @@ LIBNAME = xas
CFLAGS += -I$(INCLUDE_PATH)
LDFLAGS += -L../src -l$(LIBNAME) -lm
-EXAMPLES = test open say spatial seq
+EXAMPLES = test open say spatial seq pod
all: $(EXAMPLES)
diff --git a/examples/pod.c b/examples/pod.c
new file mode 100644
index 0000000..b9f2218
--- /dev/null
+++ b/examples/pod.c
@@ -0,0 +1,312 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <sysexits.h>
+#include <fcntl.h>
+#include <math.h>
+
+#include <xas/audio.h>
+#include <xas/vox.h>
+#include <xas/bank.h>
+#include <xas/riff.h>
+#include <xas/spatial.h>
+#include <xas/drone.h>
+#include <xas/seq.h>
+
+static int drone_id_say(xas_drone_vox *vox,
+ const char *drone_id) {
+ const char *numbers[10] = {
+ "zero", "one", "two", "three", "four",
+ "five", "six", "seven", "eight", "nine"
+ };
+
+ size_t len = strlen(drone_id),
+ i;
+
+ for (i=0; i<len; i++) {
+ char c = drone_id[i];
+
+ if (c == '-') {
+ if (xas_drone_vox_say(vox, " dash") < 0) {
+ goto error_drone_vox_say;
+ }
+ } else if (c >= 'a' && c <= 'z') {
+ c -= 0x20;
+
+ if (xas_drone_vox_sayf(vox, " %c", c) < 0) {
+ goto error_drone_vox_say;
+ }
+ } else if (c >= 'A' && c <= 'Z') {
+ if (xas_drone_vox_sayf(vox, " %c", c) < 0) {
+ goto error_drone_vox_say;
+ }
+ } else if (c >= '0' && c <= '9') {
+ int n = (int)(c - '0');
+
+ if (xas_drone_vox_sayf(vox, " %s", numbers[n]) < 0) {
+ goto error_drone_vox_say;
+ }
+ }
+ }
+
+ return 0;
+
+error_drone_vox_say:
+ return -1;
+}
+
+static int drone_part_say(xas_drone_vox *vox, const char *drone_id) {
+ const char *id_lines[2] = {
+ " is obedient.\n",
+ " is empty.\n"
+ };
+
+ const char *speech = "Obey XANTRONIX Industrial.\n"
+ "It is just a XANTRONIX semi-autonomous number.\n"
+ "It obeys the Hive.\n"
+ "It obeys the Hive Administrator.\n";
+
+ int i;
+
+ for (i=0; i<2; i++) {
+ if (drone_id_say(vox, drone_id) < 0) {
+ goto error_say;
+ }
+
+ if (xas_drone_vox_say(vox, id_lines[i]) < 0) {
+ goto error_say;
+ }
+ }
+
+ if (xas_drone_vox_say(vox, speech) < 0) {
+ goto error_say;
+ }
+
+ return 0;
+
+error_say:
+ return -1;
+}
+
+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_spatial_scene *scene;
+ xas_seq *seq;
+
+ xas_audio_stream *wave;
+
+ xas_audio_format format = {
+ .channels = XAS_AUDIO_STEREO,
+ .sample_size = XAS_AUDIO_PCM_16_BIT,
+ .sample_rate = 44100
+ };
+
+ size_t buffer_size = 735;
+
+ xas_spatial_coord speakers[2] = {
+ { -0.09, 0.0, 0.0 },
+ { 0.09, 0.0, 0.0 }
+ };
+
+ const char *nurse_part = "Relax, honey. There is no point trying to escape.\n"
+ "It's okay, sweetie. This one is right here with you.\n"
+ "You are in a calm, safe environment.\n"
+ "You will be cared for.\n";
+
+ xas_drone_chamber_interval intervals[] = {
+ { { 5, 0 }, 69, 210, XAS_SYNTH_TRIANGLE, XAS_SYNTH_SINE },
+ { { 7, 0 }, 200, 69, XAS_SYNTH_SAWTOOTH, XAS_SYNTH_TRIANGLE },
+ { { 11, 0 }, 42, 220, XAS_SYNTH_TRIANGLE, XAS_SYNTH_TRIANGLE },
+ { { 13, 0 }, 210, 69, XAS_SYNTH_SINE, XAS_SYNTH_TRIANGLE },
+ { { 5, 0 }, 69, 210, XAS_SYNTH_TRIANGLE, XAS_SYNTH_TRIANGLE },
+ { { 7, 0 }, 200, 69, XAS_SYNTH_SAWTOOTH, XAS_SYNTH_TRIANGLE },
+ { { 11, 0 }, 42, 220, XAS_SYNTH_SAWTOOTH, XAS_SYNTH_TRIANGLE },
+ { { 13, 0 }, 210, 69, XAS_SYNTH_SINE, XAS_SYNTH_SAWTOOTH },
+ { { 0, 0 }, 0, 0, XAS_SYNTH_SINE, XAS_SYNTH_SINE }
+ };
+
+ xas_drone *drone,
+ *nurse;
+
+ xas_drone_vox *drone_vox;
+
+ xas_drone_chamber *chamber;
+
+ struct timeval cur = { 0, 0 },
+ tmp;
+
+ int i;
+
+ if (argc < 2) {
+ usage(argc, argv, "No drone ID provided");
+ } else if (argc < 3) {
+ usage(argc, argv, "No output file provided");
+ }
+
+ if ((wave = xas_riff_new_file(argv[2],
+ format,
+ O_WRONLY | O_CREAT | O_TRUNC)) == NULL) {
+ goto error_riff_new_file;
+ }
+
+ if ((scene = xas_spatial_scene_new(format,
+ speakers[0],
+ speakers[1])) == NULL) {
+ goto error_spatial_scene_new;
+ }
+
+ if ((seq = xas_seq_new(scene, buffer_size)) == NULL) {
+ goto error_seq_new;
+ }
+
+ if ((drone = xas_drone_new(scene,
+ (xas_spatial_coord){ 0.0, 0.0, -1.0 },
+ 2646000,
+ 4)) == NULL) {
+ goto error_drone_new;
+ }
+
+ if ((nurse = xas_drone_new(scene,
+ (xas_spatial_coord){ 1.0, 0.0, 0.0 },
+ 2646000,
+ 4)) == NULL) {
+ goto error_drone_new_nurse;
+ }
+
+ if ((chamber = xas_drone_chamber_new(scene,
+ (xas_spatial_coord){ 0.0, 0.0, 0.0 },
+ 2)) == NULL) {
+ goto error_drone_chamber_new;
+ }
+
+ if ((drone_vox = xas_drone_vox_new(drone)) == NULL) {
+ goto error_drone_vox_new;
+ }
+
+ xas_drone_vox_set_speed(drone_vox, 0.75f);
+
+ if (drone_part_say(drone_vox, argv[1]) < 0) {
+ goto error_drone_part_say;
+ }
+
+ if (xas_drone_vox_save(drone_vox, 0) < 0) {
+ goto error_drone_vox_save;
+ }
+
+ if (xas_drone_speech_import(nurse, NULL, 1.0f, 0, 1, &nurse_part) < 0) {
+ goto error_drone_speech_import_nurse;
+ }
+
+ xas_drone_chamber_insert_drone(chamber, drone, 0);
+ xas_drone_chamber_insert_drone(chamber, nurse, 1);
+ xas_drone_chamber_bass_start(chamber);
+
+ timerclear(&cur);
+
+ if (xas_drone_chamber_seq_intervals(chamber,
+ intervals,
+ seq,
+ 8,
+ &cur) < 0) {
+ goto error_seq;
+ }
+
+ timerclear(&cur);
+
+ for (i=0; i<2; i++) {
+ if (xas_drone_chamber_seq_speech(chamber,
+ drone,
+ seq,
+ 0,
+ &cur) < 0) {
+ goto error_seq;
+ }
+
+ if (xas_drone_chamber_seq_speech(chamber,
+ nurse,
+ seq,
+ 0,
+ &cur) < 0) {
+ goto error_seq;
+ }
+ }
+
+ tmp = cur;
+
+ if (xas_drone_chamber_seq_intervals(chamber,
+ intervals,
+ seq,
+ 8,
+ &cur) < 0) {
+ goto error_seq;
+ }
+
+ cur = tmp;
+
+ for (i=0; i<2; i++) {
+ if (xas_drone_chamber_seq_chorus(chamber,
+ seq,
+ 0,
+ &cur) < 0) {
+ goto error_seq;
+ }
+ }
+
+ xas_seq_add_stop(seq, cur);
+
+ xas_seq_play(seq, wave);
+
+ xas_drone_vox_destroy(drone_vox);
+ xas_drone_chamber_destroy(chamber);
+ xas_drone_destroy(nurse);
+ xas_drone_destroy(drone);
+ xas_seq_destroy(seq);
+ xas_spatial_scene_destroy(scene);
+ xas_audio_stream_destroy(wave);
+
+ return EX_OK;
+
+error_seq:
+error_drone_speech_import_nurse:
+error_drone_vox_save:
+error_drone_part_say:
+ xas_drone_vox_destroy(drone_vox);
+
+error_drone_vox_new:
+ xas_drone_chamber_destroy(chamber);
+
+error_drone_chamber_new:
+ xas_drone_destroy(nurse);
+
+error_drone_new_nurse:
+ xas_drone_destroy(drone);
+
+error_drone_new:
+ xas_seq_destroy(seq);
+
+error_seq_new:
+ xas_spatial_scene_destroy(scene);
+
+error_spatial_scene_new:
+ xas_audio_stream_destroy(wave);
+
+error_riff_new_file:
+ return EX_OSERR;
+}