[1.46.45]

Indian languages, rename aspirated phonemes with # instead of h (eg. [t#] not [th]).


git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@311 d46cf337-b52f-0410-862d-fd96e6ae7743
This commit is contained in:
jonsd
2013-03-10 13:58:09 +00:00
parent ad8798cf22
commit 6691b67f02
35 changed files with 2174 additions and 2172 deletions
+96 -106
View File
@@ -67,7 +67,8 @@ MNEM_TAB mnem_rules[] = {
{"p_alt5", 0x25},
{"p_alt6", 0x26},
{"p_alt", 0x21},
{NULL, -1} };
{NULL, -1}
};
MNEM_TAB mnem_flags[] = {
// these in the first group put a value in bits0-3 of dictionary_flags
@@ -182,13 +183,13 @@ const char *LookupMnemName(MNEM_TAB *table, const int value)
//==========================================================
/* Lookup a mnemonic string in a table, return its name */
{
while(table->mnem != NULL)
{
if(table->value==value)
return(table->mnem);
table++;
}
return(""); /* not found */
while(table->mnem != NULL)
{
if(table->value==value)
return(table->mnem);
table++;
}
return(""); /* not found */
} /* end of LookupMnemValue */
@@ -200,27 +201,27 @@ void print_dictionary_flags(unsigned int *flags, char *buf, int buf_len)
int len;
int total = 0;
buf[0] = 0;
buf[0] = 0;
if((stress = flags[0] & 0xf) != 0)
{
sprintf(buf, "%s", LookupMnemName(mnem_flags, stress + 0x40));
total = strlen(buf);
buf += total;
sprintf(buf, "%s", LookupMnemName(mnem_flags, stress + 0x40));
total = strlen(buf);
buf += total;
}
for(ix=8; ix<64; ix++)
{
if(((ix < 30) && (flags[0] & (1 << ix))) || ((ix >= 0x20) && (flags[1] & (1 << (ix-0x20)))))
{
name = LookupMnemName(mnem_flags, ix);
len = strlen(name) + 1;
total += len;
if(total >= buf_len)
continue;
sprintf(buf, " %s", name);
buf += len;
}
}
for(ix=8; ix<64; ix++)
{
if(((ix < 30) && (flags[0] & (1 << ix))) || ((ix >= 0x20) && (flags[1] & (1 << (ix-0x20)))))
{
name = LookupMnemName(mnem_flags, ix);
len = strlen(name) + 1;
total += len;
if(total >= buf_len)
continue;
sprintf(buf, " %s", name);
buf += len;
}
}
}
@@ -228,12 +229,12 @@ void print_dictionary_flags(unsigned int *flags, char *buf, int buf_len)
char *DecodeRule(const char *group_chars, int group_length, char *rule, int control)
{//=================================================================================
/* Convert compiled match template to ascii */
/* Convert compiled match template to ascii */
unsigned char rb;
unsigned char rb;
unsigned char c;
char *p;
int ix;
int ix;
int match_type;
int finished=0;
int value;
@@ -243,18 +244,20 @@ char *DecodeRule(const char *group_chars, int group_length, char *rule, int cont
int condition_num=0;
int at_start = 0;
const char *name;
char buf[60];
char buf_pre[60];
char buf[60];
char buf_pre[60];
char suffix[20];
static char output[60];
static char symbols[] = {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
'&','%','+','#','S','D','Z','A','L','!',' ','@','?','J','N','K','V','?','T','X','?','W'};
static char symbols[] =
{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
'&','%','+','#','S','D','Z','A','L','!',' ','@','?','J','N','K','V','?','T','X','?','W'
};
static char symbols_lg[] = {'A','B','C','H','F','G','Y'};
match_type = 0;
buf_pre[0] = 0;
buf_pre[0] = 0;
for(ix=0; ix<group_length; ix++)
{
@@ -263,8 +266,8 @@ char *DecodeRule(const char *group_chars, int group_length, char *rule, int cont
buf[ix] = 0;
p = &buf[strlen(buf)];
while(!finished)
{
while(!finished)
{
rb = *rule++;
if(rb <= RULE_LINENUM)
@@ -315,8 +318,7 @@ char *DecodeRule(const char *group_chars, int group_length, char *rule, int cont
}
c = ' ';
}
else
if(rb == RULE_ENDING)
else if(rb == RULE_ENDING)
{
static const char *flag_chars = "eipvdfq tba ";
flags = ((rule[0] & 0x7f)<< 8) + (rule[1] & 0x7f);
@@ -325,7 +327,7 @@ char *DecodeRule(const char *group_chars, int group_length, char *rule, int cont
suffix_char = 'P';
sprintf(suffix,"%c%d",suffix_char,rule[2] & 0x7f);
rule += 3;
for(ix=0;ix<9;ix++)
for(ix=0; ix<9; ix++)
{
if(flags & 1)
sprintf(&suffix[strlen(suffix)],"%c",flag_chars[ix]);
@@ -335,13 +337,11 @@ char *DecodeRule(const char *group_chars, int group_length, char *rule, int cont
p += strlen(suffix);
c = ' ';
}
else
if(rb == RULE_LETTERGP)
else if(rb == RULE_LETTERGP)
{
c = symbols_lg[*rule++ - 'A'];
}
else
if(rb == RULE_LETTERGP2)
else if(rb == RULE_LETTERGP2)
{
value = *rule++ - 'A';
p[0] = 'L';
@@ -355,11 +355,9 @@ char *DecodeRule(const char *group_chars, int group_length, char *rule, int cont
}
p+=2;
}
else
if(rb <= RULE_LAST_RULE)
else if(rb <= RULE_LAST_RULE)
c = symbols[rb];
else
if(rb == RULE_SPACE)
else if(rb == RULE_SPACE)
c = '_';
else
c = rb;
@@ -393,7 +391,7 @@ char *DecodeRule(const char *group_chars, int group_length, char *rule, int cont
while(ix < 8)
output[ix++]=' ';
output[ix]=0;
return(output);
return(output);
} /* end of DecodeRule */
@@ -427,7 +425,7 @@ static int compile_line(char *linebuf, char *dict_line, int *hash)
unsigned char flag_codes[100];
char encoded_ph[200];
unsigned char bad_phoneme[4];
static char nullstring[] = {0};
static char nullstring[] = {0};
text_not_phonemes = 0;
phonetic = word = nullstring;
@@ -500,13 +498,11 @@ static char nullstring[] = {0};
{
text_mode = 1;
}
else
if(flagnum == 201)
else if(flagnum == 201)
{
text_mode = 0;
}
else
if(flagnum == BITNUM_FLAG_TEXTMODE)
else if(flagnum == BITNUM_FLAG_TEXTMODE)
{
text_not_phonemes = 1;
}
@@ -536,8 +532,7 @@ static char nullstring[] = {0};
word = p+1;
step = 1;
}
else
if(!isspace2(c))
else if(!isspace2(c))
{
word = p;
step = 1;
@@ -571,8 +566,7 @@ static char nullstring[] = {0};
step = 3;
}
}
else
if(c == ')')
else if(c == ')')
{
if(multiple_words)
{
@@ -580,8 +574,7 @@ static char nullstring[] = {0};
multiple_words = 0;
step = 3;
}
else
if(word[0] != '_')
else if(word[0] != '_')
{
fprintf(f_log, "%5d: Missing '('\n", linenum);
error_count++;
@@ -595,8 +588,7 @@ static char nullstring[] = {0};
{
multiple_words++;
}
else
if(c == ')')
else if(c == ')')
{
p[0] = ' '; // terminate extra string
multiple_string_end = p+1;
@@ -641,8 +633,8 @@ static char nullstring[] = {0};
// This is a special word, used by eSpeak. Translate this into phonemes now
strcat(phonetic, " "); // need a space to indicate word-boundary
// PROBLEM vowel reductions are not applied to the translated phonemes
// condition rules are not applied
// PROBLEM vowel reductions are not applied to the translated phonemes
// condition rules are not applied
TranslateWord(translator,phonetic,0,NULL,NULL);
text_not_phonemes = 0;
strncpy0(encoded_ph, word_phonemes, N_WORD_BYTES-4);
@@ -653,11 +645,11 @@ static char nullstring[] = {0};
error_need_dictionary++;
fprintf(f_log,"%5d: Need to compile dictionary again\n",linenum);
}
{
{
//char decoded_phonemes[128];
//DecodePhonemes(word_phonemes,decoded_phonemes);
//printf("Translator %x %s [%s] [%s]\n",translator->translator_name,word,phonetic,decoded_phonemes);
}
}
}
else
{
@@ -694,8 +686,7 @@ static char nullstring[] = {0};
ix = utf8_out(wc, word);
word[ix] = 0;
}
else
if(word[0] != '_')
else if(word[0] != '_')
{
// convert to lower case, and note if the word is all-capitals
int c2;
@@ -1082,8 +1073,7 @@ static void copy_rule_string(char *string, int &state)
fprintf(f_log,"%5d: Expected 2 digits after 'L'\n",linenum);
error_count++;
}
else
if((c <= 0) || (c >= N_LETTER_GROUPS) || (letterGroupsDefined[(int)c] == 0))
else if((c <= 0) || (c >= N_LETTER_GROUPS) || (letterGroupsDefined[(int)c] == 0))
{
fprintf(f_log,"%5d: Letter group L%.2d not defined\n",linenum,c);
error_count++;
@@ -1162,9 +1152,9 @@ static void copy_rule_string(char *string, int &state)
case 'a':
sxflags |= SUFX_A;
break;
case 'm':
sxflags |= SUFX_M;
break;
case 'm':
sxflags |= SUFX_M;
break;
default:
if(isdigit(c))
value = (value*10) + (c - '0');
@@ -1376,11 +1366,11 @@ int __cdecl string_sorter(char **a, char **b)
char *pa, *pb;
int ix;
if((ix = strcmp(pa = *a,pb = *b)) != 0)
return(ix);
if((ix = strcmp(pa = *a,pb = *b)) != 0)
return(ix);
pa += (strlen(pa)+1);
pb += (strlen(pb)+1);
return(strcmp(pa,pb));
return(strcmp(pa,pb));
} /* end of string_sorter */
@@ -1471,12 +1461,12 @@ static void print_rule_group(FILE *f_out, int n_rules, char **rules, char *name)
if(rule_pre[0] != 0)
{
p = buf;
for(ix=strlen(rule_pre)-1;ix>=0;ix--)
for(ix=strlen(rule_pre)-1; ix>=0; ix--)
*p++ = rule_pre[ix];
sprintf(p,") ");
spaces -= strlen(buf);
for(ix=0; ix<spaces; ix++)
fputc(' ',f_out);
fputc(' ',f_out);
fprintf(f_out,"%s",buf);
spaces = 0;
}
@@ -1580,7 +1570,7 @@ static int compile_lettergroup(char *input, FILE *f_out)
int length;
int max_length = 0;
#define N_LETTERGP_ITEMS 200
#define N_LETTERGP_ITEMS 200
char *items[N_LETTERGP_ITEMS];
char item_length[N_LETTERGP_ITEMS];
@@ -1797,37 +1787,37 @@ static int compile_dictrules(FILE *f_in, FILE *f_out, char *fname_temp)
break;
case 2: // .replace
{
int replace1;
int replace2;
char *p;
{
int replace1;
int replace2;
char *p;
p = buf;
replace1 = 0;
replace2 = 0;
while(isspace2(*p)) p++;
ix = 0;
while((unsigned char)(*p) > 0x20) // not space or zero-byte
{
p += utf8_in(&c,p);
replace1 += (c << ix);
ix += 16;
}
while(isspace2(*p)) p++;
ix = 0;
while((unsigned char)(*p) > 0x20)
{
p += utf8_in(&c,p);
replace2 += (c << ix);
ix += 16;
}
if(replace1 != 0)
{
Write4Bytes(f_out,replace1); // write as little-endian
Write4Bytes(f_out,replace2); // if big-endian, reverse the bytes in LoadDictionary()
}
p = buf;
replace1 = 0;
replace2 = 0;
while(isspace2(*p)) p++;
ix = 0;
while((unsigned char)(*p) > 0x20) // not space or zero-byte
{
p += utf8_in(&c,p);
replace1 += (c << ix);
ix += 16;
}
break;
while(isspace2(*p)) p++;
ix = 0;
while((unsigned char)(*p) > 0x20)
{
p += utf8_in(&c,p);
replace2 += (c << ix);
ix += 16;
}
if(replace1 != 0)
{
Write4Bytes(f_out,replace1); // write as little-endian
Write4Bytes(f_out,replace2); // if big-endian, reverse the bytes in LoadDictionary()
}
}
break;
}
}
fclose(f_temp);
+272 -301
View File
File diff suppressed because it is too large Load Diff
+403 -405
View File
File diff suppressed because it is too large Load Diff
+13 -13
View File
@@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (C) 2005 to 2011 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 *
@@ -133,7 +133,7 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
PHONEME_LIST2 *plist2;
WORD_PH_DATA worddata;
memset(&worddata, 0, sizeof(worddata));
memset(&worddata, 0, sizeof(worddata));
plist2 = ph_list2;
phlist = phoneme_list;
end_sourceix = plist2[n_ph_list2-1].sourceix;
@@ -142,7 +142,7 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
max_stress = 0;
for(j = n_ph_list2-3; j>=0; j--)
{
// start with the last phoneme (before the terminating pauses) and move forwards
// start with the last phoneme (before the terminating pauses) and move backwards
if((plist2[j].stresslevel & 0x7f) > max_stress)
max_stress = plist2[j].stresslevel & 0x7f;
if(plist2[j].sourceix != 0)
@@ -204,21 +204,18 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
{
voicing = 1;
}
else
if((voicing==2) && (ph->end_type != 0)) // use end_type field for voicing_switch for consonants
else if((voicing==2) && (ph->end_type != 0)) // use end_type field for voicing_switch for consonants
{
plist2[j].phcode = ph->end_type; // change to voiced equivalent
}
}
else
if((type==phVSTOP) || type==(phVFRICATIVE))
else if((type==phVSTOP) || type==(phVFRICATIVE))
{
if((voicing==0) && (regression & 0xf))
{
voicing = 2;
}
else
if((voicing==1) && (ph->end_type != 0))
else if((voicing==1) && (ph->end_type != 0))
{
plist2[j].phcode = ph->end_type; // change to unvoiced equivalent
}
@@ -331,6 +328,9 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
if(plist3->phcode == phonSWITCH)
{
if((plist3[1].phcode == phonSWITCH) || ((plist3[1].type == phPAUSE) && (plist3[2].phcode == phonSWITCH)))
continue; // next phoneme is also a phonSWITCH, so ignore
// change phoneme table
SelectPhonemeTable(plist3->tone_ph);
switched_language ^= SFLAG_SWITCHED_LANG;
@@ -580,18 +580,18 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
phlist[ix].newword = 2; // end of clause
phlist[ix].phcode = phonPAUSE;
phlist[ix].type = phPAUSE; // terminate with 2 Pause phonemes
phlist[ix].type = phPAUSE; // terminate with 2 Pause phonemes
phlist[ix].length = post_pause; // length of the pause, depends on the punctuation
phlist[ix].sourceix = end_sourceix;
phlist[ix].synthflags = 0;
phlist[ix++].ph = phoneme_tab[phonPAUSE];
phlist[ix++].ph = phoneme_tab[phonPAUSE];
phlist[ix].phcode = phonPAUSE;
phlist[ix].type = phPAUSE;
phlist[ix].type = phPAUSE;
phlist[ix].length = 0;
phlist[ix].sourceix=0;
phlist[ix].synthflags = 0;
phlist[ix++].ph = phoneme_tab[phonPAUSE_SHORT];
phlist[ix++].ph = phoneme_tab[phonPAUSE_SHORT];
n_phoneme_list = ix;
} // end of MakePhonemeList
+18 -9
View File
@@ -842,14 +842,13 @@ static int LoadSoundFile2(const char *fname)
static int AnnouncePunctuation(Translator *tr, int c1, int *c2_ptr, char *output, int *bufix, int end_clause)
{//==========================================================================================================
{//=============================================================================================================
// announce punctuation names
// c1: the punctuation character
// c2: the following character
int punct_count;
const char *punctname;
int found = 0;
const char *punctname = NULL;
int soundicon;
int attributes;
int short_pause;
@@ -858,6 +857,7 @@ static int AnnouncePunctuation(Translator *tr, int c1, int *c2_ptr, char *output
int bufix1;
char buf[200];
char buf2[80];
char ph_buf[30];
c2 = *c2_ptr;
buf[0] = 0;
@@ -867,12 +867,24 @@ static int AnnouncePunctuation(Translator *tr, int c1, int *c2_ptr, char *output
// add an embedded command to play the soundicon
sprintf(buf,"\001%dI ",soundicon);
UngetC(c2);
found = 1;
}
else
if((punctname = LookupCharName(tr, c1, 0)) != NULL)
{
found = 1;
if((c1 == '.') && (end_clause) && (c2 != '.'))
{
if(LookupSpecial(tr, "_.p", ph_buf))
{
punctname = ph_buf; // use word for 'period' instead of 'dot'
}
}
if(punctname == NULL)
{
punctname = LookupCharName(tr, c1, 0);
}
if(punctname == NULL)
return(-1);
if((*bufix==0) || (end_clause ==0) || (tr->langopts.param[LOPT_ANNOUNCE_PUNCT] & 2))
{
punct_count=1;
@@ -932,9 +944,6 @@ static int AnnouncePunctuation(Translator *tr, int c1, int *c2_ptr, char *output
}
}
if(found == 0)
return(-1);
bufix1 = *bufix;
len = strlen(buf);
strcpy(&output[*bufix],buf);
+1 -1
View File
@@ -35,7 +35,7 @@
#include "translate.h"
#include "wave.h"
const char *version_string = "1.46.44 08.Mar.13";
const char *version_string = "1.46.45 10.Mar.13";
const int version_phdata = 0x014640;
int option_device_number = -1;
+47 -40
View File
@@ -79,7 +79,7 @@ ALPHABET alphabets [] = {
{"_dv", OFFSET_THAANA, 0x780, 0x7bf, 0, 0},
{"_hi", OFFSET_DEVANAGARI, 0x900, 0x97f,L('h','i'), AL_WORDS},
{"_bn", OFFSET_BENGALI, 0x0980, 0x9ff, 0, 0},
{"_gur", OFFSET_GURMUKHI, 0xa00, 0xa7f, 0, 0},
{"_gur", OFFSET_GURMUKHI, 0xa00, 0xa7f, L('p','a'), AL_WORDS},
{"_gu", OFFSET_GUJARATI, 0xa80, 0xaff, 0, 0},
{"_or", OFFSET_ORIYA, 0xb00, 0xb7f, 0, 0},
{"_ta", OFFSET_TAMIL, 0xb80, 0xbff, L('t','a'), AL_WORDS},
@@ -94,24 +94,26 @@ ALPHABET alphabets [] = {
{"_ka", OFFSET_GEORGIAN, 0x10a0,0x10ff, L('k','a'), AL_WORDS},
{"_ko", OFFSET_KOREAN, 0x1100,0x11ff, 0, 0},
{"_eth", OFFSET_ETHIOPIC, 0x1200,0x139f, 0, 0},
{"_ja", 0x3040, 0x3040,0x30ff, 0, AL_NOT_CODE},
{"_zh", 0x3100, 0x3100,0x9fff, 0, AL_NOT_CODE},
{NULL, 0, 0, 0, 0, 0}
};
ALPHABET *AlphabetFromChar(int c)
{//===============================
// Find the alphabet from a character.
ALPHABET *alphabet = alphabets;
// Find the alphabet from a character.
ALPHABET *alphabet = alphabets;
while(alphabet->name != NULL)
{
if((c >= alphabet->range_min) && (c <= alphabet->range_max))
{
return(alphabet);
}
alphabet++;
}
return(NULL);
while(alphabet->name != NULL)
{
if((c >= alphabet->range_min) && (c <= alphabet->range_max))
{
return(alphabet);
}
alphabet++;
}
return(NULL);
}
@@ -514,7 +516,7 @@ Translator *SelectTranslator(const char *name)
tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
tr->langopts.stress_rule = STRESSPOSN_1L;
tr->langopts.stress_flags = 0x10004; // use 'diminished' for unstressed final syllable
tr->langopts.stress_flags = S_MID_DIM | S_FINAL_DIM; // use 'diminished' for unstressed final syllable
tr->letter_bits_offset = OFFSET_BENGALI;
SetIndicLetters(tr); // call this after setting OFFSET_BENGALI
SetLetterBitsRange(tr,LETTERGP_F,0x3e,0x4c); // vowel signs, but not virama
@@ -601,7 +603,7 @@ Translator *SelectTranslator(const char *name)
tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
tr->letter_bits_offset = OFFSET_THAANA;
tr->langopts.stress_rule = STRESSPOSN_1L;
tr->langopts.stress_flags = 0x10004; // use 'diminished' for unstressed final syllable
tr->langopts.stress_flags = S_MID_DIM | S_FINAL_DIM; // use 'diminished' for unstressed final syllable
SetLetterBitsRange(tr,LETTERGP_B,0x26,0x30); // vowel signs, and virama
tr->langopts.break_numbers = 0x14a8; // 1000, 100,000 10,000,000
tr->langopts.numbers = 1;
@@ -705,7 +707,7 @@ Translator *SelectTranslator(const char *name)
// stress last syllable if it doesn't end in vowel or "s" or "n"
// 'diminished' is an unstressed final syllable
tr->langopts.stress_flags = 0x200 | 0x6 | 0x10;
tr->langopts.stress_flags = S_FINAL_SPANISH | S_FINAL_DIM_ONLY | S_FINAL_NO_2;
tr->langopts.unstressed_wd1 = 0;
tr->langopts.unstressed_wd2 = 2;
tr->langopts.param[LOPT_SONORANT_MIN] = 120; // limit the shortening of sonorants before short vowels
@@ -715,18 +717,20 @@ Translator *SelectTranslator(const char *name)
if(name2 == L('c','a'))
{
// stress last syllable unless word ends with a vowel
tr->punct_within_word = ca_punct_within_word;
tr->langopts.stress_flags = 0x200 | 0x6 | 0x30; // stress last syllable unless word ends with a vowel
tr->langopts.stress_flags = S_FINAL_SPANISH | S_FINAL_DIM_ONLY | S_FINAL_NO_2 | S_NO_AUTO_2;
}
else
if(name2 == L('a','n'))
{
tr->langopts.stress_flags = 0x200 | 0x6 | 0x10;
tr->langopts.stress_flags = S_FINAL_SPANISH | S_FINAL_DIM_ONLY | S_FINAL_NO_2;
}
else
if(name2 == L_pap)
{
tr->langopts.stress_flags = 0x100 | 0x6 | 0x30; // stress last syllable unless word ends with a vowel
// stress last syllable unless word ends with a vowel
tr->langopts.stress_flags = S_FINAL_STRESS_C | S_FINAL_DIM_ONLY | S_FINAL_NO_2 | S_NO_AUTO_2;
}
else
{
@@ -786,7 +790,7 @@ Translator *SelectTranslator(const char *name)
SetupTranslator(tr,stress_lengths_fi,stress_amps_fi);
tr->langopts.stress_rule = STRESSPOSN_1L;
tr->langopts.stress_flags = 0x56; // move secondary stress from light to a following heavy syllable
tr->langopts.stress_flags = S_FINAL_DIM_ONLY | S_FINAL_NO_2 | S_2_TO_HEAVY; // move secondary stress from light to a following heavy syllable
tr->langopts.param[LOPT_IT_DOUBLING] = 1;
tr->langopts.long_stop = 130;
@@ -802,7 +806,7 @@ Translator *SelectTranslator(const char *name)
{
SetupTranslator(tr,stress_lengths_fr,stress_amps_fr);
tr->langopts.stress_rule = STRESSPOSN_1R; // stress on final syllable
tr->langopts.stress_flags = 0x0024; // don't use secondary stress
tr->langopts.stress_flags = S_NO_AUTO_2 | S_FINAL_DIM; // don't use secondary stress
tr->langopts.param[LOPT_IT_LENGTHEN] = 1; // remove lengthen indicator from unstressed syllables
tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
tr->langopts.accents = 2; // Say "Capital" after the letter.
@@ -812,12 +816,12 @@ Translator *SelectTranslator(const char *name)
}
break;
case L('g','a'): // irish
{
tr->langopts.stress_rule = STRESSPOSN_1L;
tr->langopts.numbers = 1;
}
break;
case L('g','a'): // irish
{
tr->langopts.stress_rule = STRESSPOSN_1L;
tr->langopts.numbers = 1;
}
break;
case L('h','i'): // Hindi
case L('n','e'): // Nepali
@@ -831,7 +835,7 @@ Translator *SelectTranslator(const char *name)
tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
tr->langopts.stress_rule = 6; // stress on last heaviest syllable, excluding final syllable
tr->langopts.stress_flags = 0x10004; // use 'diminished' for unstressed final syllable
tr->langopts.stress_flags = S_MID_DIM | S_FINAL_DIM; // use 'diminished' for unstressed final syllable
tr->langopts.numbers = NUM_SWAP_TENS;
tr->langopts.break_numbers = 0x14aa8; // for languages which have numbers for 100,000 and 100,00,000, eg Hindi
tr->letter_bits_offset = OFFSET_DEVANAGARI;
@@ -875,7 +879,7 @@ SetupTranslator(tr,stress_lengths_equal,stress_amps_equal);
tr->charset_a0 = charsets[2]; // ISO-8859-2
tr->langopts.stress_rule = STRESSPOSN_1L;
tr->langopts.stress_flags = 0x10;
tr->langopts.stress_flags = S_FINAL_NO_2;
tr->langopts.param[LOPT_REGRESSIVE_VOICING] = 0x3;
tr->langopts.max_initial_consonants = 5;
tr->langopts.spelling_stress = 1;
@@ -894,7 +898,7 @@ SetupTranslator(tr,stress_lengths_equal,stress_amps_equal);
case L('h','t'): // Haitian Creole
// memcpy(tr->stress_lengths,stress_lengths_fr,sizeof(tr->stress_lengths));
tr->langopts.stress_rule = STRESSPOSN_1R; // stress on final syllable
tr->langopts.stress_flags = 0x0024; // don't use secondary stress
tr->langopts.stress_flags = S_NO_AUTO_2 | S_FINAL_DIM; // don't use secondary stress
tr->langopts.numbers = NUM_SINGLE_STRESS | NUM_OMIT_1_HUNDRED | NUM_NOPAUSE | NUM_ROMAN | NUM_VIGESIMAL | NUM_DFRACTION_4;
break;
@@ -909,7 +913,7 @@ SetupTranslator(tr,stress_lengths_equal,stress_amps_equal);
tr->langopts.vowel_pause = 0x20;
tr->langopts.stress_rule = STRESSPOSN_1L;
tr->langopts.stress_flags = 0x8036 | S_HYPEN_UNSTRESS;
tr->langopts.stress_flags = S_FINAL_DIM_ONLY | S_FINAL_NO_2 | S_NO_AUTO_2 | 0x8000 | S_HYPEN_UNSTRESS;
tr->langopts.unstressed_wd1 = 2;
tr->langopts.param[LOPT_IT_DOUBLING] = 1;
tr->langopts.param[LOPT_ANNOUNCE_PUNCT] = 2; // don't break clause before announcing . ? !
@@ -942,7 +946,7 @@ SetLengthMods(tr,3); // all equal
SetLetterBits(tr,LETTERGP_C,hy_consonants);
tr->langopts.max_initial_consonants = 6;
tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_OMIT_1_HUNDRED;
// tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words
// tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words
}
break;
@@ -954,7 +958,7 @@ SetLengthMods(tr,3); // all equal
SetupTranslator(tr,stress_lengths_id,stress_amps_id);
tr->langopts.stress_rule = STRESSPOSN_2R;
tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_ALLOW_SPACE | NUM_ROMAN;
tr->langopts.stress_flags = 0x6 | 0x10;
tr->langopts.stress_flags = S_FINAL_DIM_ONLY | S_FINAL_NO_2;
tr->langopts.accents = 2; // "capital" after letter name
}
break;
@@ -966,7 +970,7 @@ SetLengthMods(tr,3); // all equal
SetupTranslator(tr,stress_lengths_is,NULL);
tr->langopts.stress_rule = STRESSPOSN_1L;
tr->langopts.stress_flags = 0x10;
tr->langopts.stress_flags = S_FINAL_NO_2;
tr->langopts.param[LOPT_IT_LENGTHEN] = 0x11; // remove lengthen indicator from unstressed vowels
tr->langopts.param[LOPT_REDUCE] = 2;
@@ -989,7 +993,7 @@ SetLengthMods(tr,3); // all equal
tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
tr->langopts.stress_rule = STRESSPOSN_2R;
tr->langopts.stress_flags = 0x10 | S_PRIORITY_STRESS;
tr->langopts.stress_flags = S_FINAL_NO_2 | S_PRIORITY_STRESS;
tr->langopts.vowel_pause = 1;
tr->langopts.unstressed_wd1 = 2;
tr->langopts.unstressed_wd2 = 2;
@@ -1024,8 +1028,9 @@ SetLengthMods(tr,3); // all equal
{
// character codes offset by 0x1080
static const char ka_vowels[] = {0x30,0x34,0x38,0x3d,0x43,0x55,0x57,0};
static const char ka_consonants[] = {0x31,0x32,0x33,0x35,0x36,0x37,0x39,0x3a,0x3b,0x3c,0x3e,0x3f,
0x40,0x41,0x42,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x56,0};
static const char ka_consonants[] =
{0x31,0x32,0x33,0x35,0x36,0x37,0x39,0x3a,0x3b,0x3c,0x3e,0x3f,0x40,0x41,0x42,0x44,
0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x56,0};
SetupTranslator(tr,stress_lengths_ta,stress_amps_ta);
memset(tr->letter_bits,0,sizeof(tr->letter_bits));
SetLetterBits(tr,LETTERGP_A,ka_vowels);
@@ -1149,7 +1154,7 @@ SetLengthMods(tr,3); // all equal
tr->langopts.spelling_stress = 1;
tr->charset_a0 = charsets[4]; // ISO-8859-4
tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_OMIT_1_HUNDRED | NUM_DFRACTION_4 | NUM_ORDINAL_DOT;
tr->langopts.stress_flags = 0x16 + 0x40000;
tr->langopts.stress_flags = S_FINAL_DIM_ONLY | S_FINAL_NO_2 | S_EO_CLAUSE1;
}
break;
@@ -1496,14 +1501,14 @@ SetLengthMods(tr,3); // all equal
break;
case L('t','t'): // Tatar
{
{
SetCyrillicLetters(tr);
SetupTranslator(tr,stress_lengths_fr,stress_amps_fr);
tr->langopts.stress_rule = STRESSPOSN_1R; // stress on final syllable
tr->langopts.stress_flags = S_NO_AUTO_2; //no automatic secondary stress
tr->langopts.numbers = NUM_SINGLE_STRESS | NUM_DECIMAL_COMMA | NUM_OMIT_1_HUNDRED | NUM_OMIT_1_THOUSAND | NUM_DFRACTION_4;
}
break;
}
break;
case L('u','k'): // Ukrainian
{
@@ -1513,10 +1518,12 @@ SetLengthMods(tr,3); // all equal
break;
case L('u','r'): // Urdu
{
tr->letter_bits_offset = OFFSET_ARABIC;
tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words
tr->langopts.numbers = NUM_SWAP_TENS;
tr->langopts.break_numbers = 0x52a8; // for languages which have numbers for 100,000 and 100,00,000, eg Hindi
}
break;
case L('v','i'): // Vietnamese
+450 -474
View File
File diff suppressed because it is too large Load Diff
+9 -3
View File
@@ -275,7 +275,8 @@ extern ALPHABET *current_alphabet;
// alphabet flags
#define AL_DONT_NAME 0x01 // don't speak the alphabet name
#define AL_NOT_LETTERS 0x02 // don't use the language for speaking letters
#define AL_WORDS 0x04 // use the language to speak words
#define AL_WORDS 0x04 // use the language to speak words
#define AL_NOT_CODE 0x08 // don't speak the character code
#define N_LOPTS 21
@@ -402,12 +403,18 @@ typedef struct {
#define S_INITIAL_2 0x2000
// bit13= If there is only one syllable before the primary stress, give it a secondary stress
#define S_MID_DIM 0x10000
// bit 16= Set (not first or last) syllables to diminished stress
#define S_PRIORITY_STRESS 0x20000
// bit17= "priority" stress reduces other primary stress to "unstressed" not "secondary"
#define S_EO_CLAUSE1 0x40000
// bit18= don't lengthen short vowels more than long vowels at end-of-clause
#define S_FINAL_LONG 0x80000
// bit19=stress on final syllable if it has a long vowel, but previous syllable has a short vowel
#define S_HYPEN_UNSTRESS 0x100000
// bit20= hyphenated words, 2nd part is unstressed
@@ -416,7 +423,6 @@ typedef struct {
// bit21= don't lengthen vowels at end-of-clause
// bit15= Give stress to the first unstressed syllable
// bit19=stress on final syllable if it has a long vowel, but previous syllable has a short vowel
int stress_flags;
@@ -566,7 +572,7 @@ typedef struct
const char *transpose_map;
char dictionary_name[40];
char phon_out[400];
char phon_out[500];
char phonemes_repeat[20];
int phonemes_repeat_count;
int phoneme_tab_ix;
+184 -181
View File
@@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (C) 2005 to 2010 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 *
@@ -47,7 +47,8 @@ MNEM_TAB genders [] = {
{"unknown", 0},
{"male", 1},
{"female", 2},
{NULL, 0 }};
{NULL, 0 }
};
int tone_points[12] = {600,170, 1200,135, 2000,110, 3000,110, -1,0};
//int tone_points[12] = {250,200, 400,170, 600,170, 1200,135, 2000,110, -1,0};
@@ -98,6 +99,7 @@ enum {
V_STRESSADD,
V_DICTRULES,
V_STRESSRULE,
V_STRESSOPT,
V_CHARSET,
V_NUMBERS,
V_OPTION,
@@ -118,7 +120,8 @@ enum {
static MNEM_TAB options_tab[] = {
{"reduce_t", LOPT_REDUCE_T},
{"bracket", LOPT_BRACKET_PAUSE},
{NULL, -1} };
{NULL, -1}
};
static MNEM_TAB keyword_tab[] = {
{"name", V_NAME},
@@ -128,7 +131,7 @@ static MNEM_TAB keyword_tab[] = {
{"formant", V_FORMANT},
{"pitch", V_PITCH},
{"phonemes", V_PHONEMES},
{"translator", V_TRANSLATOR},
{"translator", V_TRANSLATOR},
{"dictionary", V_DICTIONARY},
{"stressLength", V_STRESSLENGTH},
{"stressAmp", V_STRESSAMP},
@@ -137,6 +140,7 @@ static MNEM_TAB keyword_tab[] = {
{"tunes", V_TUNES},
{"dictrules", V_DICTRULES},
{"stressrule", V_STRESSRULE},
{"stressopt", V_STRESSOPT},
{"charset", V_CHARSET},
{"replace", V_REPLACE},
{"words", V_WORDGAP},
@@ -166,7 +170,8 @@ static MNEM_TAB keyword_tab[] = {
{"l_sonorant_min", 0x100+LOPT_SONORANT_MIN},
{"l_length_mods", 0x100+LOPT_LENGTH_MODS},
{"apostrophe", 0x100+LOPT_APOSTROPHE},
{NULL, 0} };
{NULL, 0}
};
#define N_VOICE_VARIANTS 12
const char variants_either[N_VOICE_VARIANTS] = {1,2,12,3,13,4,14,5,11,0};
@@ -260,9 +265,9 @@ void ReadTonePoints(char *string, int *tone_pts)
tone_pts[ix] = -1;
sscanf(string,"%d %d %d %d %d %d %d %d %d %d",
&tone_pts[0],&tone_pts[1],&tone_pts[2],&tone_pts[3],
&tone_pts[4],&tone_pts[5],&tone_pts[6],&tone_pts[7],
&tone_pts[8],&tone_pts[9]);
&tone_pts[0],&tone_pts[1],&tone_pts[2],&tone_pts[3],
&tone_pts[4],&tone_pts[5],&tone_pts[6],&tone_pts[7],
&tone_pts[8],&tone_pts[9]);
}
@@ -316,8 +321,7 @@ static espeak_VOICE *ReadVoiceFile(FILE *f_in, const char *fname, const char*lea
while(isspace(*p)) p++;
strncpy0(vname,p,sizeof(vname));
}
else
if(memcmp(linebuf,"language",8)==0)
else if(memcmp(linebuf,"language",8)==0)
{
priority = DEFAULT_LANGUAGE_PRIORITY;
vlanguage[0] = 0;
@@ -334,13 +338,11 @@ static espeak_VOICE *ReadVoiceFile(FILE *f_in, const char *fname, const char*lea
n_languages++;
}
}
else
if(memcmp(linebuf,"gender",6)==0)
else if(memcmp(linebuf,"gender",6)==0)
{
sscanf(&linebuf[6],"%s %d",vgender,&age);
}
else
if(memcmp(linebuf,"variants",8)==0)
else if(memcmp(linebuf,"variants",8)==0)
{
sscanf(&linebuf[8],"%d",&n_variants);
}
@@ -443,7 +445,7 @@ void VoiceReset(int tone_only)
// Adjustment of harmonic amplitudes, steps of 8Hz
// value of 128 means no change
// memset(voice->tone_adjust,128,sizeof(voice->tone_adjust));
SetToneAdjust(voice,tone_points);
SetToneAdjust(voice,tone_points);
// default values of speed factors
voice->speedf1 = 256;
@@ -517,7 +519,7 @@ static int Read8Numbers(char *data_in,int *data)
// Read 8 integer numbers
memset(data, 0, 8+sizeof(int));
return(sscanf(data_in,"%d %d %d %d %d %d %d %d",
&data[0],&data[1],&data[2],&data[3],&data[4],&data[5],&data[6],&data[7]));
&data[0],&data[1],&data[2],&data[3],&data[4],&data[5],&data[6],&data[7]));
}
@@ -557,7 +559,7 @@ voice_t *LoadVoice(const char *vname, int control)
char buf[sizeof(path_home)+30];
char path_voices[sizeof(path_home)+12];
int dict_min = 0;
int dict_min = 0;
int stress_amps[8];
int stress_lengths[8];
int stress_add[8];
@@ -572,11 +574,11 @@ voice_t *LoadVoice(const char *vname, int control)
static char voice_name[40]; // voice name for current_voice_selected
static char voice_languages[100]; // list of languages and priorities for current_voice_selected
// which directory to look for a named voice
static const char *voices_asia =
"fa fa-pin hi hy hy-west id ka kn ku ml ne pa ta tr vi vi-hue zh zh-yue ";
static const char *voices_europe =
"bg bs ca cs cy da el es et fi fr-be hr hu is it lt lv mk nl no pl pt-pt ro ru sk sq sr sv ";
// which directory to look for a named voice
static const char *voices_asia =
"fa fa-pin hi hy hy-west id ka kn ku ml ne pa ta tr vi vi-hue zh zh-yue ";
static const char *voices_europe =
"bg bs ca cs cy da el es et fi fr-be hr hu is it lt lv mk nl no pl pt-pt ro ru sk sq sr sv ";
strncpy0(voicename, vname, sizeof(voicename));
@@ -588,38 +590,37 @@ voice_t *LoadVoice(const char *vname, int control)
}
else
{
if(voicename[0]==0)
strcpy(voicename,"default");
if(voicename[0]==0)
strcpy(voicename,"default");
sprintf(path_voices,"%s%cvoices%c",path_home,PATHSEP,PATHSEP);
sprintf(buf,"%s%s",path_voices,voicename); // first, look in the main voices directory
if(GetFileLength(buf) <= 0)
{
// then look in the appropriate subdirectory
if((voicename[0]=='m') && (voicename[1]=='b'))
{
voice_dir = "mb"; // mbrola voices
}
else
{
sprintf(name2, "%s ", voicename);
if(strstr(voices_europe, voicename) != NULL)
voice_dir = "europe";
else
if(strstr(voices_asia, voicename) != NULL)
voice_dir = "asia";
else
voice_dir = "other";
// then look in the appropriate subdirectory
if((voicename[0]=='m') && (voicename[1]=='b'))
{
voice_dir = "mb"; // mbrola voices
}
else
{
sprintf(name2, "%s ", voicename);
if(strstr(voices_europe, voicename) != NULL)
voice_dir = "europe";
else if(strstr(voices_asia, voicename) != NULL)
voice_dir = "asia";
else
voice_dir = "other";
sprintf(buf,"%s%s%c%s", path_voices,voice_dir,PATHSEP,voicename);
sprintf(buf,"%s%s%c%s", path_voices,voice_dir,PATHSEP,voicename);
if(GetFileLength(buf) <= 0)
{
// if not found, look in "test" sub-directory
sprintf(buf,"%stest%c%s",path_voices,PATHSEP,voicename);
}
}
if(GetFileLength(buf) <= 0)
{
// if not found, look in "test" sub-directory
sprintf(buf,"%stest%c%s",path_voices,PATHSEP,voicename);
}
}
}
}
@@ -685,48 +686,48 @@ voice_t *LoadVoice(const char *vname, int control)
switch(key)
{
case V_LANGUAGE:
{
unsigned int len;
int priority;
if(tone_only)
break;
priority = DEFAULT_LANGUAGE_PRIORITY;
language_name[0] = 0;
sscanf(p,"%s %d",language_name,&priority);
if(strcmp(language_name,"variant") == 0)
break;
len = strlen(language_name) + 2;
// check for space in languages[]
if(len < (sizeof(voice_languages)-langix-1))
{
unsigned int len;
int priority;
voice_languages[langix] = priority;
if(tone_only)
break;
priority = DEFAULT_LANGUAGE_PRIORITY;
language_name[0] = 0;
sscanf(p,"%s %d",language_name,&priority);
if(strcmp(language_name,"variant") == 0)
break;
len = strlen(language_name) + 2;
// check for space in languages[]
if(len < (sizeof(voice_languages)-langix-1))
{
voice_languages[langix] = priority;
strcpy(&voice_languages[langix+1],language_name);
langix += len;
}
// only act on the first language line
if(language_set == 0)
{
language_type = strtok(language_name,"-");
language_set = 1;
strcpy(translator_name,language_type);
strcpy(new_dictionary,language_type);
strcpy(phonemes_name,language_type);
SelectPhonemeTableName(phonemes_name);
if(new_translator != NULL)
DeleteTranslator(new_translator);
new_translator = SelectTranslator(translator_name);
langopts = &new_translator->langopts;
}
strcpy(&voice_languages[langix+1],language_name);
langix += len;
}
break;
// only act on the first language line
if(language_set == 0)
{
language_type = strtok(language_name,"-");
language_set = 1;
strcpy(translator_name,language_type);
strcpy(new_dictionary,language_type);
strcpy(phonemes_name,language_type);
SelectPhonemeTableName(phonemes_name);
if(new_translator != NULL)
DeleteTranslator(new_translator);
new_translator = SelectTranslator(translator_name);
langopts = &new_translator->langopts;
}
}
break;
case V_NAME:
if(tone_only == 0)
@@ -737,14 +738,14 @@ voice_t *LoadVoice(const char *vname, int control)
break;
case V_GENDER:
{
int age = 0;
char vgender[80];
sscanf(p,"%s %d",vgender,&age);
current_voice_selected.gender = LookupMnem(genders,vgender);
current_voice_selected.age = age;
}
break;
{
int age = 0;
char vgender[80];
sscanf(p,"%s %d",vgender,&age);
current_voice_selected.gender = LookupMnem(genders,vgender);
current_voice_selected.age = age;
}
break;
case V_TRANSLATOR:
if(tone_only) break;
@@ -752,7 +753,7 @@ voice_t *LoadVoice(const char *vname, int control)
sscanf(p,"%s",translator_name);
if(new_translator != NULL)
DeleteTranslator(new_translator);
DeleteTranslator(new_translator);
new_translator = SelectTranslator(translator_name);
langopts = &new_translator->langopts;
@@ -771,16 +772,16 @@ voice_t *LoadVoice(const char *vname, int control)
break;
case V_PITCH:
{
double factor;
// default is pitch 82 118
n = sscanf(p,"%d %d",&pitch1,&pitch2);
voice->pitch_base = (pitch1 - 9) << 12;
voice->pitch_range = (pitch2 - pitch1) * 108;
factor = double(pitch1 - 82)/82;
voice->formant_factor = (int)((1+factor/4) * 256); // nominal formant shift for a different voice pitch
}
break;
{
double factor;
// default is pitch 82 118
n = sscanf(p,"%d %d",&pitch1,&pitch2);
voice->pitch_base = (pitch1 - 9) << 12;
voice->pitch_range = (pitch2 - pitch1) * 108;
factor = double(pitch1 - 82)/82;
voice->formant_factor = (int)((1+factor/4) * 256); // nominal formant shift for a different voice pitch
}
break;
case V_STRESSLENGTH: // stressLength
stress_lengths_set = Read8Numbers(p,stress_lengths);
@@ -817,7 +818,8 @@ voice_t *LoadVoice(const char *vname, int control)
case V_DICTRULES: // conditional dictionary rules and list entries
case V_NUMBERS:
// expect a list of numbers
case V_STRESSOPT:
// expect a list of numbers
while(*p != 0)
{
while(isspace(*p)) p++;
@@ -825,16 +827,22 @@ voice_t *LoadVoice(const char *vname, int control)
if((n = atoi(p)) > 0)
{
p++;
if((key==V_DICTRULES) && (n < 32))
conditional_rules |= (1 << n);
if(n < 32)
{
if(key==V_DICTRULES)
conditional_rules |= (1 << n);
else if(key==V_NUMBERS)
langopts->numbers |= (1 << n);
else if(key==V_STRESSOPT)
langopts->stress_flags |= (1 << n);
}
else
if((key==V_NUMBERS) && (n < 32))
langopts->numbers |= (1 << n);
else
if((key==V_NUMBERS) && (n < 64))
langopts->numbers |= (1 << (n-32));
else
fprintf(stderr,"Bad option number %d\n", n);
{
if((key==V_NUMBERS) && (n < 64))
langopts->numbers |= (1 << (n-32));
else
fprintf(stderr,"Bad option number %d\n", n);
}
}
while(isalnum(*p)) p++;
}
@@ -856,9 +864,9 @@ voice_t *LoadVoice(const char *vname, int control)
case V_STRESSRULE:
sscanf(p,"%d %d %d %d",&langopts->stress_rule,
&langopts->stress_flags,
&langopts->unstressed_wd1,
&langopts->unstressed_wd2);
&langopts->stress_flags,
&langopts->unstressed_wd1,
&langopts->unstressed_wd2);
break;
case V_CHARSET:
@@ -909,12 +917,12 @@ voice_t *LoadVoice(const char *vname, int control)
break;
case V_TONE:
{
int tone_data[12];
ReadTonePoints(p,tone_data);
SetToneAdjust(voice,tone_data);
}
break;
{
int tone_data[12];
ReadTonePoints(p,tone_data);
SetToneAdjust(voice,tone_data);
}
break;
case V_VOICING:
if(sscanf(p,"%d",&value)==1)
@@ -922,16 +930,16 @@ voice_t *LoadVoice(const char *vname, int control)
break;
case V_BREATH:
voice->breath[0] = Read8Numbers(p,&voice->breath[1]);
for(ix=1; ix<8; ix++)
{
if(ix % 2)
voice->breath[ix] = -voice->breath[ix];
}
voice->breath[0] = Read8Numbers(p,&voice->breath[1]);
for(ix=1; ix<8; ix++)
{
if(ix % 2)
voice->breath[ix] = -voice->breath[ix];
}
break;
case V_BREATHW:
voice->breathw[0] = Read8Numbers(p,&voice->breathw[1]);
voice->breathw[0] = Read8Numbers(p,&voice->breathw[1]);
break;
case V_CONSONANTS:
@@ -943,20 +951,20 @@ voice_t *LoadVoice(const char *vname, int control)
break;
case V_MBROLA:
{
int srate = 16000;
char name[40];
char phtrans[40];
{
int srate = 16000;
char name[40];
char phtrans[40];
phtrans[0] = 0;
sscanf(p,"%s %s %d",name,phtrans,&srate);
if(LoadMbrolaTable(name,phtrans,srate) != EE_OK)
{
fprintf(stderr,"mbrola voice not found\n");
}
voice->samplerate = srate;
phtrans[0] = 0;
sscanf(p,"%s %s %d",name,phtrans,&srate);
if(LoadMbrolaTable(name,phtrans,srate) != EE_OK)
{
fprintf(stderr,"mbrola voice not found\n");
}
break;
voice->samplerate = srate;
}
break;
case V_KLATT:
voice->klattv[0] = 1; // default source: IMPULSIVE
@@ -969,9 +977,9 @@ voice_t *LoadVoice(const char *vname, int control)
SetSpeed(3);
break;
case V_DICTMIN:
case V_DICTMIN:
sscanf(p,"%d",&dict_min);
break;
break;
default:
if((key & 0xff00) == 0x100)
@@ -1015,7 +1023,7 @@ voice_t *LoadVoice(const char *vname, int control)
}
voice->phoneme_tab_ix = ix;
new_translator->phoneme_tab_ix = ix;
new_translator->dict_min_size = dict_min;
new_translator->dict_min_size = dict_min;
LoadDictionary(new_translator, new_dictionary, control & 4);
if(dictionary_name[0]==0)
return(NULL); // no dictionary loaded
@@ -1255,15 +1263,14 @@ static int ScoreVoice(espeak_VOICE *voice_spec, const char *spec_language, int s
// match on voice name
score += 500;
}
else
if(strcmp(voice_spec->name,voice->identifier)==0)
else if(strcmp(voice_spec->name,voice->identifier)==0)
{
score += 400;
}
}
if(((voice_spec->gender == 1) || (voice_spec->gender == 2)) &&
((voice->gender == 1) || (voice->gender == 2)))
((voice->gender == 1) || (voice->gender == 2)))
{
if(voice_spec->gender == voice->gender)
score += 50;
@@ -1395,8 +1402,7 @@ espeak_VOICE *SelectVoiceByName(espeak_VOICE **voices, const char *name2)
{
match_fname = ix; // matching identifier, use this if no matching name
}
else
if(strcmp(last_part,&id[strlen(id)-last_part_len])==0)
else if(strcmp(last_part,&id[strlen(id)-last_part_len])==0)
{
match_fname2 = ix;
}
@@ -1493,8 +1499,7 @@ char const *SelectVoice(espeak_VOICE *voice_select, int *found)
gender = 0;
if((voice_select2.gender == 2) || ((voice_select2.age > 0) && (voice_select2.age < 13)))
gender = 2;
else
if(voice_select2.gender == 1)
else if(voice_select2.gender == 1)
gender = 1;
#define AGE_OLD 60
@@ -1625,8 +1630,8 @@ static void GetVoices(const char *path)
}
#else
#ifdef PLATFORM_WINDOWS
WIN32_FIND_DATAA FindFileData;
HANDLE hFind = INVALID_HANDLE_VALUE;
WIN32_FIND_DATAA FindFileData;
HANDLE hFind = INVALID_HANDLE_VALUE;
#undef UNICODE // we need FindFirstFileA() which takes an 8-bit c-string
sprintf(fname,"%s\\*",path);
@@ -1640,30 +1645,29 @@ static void GetVoices(const char *path)
if(FindFileData.cFileName[0] != '.')
{
sprintf(fname,"%s%c%s",path,PATHSEP,FindFileData.cFileName);
ftype = GetFileLength(fname);
sprintf(fname,"%s%c%s",path,PATHSEP,FindFileData.cFileName);
ftype = GetFileLength(fname);
if(ftype == -2)
{
// a sub-sirectory
GetVoices(fname);
}
else
if(ftype > 0)
{
// a regular line, add it to the voices list
if((f_voice = fopen(fname,"r")) == NULL)
continue;
if(ftype == -2)
{
// a sub-sirectory
GetVoices(fname);
}
else if(ftype > 0)
{
// a regular line, add it to the voices list
if((f_voice = fopen(fname,"r")) == NULL)
continue;
// pass voice file name within the voices directory
voice_data = ReadVoiceFile(f_voice, fname+len_path_voices, FindFileData.cFileName);
fclose(f_voice);
// pass voice file name within the voices directory
voice_data = ReadVoiceFile(f_voice, fname+len_path_voices, FindFileData.cFileName);
fclose(f_voice);
if(voice_data != NULL)
{
voices_list[n_voices_list++] = voice_data;
}
}
if(voice_data != NULL)
{
voices_list[n_voices_list++] = voice_data;
}
}
}
} while(FindNextFileA(hFind, &FindFileData) != 0);
FindClose(hFind);
@@ -1680,8 +1684,8 @@ static void GetVoices(const char *path)
if(n_voices_list >= (N_VOICES_LIST-2))
break; // voices list is full
if(ent->d_name[0] == '.')
continue;
if(ent->d_name[0] == '.')
continue;
sprintf(fname,"%s%c%s",path,PATHSEP,ent->d_name);
@@ -1692,8 +1696,7 @@ static void GetVoices(const char *path)
// a sub-sirectory
GetVoices(fname);
}
else
if(ftype > 0)
else if(ftype > 0)
{
// a regular line, add it to the voices list
if((f_voice = fopen(fname,"r")) == NULL)
@@ -1728,7 +1731,7 @@ espeak_ERROR SetVoiceByName(const char *name)
variant_name = ExtractVoiceVariantName(buf, 0, 1);
for(ix=0; ;ix++)
for(ix=0; ; ix++)
{
// convert voice name to lower case (ascii)
if((buf[ix] = tolower(buf[ix])) == 0)
@@ -1833,7 +1836,7 @@ ESPEAK_API const espeak_VOICE **espeak_ListVoices(espeak_VOICE *voice_spec)
// sort the voices list
qsort(voices_list,n_voices_list,sizeof(espeak_VOICE *),
(int (__cdecl *)(const void *,const void *))VoiceNameSorter);
(int (__cdecl *)(const void *,const void *))VoiceNameSorter);
if(voice_spec)