From e3acf32e756e5c67961542d4422303eea7f9f379 Mon Sep 17 00:00:00 2001 From: Adrian Cochrane Date: Thu, 9 Apr 2020 10:37:47 +1200 Subject: [PATCH] Insert audio cues. --- src/main.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/main.c b/src/main.c index ed98750..6659a7c 100644 --- a/src/main.c +++ b/src/main.c @@ -43,11 +43,42 @@ int choose_format(char *path) { return SF_FORMAT_WAV; } +int should_play(int type, const char *uri, const char *base) { + return strncmp(uri, "file:///", strlen("file:///")); +} +#define BUFFER_LEN 1024 +#define MAX_CHANNELS 6 +// FIXME convert samplerate +int read_mono(SNDFILE *fd, SF_INFO *info, short *out) { + sf_count_t count = sf_read_short(fd, out, BUFFER_LEN); + if (info->channels == 1) return count; + + int i = 0; + for (int j = 0; j < count; j += info->channels) out[i++] = out[j]; + return i; +} + int synth_callback(short *wav, int numsamples, espeak_EVENT *events) { if (wav == NULL) return 0; while (events->type != 0) { if (events->type == espeakEVENT_SAMPLERATE) samplerate = events->id.number; + if (events->type == espeakEVENT_PLAY) { + SF_INFO info; + info.format = 0; + short buf[BUFFER_LEN]; + int len; + SNDFILE *fd = sf_open(events->id.name + strlen("file://"), SFM_READ, &info); + if (fd == NULL || info.channels > MAX_CHANNELS) { + fprintf(stderr, "Failed to open %s: %s\n", events->id.name + strlen("file://"), + sf_strerror(fd)); + events++; + continue; + } + while ((len = read_mono(fd, &info, buf)) != 0) + sf_write_short(fd_wav, buf, len); + sf_close(fd); + } events++; } @@ -74,6 +105,7 @@ int speak_initialize() { if (path_wav != NULL) { result = espeak_ng_InitializeOutput(ENOUTPUT_MODE_SYNCHRONOUS, 0, NULL); + espeak_SetUriCallback(should_play); espeak_SetSynthCallback(synth_callback); } else { result = espeak_ng_InitializeOutput(ENOUTPUT_MODE_SPEAK_AUDIO, 0, NULL); -- 2.30.2