diff options
Diffstat (limited to 'navit/support/espeak/speak.c')
-rw-r--r--[-rwxr-xr-x] | navit/support/espeak/speak.c | 177 |
1 files changed, 113 insertions, 64 deletions
diff --git a/navit/support/espeak/speak.c b/navit/support/espeak/speak.c index ab33a867b..afd9dfafd 100755..100644 --- a/navit/support/espeak/speak.c +++ b/navit/support/espeak/speak.c @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005 to 2007 by Jonathan Duddington * + * Copyright (C) 2005 to 2013 by Jonathan Duddington * * email: jonsd@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * @@ -24,9 +24,12 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <ctype.h> #ifndef PLATFORM_DOS #ifdef PLATFORM_WINDOWS +#include <fcntl.h> +#include <io.h> #include <windows.h> #include <winreg.h> #else @@ -36,6 +39,7 @@ #ifndef NEED_GETOPT #include <getopt.h> +#include <stdbool.h> // for "true" #endif #include <time.h> #include <signal.h> @@ -69,48 +73,52 @@ static const char *help_text = "\nspeak [options] [\"<words>\"]\n\n" "-f <text file> Text file to speak\n" "--stdin Read text input from stdin instead of a file\n\n" -"If neither -f nor --stdin, <words> are spoken, or if none then text is\n" -"spoken from stdin, each line separately.\n\n" +"If neither -f nor --stdin, then <words> are spoken, or if none then text\n" +"is spoken from stdin, each line separately.\n\n" "-a <integer>\n" "\t Amplitude, 0 to 200, default is 100\n" "-g <integer>\n" "\t Word gap. Pause between words, units of 10mS at the default speed\n" +"-k <integer>\n" +"\t Indicate capital letters with: 1=sound, 2=the word \"capitals\",\n" +"\t higher values indicate a pitch increase (try -k20).\n" "-l <integer>\n" "\t Line length. If not zero (which is the default), consider\n" "\t lines less than this length as end-of-clause\n" "-p <integer>\n" "\t Pitch adjustment, 0 to 99, default is 50\n" "-s <integer>\n" -"\t Speed in words per minute 80 to 390, default is 170\n" +"\t Speed in words per minute, 80 to 450, default is 175\n" "-v <voice name>\n" "\t Use voice file of this name from espeak-data/voices\n" "-w <wave file name>\n" -"\t Write output to this WAV file, rather than speaking it directly\n" +"\t Write speech to this WAV file, rather than speaking it directly\n" "-b\t Input text encoding, 1=UTF8, 2=8 bit, 4=16 bit \n" "-m\t Interpret SSML markup, and ignore other < > tags\n" "-q\t Quiet, don't produce any speech (may be useful with -x)\n" "-x\t Write phoneme mnemonics to stdout\n" "-X\t Write phonemes mnemonics and translation trace to stdout\n" "-z\t No final sentence pause at the end of the text\n" -"--stdout Write speech output to stdout\n" "--compile=<voice name>\n" -"\t Compile the pronunciation rules and dictionary in the current\n" -"\t directory. =<voice name> is optional and specifies which language\n" +"\t Compile pronunciation rules and dictionary from the current\n" +"\t directory. <voice name> specifies the language\n" +"--ipa Write phonemes to stdout using International Phonetic Alphabet\n" +"\t --ipa=1 Use ties, --ipa=2 Use ZWJ, --ipa=3 Separate with _\n" "--path=\"<path>\"\n" "\t Specifies the directory containing the espeak-data directory\n" +"--pho Write mbrola phoneme data (.pho) to stdout or to the file in --phonout\n" "--phonout=\"<filename>\"\n" -"\t Write output from -x -X commands and mbrola phoneme data to this file\n" +"\t Write phoneme output from -x -X --ipa and --pho to this file\n" "--punct=\"<characters>\"\n" "\t Speak the names of punctuation characters during speaking. If\n" "\t =<characters> is omitted, all punctuation is spoken.\n" "--split=\"<minutes>\"\n" "\t Starts a new WAV file every <minutes>. Used with -w\n" +"--stdout Write speech output to stdout\n" +"--version Shows version number and date, and location of espeak-data\n" "--voices=<language>\n" "\t List the available voices for the specified language.\n" -"\t If <language> is omitted, then list all voices.\n" -"-k <integer>\n" -"\t Indicate capital letters with: 1=sound, 2=the word \"capitals\",\n" -"\t higher values = a pitch increase (try -k20).\n"; +"\t If <language> is omitted, then list all voices.\n"; void DisplayVoices(FILE *f_out, char *language); @@ -155,14 +163,16 @@ void DisplayVoices(FILE *f_out, char *language) const char *p; int len; int count; - int scores = 0; + int c; + int j; const espeak_VOICE *v; const char *lang_name; char age_buf[12]; + char buf[80]; const espeak_VOICE **voices; espeak_VOICE voice_select; - static char genders[4] = {' ','M','F',' '}; + static char genders[4] = {'-','M','F','-'}; if((language != NULL) && (language[0] != 0)) { @@ -172,14 +182,13 @@ void DisplayVoices(FILE *f_out, char *language) voice_select.gender = 0; voice_select.name = NULL; voices = espeak_ListVoices(&voice_select); - scores = 1; } else { voices = espeak_ListVoices(NULL); } - fprintf(f_out,"Pty Language Age/Gender VoiceName File Other Langs\n"); + fprintf(f_out,"Pty Language Age/Gender VoiceName File Other Languages\n"); for(ix=0; (v = voices[ix]) != NULL; ix++) { @@ -197,8 +206,16 @@ void DisplayVoices(FILE *f_out, char *language) if(count==0) { - fprintf(f_out,"%2d %-12s%s%c %-17s %-11s ", - p[0],lang_name,age_buf,genders[v->gender],v->name,v->identifier); + for(j=0; j < sizeof(buf); j++) + { + // replace spaces in the name + if((c = v->name[j]) == ' ') + c = '_'; + if((buf[j] = c) == 0) + break; + } + fprintf(f_out,"%2d %-12s%s%c %-20s %-13s ", + p[0],lang_name,age_buf,genders[v->gender],buf,v->identifier); } else { @@ -207,14 +224,14 @@ void DisplayVoices(FILE *f_out, char *language) count++; p += len+2; } -// if(scores) -// fprintf(f_out,"%3d ",v->score); fputc('\n',f_out); } } // end of DisplayVoices - +void WVoiceChanged(voice_t *wvoice) +{ +} static int OpenWaveFile(const char *path, int rate) //================================================= @@ -229,10 +246,22 @@ static int OpenWaveFile(const char *path, int rate) if(path == NULL) return(2); - if(strcmp(path,"stdout")==0) - f_wave = stdout; - else - f_wave = fopen(path,"wb"); + while(isspace(*path)) path++; + + f_wave = NULL; + if(path[0] != 0) + { + if(strcmp(path,"stdout")==0) + { +#ifdef PLATFORM_WINDOWS +// prevent Windows adding 0x0d before 0x0a bytes + _setmode(_fileno(stdout), _O_BINARY); +#endif + f_wave = stdout; + } + else + f_wave = fopen(path,"wb"); + } if(f_wave != NULL) { @@ -274,7 +303,7 @@ static void CloseWaveFile() -void MarkerEvent(int type, unsigned int char_position, int value, unsigned char *out_ptr) +void MarkerEvent(int type, unsigned int char_position, int value, int value2, unsigned char *out_ptr) {//====================================================================================== // Do nothing in the command-line version. if(type == 2) @@ -285,7 +314,7 @@ void MarkerEvent(int type, unsigned int char_position, int value, unsigned char static int WavegenFile(void) {//========================= int finished; - unsigned char wav_outbuf[512]; + unsigned char wav_outbuf[1024]; char fname[210]; out_ptr = out_start = wav_outbuf; @@ -340,14 +369,12 @@ static void init_path(char *argv0, char *path_specified) char *env; unsigned char buf[sizeof(path_home)-12]; -#if 0 if(((env = getenv("ESPEAK_DATA_PATH")) != NULL) && ((strlen(env)+12) < sizeof(path_home))) { sprintf(path_home,"%s\\espeak-data",env); if(GetFileLength(path_home) == -2) return; // an espeak-data directory exists in the directory specified by environment variable } -#endif strcpy(path_home,argv0); if((p = strrchr(path_home,'\\')) != NULL) @@ -370,16 +397,13 @@ static void init_path(char *argv0, char *path_specified) strcpy(path_home,PATH_ESPEAK_DATA); #else char *env; -#if 0 if((env = getenv("ESPEAK_DATA_PATH")) != NULL) { snprintf(path_home,sizeof(path_home),"%s/espeak-data",env); if(GetFileLength(path_home) == -2) return; // an espeak-data directory exists } -#endif -#if 0 snprintf(path_home,sizeof(path_home),"%s/espeak-data",getenv("HOME")); if(access(path_home,R_OK) != 0) { @@ -387,7 +411,6 @@ static void init_path(char *argv0, char *path_specified) } #endif #endif -#endif } @@ -395,6 +418,7 @@ static int initialise(void) {//======================== int param; int result; + int srate = 22050; // default sample rate // It seems that the wctype functions don't work until the locale has been set // to something other than the default "C". Then, not only Latin1 but also the @@ -402,18 +426,15 @@ static int initialise(void) #ifdef PLATFORM_RISCOS setlocale(LC_CTYPE,"ISO8859-1"); #else -#if 0 if(setlocale(LC_CTYPE,"en_US.UTF-8") == NULL) { if(setlocale(LC_CTYPE,"UTF-8") == NULL) setlocale(LC_CTYPE,""); } #endif -#endif - WavegenInit(22050,0); // 22050 - if((result = LoadPhData()) != 1) + if((result = LoadPhData(&srate)) != 1) { if(result == -1) { @@ -423,8 +444,9 @@ static int initialise(void) else fprintf(stderr,"Wrong version of espeak-data 0x%x (expects 0x%x) at %s\n",result,version_phdata,path_home); } + WavegenInit(srate,0); LoadConfig(); - SetVoiceStack(NULL); + SetVoiceStack(NULL, ""); SynthesizeInit(); for(param=0; param<N_SPEECH_PARAM; param++) @@ -436,14 +458,16 @@ static int initialise(void) static void StopSpeak(int unused) {//============================== -// signal(SIGINT,SIG_IGN); + signal(SIGINT,SIG_IGN); // DEBUG // printf("\n*** Interrupting speech output (use Ctrl-D to actually quit).\n"); fflush(stdout); SpeakNextClause(NULL,NULL,5); -// signal(SIGINT,StopSpeak); + signal(SIGINT,StopSpeak); } // end of StopSpeak() + + #ifdef NEED_GETOPT struct option { char *name; @@ -480,7 +504,10 @@ int main (int argc, char **argv) {"stdout", no_argument, 0, 0x105}, {"split", optional_argument, 0, 0x106}, {"path", required_argument, 0, 0x107}, - {"phonout", required_argument, 0, 0x108}, + {"phonout", required_argument, 0, 0x108}, + {"pho", no_argument, 0, 0x109}, + {"ipa", optional_argument, 0, 0x10a}, + {"version", no_argument, 0, 0x10b}, {0, 0, 0, 0} }; @@ -493,7 +520,7 @@ int main (int argc, char **argv) int option_index = 0; int c; int value; - int speed=170; + int speed=175; int ix; char *optarg2; int amp = 100; // default @@ -505,11 +532,9 @@ int main (int argc, char **argv) espeak_VOICE voice_select; char filename[200]; char voicename[40]; - char dictname[40]; voicename[0] = 0; mbrola_name[0] = 0; - dictname[0] = 0; wavefile[0] = 0; filename[0] = 0; option_linelength = 0; @@ -544,6 +569,9 @@ int main (int argc, char **argv) if(c == '-') { + if(p[0] == 0) + break; // -- means don't interpret further - as commands + opt_string=""; for(ix=0; ;ix++) { @@ -574,7 +602,7 @@ int main (int argc, char **argv) } } #else - while(1) + while(true) { c = getopt_long (argc, argv, "a:b:f:g:hk:l:p:qs:v:w:xXmz", // NOTE: also change arg_opts to indicate which commands have a numeric value long_options, &option_index); @@ -595,9 +623,9 @@ int main (int argc, char **argv) break; case 'h': - printf("\nspeak text-to-speech: %s\n%s",version_string,help_text); + init_path(argv[0],data_path); + printf("\nspeak text-to-speech: %s Data at: %s\n%s",version_string,path_home,help_text); exit(0); - break; case 'k': option_capitals = atoi(optarg2); @@ -710,6 +738,30 @@ int main (int argc, char **argv) } break; + case 0x109: // --pho + option_mbrola_phonemes = 16; + break; + + case 0x10a: // --ipa + option_phonemes = 3; + if(optarg2 != NULL) + { + value = -1; + sscanf(optarg2,"%d",&value); + if((value<0) || (value>3)) + { + fprintf(stderr,"Bad value for -ipa=\n"); + value = 0; + } + option_phonemes += value; + } + break; + + case 0x10b: // --version + init_path(argv[0],data_path); + printf("speak text-to-speech: %s Data at: %s\n",version_string,path_home); + exit(0); + default: exit(0); } @@ -718,11 +770,22 @@ int main (int argc, char **argv) init_path(argv[0],data_path); initialise(); + if(voicename[0] == 0) + strcpy(voicename,"default"); - if(flag_compile) + if(SetVoiceByName(voicename) != EE_OK) { - LoadVoice(voicename,5); + memset(&voice_select,0,sizeof(voice_select)); + voice_select.languages = voicename; + if(SetVoiceByProperties(&voice_select) != EE_OK) + { + fprintf(stderr,"%svoice '%s'\n",err_load,voicename); + exit(2); + } + } + if(flag_compile) + { #ifdef PLATFORM_DOS char path_dsource[sizeof(path_home)+20]; strcpy(path_dsource,path_home); @@ -744,20 +807,6 @@ int main (int argc, char **argv) } - if(voicename[0] == 0) - strcpy(voicename,"default"); - - if(SetVoiceByName(voicename) != EE_OK) - { - memset(&voice_select,0,sizeof(voice_select)); - voice_select.languages = voicename; - if(SetVoiceByProperties(&voice_select) != EE_OK) - { - fprintf(stderr,"%svoice '%s'\n",err_load,voicename); - exit(2); - } - } - SetParameter(espeakRATE,speed,0); SetParameter(espeakVOLUME,amp,0); SetParameter(espeakCAPITALS,option_capitals,0); |