mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-11-07 15:24:02 +00:00
[1.40.09]
Changed -b option to include an option for 16 bit character input. numbers.cpp: Added option for vigesimal number systems for tens+units. Fixed problems with word-length indications in callback events. -m option now ignores XML comments. git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@216 d46cf337-b52f-0410-862d-fd96e6ae7743
This commit is contained in:
+9
-4
@@ -1030,8 +1030,8 @@ void ChangeWordStress(Translator *tr, char *word, int new_stress)
|
||||
|
||||
|
||||
|
||||
void SetWordStress(Translator *tr, char *output, unsigned int dictionary_flags, int tonic, int prev_stress)
|
||||
{//========================================================================================================
|
||||
void SetWordStress(Translator *tr, char *output, unsigned int &dictionary_flags, int tonic, int prev_stress)
|
||||
{//=========================================================================================================
|
||||
/* Guess stress pattern of word. This is language specific
|
||||
|
||||
'dictionary_flags' has bits 0-3 position of stressed vowel (if > 0)
|
||||
@@ -1109,6 +1109,13 @@ void SetWordStress(Translator *tr, char *output, unsigned int dictionary_flags,
|
||||
|
||||
max_stress = GetVowelStress(tr, phonetic, vowel_stress, vowel_count, stressed_syllable, 1);
|
||||
|
||||
if((max_stress == 0) && (tr->langopts.stress_flags & 1) && (vowel_count == 2))
|
||||
{
|
||||
// option: don't stress monosyllables except at end-of-clause
|
||||
vowel_stress[1] = 1;
|
||||
dictionary_flags |= FLAG_STRESS_END;
|
||||
}
|
||||
|
||||
// heavy or light syllables
|
||||
ix = 1;
|
||||
for(p = phonetic; *p != 0; p++)
|
||||
@@ -1219,8 +1226,6 @@ void SetWordStress(Translator *tr, char *output, unsigned int dictionary_flags,
|
||||
else
|
||||
{
|
||||
stressed_syllable = 1;
|
||||
if(stressflags & 0x1)
|
||||
max_stress = 3; // don't give full stress to monosyllables
|
||||
}
|
||||
|
||||
// only set the stress if it's not already marked explicitly
|
||||
|
||||
+8
-3
@@ -52,7 +52,7 @@ static const char *help_text =
|
||||
"\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"
|
||||
"-b\t Input text is 8-bit encoding\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"
|
||||
@@ -330,6 +330,7 @@ int main (int argc, char **argv)
|
||||
int option_index = 0;
|
||||
int c;
|
||||
int ix;
|
||||
int value;
|
||||
int flag_stdin = 0;
|
||||
int flag_compile = 0;
|
||||
int filesize = 0;
|
||||
@@ -362,7 +363,7 @@ int main (int argc, char **argv)
|
||||
|
||||
while(true)
|
||||
{
|
||||
c = getopt_long (argc, argv, "a:bf:g:hk:l:mp:qs:v:w:xXz",
|
||||
c = getopt_long (argc, argv, "a:b:f:g:hk:l:mp:qs:v:w:xXz",
|
||||
long_options, &option_index);
|
||||
|
||||
/* Detect the end of the options. */
|
||||
@@ -372,7 +373,11 @@ int main (int argc, char **argv)
|
||||
switch (c)
|
||||
{
|
||||
case 'b':
|
||||
synth_flags |= espeakCHARS_8BIT;
|
||||
// input character encoding, 8bit, 16bit, UTF8
|
||||
if((sscanf(optarg,"%d",&value) == 1) && (value <= 4))
|
||||
synth_flags |= value;
|
||||
else
|
||||
synth_flags |= espeakCHARS_8BIT;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
|
||||
+12
-8
@@ -192,7 +192,7 @@ t_espeak_command* create_espeak_mark(const void *text, size_t size, const char *
|
||||
//>
|
||||
//< create_espeak_key, create_espeak_char
|
||||
|
||||
t_espeak_command* create_espeak_key(const char *key_name)
|
||||
t_espeak_command* create_espeak_key(const char *key_name, void *user_data)
|
||||
{
|
||||
ENTER("create_espeak_key");
|
||||
int a_error=1;
|
||||
@@ -205,7 +205,9 @@ t_espeak_command* create_espeak_key(const char *key_name)
|
||||
|
||||
a_command->type = ET_KEY;
|
||||
a_command->state = CS_UNDEFINED;
|
||||
a_command->u.my_key = strdup( key_name);
|
||||
a_command->u.my_key.user_data = user_data;
|
||||
a_command->u.my_key.unique_identifier = ++my_current_text_id;
|
||||
a_command->u.my_key.key_name = strdup( key_name);
|
||||
a_error=0;
|
||||
|
||||
key_error:
|
||||
@@ -223,7 +225,7 @@ t_espeak_command* create_espeak_key(const char *key_name)
|
||||
return a_command;
|
||||
}
|
||||
|
||||
t_espeak_command* create_espeak_char(wchar_t character)
|
||||
t_espeak_command* create_espeak_char(wchar_t character, void* user_data)
|
||||
{
|
||||
ENTER("create_espeak_char");
|
||||
int a_error=1;
|
||||
@@ -235,7 +237,9 @@ t_espeak_command* create_espeak_char(wchar_t character)
|
||||
|
||||
a_command->type = ET_CHAR;
|
||||
a_command->state = CS_UNDEFINED;
|
||||
a_command->u.my_char = character;
|
||||
a_command->u.my_char.user_data = user_data;
|
||||
a_command->u.my_char.unique_identifier = ++my_current_text_id;
|
||||
a_command->u.my_char.character = character;
|
||||
a_error=0;
|
||||
|
||||
char_error:
|
||||
@@ -463,9 +467,9 @@ int delete_espeak_command( t_espeak_command* the_command)
|
||||
break;
|
||||
|
||||
case ET_KEY:
|
||||
if (the_command->u.my_key)
|
||||
if (the_command->u.my_key.key_name)
|
||||
{
|
||||
free((void*)(the_command->u.my_key));
|
||||
free((void*)(the_command->u.my_key.key_name));
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -562,14 +566,14 @@ void process_espeak_command( t_espeak_command* the_command)
|
||||
|
||||
case ET_KEY:
|
||||
{
|
||||
const char* data = the_command->u.my_key;
|
||||
const char* data = the_command->u.my_key.key_name;
|
||||
sync_espeak_Key(data);
|
||||
}
|
||||
break;
|
||||
|
||||
case ET_CHAR:
|
||||
{
|
||||
const wchar_t data = the_command->u.my_char;
|
||||
const wchar_t data = the_command->u.my_char.character;
|
||||
sync_espeak_Char( data);
|
||||
}
|
||||
break;
|
||||
|
||||
+20
-4
@@ -42,12 +42,28 @@ typedef struct
|
||||
void* user_data;
|
||||
} t_espeak_mark;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int unique_identifier;
|
||||
void* user_data;
|
||||
wchar_t character;
|
||||
} t_espeak_character;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int unique_identifier;
|
||||
void* user_data;
|
||||
const char* key_name;
|
||||
} t_espeak_key;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int unique_identifier;
|
||||
void* user_data;
|
||||
} t_espeak_terminated_msg;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
espeak_PARAMETER parameter;
|
||||
@@ -71,8 +87,8 @@ typedef struct
|
||||
{
|
||||
t_espeak_text my_text;
|
||||
t_espeak_mark my_mark;
|
||||
const char* my_key;
|
||||
wchar_t my_char;
|
||||
t_espeak_key my_key;
|
||||
t_espeak_character my_char;
|
||||
t_espeak_parameter my_param;
|
||||
const wchar_t* my_punctuation_list;
|
||||
const char *my_voice_name;
|
||||
@@ -88,9 +104,9 @@ t_espeak_command* create_espeak_mark(const void *text, size_t size, const char *
|
||||
|
||||
t_espeak_command* create_espeak_terminated_msg(unsigned int unique_identifier, void* user_data);
|
||||
|
||||
t_espeak_command* create_espeak_key(const char *key_name);
|
||||
t_espeak_command* create_espeak_key(const char *key_name, void *user_data);
|
||||
|
||||
t_espeak_command* create_espeak_char(wchar_t character);
|
||||
t_espeak_command* create_espeak_char(wchar_t character, void *user_data);
|
||||
|
||||
t_espeak_command* create_espeak_parameter(espeak_PARAMETER parameter, int value, int relative);
|
||||
|
||||
|
||||
+47
-22
@@ -747,6 +747,9 @@ void SetSpellingStress(Translator *tr, char *phonemes, int control, int n_chars)
|
||||
|
||||
|
||||
|
||||
// Numbers
|
||||
|
||||
static char ph_ordinal2[12];
|
||||
|
||||
int TranslateRoman(Translator *tr, char *word, char *ph_out)
|
||||
{//=====================================================
|
||||
@@ -905,13 +908,14 @@ static int LookupNum2(Translator *tr, int value, int control, char *ph_out)
|
||||
int found_ordinal = 0;
|
||||
int next_phtype;
|
||||
char string[12]; // for looking up entries in *_list
|
||||
char ph_ordinal[20];
|
||||
char ph_tens[50];
|
||||
char ph_digits[50];
|
||||
char ph_and[12];
|
||||
char ph_ordinal[12];
|
||||
|
||||
// is there a special pronunciation for this 2-digit number
|
||||
found = 0;
|
||||
ph_ordinal[0] = 0;
|
||||
|
||||
if(control & 4)
|
||||
{
|
||||
@@ -920,6 +924,8 @@ static int LookupNum2(Translator *tr, int value, int control, char *ph_out)
|
||||
}
|
||||
if(control & 2)
|
||||
{
|
||||
strcpy(ph_ordinal, ph_ordinal2);
|
||||
|
||||
sprintf(string,"_%do",value);
|
||||
if((found = Lookup(tr, string, ph_digits)) != 0)
|
||||
{
|
||||
@@ -969,6 +975,14 @@ static int LookupNum2(Translator *tr, int value, int control, char *ph_out)
|
||||
Lookup(tr, string, ph_tens);
|
||||
}
|
||||
|
||||
if((ph_tens[0] == 0) && (tr->langopts.numbers & NUM_VIGESIMAL))
|
||||
{
|
||||
// tens not found, (for example) 73 is 60+13
|
||||
units = (value % 20);
|
||||
sprintf(string,"_%dX",(value / 10) & 0xfe);
|
||||
Lookup(tr, string, ph_tens);
|
||||
}
|
||||
|
||||
ph_digits[0] = 0;
|
||||
if(units > 0)
|
||||
{
|
||||
@@ -997,8 +1011,7 @@ static int LookupNum2(Translator *tr, int value, int control, char *ph_out)
|
||||
}
|
||||
}
|
||||
|
||||
ph_ordinal[0] = 0;
|
||||
if((control & 2) && (found_ordinal == 0))
|
||||
if((control & 2) && (found_ordinal == 0) && (ph_ordinal[0] == 0))
|
||||
{
|
||||
if((value >= 20) && (((value % 10) == 0) || (tr->langopts.numbers & 0x10)))
|
||||
Lookup(tr, "_ord20", ph_ordinal);
|
||||
@@ -1196,10 +1209,6 @@ static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null
|
||||
} // end of LookupNum3
|
||||
|
||||
|
||||
static const char *ordinalstr_en[] = {"th","st","nd","rd",NULL,};
|
||||
static const char *ordinalstr_af[] = {"de","ste",NULL,};
|
||||
static const char **ordinal_strings[] = {NULL, ordinalstr_en, ordinalstr_af};
|
||||
|
||||
static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned int *flags, int wflags)
|
||||
{//====================================================================================================
|
||||
// Number translation with various options
|
||||
@@ -1208,7 +1217,7 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned
|
||||
|
||||
int n_digits;
|
||||
int value;
|
||||
int ix;
|
||||
unsigned int ix;
|
||||
unsigned char c;
|
||||
int suppress_null = 0;
|
||||
int decimal_point = 0;
|
||||
@@ -1221,41 +1230,57 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned
|
||||
int decimal_count;
|
||||
int max_decimal_count;
|
||||
int decimal_mode;
|
||||
int len;
|
||||
const char *p;
|
||||
const char **pp;
|
||||
char string[12]; // for looking up entries in de_list
|
||||
int hyphen;
|
||||
char *p;
|
||||
char string[20]; // for looking up entries in **_list
|
||||
char buf1[100];
|
||||
char ph_append[50];
|
||||
char ph_buf[200];
|
||||
char ph_buf2[50];
|
||||
char suffix[20];
|
||||
|
||||
static const char str_pause[2] = {phonPAUSE_NOLINK,0};
|
||||
|
||||
*flags = 0;
|
||||
|
||||
for(ix=0; isdigit(word[ix]); ix++) ;
|
||||
n_digits = ix;
|
||||
value = this_value = atoi(word);
|
||||
|
||||
ph_ordinal2[0] = 0;
|
||||
if((tr->langopts.numbers & 0x10000) && (word[ix] == '.'))
|
||||
{
|
||||
// ordinal number
|
||||
// ordinal number is indicated by dot after the number
|
||||
ordinal = 2;
|
||||
word[ix] = ' ';
|
||||
}
|
||||
else
|
||||
if(tr->langopts.ordinals)
|
||||
{
|
||||
// ordinal numbers are recognized by letters after the number
|
||||
// look for an ordinal number suffix after the number
|
||||
ix++;
|
||||
pp = ordinal_strings[tr->langopts.ordinals];
|
||||
while((p = *pp++) != NULL)
|
||||
hyphen = 0;
|
||||
p = suffix;
|
||||
if(word[ix] == '-')
|
||||
{
|
||||
len = strlen(p);
|
||||
if((word[ix+len] == ' ') && (memcmp(&word[ix], p, len) == 0))
|
||||
*p++ = '-';
|
||||
hyphen = 1;
|
||||
ix += 2;
|
||||
}
|
||||
while((word[ix] != 0) && (word[ix] != ' ') && (ix < (sizeof(suffix)-1)))
|
||||
{
|
||||
*p++ = word[ix++];
|
||||
}
|
||||
*p = 0;
|
||||
|
||||
if(suffix[0] != 0)
|
||||
{
|
||||
sprintf(string,"_0%s",suffix);
|
||||
if(Lookup(tr, string, ph_ordinal2))
|
||||
{
|
||||
// this is an ordinal suffix
|
||||
ordinal = 2;
|
||||
memset(&word[ix], ' ', len);
|
||||
break;
|
||||
flags[0] |= FLAG_SKIPWORDS;
|
||||
dictionary_skipwords = 1 + hyphen;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1462,7 +1487,7 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned
|
||||
strcat(ph_out,str_pause); // don't add pause for 100s, 6th, etc.
|
||||
}
|
||||
|
||||
*flags = FLAG_FOUND;
|
||||
*flags |= FLAG_FOUND;
|
||||
prev_value = this_value;
|
||||
return(1);
|
||||
} // end of TranslateNumber_1
|
||||
|
||||
+75
-44
@@ -51,7 +51,7 @@ char *namedata = NULL;
|
||||
|
||||
static FILE *f_input = NULL;
|
||||
static int ungot_char2 = 0;
|
||||
char *p_textinput;
|
||||
unsigned char *p_textinput;
|
||||
wchar_t *p_wchar_input;
|
||||
static int ungot_char;
|
||||
static const char *ungot_word = NULL;
|
||||
@@ -373,13 +373,21 @@ int Eof(void)
|
||||
|
||||
static int GetC_get(void)
|
||||
{//======================
|
||||
int c;
|
||||
unsigned int c;
|
||||
unsigned int c2;
|
||||
|
||||
if(f_input != NULL)
|
||||
{
|
||||
c = fgetc(f_input);
|
||||
if(feof(f_input)) c = ' ';
|
||||
return(c & 0xff);
|
||||
|
||||
if(option_multibyte == espeakCHARS_16BIT)
|
||||
{
|
||||
c2 = fgetc(f_input);
|
||||
if(feof(f_input)) c2 = 0;
|
||||
c = c + (c2 << 8);
|
||||
}
|
||||
return(c);
|
||||
}
|
||||
|
||||
if(option_multibyte == espeakCHARS_WCHAR)
|
||||
@@ -402,7 +410,15 @@ static int GetC_get(void)
|
||||
}
|
||||
|
||||
if(!end_of_input)
|
||||
{
|
||||
if(option_multibyte == espeakCHARS_16BIT)
|
||||
{
|
||||
c = p_textinput[0] + (p_textinput[1] << 8);
|
||||
p_textinput += 2;
|
||||
return(c);
|
||||
}
|
||||
return(*p_textinput++ & 0xff);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
@@ -440,7 +456,7 @@ static int GetC(void)
|
||||
c1 = GetC_get();
|
||||
}
|
||||
|
||||
if(option_multibyte == espeakCHARS_WCHAR)
|
||||
if((option_multibyte == espeakCHARS_WCHAR) || (option_multibyte == espeakCHARS_16BIT))
|
||||
{
|
||||
count_characters++;
|
||||
return(c1); // wchar_t text
|
||||
@@ -1862,8 +1878,8 @@ static MNEM_TAB xml_char_mnemonics[] = {
|
||||
{NULL,-1}};
|
||||
|
||||
|
||||
int ReadClause(Translator *tr, FILE *f_in, char *buf, short *charix, int n_buf, int *tone_type)
|
||||
{//============================================================================================
|
||||
int ReadClause(Translator *tr, FILE *f_in, char *buf, short *charix, int *charix_top, int n_buf, int *tone_type)
|
||||
{//=============================================================================================================
|
||||
/* Find the end of the current clause.
|
||||
Write the clause into buf
|
||||
|
||||
@@ -2031,49 +2047,62 @@ f_input = f_in; // for GetC etc
|
||||
}
|
||||
}
|
||||
else
|
||||
if((c1 == '<') && (ssml_ignore_l_angle != '<') && ((c2 == '/') || iswalpha(c2)))
|
||||
if((c1 == '<') && (ssml_ignore_l_angle != '<'))
|
||||
{
|
||||
// SSML Tag
|
||||
n_xml_buf = 0;
|
||||
c1 = c2;
|
||||
while(!Eof() && (c1 != '>') && (n_xml_buf < N_XML_BUF))
|
||||
if(c2 == '!')
|
||||
{
|
||||
xml_buf[n_xml_buf++] = c1;
|
||||
c1 = GetC();
|
||||
}
|
||||
xml_buf[n_xml_buf] = 0;
|
||||
c2 = ' ';
|
||||
|
||||
buf[ix++] = ' ';
|
||||
|
||||
self_closing = 0;
|
||||
if(xml_buf[n_xml_buf-1] == '/')
|
||||
{
|
||||
// a self-closing tag
|
||||
xml_buf[n_xml_buf-1] = ' ';
|
||||
self_closing = 1;
|
||||
}
|
||||
|
||||
terminator = ProcessSsmlTag(xml_buf,buf,ix,n_buf,self_closing);
|
||||
|
||||
if(terminator != 0)
|
||||
{
|
||||
buf[ix] = ' ';
|
||||
buf[ix++] = 0;
|
||||
|
||||
if(terminator & CLAUSE_BIT_VOICE)
|
||||
// a comment, ignore until closing '<'
|
||||
while(!Eof() && (c1 != '>'))
|
||||
{
|
||||
// a change in voice, write the new voice name to the end of the buf
|
||||
p = current_voice_id;
|
||||
while((*p != 0) && (ix < (n_buf-1)))
|
||||
{
|
||||
buf[ix++] = *p++;
|
||||
}
|
||||
buf[ix++] = 0;
|
||||
c1 = GetC();
|
||||
}
|
||||
return(terminator);
|
||||
c2 = ' ';
|
||||
}
|
||||
else
|
||||
if((c2 == '/') || iswalpha(c2))
|
||||
{
|
||||
// SSML Tag
|
||||
n_xml_buf = 0;
|
||||
c1 = c2;
|
||||
while(!Eof() && (c1 != '>') && (n_xml_buf < N_XML_BUF))
|
||||
{
|
||||
xml_buf[n_xml_buf++] = c1;
|
||||
c1 = GetC();
|
||||
}
|
||||
xml_buf[n_xml_buf] = 0;
|
||||
c2 = ' ';
|
||||
|
||||
buf[ix++] = ' ';
|
||||
|
||||
self_closing = 0;
|
||||
if(xml_buf[n_xml_buf-1] == '/')
|
||||
{
|
||||
// a self-closing tag
|
||||
xml_buf[n_xml_buf-1] = ' ';
|
||||
self_closing = 1;
|
||||
}
|
||||
|
||||
terminator = ProcessSsmlTag(xml_buf,buf,ix,n_buf,self_closing);
|
||||
|
||||
if(terminator != 0)
|
||||
{
|
||||
buf[ix] = ' ';
|
||||
buf[ix++] = 0;
|
||||
|
||||
if(terminator & CLAUSE_BIT_VOICE)
|
||||
{
|
||||
// a change in voice, write the new voice name to the end of the buf
|
||||
p = current_voice_id;
|
||||
while((*p != 0) && (ix < (n_buf-1)))
|
||||
{
|
||||
buf[ix++] = *p++;
|
||||
}
|
||||
buf[ix++] = 0;
|
||||
}
|
||||
return(terminator);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ssml_ignore_l_angle=0;
|
||||
@@ -2087,6 +2116,7 @@ f_input = f_in; // for GetC etc
|
||||
if((punct = lookupwchar(punct_chars,c1)) == 0)
|
||||
{
|
||||
charix[ix] = count_characters - clause_start_char;
|
||||
*charix_top = ix;
|
||||
ix += utf8_out(c1,&buf[ix]);
|
||||
terminator = CLAUSE_PERIOD; // line doesn't end in punctuation, assume period
|
||||
}
|
||||
@@ -2342,6 +2372,7 @@ if(option_ssml) parag=1;
|
||||
while(j < ix)
|
||||
charix[j++] = -1; // subsequent bytes of a multibyte character
|
||||
}
|
||||
*charix_top = ix;
|
||||
|
||||
if(((ix > (n_buf-20)) && !IsAlpha(c1) && !iswdigit(c1)) || (ix >= (n_buf-2)))
|
||||
{
|
||||
|
||||
+5
-2
@@ -86,7 +86,7 @@ static const char *help_text =
|
||||
"\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"
|
||||
"-b\t Input text is 8-bit encoding\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"
|
||||
@@ -568,7 +568,7 @@ int main (int argc, char **argv)
|
||||
#else
|
||||
while(true)
|
||||
{
|
||||
c = getopt_long (argc, argv, "a:bf:g:hk:l:p:qs:v:w:xXmz",
|
||||
c = getopt_long (argc, argv, "a:b:f:g:hk:l:p:qs:v:w:xXmz",
|
||||
long_options, &option_index);
|
||||
|
||||
/* Detect the end of the options. */
|
||||
@@ -580,7 +580,10 @@ int main (int argc, char **argv)
|
||||
switch (c)
|
||||
{
|
||||
case 'b':
|
||||
// input character encoding, 8bit, 16bit, UTF8
|
||||
option_multibyte = espeakCHARS_8BIT;
|
||||
if((sscanf(optarg2,"%d",&value) == 1) && (value <= 4))
|
||||
option_multibyte= value;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
|
||||
+2
-2
@@ -884,7 +884,7 @@ ESPEAK_API espeak_ERROR espeak_Key(const char *key)
|
||||
}
|
||||
|
||||
#ifdef USE_ASYNC
|
||||
t_espeak_command* c = create_espeak_key( key);
|
||||
t_espeak_command* c = create_espeak_key( key, NULL);
|
||||
a_error = fifo_add_command(c);
|
||||
if (a_error != EE_OK)
|
||||
{
|
||||
@@ -910,7 +910,7 @@ ESPEAK_API espeak_ERROR espeak_Char(wchar_t character)
|
||||
return(EE_OK);
|
||||
}
|
||||
|
||||
t_espeak_command* c = create_espeak_char( character);
|
||||
t_espeak_command* c = create_espeak_char( character, NULL);
|
||||
a_error = fifo_add_command(c);
|
||||
if (a_error != EE_OK)
|
||||
{
|
||||
|
||||
+4
-1
@@ -27,7 +27,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define ESPEAK_API_REVISION 3
|
||||
#define ESPEAK_API_REVISION 5
|
||||
/*
|
||||
Revision 2
|
||||
Added parameter "options" to eSpeakInitialize()
|
||||
@@ -38,6 +38,8 @@ Revision 3
|
||||
Revision 4
|
||||
Added flags parameter to espeak_CompileDictionary()
|
||||
|
||||
Revision 5
|
||||
Added espeakCHARS_16BIT
|
||||
*/
|
||||
/********************/
|
||||
/* Initialization */
|
||||
@@ -227,6 +229,7 @@ int UriCallback(int type, const char *uri, const char *base);
|
||||
#define espeakCHARS_UTF8 1
|
||||
#define espeakCHARS_8BIT 2
|
||||
#define espeakCHARS_WCHAR 3
|
||||
#define espeakCHARS_16BIT 4
|
||||
|
||||
#define espeakSSML 0x10
|
||||
#define espeakPHONEMES 0x100
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@
|
||||
#include "translate.h"
|
||||
#include "wave.h"
|
||||
|
||||
const char *version_string = "1.40.07 13.Jan.09";
|
||||
const char *version_string = "1.40.09 11.Mar.09";
|
||||
const int version_phdata = 0x014000;
|
||||
|
||||
int option_device_number = -1;
|
||||
|
||||
+16
-6
@@ -263,7 +263,6 @@ Translator *SelectTranslator(const char *name)
|
||||
SetLetterVowel(tr,'y'); // add 'y' to vowels
|
||||
|
||||
tr->langopts.numbers = 0x8d1 + NUM_ROMAN;
|
||||
tr->langopts.ordinals = 2;
|
||||
tr->langopts.accents = 1;
|
||||
}
|
||||
break;
|
||||
@@ -345,7 +344,6 @@ Translator *SelectTranslator(const char *name)
|
||||
|
||||
tr->langopts.stress_rule = 0;
|
||||
tr->langopts.numbers = 0x841 + NUM_ROMAN;
|
||||
tr->langopts.ordinals = 1;
|
||||
tr->langopts.param[LOPT_COMBINE_WORDS] = 2; // allow "mc" to cmbine with the following word
|
||||
}
|
||||
break;
|
||||
@@ -446,6 +444,17 @@ Translator *SelectTranslator(const char *name)
|
||||
break;
|
||||
|
||||
|
||||
case L('e','u'): // basque
|
||||
{
|
||||
static const short stress_lengths_eu[8] = {200, 200, 200, 200, 0, 0, 210, 230}; // very weak stress
|
||||
static const unsigned char stress_amps_eu[8] = {16,16, 18,18, 18,18, 18,18 };
|
||||
SetupTranslator(tr,stress_lengths_eu,stress_amps_eu);
|
||||
tr->langopts.stress_rule = 1; // ?? second syllable ??
|
||||
tr->langopts.numbers = 0x569 + NUM_VIGESIMAL;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case L('f','i'): // Finnish
|
||||
{
|
||||
static const unsigned char stress_amps_fi[8] = {18,16, 22,22, 20,22, 22,22 };
|
||||
@@ -466,6 +475,7 @@ Translator *SelectTranslator(const char *name)
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case L('f','r'): // french
|
||||
{
|
||||
static const short stress_lengths_fr[8] = {190, 170, 190, 200, 0, 0, 235, 240};
|
||||
@@ -473,10 +483,10 @@ Translator *SelectTranslator(const char *name)
|
||||
|
||||
SetupTranslator(tr,stress_lengths_fr,stress_amps_fr);
|
||||
tr->langopts.stress_rule = 3; // stress on final syllable
|
||||
tr->langopts.stress_flags = 0x0024; // don't use secondary stress
|
||||
tr->langopts.stress_flags = 0x0024 + 0x1; // don't use secondary stress, monosyllables are unstressed
|
||||
tr->langopts.param[LOPT_IT_LENGTHEN] = 1; // remove lengthen indicator from unstressed syllables
|
||||
|
||||
tr->langopts.numbers = 0x1509 + 0x8000 + NUM_NOPAUSE | NUM_ROMAN;
|
||||
tr->langopts.numbers = 0x1509 + 0x8000 + NUM_NOPAUSE | NUM_ROMAN | NUM_VIGESIMAL;
|
||||
SetLetterVowel(tr,'y');
|
||||
}
|
||||
break;
|
||||
@@ -958,7 +968,7 @@ SetLengthMods(tr,3); // all equal
|
||||
SetupTranslator(tr,stress_lengths_th,stress_amps_th);
|
||||
|
||||
tr->langopts.stress_rule = 0; // stress on final syllable of a "word"
|
||||
tr->langopts.stress_flags = 1; // don't automatically set diminished stress (may be set in the intonation module)
|
||||
tr->langopts.stress_flags = 2; // don't automatically set diminished stress (may be set in the intonation module)
|
||||
tr->langopts.tone_language = 1; // Tone language, use CalcPitches_Tone() rather than CalcPitches()
|
||||
tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
|
||||
// tr->langopts.tone_numbers = 1; // a number after letters indicates a tone number (eg. pinyin or jyutping)
|
||||
@@ -1024,7 +1034,7 @@ SetLengthMods(tr,3); // all equal
|
||||
SetupTranslator(tr,stress_lengths_zh,stress_amps_zh);
|
||||
|
||||
tr->langopts.stress_rule = 3; // stress on final syllable of a "word"
|
||||
tr->langopts.stress_flags = 1; // don't automatically set diminished stress (may be set in the intonation module)
|
||||
tr->langopts.stress_flags = 2; // don't automatically set diminished stress (may be set in the intonation module)
|
||||
tr->langopts.vowel_pause = 0;
|
||||
tr->langopts.tone_language = 1; // Tone language, use CalcPitches_Tone() rather than CalcPitches()
|
||||
tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
|
||||
|
||||
+29
-21
@@ -86,7 +86,7 @@ PHONEME_LIST2 ph_list2[N_PHONEME_LIST]; // first stage of text->phonemes
|
||||
|
||||
wchar_t option_punctlist[N_PUNCTLIST]={0};
|
||||
char ctrl_embedded = '\001'; // to allow an alternative CTRL for embedded commands
|
||||
int option_multibyte=espeakCHARS_AUTO; // 0=auto, 1=utf8, 2=8bit, 3=wchar
|
||||
int option_multibyte=espeakCHARS_AUTO; // 0=auto, 1=utf8, 2=8bit, 3=wchar, 4=16bit
|
||||
|
||||
// these are overridden by defaults set in the "speak" file
|
||||
int option_linelength = 0;
|
||||
@@ -1950,7 +1950,7 @@ void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *t
|
||||
int finished;
|
||||
int single_quoted;
|
||||
int phoneme_mode = 0;
|
||||
int dict_flags; // returned from dictionary lookup
|
||||
int dict_flags = 0; // returned from dictionary lookup
|
||||
int word_flags; // set here
|
||||
int next_word_flags;
|
||||
int embedded_count = 0;
|
||||
@@ -1962,8 +1962,9 @@ void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *t
|
||||
char *p;
|
||||
int j, k;
|
||||
int n_digits;
|
||||
int charix_top;
|
||||
|
||||
short charix[N_TR_SOURCE+1];
|
||||
short charix[N_TR_SOURCE+4];
|
||||
WORD_TAB words[N_CLAUSE_WORDS];
|
||||
int word_count=0; // index into words
|
||||
|
||||
@@ -1973,7 +1974,7 @@ void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *t
|
||||
int tone;
|
||||
int tone2;
|
||||
|
||||
p_textinput = (char *)vp_input;
|
||||
p_textinput = (unsigned char *)vp_input;
|
||||
p_wchar_input = (wchar_t *)vp_input;
|
||||
|
||||
embedded_ix = 0;
|
||||
@@ -1987,9 +1988,11 @@ void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *t
|
||||
|
||||
for(ix=0; ix<N_TR_SOURCE; ix++)
|
||||
charix[ix] = 0;
|
||||
terminator = ReadClause(tr, f_text, source, charix, N_TR_SOURCE, &tone2);
|
||||
terminator = ReadClause(tr, f_text, source, charix, &charix_top, N_TR_SOURCE, &tone2);
|
||||
|
||||
charix[N_TR_SOURCE] = count_characters;
|
||||
charix[charix_top+1] = 0;
|
||||
charix[charix_top+2] = 0x7fff;
|
||||
charix[charix_top+3] = 0;
|
||||
|
||||
clause_pause = (terminator & 0xfff) * 10; // mS
|
||||
tone = (terminator >> 12) & 0xf;
|
||||
@@ -2454,18 +2457,16 @@ if((c == '/') && (tr->langopts.testing & 2) && IsDigit09(next_in) && IsAlpha(pre
|
||||
|
||||
if(IsSpace(c))
|
||||
{
|
||||
if(space_inserted)
|
||||
{
|
||||
source_index = prev_source_index; // rewind to the previous character
|
||||
char_inserted = 0;
|
||||
space_inserted = 0;
|
||||
}
|
||||
|
||||
if(prev_out == ' ')
|
||||
{
|
||||
continue; // multiple spaces
|
||||
}
|
||||
|
||||
if(space_inserted)
|
||||
{
|
||||
words[word_count].length = source_index - words[word_count].sourceix;
|
||||
}
|
||||
|
||||
// end of 'word'
|
||||
sbuf[ix++] = ' ';
|
||||
|
||||
@@ -2516,6 +2517,13 @@ if((c == '/') && (tr->langopts.testing & 2) && IsDigit09(next_in) && IsAlpha(pre
|
||||
all_upper_case = FLAG_ALL_UPPER;
|
||||
syllable_marked = 0;
|
||||
}
|
||||
|
||||
if(space_inserted)
|
||||
{
|
||||
source_index = prev_source_index; // rewind to the previous character
|
||||
char_inserted = 0;
|
||||
space_inserted = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2644,12 +2652,12 @@ if((c == '/') && (tr->langopts.testing & 2) && IsDigit09(next_in) && IsAlpha(pre
|
||||
|
||||
// include the next few characters, in case there are an ordinal indicator
|
||||
pn[0] = ' ';
|
||||
memcpy(pn+1, pw, 5);
|
||||
pn[5] = 0;
|
||||
memcpy(pn+1, pw, 8);
|
||||
pn[8] = 0;
|
||||
|
||||
for(pw = &number_buf[1]; pw < pn;)
|
||||
{
|
||||
TranslateWord2(tr, pw, &words[ix], words[ix].pre_pause,0 );
|
||||
dict_flags = TranslateWord2(tr, pw, &words[ix], words[ix].pre_pause,0 );
|
||||
while(*pw++ != ' ');
|
||||
words[ix].pre_pause = 0;
|
||||
words[ix].flags = 0;
|
||||
@@ -2679,11 +2687,6 @@ if((c == '/') && (tr->langopts.testing & 2) && IsDigit09(next_in) && IsAlpha(pre
|
||||
}
|
||||
}
|
||||
|
||||
if(dict_flags & FLAG_SKIPWORDS)
|
||||
{
|
||||
ix += dictionary_skipwords; // dictionary indicates skip next word(s)
|
||||
}
|
||||
|
||||
if((dict_flags & FLAG_DOT) && (ix == word_count-1) && (terminator == CLAUSE_PERIOD))
|
||||
{
|
||||
// probably an abbreviation such as Mr. or B. rather than end of sentence
|
||||
@@ -2691,6 +2694,11 @@ if((c == '/') && (tr->langopts.testing & 2) && IsDigit09(next_in) && IsAlpha(pre
|
||||
tone = 4;
|
||||
}
|
||||
}
|
||||
|
||||
if(dict_flags & FLAG_SKIPWORDS)
|
||||
{
|
||||
ix += dictionary_skipwords; // dictionary indicates skip next word(s)
|
||||
}
|
||||
}
|
||||
|
||||
for(ix=0; ix<2; ix++)
|
||||
|
||||
+6
-5
@@ -301,7 +301,7 @@ typedef struct {
|
||||
int vowel_pause;
|
||||
int stress_rule; // 1=first syllable, 2=penultimate, 3=last
|
||||
|
||||
// bit0=don't stress monosyllables,
|
||||
// bit0=don't stress monosyllables, except at end of clause
|
||||
// bit1=don't set diminished stress,
|
||||
// bit2=mark unstressed final syllables as diminished
|
||||
// bit4=don't allow secondary stress on last syllable
|
||||
@@ -328,6 +328,7 @@ typedef struct {
|
||||
#define NUM_ROMAN_UC 0x40000
|
||||
#define NUM_NOPAUSE 0x80000
|
||||
#define NUM_ROMAN_AFTER 0x200000
|
||||
#define NUM_VIGESIMAL 0x400000
|
||||
|
||||
// bits0-1=which numbers routine to use.
|
||||
// bit2= thousands separator must be space
|
||||
@@ -348,6 +349,7 @@ typedef struct {
|
||||
// bit19=don't add pause after a number
|
||||
// bit20='and' before hundreds
|
||||
// bit21= say "roman" after the number, not before
|
||||
// bit22= vigesimal number, if tens are not found
|
||||
int numbers;
|
||||
|
||||
#define NUM2_100000 0x800 // numbers for 100,000 and 10,000,000
|
||||
@@ -364,7 +366,6 @@ typedef struct {
|
||||
int max_roman;
|
||||
int thousands_sep;
|
||||
int decimal_sep;
|
||||
int ordinals;
|
||||
|
||||
// bit 0, accent name before the letter name, bit 1 "capital" after letter name
|
||||
int accents;
|
||||
@@ -514,7 +515,7 @@ extern Translator *translator2;
|
||||
extern const unsigned short *charsets[N_CHARSETS];
|
||||
extern char dictionary_name[40];
|
||||
extern char ctrl_embedded; // to allow an alternative CTRL for embedded commands
|
||||
extern char *p_textinput;
|
||||
extern unsigned char *p_textinput;
|
||||
extern wchar_t *p_wchar_input;
|
||||
extern int dictionary_skipwords;
|
||||
|
||||
@@ -568,11 +569,11 @@ void CalcPitches(Translator *tr, int clause_tone);
|
||||
|
||||
int RemoveEnding(Translator *tr, char *word, int end_type, char *word_copy);
|
||||
int Unpronouncable(Translator *tr, char *word);
|
||||
void SetWordStress(Translator *tr, char *output, unsigned int dictionary_flags, int tonic, int prev_stress);
|
||||
void SetWordStress(Translator *tr, char *output, unsigned int &dictionary_flags, int tonic, int prev_stress);
|
||||
int TranslateRules(Translator *tr, char *p, char *phonemes, int size, char *end_phonemes, int end_flags, unsigned int *dict_flags);
|
||||
int TranslateWord(Translator *tr, char *word1, int next_pause, WORD_TAB *wtab);
|
||||
void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *tone, char **voice_change);
|
||||
int ReadClause(Translator *tr, FILE *f_in, char *buf, short *charix, int n_buf, int *tone_type);
|
||||
int ReadClause(Translator *tr, FILE *f_in, char *buf, short *charix, int *charix_top, int n_buf, int *tone_type);
|
||||
|
||||
void SetVoiceStack(espeak_VOICE *v);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user