summaryrefslogtreecommitdiff
path: root/navit/support/espeak/speak.c
diff options
context:
space:
mode:
Diffstat (limited to 'navit/support/espeak/speak.c')
-rw-r--r--[-rwxr-xr-x]navit/support/espeak/speak.c177
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);