~alcinnz/rhapsode

8ff372bd5e005f82493738bb7e33e88af1aa9c2a — Adrian Cochrane 4 years ago f5205f5
Import libsndfile, prepare to use it for writing audio files.
2 files changed, 21 insertions(+), 15 deletions(-)

M rhapsode.cabal
M src/main.c
M rhapsode.cabal => rhapsode.cabal +1 -1
@@ 75,7 75,7 @@ library
executable rhapsode
  main-is: main.c
  ghc-options: -no-hs-main
  extra-libraries: espeak-ng
  extra-libraries: espeak-ng, sndfile
  build-depends:       base >=4.9 && <=4.12, rhapsode
  other-modules: Stub
  hs-source-dirs: src

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