mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-11-15 18:04:26 +00:00
[1.46.24]
Changes to: pt, tt, es Added new language data: ko (Korean) Phoneme definitions, added new condition: prevVowel() git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@289 d46cf337-b52f-0410-862d-fd96e6ae7743
This commit is contained in:
+57
-44
@@ -90,17 +90,18 @@ static keywtab_t k_conditions[] = {
|
||||
{"AND", 0, k_AND},
|
||||
{"OR", 0, k_OR},
|
||||
{"THEN", 0, k_THEN},
|
||||
{"prevPh", tWHICH_PHONEME, 0x000},
|
||||
{"prevPhW", tWHICH_PHONEME, 0x500},
|
||||
{"thisPh", tWHICH_PHONEME, 0x100},
|
||||
{"nextPh", tWHICH_PHONEME, 0x200},
|
||||
{"next2Ph", tWHICH_PHONEME, 0x300},
|
||||
{"nextPhW", tWHICH_PHONEME, 0x400},
|
||||
{"nextVowel",tWHICH_PHONEME, 0x600},
|
||||
// {"next2PhW", tWHICH_PHONEME, 0x700},
|
||||
{"prevPh", tWHICH_PHONEME, 0},
|
||||
{"prevPhW", tWHICH_PHONEME, 5},
|
||||
{"thisPh", tWHICH_PHONEME, 1},
|
||||
{"nextPh", tWHICH_PHONEME, 2},
|
||||
{"next2Ph", tWHICH_PHONEME, 3},
|
||||
{"nextPhW", tWHICH_PHONEME, 4},
|
||||
{"next2PhW", tWHICH_PHONEME, 6},
|
||||
{"nextVowel",tWHICH_PHONEME, 7},
|
||||
{"prevVowel",tWHICH_PHONEME, 8},
|
||||
// {"next2PhW", tWHICH_PHONEME, 0x800},
|
||||
|
||||
// {"numVowels", tTEST, 0x000},
|
||||
// {"afterStress", tTEST, 0x000},
|
||||
|
||||
{"PreVoicing", tTEST, 0xf01},
|
||||
{"KlattSynth", tTEST, 0xf02},
|
||||
@@ -605,7 +606,7 @@ return;
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
address = ((instn & 0xf) << 16) + *pc++;
|
||||
address = ((instn & 0xf) << 16) + *pc++;
|
||||
fprintf(f_out, " %d %.5x",(instn >> 4) & 0xff,address*4);
|
||||
break;
|
||||
}
|
||||
@@ -770,7 +771,7 @@ static void CompileReport(void)
|
||||
}
|
||||
n = ix;
|
||||
qsort((void *)list,n,sizeof(REF_HASH_TAB *),(int (*)(const void *,const void *))ref_sorter);
|
||||
|
||||
|
||||
data_path = "";
|
||||
prev_mnemonic = 0;
|
||||
prev_table = 0;
|
||||
@@ -1197,7 +1198,7 @@ static int LookupPhoneme(const char *string, int control)
|
||||
|
||||
// don't use phoneme number 0, reserved for string terminator
|
||||
start = 1;
|
||||
|
||||
|
||||
if(control==2)
|
||||
start = 8; // don't look for control and stress phonemes (allows these characters to be
|
||||
// used for other purposes)
|
||||
@@ -1267,12 +1268,12 @@ static int NextItem(int type)
|
||||
int sign;
|
||||
char *p;
|
||||
keywtab_t *pk;
|
||||
|
||||
|
||||
item_type = -1;
|
||||
|
||||
f_in_displ = ftell(f_in);
|
||||
f_in_linenum = linenum;
|
||||
|
||||
|
||||
while(!feof(f_in))
|
||||
{
|
||||
c = get_char();
|
||||
@@ -1592,7 +1593,7 @@ int LoadSpect(const char *path, int control)
|
||||
|
||||
wxString filename = path_phsource + path_sep + wxString(path,wxConvLocal);
|
||||
wxFileInputStream stream(filename);
|
||||
|
||||
|
||||
if(stream.Ok() == FALSE)
|
||||
{
|
||||
error("Failed to open: '%s'",path);
|
||||
@@ -1616,7 +1617,7 @@ int LoadSpect(const char *path, int control)
|
||||
seq_out.sqflags=0;
|
||||
seq_out.length_total=0;
|
||||
|
||||
total = 0;
|
||||
total = 0;
|
||||
for(frame=0; frame < spectseq->numframes; frame++)
|
||||
{
|
||||
|
||||
@@ -1650,7 +1651,7 @@ for(ix=0; ix<8; ix++)
|
||||
seq_out.n_frames++;
|
||||
if(frame > 0)
|
||||
total += spectseq->frames[frame-1]->length;
|
||||
}
|
||||
}
|
||||
}
|
||||
seq_out.length_total = int(total);
|
||||
|
||||
@@ -1665,7 +1666,7 @@ for(ix=0; ix<8; ix++)
|
||||
for(frame=0; frame < spectseq->numframes; frame++)
|
||||
{
|
||||
fr = spectseq->frames[frame];
|
||||
|
||||
|
||||
if(fr->keyframe)
|
||||
{
|
||||
if(klatt_flag)
|
||||
@@ -1756,7 +1757,7 @@ for(ix=0; ix<8; ix++)
|
||||
n_frames++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(klatt_flag)
|
||||
{
|
||||
seqk_out.n_frames = seq_out.n_frames;
|
||||
@@ -1799,7 +1800,7 @@ static int LoadWavefile(FILE *f, const char *fname)
|
||||
fseek(f,24,SEEK_SET);
|
||||
sr1 = Read4Bytes(f);
|
||||
sr2 = Read4Bytes(f);
|
||||
fseek(f,40,SEEK_SET);
|
||||
fseek(f,40,SEEK_SET);
|
||||
|
||||
if((sr1 != samplerate_native) || (sr2 != sr1*2))
|
||||
{
|
||||
@@ -1828,7 +1829,7 @@ static int LoadWavefile(FILE *f, const char *fname)
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
f = fopen(fname_temp,"rb");
|
||||
if(f == NULL)
|
||||
{
|
||||
@@ -2078,7 +2079,7 @@ static int LoadDataFile(const char *path, int control)
|
||||
if(addr == 0)
|
||||
{
|
||||
sprintf(buf,"%s%s",path_source,path);
|
||||
|
||||
|
||||
if((f = fopen(buf,"rb")) == NULL)
|
||||
{
|
||||
sprintf(buf,"%s%s.wav",path_source,path);
|
||||
@@ -2091,7 +2092,7 @@ static int LoadDataFile(const char *path, int control)
|
||||
|
||||
id = Read4Bytes(f);
|
||||
rewind(f);
|
||||
|
||||
|
||||
if(id == 0x43455053)
|
||||
{
|
||||
addr = LoadSpect(path, control);
|
||||
@@ -2121,7 +2122,7 @@ static int LoadDataFile(const char *path, int control)
|
||||
addr = -1;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
|
||||
if(addr > 0)
|
||||
{
|
||||
fprintf(f_phcontents,"%c 0x%.5x %s\n",type_code,addr & 0x7fffff,path);
|
||||
@@ -2188,7 +2189,7 @@ static int CompileToneSpec(void)
|
||||
*prog_out++ = i_AMPENV + ((amp_env >> 16) & 0xf);
|
||||
*prog_out++ = amp_env;
|
||||
}
|
||||
|
||||
|
||||
return(0);
|
||||
} // end of CompileToneSpec
|
||||
|
||||
@@ -2217,7 +2218,7 @@ int CompileSound(int keyword, int isvowel)
|
||||
{
|
||||
value = -128;
|
||||
error("Parameter < -128",NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2256,6 +2257,7 @@ int CompileIf(int elif)
|
||||
int key;
|
||||
int finish = 0;
|
||||
int word = 0;
|
||||
int word2 = 0;
|
||||
int data;
|
||||
int bitmap;
|
||||
int brackets;
|
||||
@@ -2274,10 +2276,18 @@ int CompileIf(int elif)
|
||||
|
||||
if((key = NextItem(tCONDITION)) < 0)
|
||||
error("Expected a condition, not '%s'",item_string);
|
||||
|
||||
|
||||
if(item_type == tWHICH_PHONEME)
|
||||
{
|
||||
// prevPh(), thisPh(), nextPh(), next2Ph()
|
||||
// prevPh(), thisPh(), nextPh(), next2Ph() etc
|
||||
if(key >= 6)
|
||||
{
|
||||
// put the 'which' code in the next instruction
|
||||
word2 = key;
|
||||
key = 6;
|
||||
}
|
||||
key = key << 8;
|
||||
|
||||
data = NextItemBrackets(tPROPERTIES,0);
|
||||
if(data >= 0)
|
||||
{
|
||||
@@ -2320,6 +2330,9 @@ int CompileIf(int elif)
|
||||
prog_last_if = prog_out;
|
||||
*prog_out++ = word | i_CONDITION;
|
||||
|
||||
if(word2 != 0)
|
||||
*prog_out++ = word2;
|
||||
|
||||
// expect AND, OR, THEN
|
||||
switch(NextItem(tCONDITION))
|
||||
{
|
||||
@@ -2416,7 +2429,7 @@ int CompileElse(void)
|
||||
{
|
||||
ref = prog_out;
|
||||
*prog_out++ = 0;
|
||||
|
||||
|
||||
if((p = if_stack[if_level].p_else) != NULL)
|
||||
{
|
||||
*ref = ref - p; // backwards offset to the previous else
|
||||
@@ -2461,14 +2474,14 @@ int CompileEndif(void)
|
||||
do
|
||||
{
|
||||
chain = *p; // a chain of previous else links
|
||||
|
||||
|
||||
offset = prog_out - p;
|
||||
if(offset > MAX_JUMP)
|
||||
{
|
||||
error("IF block is too long",NULL);
|
||||
}
|
||||
*p = i_JUMP + offset;
|
||||
|
||||
|
||||
p -= chain;
|
||||
} while (chain > 0);
|
||||
}
|
||||
@@ -2489,7 +2502,7 @@ static int CompileSwitch(int type)
|
||||
// check the instructions in the Switch
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
// count_VowelStart = 0;
|
||||
// count_VowelEnding = 0;
|
||||
|
||||
@@ -2664,7 +2677,7 @@ int CompilePhoneme(int compile_phoneme)
|
||||
phoneme_flags = 0;
|
||||
place_articulation = 0;
|
||||
|
||||
NextItem(tSTRING);
|
||||
NextItem(tSTRING);
|
||||
if(compile_phoneme)
|
||||
{
|
||||
phcode = LookupPhoneme(item_string,1); // declare phoneme if not already there
|
||||
@@ -2825,7 +2838,7 @@ int CompilePhoneme(int compile_phoneme)
|
||||
phcode = LookupPhoneme(item_string,1);
|
||||
phoneme_out->start_type = phcode;
|
||||
break;
|
||||
|
||||
|
||||
case kENDTYPE:
|
||||
phcode = NextItem(tPHONEMEMNEM);
|
||||
if(phcode == -1)
|
||||
@@ -2882,7 +2895,7 @@ int CompilePhoneme(int compile_phoneme)
|
||||
case kSWITCH_PREVVOWEL:
|
||||
endphoneme = CompileSwitch(1);
|
||||
break;
|
||||
|
||||
|
||||
case kSWITCH_NEXTVOWEL:
|
||||
endphoneme = CompileSwitch(2);
|
||||
break;
|
||||
@@ -2908,7 +2921,7 @@ int CompilePhoneme(int compile_phoneme)
|
||||
DecThenCount();
|
||||
endphoneme = CompileSound(keyword,0);
|
||||
break;
|
||||
|
||||
|
||||
case kVOWELIN:
|
||||
DecThenCount();
|
||||
endphoneme = CompileVowelTransition(1);
|
||||
@@ -2968,7 +2981,7 @@ int CompilePhoneme(int compile_phoneme)
|
||||
}
|
||||
phoneme_out->phflags = place_articulation << 16;
|
||||
phoneme_out->phflags |= phoneme_flags;
|
||||
|
||||
|
||||
if(phoneme_out->phflags & phVOICED)
|
||||
{
|
||||
if(phoneme_out->type == phSTOP)
|
||||
@@ -2977,15 +2990,15 @@ int CompilePhoneme(int compile_phoneme)
|
||||
if(phoneme_out->type == phFRICATIVE)
|
||||
phoneme_out->type = phVFRICATIVE;
|
||||
}
|
||||
|
||||
|
||||
if(phoneme_out->std_length == 0)
|
||||
{
|
||||
if(phoneme_out->type == phVOWEL)
|
||||
phoneme_out->std_length = 180/2; // default length for vowel
|
||||
}
|
||||
|
||||
|
||||
phoneme_out->phflags |= phLOCAL; //declared in this phoneme table
|
||||
|
||||
|
||||
if(phoneme_out->type == phDELETED)
|
||||
{
|
||||
phoneme_out->mnemonic = 0x01; // will not be recognised
|
||||
@@ -3334,7 +3347,7 @@ static void CompilePhonemeFiles()
|
||||
stack[stack_ix].linenum = linenum;
|
||||
strcpy(stack[stack_ix].fname,current_fname);
|
||||
stack[stack_ix++].file = f_in;
|
||||
|
||||
|
||||
f_in = f;
|
||||
strncpy0(current_fname,item_string,sizeof(current_fname));
|
||||
linenum = 1;
|
||||
@@ -3382,7 +3395,7 @@ static void CompilePhonemeData2(const char *source)
|
||||
wxString report_dict;
|
||||
|
||||
#ifdef MAKE_ENVELOPES
|
||||
make_envs();
|
||||
make_envs();
|
||||
#endif
|
||||
|
||||
n_envelopes = 0;
|
||||
@@ -3525,7 +3538,7 @@ fprintf(f_errors,"\nRefs %d, Reused %d\n",count_references,duplicate_references
|
||||
{
|
||||
strncpy0(fname,(report+report_dict).mb_str(wxConvLocal),sizeof(fname));
|
||||
fprintf(stderr,"%s\n",fname);
|
||||
|
||||
|
||||
}
|
||||
} // end of CompilePhonemeData
|
||||
|
||||
@@ -3605,7 +3618,7 @@ void CompileMbrola()
|
||||
wxLogError(_T("Can't write to: ")+wxString(buf,wxConvLocal));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
data[count].name = 0; // list terminator
|
||||
Write4Bytes(f_out, mbrola_ctrl);
|
||||
|
||||
|
||||
+38
-38
@@ -18,7 +18,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
@@ -218,7 +218,7 @@ static void InitGroups(Translator *tr)
|
||||
{
|
||||
if(tr->groups2_start[c] == 255)
|
||||
tr->groups2_start[c] = tr->n_groups2;
|
||||
|
||||
|
||||
tr->groups2_count[c]++;
|
||||
tr->groups2[tr->n_groups2] = p;
|
||||
tr->groups2_name[tr->n_groups2++] = (c + (c2 << 8));
|
||||
@@ -489,7 +489,7 @@ sprintf(outptr,"* ");
|
||||
continue; /* indicates unrecognised phoneme */
|
||||
if((ph = phoneme_tab[phcode]) == NULL)
|
||||
continue;
|
||||
|
||||
|
||||
if((ph->type == phSTRESS) && (ph->std_length <= 4) && (ph->program == 0))
|
||||
{
|
||||
if(ph->std_length > 1)
|
||||
@@ -499,7 +499,7 @@ sprintf(outptr,"* ");
|
||||
{
|
||||
mnem = ph->mnemonic;
|
||||
|
||||
while((c = (mnem & 0xff)) != 0)
|
||||
while((c = (mnem & 0xff)) != 0)
|
||||
{
|
||||
*outptr++ = c;
|
||||
mnem = mnem >> 8;
|
||||
@@ -565,7 +565,7 @@ char *WritePhMnemonic(char *phon_out, PHONEME_TAB *ph, PHONEME_LIST *plist, int
|
||||
}
|
||||
else
|
||||
{
|
||||
InterpretPhoneme(NULL, 0, plist, &phdata);
|
||||
InterpretPhoneme(NULL, 0, plist, &phdata, NULL);
|
||||
}
|
||||
|
||||
len = strlen(phdata.ipa_string);
|
||||
@@ -638,7 +638,7 @@ void GetTranslatedPhonemeString(char *phon_out, int n_phon_out, int use_ipa)
|
||||
char *buf;
|
||||
char phon_buf[30];
|
||||
PHONEME_LIST *plist;
|
||||
|
||||
|
||||
static const char *stress_chars = "==,,''";
|
||||
|
||||
if(phon_out != NULL)
|
||||
@@ -694,7 +694,7 @@ void GetTranslatedPhonemeString(char *phon_out, int n_phon_out, int use_ipa)
|
||||
buf = WritePhMnemonic(buf, phoneme_tab[plist->tone_ph], NULL, use_ipa);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
len = buf - phon_buf;
|
||||
max_len = (n_phon_out - phon_out_ix - 5); // allow for " ..." and zero byte terminator
|
||||
if(len > max_len)
|
||||
@@ -939,7 +939,7 @@ static int GetVowelStress(Translator *tr, unsigned char *phonemes, signed char *
|
||||
max_stress = 4;
|
||||
primary_posn = j;
|
||||
}
|
||||
|
||||
|
||||
/* reduce any preceding primary stress markers */
|
||||
for(ix=1; ix<j; ix++)
|
||||
{
|
||||
@@ -1166,7 +1166,7 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
|
||||
max_output = output + (N_WORD_PHONEMES-3); /* check for overrun */
|
||||
|
||||
// any stress position marked in the xx_list dictionary ?
|
||||
// any stress position marked in the xx_list dictionary ?
|
||||
stressed_syllable = dflags & 0x7;
|
||||
if(dflags & 0x8)
|
||||
{
|
||||
@@ -1217,7 +1217,7 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
ix++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch(tr->langopts.stress_rule)
|
||||
{
|
||||
case 8:
|
||||
@@ -1275,12 +1275,12 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
mnem = phoneme_tab[final_ph]->mnemonic;
|
||||
mnem2 = phoneme_tab[final_ph2]->mnemonic;
|
||||
|
||||
if((mnem == 's') && (mnem2 == 'n'))
|
||||
if((mnem == 's') && (phoneme_tab[final_ph2]->type == phNASAL))
|
||||
{
|
||||
// -ns stress remains on penultimate syllable
|
||||
}
|
||||
else
|
||||
if(((mnem != 'n') && (mnem != 's')) || (phoneme_tab[final_ph2]->type != phVOWEL))
|
||||
if(((phoneme_tab[final_ph]->type != phNASAL) && (mnem != 's')) || (phoneme_tab[final_ph2]->type != phVOWEL))
|
||||
{
|
||||
stressed_syllable = vowel_count - 1;
|
||||
}
|
||||
@@ -1710,7 +1710,7 @@ void AppendPhonemes(Translator *tr, char *string, int size, const char *ph)
|
||||
/* Add new phoneme string "ph" to "string"
|
||||
Keeps count of the number of vowel phonemes in the word, and whether these
|
||||
can be stressed syllables. These values can be used in translation rules
|
||||
*/
|
||||
*/
|
||||
const char *p;
|
||||
unsigned char c;
|
||||
int unstress_mark;
|
||||
@@ -1748,7 +1748,7 @@ void AppendPhonemes(Translator *tr, char *string, int size, const char *ph)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(string != NULL)
|
||||
strcat(string,ph);
|
||||
} /* end of AppendPhonemes */
|
||||
@@ -1843,7 +1843,7 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_
|
||||
match.points = 1;
|
||||
match.end_type = 0;
|
||||
match.del_fwd = NULL;
|
||||
|
||||
|
||||
pre_ptr = *word;
|
||||
post_ptr = *word + group_length;
|
||||
|
||||
@@ -1909,7 +1909,7 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_
|
||||
case RULE_CONDITION:
|
||||
/* conditional rule, next byte gives condition number */
|
||||
condition_num = *rule++;
|
||||
|
||||
|
||||
if(condition_num >= 32)
|
||||
{
|
||||
// allow the rule only if the condition number is NOT set
|
||||
@@ -2017,7 +2017,7 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_
|
||||
else
|
||||
failed = 1;
|
||||
break;
|
||||
|
||||
|
||||
case RULE_NONALPHA:
|
||||
if(!iswalpha(letter_w))
|
||||
{
|
||||
@@ -2388,13 +2388,13 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_
|
||||
memcpy(&best,&match,sizeof(match));
|
||||
total_consumed = consumed;
|
||||
}
|
||||
|
||||
|
||||
if((option_phonemes == 2) && (match.points > 0) && ((word_flags & FLAG_NO_TRACE) == 0))
|
||||
{
|
||||
// show each rule that matches, and it's points score
|
||||
int pts;
|
||||
char decoded_phonemes[80];
|
||||
|
||||
|
||||
pts = match.points;
|
||||
if(group_length > 1)
|
||||
pts += 35; // to account for an extra letter matching
|
||||
@@ -2490,10 +2490,10 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c
|
||||
p = p_start;
|
||||
tr->word_vowel_count = 0;
|
||||
tr->word_stressed_count = 0;
|
||||
|
||||
|
||||
if(end_phonemes != NULL)
|
||||
end_phonemes[0] = 0;
|
||||
|
||||
|
||||
while(((c = *p) != ' ') && (c != 0))
|
||||
{
|
||||
wc_bytes = utf8_in(&wc,p);
|
||||
@@ -2511,7 +2511,7 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c
|
||||
string[1+wc_bytes] = 0;
|
||||
Lookup(tr, string,buf);
|
||||
if(++digit_count >= 2)
|
||||
{
|
||||
{
|
||||
strcat(buf,str_pause);
|
||||
digit_count=0;
|
||||
}
|
||||
@@ -2538,7 +2538,7 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c
|
||||
/* there are some 2 byte chains for this initial letter */
|
||||
c2 = p[1];
|
||||
c12 = c + (c2 << 8); /* 2 characters */
|
||||
|
||||
|
||||
g1 = tr->groups2_start[c];
|
||||
for(g=g1; g < (g1+n); g++)
|
||||
{
|
||||
@@ -2563,7 +2563,7 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(!found)
|
||||
{
|
||||
/* alphabetic, single letter chain */
|
||||
@@ -2619,14 +2619,14 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c
|
||||
p[-1] = ix;
|
||||
while((p[0] = p[n]) != ' ') p++;
|
||||
while(n-- > 0) *p++ = ' '; // replacement character must be no longer than original
|
||||
|
||||
|
||||
if(tr->langopts.param[LOPT_DIERESES] && (lookupwchar(diereses_list,letter) > 0))
|
||||
{
|
||||
// vowel with dieresis, replace and continue from this point
|
||||
p = p2;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
phonemes[0] = 0; // delete any phonemes which have been produced so far
|
||||
p = p_start;
|
||||
tr->word_vowel_count = 0;
|
||||
@@ -2685,7 +2685,7 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c
|
||||
|
||||
if(match1.phonemes == NULL)
|
||||
match1.phonemes = "";
|
||||
|
||||
|
||||
if(match1.points > 0)
|
||||
{
|
||||
if(word_flags & FLAG_UNPRON_TEST)
|
||||
@@ -2888,7 +2888,7 @@ int TransposeAlphabet(Translator *tr, char *text)
|
||||
if(bits >= 8)
|
||||
{
|
||||
bits -= 8;
|
||||
*p2++ = (acc >> bits);
|
||||
*p2++ = (acc >> bits);
|
||||
}
|
||||
}
|
||||
if(bits > 0)
|
||||
@@ -3206,7 +3206,7 @@ static const char *LookupDict2(Translator *tr, const char *word, const char *wor
|
||||
|
||||
if(flags != NULL)
|
||||
flags[0] |= FLAG_FOUND; // this flag indicates word was found in dictionary
|
||||
|
||||
|
||||
if(option_phonemes == 2)
|
||||
{
|
||||
char ph_decoded[N_WORD_PHONEMES];
|
||||
@@ -3344,9 +3344,9 @@ int LookupDictList(Translator *tr, char **wordptr, char *ph_out, unsigned int *f
|
||||
if(found == 0)
|
||||
{
|
||||
ph_out[0] = 0;
|
||||
|
||||
|
||||
// try modifications to find a recognised word
|
||||
|
||||
|
||||
if((end_flags & FLAG_SUFX_E_ADDED) && (word[length-1] == 'e'))
|
||||
{
|
||||
// try removing an 'e' which has been added by RemoveEnding
|
||||
@@ -3439,7 +3439,7 @@ int RemoveEnding(Translator *tr, char *word, int end_type, char *word_copy)
|
||||
This routine is language specific. In English it deals with reversing y->i and e-dropping
|
||||
that were done when the suffix was added to the original word.
|
||||
*/
|
||||
|
||||
|
||||
int i;
|
||||
char *word_end;
|
||||
int len_ending;
|
||||
@@ -3447,7 +3447,7 @@ int RemoveEnding(Translator *tr, char *word, int end_type, char *word_copy)
|
||||
const char *p;
|
||||
int len;
|
||||
static char ending[12];
|
||||
|
||||
|
||||
// these lists are language specific, but are only relevent if the 'e' suffix flag is used
|
||||
static const char *add_e_exceptions[] = {
|
||||
"ion", NULL };
|
||||
@@ -3476,7 +3476,7 @@ int RemoveEnding(Translator *tr, char *word, int end_type, char *word_copy)
|
||||
len_ending++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// remove bytes from the end of the word and replace them by spaces
|
||||
for(i=0; i<len_ending; i++)
|
||||
{
|
||||
@@ -3487,17 +3487,17 @@ int RemoveEnding(Translator *tr, char *word, int end_type, char *word_copy)
|
||||
word_end--; /* now pointing at last character of stem */
|
||||
|
||||
end_flags = (end_type & 0xfff0) | FLAG_SUFX;
|
||||
|
||||
|
||||
/* add an 'e' to the stem if appropriate,
|
||||
if stem ends in vowel+consonant
|
||||
or stem ends in 'c' (add 'e' to soften it) */
|
||||
|
||||
|
||||
if(end_type & SUFX_I)
|
||||
{
|
||||
if(word_end[0] == 'i')
|
||||
word_end[0] = 'y';
|
||||
}
|
||||
|
||||
|
||||
if(end_type & SUFX_E)
|
||||
{
|
||||
if(tr->translator_name == L('n','l'))
|
||||
@@ -3517,7 +3517,7 @@ int RemoveEnding(Translator *tr, char *word, int end_type, char *word_copy)
|
||||
if(IsLetter(tr, word_end[-1],LETTERGP_VOWEL2) && IsLetter(tr, word_end[0],1))
|
||||
{
|
||||
// vowel(incl.'y') + hard.consonant
|
||||
|
||||
|
||||
for(i=0; (p = add_e_exceptions[i]) != NULL; i++)
|
||||
{
|
||||
len = strlen(p);
|
||||
|
||||
+13
-11
@@ -63,24 +63,24 @@ static int SubstitutePhonemes(Translator *tr, PHONEME_LIST *plist_out)
|
||||
{
|
||||
if(ix < (n_ph_list2 -1))
|
||||
next = phoneme_tab[ph_list2[ix+1].phcode];
|
||||
|
||||
|
||||
word_end = 0;
|
||||
if((plist2+1)->sourceix || ((next != 0) && (next->type == phPAUSE)))
|
||||
word_end = 1; // this phoneme is the end of a word
|
||||
|
||||
|
||||
// check whether a Voice has specified that we should replace this phoneme
|
||||
for(k=0; k<n_replace_phonemes; k++)
|
||||
{
|
||||
if(plist2->phcode == replace_phonemes[k].old_ph)
|
||||
{
|
||||
replace_flags = replace_phonemes[k].type;
|
||||
|
||||
|
||||
if((replace_flags & 1) && (word_end == 0))
|
||||
continue; // this replacement only occurs at the end of a word
|
||||
|
||||
|
||||
if((replace_flags & 2) && ((plist2->stresslevel & 0x7) > 3))
|
||||
continue; // this replacement doesn't occur in stressed syllables
|
||||
|
||||
|
||||
// substitute the replacement phoneme
|
||||
plist2->phcode = replace_phonemes[k].new_ph;
|
||||
if((plist2->stresslevel > 1) && (phoneme_tab[plist2->phcode]->phflags & phUNSTRESSED))
|
||||
@@ -88,7 +88,7 @@ static int SubstitutePhonemes(Translator *tr, PHONEME_LIST *plist_out)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(plist2->phcode == 0)
|
||||
{
|
||||
continue; // phoneme has been replaced by NULL, so don't copy it
|
||||
@@ -131,7 +131,9 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
|
||||
PHONEME_LIST ph_list3[N_PHONEME_LIST];
|
||||
|
||||
PHONEME_LIST2 *plist2;
|
||||
WORD_PH_DATA worddata;
|
||||
|
||||
memset(&worddata, 0, sizeof(worddata));
|
||||
plist2 = ph_list2;
|
||||
phlist = phoneme_list;
|
||||
end_sourceix = plist2[n_ph_list2-1].sourceix;
|
||||
@@ -339,7 +341,7 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
|
||||
|
||||
if(ph == NULL) continue;
|
||||
|
||||
InterpretPhoneme(tr, 0x100, plist3, &phdata);
|
||||
InterpretPhoneme(tr, 0x100, plist3, &phdata, &worddata);
|
||||
|
||||
if((alternative = phdata.pd_param[pd_INSERTPHONEME]) > 0)
|
||||
{
|
||||
@@ -363,7 +365,7 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
|
||||
|
||||
// re-interpret the changed phoneme
|
||||
// But it doesn't obey a second ChangePhoneme()
|
||||
InterpretPhoneme(tr, 0x100, plist3, &phdata);
|
||||
InterpretPhoneme(tr, 0x100, plist3, &phdata, &worddata);
|
||||
}
|
||||
|
||||
if((alternative = phdata.pd_param[pd_CHANGEPHONEME]) > 0)
|
||||
@@ -388,7 +390,7 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
|
||||
|
||||
// re-interpret the changed phoneme
|
||||
// But it doesn't obey a second ChangePhoneme()
|
||||
InterpretPhoneme(tr, 0x100, plist3, &phdata);
|
||||
InterpretPhoneme(tr, 0x100, plist3, &phdata, &worddata);
|
||||
}
|
||||
|
||||
if(ph->type == phVOWEL)
|
||||
@@ -478,7 +480,7 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
|
||||
else
|
||||
insert_ph = phonPAUSE_VSHORT;
|
||||
}
|
||||
|
||||
|
||||
if((ph->type == phVOWEL) && ((x = tr->langopts.vowel_pause & 0x03) != 0))
|
||||
{
|
||||
// adjacent vowels over a word boundary
|
||||
@@ -487,7 +489,7 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
|
||||
else
|
||||
insert_ph = phonPAUSE_VSHORT;
|
||||
}
|
||||
|
||||
|
||||
if(((plist3+1)->stresslevel >= 4) && (tr->langopts.vowel_pause & 0x100))
|
||||
{
|
||||
// pause before a words which starts with a stressed vowel
|
||||
|
||||
+12
-12
@@ -77,7 +77,7 @@ HINSTANCE hinstDllMBR = NULL;
|
||||
BOOL load_MBR()
|
||||
{
|
||||
if(hinstDllMBR != NULL)
|
||||
return TRUE; // already loaded
|
||||
return TRUE; // already loaded
|
||||
|
||||
if ((hinstDllMBR=LoadLibraryA("mbrola.dll")) == 0)
|
||||
return FALSE;
|
||||
@@ -150,14 +150,14 @@ espeak_ERROR LoadMbrolaTable(const char *mbrola_voice, const char *phtrans, int
|
||||
}
|
||||
}
|
||||
}
|
||||
close_MBR();
|
||||
close_MBR();
|
||||
#endif
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
if(load_MBR() == FALSE) // load mbrola.dll
|
||||
{
|
||||
fprintf(stderr, "Can't load mbrola.dll\n");
|
||||
return(EE_INTERNAL_ERROR);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(init_MBR(path) != 0) // initialise the required mbrola voice
|
||||
@@ -169,14 +169,14 @@ espeak_ERROR LoadMbrolaTable(const char *mbrola_voice, const char *phtrans, int
|
||||
sprintf(path,"%s/mbrola_ph/%s",path_home,phtrans);
|
||||
size = GetFileLength(path);
|
||||
if((f_in = fopen(path,"rb")) == NULL) {
|
||||
close_MBR();
|
||||
close_MBR();
|
||||
return(EE_NOT_FOUND);
|
||||
}
|
||||
|
||||
if((mbrola_tab = (MBROLA_TAB *)realloc(mbrola_tab,size)) == NULL)
|
||||
{
|
||||
fclose(f_in);
|
||||
close_MBR();
|
||||
close_MBR();
|
||||
return(EE_INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ espeak_ERROR LoadMbrolaTable(const char *mbrola_voice, const char *phtrans, int
|
||||
fclose(f_in);
|
||||
|
||||
setVolumeRatio_MBR((float)(mbrola_control & 0xff) /16.0f);
|
||||
// srate = getFreq_MBR();
|
||||
// srate = getFreq_MBR();
|
||||
samplerate = srate;
|
||||
if(srate == 22050)
|
||||
SetParameter(espeakVOICETYPE,0,0);
|
||||
@@ -543,7 +543,7 @@ int MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, int resume, FILE *f_mbr
|
||||
|
||||
if(released == 0)
|
||||
p->synthflags |= SFLAG_NEXT_PAUSE;
|
||||
InterpretPhoneme(NULL, 0, p, &phdata);
|
||||
InterpretPhoneme(NULL, 0, p, &phdata, NULL);
|
||||
len = DoSample3(&phdata, 0, -1);
|
||||
|
||||
len = (len * 1000)/samplerate; // convert to mS
|
||||
@@ -556,7 +556,7 @@ int MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, int resume, FILE *f_mbr
|
||||
|
||||
case phFRICATIVE:
|
||||
len = 0;
|
||||
InterpretPhoneme(NULL, 0, p, &phdata);
|
||||
InterpretPhoneme(NULL, 0, p, &phdata, NULL);
|
||||
if(p->synthflags & SFLAG_LENGTHEN)
|
||||
len = DoSample3(&phdata, p->length, -1); // play it twice for [s:] etc.
|
||||
len += DoSample3(&phdata, p->length, -1);
|
||||
@@ -568,7 +568,7 @@ int MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, int resume, FILE *f_mbr
|
||||
if(next->type != phVOWEL)
|
||||
{
|
||||
memset(&fmtp, 0, sizeof(fmtp));
|
||||
InterpretPhoneme(NULL, 0, p, &phdata);
|
||||
InterpretPhoneme(NULL, 0, p, &phdata, NULL);
|
||||
fmtp.fmt_addr = phdata.sound_addr[pd_FMT];
|
||||
len = DoSpect2(p->ph, 0, &fmtp, p, -1);
|
||||
// len = DoSpect(p->ph,prev->ph,phoneme_tab[phonPAUSE],2,p,-1);
|
||||
@@ -601,7 +601,7 @@ int MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, int resume, FILE *f_mbr
|
||||
|
||||
if(pause)
|
||||
{
|
||||
len += PauseLength(pause,0);
|
||||
len += PauseLength(pause,0);
|
||||
ptr += sprintf(ptr,"_ \t%d\n",PauseLength(pause,0));
|
||||
pause = 0;
|
||||
}
|
||||
@@ -655,7 +655,7 @@ int MbrolaGenerate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
|
||||
int again = MbrolaTranslate(phoneme_list, *n_ph, resume, f_mbrola);
|
||||
if (!again)
|
||||
*n_ph = 0;
|
||||
return again;
|
||||
return again;
|
||||
}
|
||||
|
||||
|
||||
@@ -710,7 +710,7 @@ void MbrolaReset(void)
|
||||
|
||||
espeak_ERROR LoadMbrolaTable(const char *mbrola_voice, const char *phtrans, int srate)
|
||||
{
|
||||
return(EE_INTERNAL_ERROR);
|
||||
return(EE_INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
int MbrolaGenerate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
|
||||
|
||||
+110
-50
@@ -35,8 +35,8 @@
|
||||
#include "translate.h"
|
||||
#include "wave.h"
|
||||
|
||||
const char *version_string = "1.46.23 09.Sep.12";
|
||||
const int version_phdata = 0x014600;
|
||||
const char *version_string = "1.46.24 11.Sep.12";
|
||||
const int version_phdata = 0x014624;
|
||||
|
||||
int option_device_number = -1;
|
||||
FILE *f_logespeak = NULL;
|
||||
@@ -80,7 +80,7 @@ static char *ReadPhFile(void *ptr, const char *fname, int *size)
|
||||
|
||||
sprintf(buf,"%s%c%s",path_home,PATHSEP,fname);
|
||||
length = GetFileLength(buf);
|
||||
|
||||
|
||||
if((f_in = fopen(buf,"rb")) == NULL)
|
||||
{
|
||||
fprintf(stderr,"Can't read data file: '%s'\n",buf);
|
||||
@@ -89,7 +89,7 @@ static char *ReadPhFile(void *ptr, const char *fname, int *size)
|
||||
|
||||
if(ptr != NULL)
|
||||
Free(ptr);
|
||||
|
||||
|
||||
if((p = Alloc(length)) == NULL)
|
||||
{
|
||||
fclose(f_in);
|
||||
@@ -230,7 +230,7 @@ frameref_t *LookupSpect(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params,
|
||||
SPECT_SEQK *seqk, *seqk2;
|
||||
frame_t *frame;
|
||||
static frameref_t frames_buf[N_SEQ_FRAMES];
|
||||
|
||||
|
||||
seq = (SPECT_SEQ *)(&phondata_ptr[fmt_params->fmt_addr]);
|
||||
seqk = (SPECT_SEQK *)seq;
|
||||
nf = seq->n_frames;
|
||||
@@ -268,7 +268,7 @@ frameref_t *LookupSpect(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params,
|
||||
nf -= seq_break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// do we need to modify a frame for blending with a consonant?
|
||||
if((this_ph->type == phVOWEL) && (fmt_params->fmt2_addr == 0) && (fmt_params->use_vowelin))
|
||||
{
|
||||
@@ -286,7 +286,7 @@ frameref_t *LookupSpect(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params,
|
||||
// add these spectra to the main sequence
|
||||
seq2 = (SPECT_SEQ *)(&phondata_ptr[fmt_params->fmt2_addr]);
|
||||
seqk2 = (SPECT_SEQK *)seq2;
|
||||
|
||||
|
||||
// first frame of the addition just sets the length of the last frame of the main seq
|
||||
nf--;
|
||||
for(ix=0; ix<seq2->n_frames; ix++)
|
||||
@@ -306,7 +306,7 @@ frameref_t *LookupSpect(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params,
|
||||
}
|
||||
wavefile_ix = 0;
|
||||
}
|
||||
|
||||
|
||||
if(length1 > 0)
|
||||
{
|
||||
if(which==2)
|
||||
@@ -324,7 +324,7 @@ frameref_t *LookupSpect(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params,
|
||||
|
||||
|
||||
length_factor = (length_std * 256)/ length1;
|
||||
|
||||
|
||||
for(ix=0; ix<nf1; ix++)
|
||||
{
|
||||
frames[ix].length = (frames[ix].length * length_factor)/256;
|
||||
@@ -362,7 +362,7 @@ frameref_t *LookupSpect(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
*n_frames = nf;
|
||||
return(frames);
|
||||
} // end of LookupSpect
|
||||
@@ -562,7 +562,7 @@ static bool StressCondition(Translator *tr, PHONEME_LIST *plist, int condition,
|
||||
// change phoneme. Don't change phonemes which are given for the word in the dictionary.
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
if((tr->langopts.param[LOPT_REDUCE] & 0x2) && (stress_level >= pl->wordstress))
|
||||
{
|
||||
// treat the most stressed syllable in an unstressed word as stressed
|
||||
@@ -607,69 +607,107 @@ static int CountVowelPosition(PHONEME_LIST *plist)
|
||||
} // end of CoundVowelPosition
|
||||
|
||||
|
||||
static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist, int instn)
|
||||
{//========================================================================================
|
||||
static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist, USHORT *p_prog, WORD_PH_DATA *worddata)
|
||||
{//========================================================================================================================
|
||||
int which;
|
||||
unsigned int data;
|
||||
int instn;
|
||||
int instn2;
|
||||
int count;
|
||||
PHONEME_TAB *ph;
|
||||
PHONEME_LIST *plist_this;
|
||||
static int ph_position[8] = {0, 1, 2, 3, 2, 0, 1, 3}; // prevPh, thisPh, nextPh, next2Ph, nextPhW, prevPhW, nextVowel, (other conditions)
|
||||
|
||||
// instruction: 2xxx, 3xxx
|
||||
|
||||
// bits 8-10 = 0 to 6, which phoneme
|
||||
// bits 8-10 = 0 to 5, which phoneme, =6 the 'which' information is in the next instruction.
|
||||
// bit 11 = 0, bits 0-7 are a phoneme code
|
||||
// bit 11 = 1, bits 5-7 type of data, bits 0-4 data value
|
||||
|
||||
// bits 8-10 = 7, other conditions
|
||||
|
||||
|
||||
instn = (*p_prog) & 0xfff;
|
||||
data = instn & 0xff;
|
||||
instn2 = instn >> 8;
|
||||
|
||||
if(instn2 < 14)
|
||||
{
|
||||
plist_this = plist;
|
||||
which = (instn2) % 7;
|
||||
|
||||
if(which==6)
|
||||
{
|
||||
// the 'which' code is in the next instruction
|
||||
p_prog++;
|
||||
which = (*p_prog);
|
||||
}
|
||||
|
||||
if(which==4)
|
||||
{
|
||||
// nextPh not word boundary
|
||||
// nextPhW not word boundary
|
||||
if(plist[1].sourceix)
|
||||
return(false);
|
||||
}
|
||||
if(which==5)
|
||||
{
|
||||
// prevPh, not word boundary
|
||||
// prevPhW, not word boundary
|
||||
if(plist[0].sourceix)
|
||||
return(false);
|
||||
}
|
||||
if(which==6)
|
||||
{
|
||||
{
|
||||
// next2PhW, not word boundary
|
||||
if(plist[1].sourceix || plist[2].sourceix)
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
switch(which)
|
||||
{
|
||||
case 0: // prevPh
|
||||
case 5: // prevPhW
|
||||
plist--;
|
||||
break;
|
||||
|
||||
case 1: // thisPh
|
||||
break;
|
||||
|
||||
case 2: // nextPh
|
||||
case 4: // nextPhW
|
||||
plist++;
|
||||
break;
|
||||
|
||||
case 3: // next2Ph
|
||||
case 6: // next2PhW
|
||||
plist += 2;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
// nextVowel, not word boundary
|
||||
for(which=2;;which++)
|
||||
for(which=1;;which++)
|
||||
{
|
||||
if(plist[which-1].sourceix)
|
||||
if(plist[which].sourceix)
|
||||
return(false);
|
||||
if(phoneme_tab[plist[which-1].phcode]->type == phVOWEL)
|
||||
if(phoneme_tab[plist[which].phcode]->type == phVOWEL)
|
||||
{
|
||||
plist = &plist[which];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
which = ph_position[which];
|
||||
}
|
||||
break;
|
||||
|
||||
plist_this = plist;
|
||||
plist = &plist[which-1];
|
||||
case 8: // prevVowel in this word
|
||||
if((worddata==NULL) || (worddata->prev_vowel.ph == NULL))
|
||||
return(false); // no previous vowel
|
||||
plist = &(worddata->prev_vowel);
|
||||
break;
|
||||
}
|
||||
|
||||
if(which == 0)
|
||||
if((which == 0) || (which == 5))
|
||||
{
|
||||
if(plist->phcode == 1)
|
||||
{
|
||||
// This is a NULL phoneme, a phoneme has been deleted so look at the previous phoneme
|
||||
plist = &plist[-1];
|
||||
plist--;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -739,7 +777,7 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist,
|
||||
plist--;
|
||||
if((plist->stresslevel & 0xf) >= 4)
|
||||
return(true);
|
||||
|
||||
|
||||
} while (plist->sourceix == 0);
|
||||
break;
|
||||
|
||||
@@ -814,8 +852,8 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist,
|
||||
} // end of InterpretCondition
|
||||
|
||||
|
||||
static void SwitchVowelType(PHONEME_LIST *plist, PHONEME_DATA *phdata, USHORT **p_prog, int instn_type)
|
||||
{//=====================================================================================================
|
||||
static void SwitchOnVowelType(PHONEME_LIST *plist, PHONEME_DATA *phdata, USHORT **p_prog, int instn_type)
|
||||
{//========================================================================================================
|
||||
USHORT *prog;
|
||||
int voweltype;
|
||||
signed char x;
|
||||
@@ -848,18 +886,27 @@ static int NumInstnWords(USHORT *prog)
|
||||
int instn;
|
||||
int instn2;
|
||||
int instn_type;
|
||||
static char n_words[11] = {1,1,1,1,1,1,1,1,1,2,4};
|
||||
int n;
|
||||
static const char n_words[16] = {1,1,0,0,1,1,1,1,1,2,4,0,0,0,0,0};
|
||||
|
||||
instn = *prog;
|
||||
instn_type = instn >> 12;
|
||||
if(instn_type < 11)
|
||||
return(n_words[instn_type]);
|
||||
if((n = n_words[instn_type]) > 0)
|
||||
return(n);
|
||||
|
||||
// 11 to 15, 2 words
|
||||
if(instn_type < 4)
|
||||
{
|
||||
// a condition, check for a 2-word instruction
|
||||
if(((n = instn & 0x0f00) == 0x600) || (n == 0x0d00))
|
||||
return(2);
|
||||
return(1);
|
||||
}
|
||||
|
||||
// instn_type 11 to 15, 2 words
|
||||
instn2 = prog[2];
|
||||
if((instn2 >> 12) == 0xf)
|
||||
{
|
||||
// addWav(), 2 more words
|
||||
// This instruction is followed by addWav(), 2 more words
|
||||
return(4);
|
||||
}
|
||||
if(instn2 == i_CONTINUE)
|
||||
@@ -871,8 +918,8 @@ static int NumInstnWords(USHORT *prog)
|
||||
|
||||
|
||||
|
||||
void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_DATA *phdata)
|
||||
{//==========================================================================================
|
||||
void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_DATA *phdata, WORD_PH_DATA *worddata)
|
||||
{//===================================================================================================================
|
||||
// control:
|
||||
//bit 0: PreVoicing
|
||||
//bit 8: change phonemes
|
||||
@@ -893,6 +940,12 @@ void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_
|
||||
|
||||
ph = plist->ph;
|
||||
|
||||
if((worddata != NULL) && (plist->sourceix))
|
||||
{
|
||||
// start of a word, reset word data
|
||||
worddata->prev_vowel.ph = NULL;
|
||||
}
|
||||
|
||||
memset(phdata, 0, sizeof(PHONEME_DATA));
|
||||
phdata->pd_param[i_SET_LENGTH] = ph->std_length;
|
||||
phdata->pd_param[i_LENGTH_MOD] = ph->length_mod;
|
||||
@@ -901,13 +954,13 @@ void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_
|
||||
return;
|
||||
|
||||
end_flag = 0;
|
||||
|
||||
|
||||
for(prog = &phoneme_index[ph->program]; end_flag != 1; prog++)
|
||||
{
|
||||
instn = *prog;
|
||||
instn2 = (instn >> 8) & 0xf;
|
||||
or_flag = 0;
|
||||
|
||||
|
||||
switch(instn >> 12)
|
||||
{
|
||||
case 0: // 0xxx
|
||||
@@ -992,11 +1045,13 @@ void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_
|
||||
{
|
||||
// process a sequence of conditions, using boolean accumulator
|
||||
if(or_flag)
|
||||
truth = (truth || InterpretCondition(tr, control, plist, instn & 0xfff));
|
||||
truth = (truth || InterpretCondition(tr, control, plist, prog, worddata));
|
||||
else
|
||||
truth = (truth && InterpretCondition(tr, control, plist, instn & 0xfff));
|
||||
truth = (truth && InterpretCondition(tr, control, plist, prog, worddata));
|
||||
or_flag = instn & 0x1000;
|
||||
instn = *(++prog);
|
||||
prog += NumInstnWords(prog);
|
||||
instn = *prog;
|
||||
// instn = *(++prog);
|
||||
}
|
||||
|
||||
if(truth == false)
|
||||
@@ -1010,7 +1065,7 @@ void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_
|
||||
// instruction after a condition is not JUMP_FALSE, so skip the instruction.
|
||||
prog += NumInstnWords(prog);
|
||||
if((prog[0] & 0xfe00) == 0x6000)
|
||||
prog++; // and skip ELSE jump
|
||||
prog++; // and skip ELSE jump
|
||||
}
|
||||
}
|
||||
prog--;
|
||||
@@ -1029,11 +1084,11 @@ void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_
|
||||
break;
|
||||
|
||||
case 5: // NexttVowelStarts
|
||||
SwitchVowelType(plist, phdata, &prog, 2);
|
||||
SwitchOnVowelType(plist, phdata, &prog, 2);
|
||||
break;
|
||||
|
||||
case 6: // PrevVowelTypeEndings
|
||||
SwitchVowelType(plist, phdata, &prog, 3);
|
||||
SwitchOnVowelType(plist, phdata, &prog, 3);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -1130,6 +1185,11 @@ void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_
|
||||
}
|
||||
}
|
||||
|
||||
if((worddata != NULL) && (plist->type == phVOWEL))
|
||||
{
|
||||
memcpy(&worddata->prev_vowel, &plist[0], sizeof(PHONEME_LIST));
|
||||
}
|
||||
|
||||
} // end of InterpretPhoneme
|
||||
|
||||
|
||||
@@ -1150,5 +1210,5 @@ void InterpretPhoneme2(int phcode, PHONEME_DATA *phdata)
|
||||
plist[1].ph = phoneme_tab[phcode];
|
||||
plist[2].sourceix = 1;
|
||||
|
||||
InterpretPhoneme(NULL, 0, &plist[1], phdata);
|
||||
InterpretPhoneme(NULL, 0, &plist[1], phdata, NULL);
|
||||
} // end of InterpretPhoneme2
|
||||
|
||||
+20
-18
@@ -483,7 +483,7 @@ static void set_frame_rms(frame_t *fr, int new_rms)
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(fr->rms == 0) return; // check for divide by zero
|
||||
x = (new_rms * 64)/fr->rms;
|
||||
if(x >= 200) x = 199;
|
||||
@@ -507,7 +507,7 @@ static void formants_reduce_hf(frame_t *fr, int level)
|
||||
|
||||
if(voice->klattv[0])
|
||||
return;
|
||||
|
||||
|
||||
for(ix=2; ix < 8; ix++)
|
||||
{
|
||||
x = fr->fheight[ix] * level;
|
||||
@@ -594,7 +594,7 @@ static void AdjustFormants(frame_t *fr, int target, int min, int max, int f1_adj
|
||||
fr->ffreq[1] += x;
|
||||
fr->ffreq[0] += x;
|
||||
}
|
||||
formants_reduce_hf(fr,hf_reduce);
|
||||
formants_reduce_hf(fr,hf_reduce);
|
||||
}
|
||||
|
||||
|
||||
@@ -717,7 +717,7 @@ if(voice->klattv[0])
|
||||
fr = CopyFrame(seq[n_frames-1].frame,0);
|
||||
seq[n_frames-1].frame = fr;
|
||||
rms = RMS_GLOTTAL1;
|
||||
|
||||
|
||||
// degree of glottal-stop effect depends on closeness of vowel (indicated by f1 freq)
|
||||
modn_flags = 0x400 + (VowelCloseness(fr) << 8);
|
||||
}
|
||||
@@ -726,7 +726,7 @@ if(voice->klattv[0])
|
||||
fr = DuplicateLastFrame(seq,n_frames++,len);
|
||||
if(len > 36)
|
||||
seq_len_adjust += (len - 36);
|
||||
|
||||
|
||||
if(f2 != 0)
|
||||
{
|
||||
AdjustFormants(fr, f2, f2_min, f2_max, f1, f3_adj, f3_amp, flags);
|
||||
@@ -741,7 +741,7 @@ if(voice->klattv[0])
|
||||
{
|
||||
fr = CopyFrame(seq[ix].frame,0);
|
||||
seq[ix].frame = fr;
|
||||
|
||||
|
||||
for(formant=1; formant<=5; formant++)
|
||||
{
|
||||
int x;
|
||||
@@ -1182,7 +1182,7 @@ if(which==1)
|
||||
q[1] = len + (modulation << 16);
|
||||
q[2] = (long64)frame1;
|
||||
q[3] = (long64)frame2;
|
||||
|
||||
|
||||
WcmdqInc();
|
||||
}
|
||||
last_frame = frame1 = frame2;
|
||||
@@ -1348,6 +1348,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
|
||||
PHONEME_DATA phdata_next;
|
||||
PHONEME_DATA phdata_tone;
|
||||
FMT_PARAMS fmtp;
|
||||
static WORD_PH_DATA worddata;
|
||||
|
||||
if(option_quiet)
|
||||
return(0);
|
||||
@@ -1372,6 +1373,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
|
||||
syllable_centre = -1;
|
||||
last_pitch_cmd = -1;
|
||||
memset(vowel_transition,0,sizeof(vowel_transition));
|
||||
memset(&worddata, 0, sizeof(worddata));
|
||||
DoPause(0,0); // isolate from the previous clause
|
||||
}
|
||||
|
||||
@@ -1463,13 +1465,13 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
|
||||
if(released == 0)
|
||||
p->synthflags |= SFLAG_NEXT_PAUSE;
|
||||
|
||||
InterpretPhoneme(NULL, 0, p, &phdata);
|
||||
InterpretPhoneme(NULL, 0, p, &phdata, &worddata);
|
||||
phdata.pd_control |= pd_DONTLENGTHEN;
|
||||
DoSample3(&phdata, 0, 0);
|
||||
break;
|
||||
|
||||
case phFRICATIVE:
|
||||
InterpretPhoneme(NULL, 0, p, &phdata);
|
||||
InterpretPhoneme(NULL, 0, p, &phdata, &worddata);
|
||||
|
||||
if(p->synthflags & SFLAG_LENGTHEN)
|
||||
{
|
||||
@@ -1509,7 +1511,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
|
||||
if((prev->type==phVOWEL) || (prev->ph->phflags & phVOWEL2) || (ph->phflags & phPREVOICE))
|
||||
{
|
||||
// a period of voicing before the release
|
||||
InterpretPhoneme(NULL, 0x01, p, &phdata);
|
||||
InterpretPhoneme(NULL, 0x01, p, &phdata, &worddata);
|
||||
fmtp.fmt_addr = phdata.sound_addr[pd_FMT];
|
||||
fmtp.fmt_amp = phdata.sound_param[pd_FMT];
|
||||
|
||||
@@ -1537,7 +1539,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
|
||||
{
|
||||
p->synthflags |= SFLAG_NEXT_PAUSE;
|
||||
}
|
||||
InterpretPhoneme(NULL,0, p, &phdata);
|
||||
InterpretPhoneme(NULL,0, p, &phdata, &worddata);
|
||||
fmtp.fmt_addr = phdata.sound_addr[pd_FMT];
|
||||
fmtp.fmt_amp = phdata.sound_param[pd_FMT];
|
||||
fmtp.wav_addr = phdata.sound_addr[pd_ADDWAV];
|
||||
@@ -1582,7 +1584,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
|
||||
{
|
||||
p->synthflags |= SFLAG_NEXT_PAUSE;
|
||||
}
|
||||
InterpretPhoneme(NULL,0, p, &phdata);
|
||||
InterpretPhoneme(NULL,0, p, &phdata, &worddata);
|
||||
memset(&fmtp, 0, sizeof(fmtp));
|
||||
fmtp.std_length = phdata.pd_param[i_SET_LENGTH]*2;
|
||||
fmtp.fmt_addr = phdata.sound_addr[pd_FMT];
|
||||
@@ -1608,7 +1610,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
|
||||
last_frame = NULL;
|
||||
}
|
||||
|
||||
InterpretPhoneme(NULL,0, p, &phdata);
|
||||
InterpretPhoneme(NULL,0, p, &phdata, &worddata);
|
||||
fmtp.std_length = phdata.pd_param[i_SET_LENGTH]*2;
|
||||
fmtp.fmt_addr = phdata.sound_addr[pd_FMT];
|
||||
fmtp.fmt_amp = phdata.sound_param[pd_FMT];
|
||||
@@ -1653,7 +1655,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
|
||||
{
|
||||
StartSyllable();
|
||||
}
|
||||
InterpretPhoneme(NULL, 0, p, &phdata);
|
||||
InterpretPhoneme(NULL, 0, p, &phdata, &worddata);
|
||||
fmtp.std_length = phdata.pd_param[i_SET_LENGTH]*2;
|
||||
fmtp.fmt_addr = phdata.sound_addr[pd_FMT];
|
||||
fmtp.fmt_amp = phdata.sound_param[pd_FMT];
|
||||
@@ -1669,7 +1671,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
|
||||
|
||||
memset(&fmtp, 0, sizeof(fmtp));
|
||||
|
||||
InterpretPhoneme(NULL, 0, p, &phdata);
|
||||
InterpretPhoneme(NULL, 0, p, &phdata, &worddata);
|
||||
fmtp.std_length = phdata.pd_param[i_SET_LENGTH] * 2;
|
||||
|
||||
if(((fmtp.fmt_addr = phdata.sound_addr[pd_VWLSTART]) != 0) && ((phdata.pd_control & pd_FORNEXTPH) == 0))
|
||||
@@ -1681,7 +1683,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
|
||||
if(prev->type != phPAUSE)
|
||||
{
|
||||
// check the previous phoneme
|
||||
InterpretPhoneme(NULL, 0, prev, &phdata_prev);
|
||||
InterpretPhoneme(NULL, 0, prev, &phdata_prev, NULL);
|
||||
if((fmtp.fmt_addr = phdata_prev.sound_addr[pd_VWLSTART]) != 0)
|
||||
{
|
||||
// a vowel start has been specified by the Vowel program
|
||||
@@ -1763,7 +1765,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
|
||||
if(next->type != phPAUSE)
|
||||
{
|
||||
fmtp.fmt2_lenadj = 0;
|
||||
InterpretPhoneme(NULL, 0, next, &phdata_next);
|
||||
InterpretPhoneme(NULL, 0, next, &phdata_next, NULL);
|
||||
|
||||
fmtp.use_vowelin = 1;
|
||||
fmtp.transition0 = phdata_next.vowel_transition[2]; // always do vowel_transition, even if ph_VWLEND ?? consider [N]
|
||||
@@ -1939,7 +1941,7 @@ int SpeakNextClause(FILE *f_in, const void *text_in, int control)
|
||||
if(option_phonemes > 0)
|
||||
{
|
||||
fprintf(f_trans,"%s\n",translator->phon_out);
|
||||
|
||||
|
||||
if(!iswalpha(0x010d))
|
||||
{
|
||||
// check that c-caron is recognized as an alphabetic character
|
||||
|
||||
+4
-1
@@ -265,6 +265,9 @@ typedef struct {
|
||||
int std_length;
|
||||
} FMT_PARAMS;
|
||||
|
||||
typedef struct {
|
||||
PHONEME_LIST prev_vowel;
|
||||
} WORD_PH_DATA;
|
||||
|
||||
// instructions
|
||||
|
||||
@@ -417,7 +420,7 @@ typedef struct {
|
||||
unsigned char split_tail_start;
|
||||
unsigned char split_tail_end;
|
||||
unsigned char split_tune;
|
||||
|
||||
|
||||
unsigned char spare[8];
|
||||
int spare2; // the struct length should be a multiple of 4 bytes
|
||||
} TUNE;
|
||||
|
||||
+12
-12
@@ -18,7 +18,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#define L(c1,c2) (c1<<8)+c2 // combine two characters into an integer for translator name
|
||||
#define L(c1,c2) (c1<<8)+c2 // combine two characters into an integer for translator name
|
||||
|
||||
#define CTRL_EMBEDDED 0x01 // control character at the start of an embedded command
|
||||
#define REPLACED_E 'E' // 'e' replaced by silent e
|
||||
@@ -29,7 +29,7 @@
|
||||
#define N_RULE_GROUP2 120 // max num of two-letter rule chains
|
||||
#define N_HASH_DICT 1024
|
||||
#define N_CHARSETS 20
|
||||
#define N_LETTER_GROUPS 95 // maximum is 127-32
|
||||
#define N_LETTER_GROUPS 95 // maximum is 127-32
|
||||
|
||||
|
||||
/* dictionary flags, word 1 */
|
||||
@@ -52,7 +52,7 @@
|
||||
#define FLAG_STEM 0x40000 // must have a suffix
|
||||
|
||||
#define FLAG_DOUBLING 0x80000 // doubles the following consonant
|
||||
#define BITNUM_FLAG_ALT 19 // bit number of FLAG_ALT_TRANS - 1
|
||||
#define BITNUM_FLAG_ALT 19 // bit number of FLAG_ALT_TRANS - 1
|
||||
#define FLAG_ALT_TRANS 0x100000 // language specific
|
||||
#define FLAG_ALT2_TRANS 0x200000 // language specific
|
||||
#define FLAG_ALT3_TRANS 0x400000 // language specific
|
||||
@@ -110,7 +110,7 @@
|
||||
#define FLAG_MULTIPLE_SPACES 0x40000 // word is preceded by multiple spaces, newline, or tab
|
||||
#define FLAG_INDIVIDUAL_DIGITS 0x80000 // speak number as individual digits
|
||||
#define FLAG_DELETE_WORD 0x100000 // don't speak this word, it has been spoken as part of the previous word
|
||||
#define FLAG_CHAR_REPLACED 0x200000 // characters have been replaced by .replace in the *_rules
|
||||
#define FLAG_CHAR_REPLACED 0x200000 // characters have been replaced by .replace in the *_rules
|
||||
|
||||
#define FLAG_SUFFIX_VOWEL 0x08000000 // remember an initial vowel from the suffix
|
||||
#define FLAG_NO_TRACE 0x10000000 // passed to TranslateRules() to suppress dictionary lookup printout
|
||||
@@ -235,7 +235,7 @@ typedef struct {
|
||||
int end_type;
|
||||
char *del_fwd;
|
||||
} MatchRecord;
|
||||
|
||||
|
||||
|
||||
// used to mark words with the source[] buffer
|
||||
typedef struct{
|
||||
@@ -377,7 +377,7 @@ typedef struct {
|
||||
// bit20= hyphenated words, 2nd part is unstressed
|
||||
// bit21= don't lengthen vowels at end-of-clause
|
||||
|
||||
int stress_flags;
|
||||
int stress_flags;
|
||||
int unstressed_wd1; // stress for $u word of 1 syllable
|
||||
int unstressed_wd2; // stress for $u word of >1 syllable
|
||||
int param[N_LOPTS];
|
||||
@@ -542,18 +542,18 @@ typedef struct
|
||||
|
||||
// groups1 and groups2 are indexes into data_dictrules, set up by InitGroups()
|
||||
// the two-letter rules for each letter must be consecutive in the language_rules source
|
||||
|
||||
|
||||
char *groups1[256]; // translation rule lists, index by single letter
|
||||
char *groups3[128]; // index by offset letter
|
||||
char *groups2[N_RULE_GROUP2]; // translation rule lists, indexed by two-letter pairs
|
||||
unsigned int groups2_name[N_RULE_GROUP2]; // the two letter pairs for groups2[]
|
||||
int n_groups2; // number of groups2[] entries used
|
||||
|
||||
|
||||
unsigned char groups2_count[256]; // number of 2 letter groups for this initial letter
|
||||
unsigned char groups2_start[256]; // index into groups2
|
||||
const short *frequent_pairs; // list of frequent pairs of letters, for use in compressed *_list
|
||||
|
||||
|
||||
|
||||
|
||||
int expect_verb;
|
||||
int expect_past; // expect past tense
|
||||
int expect_verb_s;
|
||||
@@ -563,7 +563,7 @@ typedef struct
|
||||
|
||||
int word_vowel_count; // number of vowels so far
|
||||
int word_stressed_count; // number of vowels so far which could be stressed
|
||||
|
||||
|
||||
int clause_upper_count; // number of upper case letters in the clause
|
||||
int clause_lower_count; // number of lower case letters in the clause
|
||||
|
||||
@@ -685,7 +685,7 @@ void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *t
|
||||
int ReadClause(Translator *tr, FILE *f_in, char *buf, short *charix, int *charix_top, int n_buf, int *tone_type, char *voice_change);
|
||||
|
||||
void SetVoiceStack(espeak_VOICE *v, const char *variant_name);
|
||||
void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_DATA *phdata);
|
||||
void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_DATA *phdata, WORD_PH_DATA *worddata);
|
||||
void InterpretPhoneme2(int phcode, PHONEME_DATA *phdata);
|
||||
char *WritePhMnemonic(char *phon_out, PHONEME_TAB *ph, PHONEME_LIST *plist, int use_ipa);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user