lede-packages-rs

git clone git://archive.git.mtrnord.blog/MTRNord/lede-packages-rs.git
Log | Files | Refs | README | LICENSE

0003-pico2wave-Convert-text-to-.wav-using-svox-text-to-sp.patch (15439B)


      1 From 8bec80dccc9f4fe147a500486813f4e89a0d56d8 Mon Sep 17 00:00:00 2001
      2 From: Mathieu Parent <math.parent@gmail.com>
      3 Date: Sun, 25 Oct 2009 15:19:01 +0100
      4 Subject: [PATCH 3/7] pico2wave: Convert text to .wav using svox text-to-speech system.
      5 
      6 ---
      7  pico/.gitignore      |    1 +
      8  pico/Makefile.am     |    7 +
      9  pico/bin/pico2wave.c |  341 ++++++++++++++++++++++++++++++++++++++++++++++++++
     10  pico/configure.in    |    3 +
     11  4 files changed, 352 insertions(+), 0 deletions(-)
     12  create mode 100644 pico/bin/pico2wave.c
     13 
     14 diff --git a/pico/.gitignore b/pico/.gitignore
     15 index 4235569..a110298 100644
     16 --- a/pico/.gitignore
     17 +++ b/pico/.gitignore
     18 @@ -29,4 +29,5 @@ libtool
     19  *.lo
     20  .libs
     21  libttspico.la
     22 +pico2wave
     23  
     24 diff --git a/pico/Makefile.am b/pico/Makefile.am
     25 index 6d8a10c..0d9472d 100644
     26 --- a/pico/Makefile.am
     27 +++ b/pico/Makefile.am
     28 @@ -34,3 +34,10 @@ libttspico_la_SOURCES = \
     29  	lib/picotrns.c \
     30  	lib/picowa.c
     31  
     32 +bin_PROGRAMS = pico2wave
     33 +pico2wave_SOURCES = \
     34 +	bin/pico2wave.c
     35 +pico2wave_LDADD = \
     36 +	libttspico.la -lm -lpopt
     37 +pico2wave_CFLAGS = -Wall -I lib
     38 +
     39 diff --git a/pico/bin/pico2wave.c b/pico/bin/pico2wave.c
     40 new file mode 100644
     41 index 0000000..0c035a7
     42 --- /dev/null
     43 +++ b/pico/bin/pico2wave.c
     44 @@ -0,0 +1,341 @@
     45 +/* pico2wave.c
     46 +
     47 + * Copyright (C) 2009 Mathieu Parent <math.parent@gmail.com>
     48 + *
     49 + * Licensed under the Apache License, Version 2.0 (the "License");
     50 + * you may not use this file except in compliance with the License.
     51 + * You may obtain a copy of the License at
     52 + *
     53 + *     http://www.apache.org/licenses/LICENSE-2.0
     54 + *
     55 + * Unless required by applicable law or agreed to in writing, software
     56 + * distributed under the License is distributed on an "AS IS" BASIS,
     57 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     58 + * See the License for the specific language governing permissions and
     59 + * limitations under the License.
     60 + *
     61 + *   Convert text to .wav using svox text-to-speech system.
     62 + *
     63 + */
     64 +
     65 +
     66 +#include <popt.h>
     67 +#include <stdio.h>
     68 +#include <stdlib.h>
     69 +#include <string.h>
     70 +
     71 +#include <picoapi.h>
     72 +#include <picoapid.h>
     73 +#include <picoos.h>
     74 +
     75 +
     76 +/* adaptation layer defines */
     77 +#define PICO_MEM_SIZE       2500000
     78 +#define DummyLen 100000000
     79 +
     80 +/* string constants */
     81 +#define MAX_OUTBUF_SIZE     128
     82 +const char * PICO_LINGWARE_PATH             = "./lang/";
     83 +const char * PICO_VOICE_NAME                = "PicoVoice";
     84 +
     85 +/* supported voices
     86 +   Pico does not separately specify the voice and locale.   */
     87 +const char * picoSupportedLangIso3[]        = { "eng",              "eng",              "deu",              "spa",              "fra",              "ita" };
     88 +const char * picoSupportedCountryIso3[]     = { "USA",              "GBR",              "DEU",              "ESP",              "FRA",              "ITA" };
     89 +const char * picoSupportedLang[]            = { "en-US",            "en-GB",            "de-DE",            "es-ES",            "fr-FR",            "it-IT" };
     90 +const char * picoInternalLang[]             = { "en-US",            "en-GB",            "de-DE",            "es-ES",            "fr-FR",            "it-IT" };
     91 +const char * picoInternalTaLingware[]       = { "en-US_ta.bin",     "en-GB_ta.bin",     "de-DE_ta.bin",     "es-ES_ta.bin",     "fr-FR_ta.bin",     "it-IT_ta.bin" };
     92 +const char * picoInternalSgLingware[]       = { "en-US_lh0_sg.bin", "en-GB_kh0_sg.bin", "de-DE_gl0_sg.bin", "es-ES_zl0_sg.bin", "fr-FR_nk0_sg.bin", "it-IT_cm0_sg.bin" };
     93 +const char * picoInternalUtppLingware[]     = { "en-US_utpp.bin",   "en-GB_utpp.bin",   "de-DE_utpp.bin",   "es-ES_utpp.bin",   "fr-FR_utpp.bin",   "it-IT_utpp.bin" };
     94 +const int picoNumSupportedVocs              = 6;
     95 +
     96 +/* adapation layer global variables */
     97 +void *          picoMemArea         = NULL;
     98 +pico_System     picoSystem          = NULL;
     99 +pico_Resource   picoTaResource      = NULL;
    100 +pico_Resource   picoSgResource      = NULL;
    101 +pico_Resource   picoUtppResource    = NULL;
    102 +pico_Engine     picoEngine          = NULL;
    103 +pico_Char *     picoTaFileName      = NULL;
    104 +pico_Char *     picoSgFileName      = NULL;
    105 +pico_Char *     picoUtppFileName    = NULL;
    106 +pico_Char *     picoTaResourceName  = NULL;
    107 +pico_Char *     picoSgResourceName  = NULL;
    108 +pico_Char *     picoUtppResourceName = NULL;
    109 +int     picoSynthAbort = 0;
    110 +
    111 +
    112 +int main(int argc, const char *argv[]) {
    113 +    char * wavefile = NULL;
    114 +    char * lang = "en-US";
    115 +    int langIndex = -1, langIndexTmp = -1;
    116 +    char * text;
    117 +    int8_t * buffer;
    118 +    size_t bufferSize = 256;
    119 +    
    120 +    /* Parsing options */
    121 +	poptContext optCon; /* context for parsing command-line options */
    122 +	int opt; /* used for argument parsing */
    123 +
    124 +	struct poptOption optionsTable[] = {
    125 +		{ "wave", 'w', POPT_ARG_STRING, &wavefile, 0,
    126 +		  "Write output to this WAV file (extension SHOULD be .wav)", "filename.wav" },
    127 +		{ "lang", 'l', POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &lang, 0,
    128 +		  "Language", "lang" },
    129 +		POPT_AUTOHELP
    130 +		POPT_TABLEEND
    131 +	};
    132 +	optCon = poptGetContext(NULL, argc, argv, optionsTable, POPT_CONTEXT_POSIXMEHARDER);
    133 +    poptSetOtherOptionHelp(optCon, "<words>");
    134 +
    135 +    /* Reporting about invalid extra options */
    136 +	while ((opt = poptGetNextOpt(optCon)) != -1) {
    137 +		switch (opt) {
    138 +		default:
    139 +			fprintf(stderr, "Invalid option %s: %s\n", 
    140 +				poptBadOption(optCon, 0), poptStrerror(opt));
    141 +			poptPrintHelp(optCon, stderr, 0);
    142 +			exit(1);
    143 +		}
    144 +	}
    145 +
    146 +    /* Mandatory option: --wave */
    147 +	if(!wavefile) {
    148 +		fprintf(stderr, "Mandatory option: %s\n\n", 
    149 +			"--wave=filename.wav");
    150 +		poptPrintHelp(optCon, stderr, 0);
    151 +		exit(1);
    152 +	}
    153 +	/* option: --lang */
    154 +	for(langIndexTmp =0; langIndexTmp<picoNumSupportedVocs; langIndexTmp++) {
    155 +	    if(!strcmp(picoSupportedLang[langIndexTmp], lang)) {
    156 +	        langIndex = langIndexTmp;
    157 +	        break;
    158 +	    }
    159 +	}
    160 +	if(langIndex == -1) {
    161 +		fprintf(stderr, "Unknown language: %s\nValid languages:\n", 
    162 +			lang);
    163 +	    for(langIndexTmp =0; langIndexTmp<picoNumSupportedVocs; langIndexTmp++) {
    164 +	        fprintf(stderr, "%s\n", picoSupportedLang[langIndexTmp]);
    165 +	    }
    166 +	    lang = "en-US";
    167 +		fprintf(stderr, "\n");
    168 +		poptPrintHelp(optCon, stderr, 0);
    169 +		exit(1);
    170 +	}
    171 +
    172 +	/* Remaining argument is <words> */
    173 +	const char **extra_argv;
    174 +	extra_argv = poptGetArgs(optCon);
    175 +    if(extra_argv) {
    176 +		text = (char *) &(*extra_argv)[0];
    177 +    } else {
    178 +        //TODO: stdin not supported yet.
    179 +		fprintf(stderr, "Missing argument: %s\n\n", 
    180 +			"<words>");
    181 +		poptPrintHelp(optCon, stderr, 0);
    182 +		exit(1);
    183 +    }
    184 +
    185 +    poptFreeContext(optCon);
    186 +    
    187 +    buffer = malloc( bufferSize );
    188 +    
    189 +    int ret, getstatus;
    190 +    pico_Char * inp = NULL;
    191 +    pico_Char * local_text = NULL;
    192 +    short       outbuf[MAX_OUTBUF_SIZE/2];
    193 +    pico_Int16  bytes_sent, bytes_recv, text_remaining, out_data_type;
    194 +    pico_Retstring outMessage;
    195 +    
    196 +    picoSynthAbort = 0;
    197 +
    198 +    picoMemArea = malloc( PICO_MEM_SIZE );
    199 +    if((ret = pico_initialize( picoMemArea, PICO_MEM_SIZE, &picoSystem ))) {
    200 +        pico_getSystemStatusMessage(picoSystem, ret, outMessage);
    201 +        fprintf(stderr, "Cannot initialize pico (%i): %s\n", ret, outMessage);
    202 +        goto terminate;
    203 +    }
    204 +    
    205 +    /* Load the text analysis Lingware resource file.   */
    206 +    picoTaFileName      = (pico_Char *) malloc( PICO_MAX_DATAPATH_NAME_SIZE + PICO_MAX_FILE_NAME_SIZE );
    207 +    strcpy((char *) picoTaFileName,   PICO_LINGWARE_PATH);
    208 +    strcat((char *) picoTaFileName,   (const char *) picoInternalTaLingware[langIndex]);
    209 +    if((ret = pico_loadResource( picoSystem, picoTaFileName, &picoTaResource ))) {
    210 +        pico_getSystemStatusMessage(picoSystem, ret, outMessage);
    211 +        fprintf(stderr, "Cannot load text analysis resource file (%i): %s\n", ret, outMessage);
    212 +        goto unloadTaResource;
    213 +    }
    214 +    
    215 +    /* Load the signal generation Lingware resource file.   */
    216 +    picoSgFileName      = (pico_Char *) malloc( PICO_MAX_DATAPATH_NAME_SIZE + PICO_MAX_FILE_NAME_SIZE );
    217 +    strcpy((char *) picoSgFileName,   PICO_LINGWARE_PATH);
    218 +    strcat((char *) picoSgFileName,   (const char *) picoInternalSgLingware[langIndex]);
    219 +    if((ret = pico_loadResource( picoSystem, picoSgFileName, &picoSgResource ))) {
    220 +        pico_getSystemStatusMessage(picoSystem, ret, outMessage);
    221 +        fprintf(stderr, "Cannot load signal generation Lingware resource file (%i): %s\n", ret, outMessage);
    222 +        goto unloadSgResource;
    223 +    }
    224 + 
    225 +    /* Load the utpp Lingware resource file if exists - NOTE: this file is optional
    226 +       and is currently not used. Loading is only attempted for future compatibility.
    227 +       If this file is not present the loading will still succeed.                      //
    228 +    picoUtppFileName      = (pico_Char *) malloc( PICO_MAX_DATAPATH_NAME_SIZE + PICO_MAX_FILE_NAME_SIZE );
    229 +    strcpy((char *) picoUtppFileName,   PICO_LINGWARE_PATH);
    230 +    strcat((char *) picoUtppFileName,   (const char *) picoInternalUtppLingware[langIndex]);
    231 +    ret = pico_loadResource( picoSystem, picoUtppFileName, &picoUtppResource );
    232 +    pico_getSystemStatusMessage(picoSystem, ret, outMessage);
    233 +    printf("pico_loadResource: %i: %s\n", ret, outMessage);
    234 +    */
    235 +    
    236 +    /* Get the text analysis resource name.     */
    237 +    picoTaResourceName  = (pico_Char *) malloc( PICO_MAX_RESOURCE_NAME_SIZE );
    238 +    if((ret = pico_getResourceName( picoSystem, picoTaResource, (char *) picoTaResourceName ))) {
    239 +        pico_getSystemStatusMessage(picoSystem, ret, outMessage);
    240 +        fprintf(stderr, "Cannot get the text analysis resource name (%i): %s\n", ret, outMessage);
    241 +        goto unloadUtppResource;
    242 +    }
    243 +
    244 +    /* Get the signal generation resource name. */
    245 +    picoSgResourceName  = (pico_Char *) malloc( PICO_MAX_RESOURCE_NAME_SIZE );
    246 +    if((ret = pico_getResourceName( picoSystem, picoSgResource, (char *) picoSgResourceName ))) {
    247 +        pico_getSystemStatusMessage(picoSystem, ret, outMessage);
    248 +        fprintf(stderr, "Cannot get the signal generation resource name (%i): %s\n", ret, outMessage);
    249 +        goto unloadUtppResource;
    250 +    }
    251 +
    252 +
    253 +    /* Create a voice definition.   */
    254 +    if((ret = pico_createVoiceDefinition( picoSystem, (const pico_Char *) PICO_VOICE_NAME ))) {
    255 +        pico_getSystemStatusMessage(picoSystem, ret, outMessage);
    256 +        fprintf(stderr, "Cannot create voice definition (%i): %s\n", ret, outMessage);
    257 +        goto unloadUtppResource;
    258 +    }
    259 +
    260 +    /* Add the text analysis resource to the voice. */
    261 +    if((ret = pico_addResourceToVoiceDefinition( picoSystem, (const pico_Char *) PICO_VOICE_NAME, picoTaResourceName ))) {
    262 +        pico_getSystemStatusMessage(picoSystem, ret, outMessage);
    263 +        fprintf(stderr, "Cannot add the text analysis resource to the voice (%i): %s\n", ret, outMessage);
    264 +        goto unloadUtppResource;
    265 +    }
    266 +    
    267 +    /* Add the signal generation resource to the voice. */
    268 +    if((ret = pico_addResourceToVoiceDefinition( picoSystem, (const pico_Char *) PICO_VOICE_NAME, picoSgResourceName ))) {
    269 +        pico_getSystemStatusMessage(picoSystem, ret, outMessage);
    270 +        fprintf(stderr, "Cannot add the signal generation resource to the voice (%i): %s\n", ret, outMessage);
    271 +        goto unloadUtppResource;
    272 +    }
    273 +
    274 +    /* Create a new Pico engine. */
    275 +    if((ret = pico_newEngine( picoSystem, (const pico_Char *) PICO_VOICE_NAME, &picoEngine ))) {
    276 +        pico_getSystemStatusMessage(picoSystem, ret, outMessage);
    277 +        fprintf(stderr, "Cannot create a new pico engine (%i): %s\n", ret, outMessage);
    278 +        goto disposeEngine;
    279 +    }
    280 +    
    281 +    local_text = (pico_Char *) text ;
    282 +    text_remaining = strlen((const char *) local_text) + 1;
    283 +
    284 +    inp = (pico_Char *) local_text;
    285 +    
    286 +    size_t bufused = 0;
    287 +    
    288 +    picoos_Common common = (picoos_Common) pico_sysGetCommon(picoSystem);
    289 +
    290 +    picoos_SDFile sdOutFile = NULL;
    291 +
    292 +    picoos_bool done = TRUE;
    293 +    if(TRUE != (done = picoos_sdfOpenOut(common, &sdOutFile,
    294 +        (picoos_char *) wavefile, SAMPLE_FREQ_16KHZ, PICOOS_ENC_LIN)))
    295 +    {
    296 +        fprintf(stderr, "Cannot open output wave file\n");
    297 +        ret = 1;
    298 +        goto disposeEngine;
    299 +    }
    300 +    
    301 +    /* synthesis loop   */
    302 +    while (text_remaining) {
    303 +        /* Feed the text into the engine.   */
    304 +        if((ret = pico_putTextUtf8( picoEngine, inp, text_remaining, &bytes_sent ))) {
    305 +            pico_getSystemStatusMessage(picoSystem, ret, outMessage);
    306 +            fprintf(stderr, "Cannot put Text (%i): %s\n", ret, outMessage);
    307 +            goto disposeEngine;
    308 +        }
    309 +    
    310 +        text_remaining -= bytes_sent;
    311 +        inp += bytes_sent;
    312 +
    313 +        do {
    314 +            if (picoSynthAbort) {
    315 +                goto disposeEngine;
    316 +            }
    317 +            /* Retrieve the samples and add them to the buffer. */
    318 +            getstatus = pico_getData( picoEngine, (void *) outbuf,
    319 +                      MAX_OUTBUF_SIZE, &bytes_recv, &out_data_type );
    320 +            if((getstatus !=PICO_STEP_BUSY) && (getstatus !=PICO_STEP_IDLE)){
    321 +                pico_getSystemStatusMessage(picoSystem, getstatus, outMessage);
    322 +                fprintf(stderr, "Cannot get Data (%i): %s\n", getstatus, outMessage);
    323 +                goto disposeEngine;
    324 +            }
    325 +            if (bytes_recv) {
    326 +                if ((bufused + bytes_recv) <= bufferSize) {
    327 +                    memcpy(buffer+bufused, (int8_t *) outbuf, bytes_recv);
    328 +                    bufused += bytes_recv;
    329 +                } else {
    330 +                    done = picoos_sdfPutSamples(
    331 +                                        sdOutFile,
    332 +                                        bufused / 2,
    333 +                                        (picoos_int16*) (buffer));
    334 +                    bufused = 0;
    335 +                    memcpy(buffer, (int8_t *) outbuf, bytes_recv);
    336 +                    bufused += bytes_recv;
    337 +                }
    338 +            }
    339 +        } while (PICO_STEP_BUSY == getstatus);
    340 +        /* This chunk of synthesis is finished; pass the remaining samples. */
    341 +        if (!picoSynthAbort) {
    342 +                    done = picoos_sdfPutSamples(
    343 +                                        sdOutFile,
    344 +                                        bufused / 2,
    345 +                                        (picoos_int16*) (buffer));
    346 +        }
    347 +        picoSynthAbort = 0;
    348 +    }
    349 +    
    350 +    if(TRUE != (done = picoos_sdfCloseOut(common, &sdOutFile)))
    351 +    {
    352 +        fprintf(stderr, "Cannot close output wave file\n");
    353 +        ret = 1;
    354 +        goto disposeEngine;
    355 +    }
    356 +
    357 +disposeEngine:
    358 +    if (picoEngine) {
    359 +        pico_disposeEngine( picoSystem, &picoEngine );
    360 +        pico_releaseVoiceDefinition( picoSystem, (pico_Char *) PICO_VOICE_NAME );
    361 +        picoEngine = NULL;
    362 +    }
    363 +unloadUtppResource:
    364 +    if (picoUtppResource) {
    365 +        pico_unloadResource( picoSystem, &picoUtppResource );
    366 +        picoUtppResource = NULL;
    367 +    }
    368 +unloadSgResource:
    369 +    if (picoSgResource) {
    370 +        pico_unloadResource( picoSystem, &picoSgResource );
    371 +        picoSgResource = NULL;
    372 +    }
    373 +unloadTaResource:
    374 +    if (picoTaResource) {
    375 +        pico_unloadResource( picoSystem, &picoTaResource );
    376 +        picoTaResource = NULL;
    377 +    }
    378 +terminate:
    379 +    if (picoSystem) {
    380 +        pico_terminate(&picoSystem);
    381 +        picoSystem = NULL;
    382 +    }
    383 +    exit(ret);
    384 +}
    385 +
    386 diff --git a/pico/configure.in b/pico/configure.in
    387 index 0afb56d..349eb1d 100644
    388 --- a/pico/configure.in
    389 +++ b/pico/configure.in
    390 @@ -14,3 +14,6 @@ AC_CONFIG_FILES([Makefile])
    391  AC_OUTPUT
    392  
    393  AC_CONFIG_MACRO_DIR([m4])
    394 +
    395 +AC_CHECK_LIB(popt, poptGetContext)
    396 +
    397 -- 
    398 1.7.1
    399