@@ 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);