@@ 6,6 6,7 @@
#include "HsFFI.h"
#include <espeak-ng/espeak_ng.h>
+#include <sndfile.h>
/* Exported Haskell functions/types */
struct session;
@@ 24,6 25,7 @@ char **c_docLinksAndRendering(struct session*, struct page*); // FIXME segfaults
/* espeak-ng integration. Based on the espeak-ng command source code. */
FILE *fd_wav = NULL;
+char *path_wav = NULL;
static int samplerate;
espeak_ng_ERROR_CONTEXT context;
@@ 37,7 39,6 @@ void write4b(int value) {
}
}
-int wrote_header = 0;
void write_header() {
static unsigned char wave_hdr[44] = {
'R', 'I', 'F', 'F', 0x24, 0xf0, 0xff, 0x7f, 'W', 'A', 'V', 'E', 'f', 'm', 't', ' ',
@@ 68,7 69,10 @@ int synth_callback(short *wav, int numsamples, espeak_EVENT *events) {
events++;
}
- if (!wrote_header) write_header();
+ if (fd_wav == NULL) {
+ fd_wav = fopen(path_wav, "wb");
+ write_header();
+ }
if (numsamples > 0) fwrite(wav, numsamples*2, 1, fd_wav);
return 0;
}
@@ 83,7 87,7 @@ int speak_initialize() {
return 2;
}
- if (fd_wav != stdout) {
+ if (path_wav != NULL) {
result = espeak_ng_InitializeOutput(ENOUTPUT_MODE_SYNCHRONOUS, 0, NULL);
espeak_SetSynthCallback(synth_callback);
} else {
@@ 108,7 112,7 @@ int speak_finalize() {
return 4;
}
- if (fd_wav != stdout) close_wav_file();
+ if (path_wav != NULL) close_wav_file();
espeak_ng_Terminate();
return 0;
}
@@ 120,8 124,8 @@ void write_links(FILE *dest, char **links) {
}
}
-FILE *parse_opt_file(char *mode) {
- FILE *ret = optarg != NULL ? fopen(optarg, mode) : stdout;
+FILE *parse_opt_file() {
+ FILE *ret = optarg != NULL ? fopen(optarg, "w") : stdout;
if (ret == NULL) {
fprintf(stderr, "Failed to open file %s\n", optarg);
hs_exit();
@@ 137,6 141,7 @@ int main(int argc, char **argv) {
char *mimes = "text/html text/xml application/xml application/xhtml+xml text/plain";
FILE *fd_ssml = NULL;
FILE *fd_links = NULL;
+ int use_espeak = 0;
int c;
opterr = 0;
@@ 146,13 151,14 @@ int main(int argc, char **argv) {
mimes = "text/xml application/xml application/xhtml+xml text/html text/plain";
break;
case 's':
- fd_ssml = parse_opt_file("w");
+ fd_ssml = parse_opt_file();
break;
case 'l':
- fd_links = parse_opt_file("w");
+ fd_links = parse_opt_file();
break;
case 'w':
- fd_wav = parse_opt_file("wb");
+ use_espeak = 1;
+ path_wav = optarg;
break;
case '?':
fprintf(stderr, "Invalid flag %c\n\n", optopt);
@@ 170,14 176,14 @@ int main(int argc, char **argv) {
}
}
if (fd_ssml == stdout && fd_links == stdout) fd_links = stderr;
- if (fd_ssml == NULL && fd_links == NULL && fd_wav == NULL) fd_wav = stdout;
+ if (fd_ssml == NULL && fd_links == NULL && !use_espeak) use_espeak = 1;
struct session *session = c_newSession();
struct page *referer = c_initialReferer();
- if (fd_wav != NULL) speak_err = speak_initialize();
+ if (use_espeak) speak_err = speak_initialize();
for (int i = optind; i < argc; i++) {
- if (fd_wav != NULL && speak_err == 0) speak(argv[i]);
+ if (use_espeak && speak_err == 0) speak(argv[i]);
else printf("%s\n", argv[i]);
struct page *page = c_fetchURL(session, mimes, referer, argv[i]);
@@ 186,11 192,11 @@ int main(int argc, char **argv) {
if (fd_ssml != NULL) fprintf(fd_ssml, "%s\n", ssml);
if (fd_links != NULL) write_links(fd_links, links);
- if (fd_wav != NULL& speak_err == 0) speak(ssml);
+ if (use_espeak & speak_err == 0) speak(ssml);
c_freePage(page);
}
- if (fd_wav != NULL & speak_err == 0) speak_err = speak_finalize();
+ if (use_espeak & speak_err == 0) speak_err = speak_finalize();
c_freePage(referer);
c_freeSession(session);