~alcinnz/rhapsode

e3acf32e756e5c67961542d4422303eea7f9f379 — Adrian Cochrane 4 years ago f04e3b5
Insert audio cues.
1 files changed, 32 insertions(+), 0 deletions(-)

M src/main.c
M src/main.c => src/main.c +32 -0
@@ 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);