mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-11-14 01:32:29 +00:00
[1.43.52]
espeakedit --compile also compiles the intonation data Added feature to produce phonemes as International Phonetic Alphabet. phoneme definitions: Added "ipa" instruction to specify IPA phoneme name. When spelling as individual characters, calculate the stress position for each character name. git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@249 d46cf337-b52f-0410-862d-fd96e6ae7743
This commit is contained in:
@@ -42,6 +42,7 @@
|
||||
|
||||
extern void FindPhonemesUsed(void);
|
||||
extern void DisplayErrorFile(const char *fname);
|
||||
extern int utf8_out(unsigned int c, char *buf);
|
||||
char path_source[sizeof(path_home)+20];
|
||||
|
||||
|
||||
@@ -290,6 +291,7 @@ static keywtab_t keywords[] = {
|
||||
{"LengthAdd", tINSTRN1, i_ADD_LENGTH},
|
||||
{"Lengthmod", tINSTRN1, i_LENGTH_MOD},
|
||||
{"lengthmod", tINSTRN1, i_LENGTH_MOD},
|
||||
{"ipa", tINSTRN1, i_IPA_NAME},
|
||||
|
||||
// flags
|
||||
{"wavef", tPHONEME_FLAG, phWAVE},
|
||||
@@ -392,6 +394,7 @@ static void DecompilePhoneme(FILE *f_out, PHONEME_TAB *ph, int compile_phoneme)
|
||||
int ix;
|
||||
int any;
|
||||
const char *name;
|
||||
char buf[120];
|
||||
|
||||
static const char *INV = "Invalid";
|
||||
|
||||
@@ -456,6 +459,18 @@ return;
|
||||
fprintf(f_out,"%s",instn0_string[data1]);
|
||||
}
|
||||
else
|
||||
if(type2 == i_IPA_NAME)
|
||||
{
|
||||
for(ix = 0; ix < data1; ix += 2)
|
||||
{
|
||||
instn = *pc++;
|
||||
buf[ix] = instn >> 8;
|
||||
buf[ix+1] = instn & 0xff;
|
||||
}
|
||||
buf[ix] = 0;
|
||||
fprintf(f_out,"ipa %s",buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(f_out,"%s(",KeyToMnem(keywords, tINSTRN1, type2));
|
||||
switch(instn1_paramtype[type2])
|
||||
@@ -2541,6 +2556,11 @@ int CompilePhoneme(int compile_phoneme)
|
||||
int keyword;
|
||||
int value;
|
||||
int phcode = 0;
|
||||
int ix;
|
||||
unsigned int c;
|
||||
char *p;
|
||||
char number_buf[12];
|
||||
char ipa_buf[N_ITEM_STRING];
|
||||
PHONEME_TAB phoneme_out2;
|
||||
PHONEME_PROG_LOG phoneme_prog_log;
|
||||
|
||||
@@ -2657,6 +2677,42 @@ int CompilePhoneme(int compile_phoneme)
|
||||
value = NextItem(tNUMBER);
|
||||
phoneme_out->length_mod = value;
|
||||
break;
|
||||
|
||||
case i_IPA_NAME:
|
||||
NextItem(tSTRING);
|
||||
|
||||
if(strcmp(item_string,"NULL")==0)
|
||||
strcpy(item_string," ");
|
||||
|
||||
// copy the string, recognize characters in the form U+9999
|
||||
p = item_string;
|
||||
ix = 0;
|
||||
while((c = *p++) != 0)
|
||||
{
|
||||
if((c=='U') && (p[0]=='+'))
|
||||
{
|
||||
// U+9999
|
||||
memcpy(number_buf,&p[1],4); // U+ should be followed by 4 hex digits
|
||||
number_buf[4] = 0;
|
||||
c = 0;
|
||||
sscanf(number_buf,"%x",&c);
|
||||
p += 5;
|
||||
ix += utf8_out(c, &ipa_buf[ix]);
|
||||
}
|
||||
else
|
||||
{
|
||||
ipa_buf[ix++] = c;
|
||||
}
|
||||
}
|
||||
ipa_buf[ix] = 0;
|
||||
value = strlen(ipa_buf); // number of UTF-8 bytes
|
||||
|
||||
*prog_out++ = (i_IPA_NAME << 8) + value;
|
||||
for(ix=0; ix < value; ix += 2)
|
||||
{
|
||||
*prog_out++ = (ipa_buf[ix] << 8) + (ipa_buf[ix+1] & 0xff);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2702,6 +2758,11 @@ int CompilePhoneme(int compile_phoneme)
|
||||
case kSTRESSTYPE:
|
||||
value = NextItem(tNUMBER);
|
||||
phoneme_out->std_length = value;
|
||||
if(prog_out > prog_buf)
|
||||
{
|
||||
error("stress phonemes can't contain program instructions",NULL);
|
||||
prog_out = prog_buf;
|
||||
}
|
||||
break;
|
||||
|
||||
case kIF:
|
||||
|
||||
+104
-20
@@ -506,20 +506,84 @@ void DecodePhonemes(const char *inptr, char *outptr)
|
||||
} // end of DecodePhonemes
|
||||
|
||||
|
||||
// using Kirschenbaum to IPA translation, ascii 0x20 to 0x7f
|
||||
unsigned short ipa1[96] = {
|
||||
0x20,0x21,0x22,0x2b0,0x24,0x25,0x0e6,0x2c8,0x28,0x27e,0x2a,0x2b,0x2cc,0x2d,0x2e,0x2f,
|
||||
0x252,0x31,0x32,0x25c,0x34,0x35,0x36,0x37,0x275,0x39,0x2d0,0x2b2,0x3c,0x3d,0x3e,0x294,
|
||||
0x259,0x251,0x3b2,0xe7,0xf0,0x25b,0x46,0x262,0x127,0x26a,0x25f,0x4b,0x4c,0x271,0x14b,0x254,
|
||||
0x3a6,0x263,0x280,0x283,0x3b8,0x28a,0x28c,0x153,0x3c7,0xf8,0x292,0x32a,0x5c,0x5d,0x5e,0x5f,
|
||||
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
|
||||
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x303,0x7f
|
||||
};
|
||||
|
||||
static void WriteMnemonic(char *phon_out, int *ix, int mnem)
|
||||
{//=========================================================
|
||||
unsigned char c;
|
||||
|
||||
while((c = mnem & 0xff) != 0)
|
||||
static void WritePhMnemonic(char *phon_out, int *ix, PHONEME_TAB *ph, PHONEME_LIST *plist)
|
||||
{//=======================================================================================
|
||||
int c;
|
||||
int mnem;
|
||||
int len;
|
||||
int first;
|
||||
unsigned int ipa_control=0; // first byte of ipa string may control the phoneme name interpretation. 0x20 = ignore this phoneme
|
||||
PHONEME_DATA phdata;
|
||||
|
||||
if(option_phonemes == 3)
|
||||
{
|
||||
// has an ipa name been defined for this phoneme ?
|
||||
phdata.ipa_string[0] = 0;
|
||||
|
||||
if(plist == NULL)
|
||||
{
|
||||
InterpretPhoneme2(ph->code, &phdata);
|
||||
}
|
||||
else
|
||||
{
|
||||
InterpretPhoneme(NULL, 0, plist, &phdata);
|
||||
}
|
||||
|
||||
len = strlen(phdata.ipa_string);
|
||||
if(len > 0)
|
||||
{
|
||||
if((ipa_control = phdata.ipa_string[0]) > 0x20)
|
||||
{
|
||||
strcpy(&phon_out[*ix], phdata.ipa_string);
|
||||
*ix += len;
|
||||
}
|
||||
if(ipa_control >= 0x20)
|
||||
return; // 0x20 = ignore phoneme
|
||||
}
|
||||
}
|
||||
|
||||
first = 1;
|
||||
for(mnem = ph->mnemonic; (c = mnem & 0xff) != 0; mnem = mnem >> 8)
|
||||
{
|
||||
if((c == '/') && (option_phoneme_variants==0))
|
||||
break; // discard phoneme variant indicator
|
||||
phon_out[(*ix)++]= c;
|
||||
// phon_out[phon_out_ix++]= ipa1[c];
|
||||
mnem = mnem >> 8;
|
||||
|
||||
if(option_phonemes == 3)
|
||||
{
|
||||
// convert from ascii to ipa
|
||||
if(first && (c == '_'))
|
||||
break; // don't show pause phonemes
|
||||
|
||||
if((c == '#') && (ph->type == phVOWEL))
|
||||
break; // # is subscript-h, but only for consonants
|
||||
|
||||
// ignore digits after the first character
|
||||
if(!first && isdigit(c))
|
||||
continue;
|
||||
|
||||
if((c >= 0x20) && (c < 128))
|
||||
c = ipa1[c-0x20];
|
||||
|
||||
*ix += utf8_out(c, &phon_out[*ix]);
|
||||
}
|
||||
else
|
||||
{
|
||||
phon_out[(*ix)++]= c;
|
||||
}
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
} // end of WritePhMnemonic
|
||||
|
||||
|
||||
|
||||
@@ -532,6 +596,7 @@ void GetTranslatedPhonemeString(char *phon_out, int n_phon_out)
|
||||
int ix;
|
||||
int phon_out_ix=0;
|
||||
int stress;
|
||||
unsigned int c;
|
||||
char *p;
|
||||
PHONEME_LIST *plist;
|
||||
|
||||
@@ -549,35 +614,52 @@ void GetTranslatedPhonemeString(char *phon_out, int n_phon_out)
|
||||
{
|
||||
if((stress = plist->stresslevel) > 1)
|
||||
{
|
||||
c = 0;
|
||||
if(stress > 5) stress = 5;
|
||||
phon_out[phon_out_ix++] = stress_chars[stress];
|
||||
|
||||
if(option_phonemes == 3)
|
||||
{
|
||||
c = 0x2cc; // ipa, secondary stress
|
||||
if(stress > 3)
|
||||
c = 0x02c8; // ipa, primary stress
|
||||
}
|
||||
else
|
||||
{
|
||||
c = stress_chars[stress];
|
||||
}
|
||||
|
||||
if(c != 0)
|
||||
{
|
||||
phon_out_ix += utf8_out(c, &phon_out[phon_out_ix]);
|
||||
}
|
||||
}
|
||||
}
|
||||
WriteMnemonic(phon_out, &phon_out_ix, plist->ph->mnemonic);
|
||||
WritePhMnemonic(phon_out, &phon_out_ix, plist->ph, plist);
|
||||
|
||||
if(plist->synthflags & SFLAG_LENGTHEN)
|
||||
{
|
||||
WriteMnemonic(phon_out, &phon_out_ix, phoneme_tab[phonLENGTHEN]->mnemonic);
|
||||
WritePhMnemonic(phon_out, &phon_out_ix, phoneme_tab[phonLENGTHEN], NULL);
|
||||
}
|
||||
if((plist->synthflags & SFLAG_SYLLABLE) && (plist->type != phVOWEL))
|
||||
{
|
||||
// syllablic consonant
|
||||
WriteMnemonic(phon_out, &phon_out_ix, phoneme_tab[phonSYLLABIC]->mnemonic);
|
||||
WritePhMnemonic(phon_out, &phon_out_ix, phoneme_tab[phonSYLLABIC], NULL);
|
||||
}
|
||||
if(plist->ph->code == phonSWITCH)
|
||||
{
|
||||
// the tone_ph field contains a phoneme table number
|
||||
p = phoneme_tab_list[plist->tone_ph].name;
|
||||
while(*p != 0)
|
||||
while((c = *p++) != 0)
|
||||
{
|
||||
phon_out[phon_out_ix++] = *p++;
|
||||
if(option_phonemes != 3)
|
||||
phon_out[phon_out_ix++] = c;
|
||||
}
|
||||
phon_out[phon_out_ix++] = ' ';
|
||||
}
|
||||
else
|
||||
if(plist->tone_ph > 0)
|
||||
{
|
||||
WriteMnemonic(phon_out, &phon_out_ix, phoneme_tab[plist->tone_ph]->mnemonic);
|
||||
WritePhMnemonic(phon_out, &phon_out_ix, phoneme_tab[plist->tone_ph], NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1049,17 +1131,19 @@ void ChangeWordStress(Translator *tr, char *word, int new_stress)
|
||||
|
||||
|
||||
|
||||
void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags, int tonic, int prev_stress)
|
||||
{//=========================================================================================================
|
||||
void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags, int tonic, int control)
|
||||
{//=====================================================================================================
|
||||
/* Guess stress pattern of word. This is language specific
|
||||
|
||||
'output' is used for input and output
|
||||
|
||||
'dictionary_flags' has bits 0-3 position of stressed vowel (if > 0)
|
||||
or unstressed (if == 7) or syllables 1 and 2 (if == 6)
|
||||
bits 8... dictionary flags
|
||||
|
||||
If 'tonic' is set (>= 0), replace highest stress by this value.
|
||||
|
||||
Parameter used for input and output
|
||||
control: bit 0 This is an individual symbol, not a word
|
||||
*/
|
||||
|
||||
unsigned char phcode;
|
||||
@@ -1495,7 +1579,7 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
p = phonetic;
|
||||
v = 1;
|
||||
|
||||
if((ph = phoneme_tab[*p]) != NULL)
|
||||
if(!(control & 1) && ((ph = phoneme_tab[*p]) != NULL))
|
||||
{
|
||||
|
||||
if(ph->type == phSTRESS)
|
||||
@@ -2564,7 +2648,7 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c
|
||||
}
|
||||
else
|
||||
{
|
||||
LookupLetter(tr, wc, -1, ph_buf);
|
||||
LookupLetter(tr, wc, -1, ph_buf, 0);
|
||||
if(ph_buf[0])
|
||||
{
|
||||
match1.phonemes = ph_buf;
|
||||
|
||||
+19
-14
@@ -34,7 +34,7 @@
|
||||
|
||||
|
||||
static const char *help_text =
|
||||
"\nspeak [options] [\"<words>\"]\n\n"
|
||||
"\nespeak [options] [\"<words>\"]\n\n"
|
||||
"-f <text file> Text file to speak\n"
|
||||
"--stdin Read text input from stdin instead of a file\n\n"
|
||||
"If neither -f nor --stdin, then <words> are spoken, or if none then text\n"
|
||||
@@ -43,6 +43,9 @@ static const char *help_text =
|
||||
"\t Amplitude, 0 to 200, default is 100\n"
|
||||
"-g <integer>\n"
|
||||
"\t Word gap. Pause between words, units of 10mS at the default speed\n"
|
||||
"-k <integer>\n"
|
||||
"\t Indicate capital letters with: 1=sound, 2=the word \"capitals\",\n"
|
||||
"\t higher values indicate a pitch increase (try -k20).\n"
|
||||
"-l <integer>\n"
|
||||
"\t Line length. If not zero (which is the default), consider\n"
|
||||
"\t lines less than this length as end-of-clause\n"
|
||||
@@ -53,34 +56,31 @@ static const char *help_text =
|
||||
"-v <voice name>\n"
|
||||
"\t Use voice file of this name from espeak-data/voices\n"
|
||||
"-w <wave file name>\n"
|
||||
"\t Write output to this WAV file, rather than speaking it directly\n"
|
||||
"\t Write speech to this WAV file, rather than speaking it directly\n"
|
||||
"-b\t Input text encoding, 1=UTF8, 2=8 bit, 4=16 bit \n"
|
||||
"-m\t Interpret SSML markup, and ignore other < > tags\n"
|
||||
"-q\t Quiet, don't produce any speech (may be useful with -x)\n"
|
||||
"-x\t Write phoneme mnemonics to stdout\n"
|
||||
"-X\t Write phonemes mnemonics and translation trace to stdout\n"
|
||||
"-z\t No final sentence pause at the end of the text\n"
|
||||
"--stdout Write speech output to stdout\n"
|
||||
"--compile=<voice name>\n"
|
||||
"\t Compile the pronunciation rules and dictionary in the current\n"
|
||||
"\t Compile pronunciation rules and dictionary from the current\n"
|
||||
"\t directory. <voice name> specifies the language\n"
|
||||
"--ipa Write phonemes to stdout using International Phonetic Alphabet\n"
|
||||
"--path=\"<path>\"\n"
|
||||
"\t Specifies the directory containing the espeak-data directory\n"
|
||||
"--pho\n"
|
||||
"\t Write mbrola phoneme data (.pho) to stdout, or to the file in --phonout\n"
|
||||
"--pho Write mbrola phoneme data (.pho) to stdout or to the file in --phonout\n"
|
||||
"--phonout=\"<filename>\"\n"
|
||||
"\t Write phoneme output from -x -X and --pho to this file\n"
|
||||
"\t Write phoneme output from -x -X --ipa and --pho to this file\n"
|
||||
"--punct=\"<characters>\"\n"
|
||||
"\t Speak the names of punctuation characters during speaking. If\n"
|
||||
"\t =<characters> is omitted, all punctuation is spoken.\n"
|
||||
"--split=\"<minutes>\"\n"
|
||||
"\t Starts a new WAV file every <minutes>. Used with -w\n"
|
||||
"--stdout Write speech output to stdout\n"
|
||||
"--voices=<language>\n"
|
||||
"\t List the available voices for the specified language.\n"
|
||||
"\t If <language> is omitted, then list all voices.\n"
|
||||
"-k <integer>\n"
|
||||
"\t Indicate capital letters with: 1=sound, 2=the word \"capitals\",\n"
|
||||
"\t higher values indicate a pitch increase (try -k20).\n";
|
||||
"\t If <language> is omitted, then list all voices.\n";
|
||||
|
||||
|
||||
|
||||
@@ -355,6 +355,7 @@ int main (int argc, char **argv)
|
||||
{"path", required_argument, 0, 0x107},
|
||||
{"phonout", required_argument, 0, 0x108},
|
||||
{"pho", no_argument, 0, 0x109},
|
||||
{"ipa", no_argument, 0, 0x10a},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -573,9 +574,9 @@ int main (int argc, char **argv)
|
||||
|
||||
case 0x106: // -- split
|
||||
if(optarg2 == NULL)
|
||||
samples_split = 30 * 60; // default 30 minutes
|
||||
samples_split_seconds = 30 * 60; // default 30 minutes
|
||||
else
|
||||
samples_split = atoi(optarg2) * 60;
|
||||
samples_split_seconds = atoi(optarg2) * 60;
|
||||
break;
|
||||
|
||||
case 0x107: // --path
|
||||
@@ -590,7 +591,11 @@ int main (int argc, char **argv)
|
||||
break;
|
||||
|
||||
case 0x109: // --pho
|
||||
option_mbrola_phonemes = 8;
|
||||
option_mbrola_phonemes = 16;
|
||||
break;
|
||||
|
||||
case 0x10a: // --ipa
|
||||
option_phonemes = 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
+19
-2
@@ -148,6 +148,7 @@ if(argc > 1)
|
||||
if(strcmp(param,"--compile")==0)
|
||||
{
|
||||
CompilePhonemeData();
|
||||
CompileIntonation();
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
@@ -197,7 +198,9 @@ BEGIN_EVENT_TABLE(MyFrame, wxMDIParentFrame)
|
||||
EVT_MENU(MENU_SPECTRUM, MyFrame::OnNewWindow)
|
||||
EVT_MENU(MENU_SPECTRUM2, MyFrame::OnNewWindow)
|
||||
EVT_MENU(MENU_PROSODY, MyFrame::OnProsody)
|
||||
EVT_MENU(MENU_PARAMS, MyFrame::OnOptions)
|
||||
EVT_MENU(MENU_OPT_SPEED, MyFrame::OnOptions)
|
||||
EVT_MENU(MENU_OPT_PUNCT, MyFrame::OnOptions)
|
||||
EVT_MENU(MENU_OPT_SPELL, MyFrame::OnOptions)
|
||||
EVT_MENU(MENU_PATH0, MyFrame::OnOptions)
|
||||
EVT_MENU(MENU_PATH1, MyFrame::OnOptions)
|
||||
EVT_MENU(MENU_PATH2, MyFrame::OnOptions)
|
||||
@@ -214,6 +217,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxMDIParentFrame)
|
||||
EVT_MENU(MENU_QUIT, MyFrame::OnQuit)
|
||||
EVT_MENU(MENU_SPEAK_TRANSLATE, MyFrame::OnSpeak)
|
||||
EVT_MENU(MENU_SPEAK_RULES, MyFrame::OnSpeak)
|
||||
EVT_MENU(MENU_SPEAK_IPA, MyFrame::OnSpeak)
|
||||
EVT_MENU(MENU_SPEAK_TEXT, MyFrame::OnSpeak)
|
||||
EVT_MENU(MENU_SPEAK_FILE, MyFrame::OnSpeak)
|
||||
EVT_MENU(MENU_SPEAK_STOP, MyFrame::OnSpeak)
|
||||
@@ -473,7 +477,7 @@ void OnOptions2(int event_id)
|
||||
|
||||
switch(event_id)
|
||||
{
|
||||
case MENU_PARAMS:
|
||||
case MENU_OPT_SPEED:
|
||||
value = wxGetNumberFromUser(_T(""),_T(""),_T("Speed"),option_speed,80,500);
|
||||
if(value > 0)
|
||||
{
|
||||
@@ -483,6 +487,18 @@ void OnOptions2(int event_id)
|
||||
}
|
||||
break;
|
||||
|
||||
case MENU_OPT_PUNCT:
|
||||
transldlg->t_source->SetValue(_T("<tts:style field=\"punctuation\" mode=\"all\">\n"));
|
||||
transldlg->t_source->SetInsertionPointEnd();
|
||||
notebook->SetSelection(1);
|
||||
break;
|
||||
|
||||
case MENU_OPT_SPELL:
|
||||
transldlg->t_source->SetValue(_T("<say-as interpret-as=\"tts:char\">\n"));
|
||||
transldlg->t_source->SetInsertionPointEnd();
|
||||
notebook->SetSelection(1);
|
||||
break;
|
||||
|
||||
case MENU_PATH0:
|
||||
string = wxFileSelector(_T("Master phonemes file"),wxFileName(path_phfile).GetPath(),
|
||||
_T(""),_T(""),_T("*"),wxOPEN);
|
||||
@@ -677,6 +693,7 @@ void MyFrame::OnSpeak(wxCommandEvent& event)
|
||||
{
|
||||
case MENU_SPEAK_TRANSLATE:
|
||||
case MENU_SPEAK_RULES:
|
||||
case MENU_SPEAK_IPA:
|
||||
case MENU_SPEAK_TEXT:
|
||||
transldlg->OnCommand(event);
|
||||
break;
|
||||
|
||||
+1
-1
@@ -192,7 +192,7 @@ static unsigned char env_risefallrise[128] = {
|
||||
|
||||
|
||||
|
||||
unsigned char *envelope_data[20] = {
|
||||
unsigned char *envelope_data[N_ENVELOPE_DATA] = {
|
||||
env_fall, env_fall,
|
||||
env_rise, env_rise,
|
||||
env_frise, env_r_frise,
|
||||
|
||||
+9
-9
@@ -458,7 +458,7 @@ if(option_log_frames)
|
||||
temp = (temp * kt_globals.fadeout) / 64;
|
||||
}
|
||||
|
||||
value = int(temp) + ((echo_buf[echo_tail++]*echo_amp) >> 8);
|
||||
value = (int)temp + ((echo_buf[echo_tail++]*echo_amp) >> 8);
|
||||
if(echo_tail >= N_ECHO_BUF)
|
||||
echo_tail=0;
|
||||
|
||||
@@ -973,7 +973,7 @@ static double DBtoLIN(long dB)
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(double(amptable[dB]) * 0.001);
|
||||
return((double)(amptable[dB]) * 0.001);
|
||||
}
|
||||
|
||||
|
||||
@@ -1050,7 +1050,7 @@ int Wavegen_Klatt(int resume)
|
||||
for(ix=0; ix < N_KLATTP; ix++)
|
||||
{
|
||||
klattp1[ix] += klattp_inc[ix];
|
||||
klattp[ix] = int(klattp1[ix]);
|
||||
klattp[ix] = (int)klattp1[ix];
|
||||
}
|
||||
|
||||
for(ix=0; ix<=6; ix++)
|
||||
@@ -1213,7 +1213,7 @@ if(option_log_frames)
|
||||
else
|
||||
{
|
||||
klattp1[ix] = klattp[ix] = fr1->klattp[ix];
|
||||
klattp_inc[ix] = double((fr2->klattp[ix] - klattp[ix]) * STEPSIZE)/length;
|
||||
klattp_inc[ix] = (double)((fr2->klattp[ix] - klattp[ix]) * STEPSIZE)/length;
|
||||
}
|
||||
|
||||
// get klatt parameter adjustments for the voice
|
||||
@@ -1226,7 +1226,7 @@ if(option_log_frames)
|
||||
for(ix=1; ix < 6; ix++)
|
||||
{
|
||||
peaks[ix].freq1 = (fr1->ffreq[ix] * v->freq[ix] / 256.0) + v->freqadd[ix];
|
||||
peaks[ix].freq = int(peaks[ix].freq1);
|
||||
peaks[ix].freq = (int)peaks[ix].freq1;
|
||||
next = (fr2->ffreq[ix] * v->freq[ix] / 256.0) + v->freqadd[ix];
|
||||
peaks[ix].freq_inc = ((next - peaks[ix].freq1) * STEPSIZE) / length;
|
||||
|
||||
@@ -1234,7 +1234,7 @@ if(option_log_frames)
|
||||
{
|
||||
// klatt bandwidth for f1, f2, f3 (others are fixed)
|
||||
peaks[ix].bw1 = fr1->bw[ix] * 2;
|
||||
peaks[ix].bw = int(peaks[ix].bw1);
|
||||
peaks[ix].bw = (int)peaks[ix].bw1;
|
||||
next = fr2->bw[ix] * 2;
|
||||
peaks[ix].bw_inc = ((next - peaks[ix].bw1) * STEPSIZE) / length;
|
||||
}
|
||||
@@ -1245,7 +1245,7 @@ if(option_log_frames)
|
||||
if(peaks[0].freq1 == 0)
|
||||
peaks[0].freq1 = kt_frame.Fhz[F_NP]; // if no nasal zero, set it to same freq as nasal pole
|
||||
|
||||
peaks[0].freq = int(peaks[0].freq1);
|
||||
peaks[0].freq = (int)peaks[0].freq1;
|
||||
next = fr2->klattp[KLATT_FNZ] * 2;
|
||||
if(next == 0)
|
||||
next = kt_frame.Fhz[F_NP];
|
||||
@@ -1262,12 +1262,12 @@ if(option_log_frames)
|
||||
for(ix=1; ix < 7; ix++)
|
||||
{
|
||||
peaks[ix].bp1 = fr1->klatt_bp[ix] * 4; // parallel bandwidth
|
||||
peaks[ix].bp = int(peaks[ix].bp1);
|
||||
peaks[ix].bp = (int)peaks[ix].bp1;
|
||||
next = fr2->klatt_bp[ix] * 2;
|
||||
peaks[ix].bp_inc = ((next - peaks[ix].bp1) * STEPSIZE) / length;
|
||||
|
||||
peaks[ix].ap1 = fr1->klatt_ap[ix]; // parallal amplitude
|
||||
peaks[ix].ap = int(peaks[ix].ap1);
|
||||
peaks[ix].ap = (int)peaks[ix].ap1;
|
||||
next = fr2->klatt_ap[ix] * 2;
|
||||
peaks[ix].ap_inc = ((next - peaks[ix].ap1) * STEPSIZE) / length;
|
||||
}
|
||||
|
||||
+5
-2
@@ -94,11 +94,11 @@ public:
|
||||
void SpeakFile(void);
|
||||
void ReadVoice(int variant);
|
||||
void OnCommand(wxCommandEvent& event);
|
||||
wxTextCtrl* t_source;
|
||||
|
||||
private:
|
||||
wxButton *t_translate;
|
||||
wxButton *t_process;
|
||||
wxTextCtrl* t_source;
|
||||
wxTextCtrl* t_phonetic;
|
||||
|
||||
|
||||
@@ -124,7 +124,9 @@ enum {
|
||||
MENU_DOCS,
|
||||
|
||||
MENU_OPTIONS,
|
||||
MENU_PARAMS,
|
||||
MENU_OPT_SPEED,
|
||||
MENU_OPT_PUNCT,
|
||||
MENU_OPT_SPELL,
|
||||
MENU_PATHS,
|
||||
MENU_PATH0,
|
||||
MENU_PATH1,
|
||||
@@ -143,6 +145,7 @@ enum {
|
||||
|
||||
MENU_SPEAK_TRANSLATE,
|
||||
MENU_SPEAK_RULES,
|
||||
MENU_SPEAK_IPA,
|
||||
MENU_SPEAK_TEXT,
|
||||
MENU_SPEAK_FILE,
|
||||
MENU_SPEAK_PAUSE,
|
||||
|
||||
+89
-62
@@ -74,19 +74,19 @@ static void log(const char *msg, ...)
|
||||
va_end(params);
|
||||
}
|
||||
|
||||
static void err(const char *err, ...)
|
||||
static void err(const char *errmsg, ...)
|
||||
{
|
||||
va_list params;
|
||||
|
||||
va_start(params, err);
|
||||
vsnprintf(mbr_errorbuf, sizeof(mbr_errorbuf), err, params);
|
||||
va_start(params, errmsg);
|
||||
vsnprintf(mbr_errorbuf, sizeof(mbr_errorbuf), errmsg, params);
|
||||
va_end(params);
|
||||
log("mbrola error: \"%s\"", mbr_errorbuf);
|
||||
log("mbrowrap error: %s", mbr_errorbuf);
|
||||
}
|
||||
|
||||
static int create_pipes(int p1[2], int p2[2], int p3[2])
|
||||
{
|
||||
int error=0;
|
||||
int error;
|
||||
|
||||
if (pipe(p1) != -1) {
|
||||
if (pipe(p2) != -1) {
|
||||
@@ -100,7 +100,8 @@ static int create_pipes(int p1[2], int p2[2], int p3[2])
|
||||
error = errno;
|
||||
close(p1[0]);
|
||||
close(p1[1]);
|
||||
}
|
||||
} else
|
||||
error = errno;
|
||||
|
||||
err("pipe(): %s", strerror(error));
|
||||
return -1;
|
||||
@@ -231,67 +232,89 @@ static void free_pending_data(void)
|
||||
mbr_pending_data_tail = NULL;
|
||||
}
|
||||
|
||||
static int mbrola_died(void)
|
||||
{
|
||||
pid_t pid;
|
||||
int status, len;
|
||||
const char *msg;
|
||||
char msgbuf[80];
|
||||
|
||||
pid = waitpid(mbr_pid, &status, WNOHANG);
|
||||
if (!pid) {
|
||||
msg = "mbrola closed stderr and did not exit";
|
||||
} else if (pid != mbr_pid) {
|
||||
msg = "waitpid() is confused";
|
||||
} else {
|
||||
mbr_pid = 0;
|
||||
if (WIFSIGNALED(status)) {
|
||||
int sig = WTERMSIG(status);
|
||||
snprintf(msgbuf, sizeof(msgbuf),
|
||||
"mbrola died by signal %d", sig);
|
||||
msg = msgbuf;
|
||||
} else if (WIFEXITED(status)) {
|
||||
int exst = WEXITSTATUS(status);
|
||||
snprintf(msgbuf, sizeof(msgbuf),
|
||||
"mbrola exited with status %d", exst);
|
||||
msg = msgbuf;
|
||||
} else {
|
||||
msg = "mbrola died and wait status is weird";
|
||||
}
|
||||
}
|
||||
|
||||
log("mbrowrap error: %s", msg);
|
||||
|
||||
len = strlen(mbr_errorbuf);
|
||||
if (!len)
|
||||
snprintf(mbr_errorbuf, sizeof(mbr_errorbuf), "%s", msg);
|
||||
else
|
||||
snprintf(mbr_errorbuf + len, sizeof(mbr_errorbuf) - len,
|
||||
", (%s)", msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int mbrola_has_errors(void)
|
||||
{
|
||||
int result, error;
|
||||
int result;
|
||||
char buffer[256];
|
||||
char *buf_ptr, *lf;
|
||||
|
||||
result = read(mbr_error_fd, mbr_errorbuf, sizeof(mbr_errorbuf)-1);
|
||||
|
||||
if (result == -1) {
|
||||
if (errno == EAGAIN)
|
||||
return 0;
|
||||
err("read(error): %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (result != 0) {
|
||||
mbr_errorbuf[result] = 0;
|
||||
if (mbr_errorbuf[result - 1] == '\n')
|
||||
mbr_errorbuf[result - 1] = 0;
|
||||
/* inhibit the reset signal message */
|
||||
if (strncmp(mbr_errorbuf, "Got a reset signal", 18) == 0) {
|
||||
mbr_errorbuf[0] = 0;
|
||||
return 0;
|
||||
buf_ptr = buffer;
|
||||
for (;;) {
|
||||
result = read(mbr_error_fd, buf_ptr,
|
||||
sizeof(buffer) - (buf_ptr - buffer) - 1);
|
||||
if (result == -1) {
|
||||
if (errno == EAGAIN)
|
||||
return 0;
|
||||
err("read(error): %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
/* don't consider this fatal at this point */
|
||||
error = 0;
|
||||
} else {
|
||||
/* EOF on stderr, assume mbrola died. */
|
||||
pid_t pid;
|
||||
int status, len;
|
||||
const char *msg;
|
||||
char msgbuf[80];
|
||||
|
||||
pid = waitpid(mbr_pid, &status, WNOHANG);
|
||||
if (!pid) {
|
||||
msg = "mbrola closed stderr and did not exit";
|
||||
} else {
|
||||
mbr_pid = 0;
|
||||
if (WIFSIGNALED(status)) {
|
||||
int sig = WTERMSIG(status);
|
||||
snprintf(msgbuf, sizeof(msgbuf),
|
||||
"mbrola died by signal %d", sig);
|
||||
msg = msgbuf;
|
||||
} else if (WIFEXITED(status)) {
|
||||
int exst = WEXITSTATUS(status);
|
||||
snprintf(msgbuf, sizeof(msgbuf),
|
||||
"mbrola exited with status %d", exst);
|
||||
msg = msgbuf;
|
||||
} else {
|
||||
msg = "mbrola died and wait status is weird";
|
||||
if (result == 0) {
|
||||
/* EOF on stderr, assume mbrola died. */
|
||||
return mbrola_died();
|
||||
}
|
||||
|
||||
buf_ptr[result] = 0;
|
||||
|
||||
for (; (lf = strchr(buf_ptr, '\n')); buf_ptr = lf + 1) {
|
||||
/* inhibit the reset signal messages */
|
||||
if (strncmp(buf_ptr, "Got a reset signal", 18) == 0 ||
|
||||
strncmp(buf_ptr, "Input Flush Signal", 18) == 0)
|
||||
continue;
|
||||
*lf = 0;
|
||||
log("mbrola: %s", buf_ptr);
|
||||
/* is this the last line? */
|
||||
if (lf == &buf_ptr[result - 1]) {
|
||||
snprintf(mbr_errorbuf, sizeof(mbr_errorbuf),
|
||||
"%s", buf_ptr);
|
||||
/* don't consider this fatal at this point */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
len = strlen(mbr_errorbuf);
|
||||
if (!len)
|
||||
snprintf(mbr_errorbuf, sizeof(mbr_errorbuf), "%s", msg);
|
||||
else
|
||||
snprintf(mbr_errorbuf+len, sizeof(mbr_errorbuf)-len,
|
||||
", (%s)", msg);
|
||||
error = -1;
|
||||
}
|
||||
|
||||
log("mbrola error: \"%s\"", mbr_errorbuf);
|
||||
return error;
|
||||
memmove(buffer, buf_ptr, result);
|
||||
buf_ptr = buffer + result;
|
||||
}
|
||||
}
|
||||
|
||||
static int send_to_mbrola(const char *cmd)
|
||||
@@ -468,7 +491,8 @@ int init_MBR(const char *voice_path)
|
||||
/* we should actually be getting only 44 bytes */
|
||||
result = receive_from_mbrola(wavhdr, 45);
|
||||
if (result != 44) {
|
||||
err("unable to get .wav header from mbrola");
|
||||
if (result >= 0)
|
||||
err("unable to get .wav header from mbrola");
|
||||
stop_mbrola();
|
||||
return -1;
|
||||
}
|
||||
@@ -482,7 +506,7 @@ int init_MBR(const char *voice_path)
|
||||
}
|
||||
mbr_samplerate = wavhdr[24] + (wavhdr[25]<<8) +
|
||||
(wavhdr[26]<<16) + (wavhdr[27]<<24);
|
||||
//log("mbrola: voice samplerate = %d", mbr_samplerate);
|
||||
//log("mbrowrap: voice samplerate = %d", mbr_samplerate);
|
||||
|
||||
/* remember the voice path for setVolumeRatio_MBR() */
|
||||
if (mbr_voice_path != voice_path) {
|
||||
@@ -568,7 +592,10 @@ void setVolumeRatio_MBR(float value)
|
||||
|
||||
int lastErrorStr_MBR(char *buffer, int bufsize)
|
||||
{
|
||||
int result = snprintf(buffer, bufsize, "%s", mbr_errorbuf);
|
||||
int result;
|
||||
if (mbr_pid)
|
||||
mbrola_has_errors();
|
||||
result = snprintf(buffer, bufsize, "%s", mbr_errorbuf);
|
||||
return result >= bufsize ? (bufsize - 1) : result;
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -71,6 +71,7 @@ wxMenuBar *MakeMenu(int type)
|
||||
speak_menu = new wxMenu;
|
||||
speak_menu->Append(MENU_SPEAK_TRANSLATE, _("&Translate"));
|
||||
speak_menu->Append(MENU_SPEAK_RULES, _("Show &Rules"));
|
||||
speak_menu->Append(MENU_SPEAK_IPA, _("Show &IPA"));
|
||||
speak_menu->Append(MENU_SPEAK_TEXT, _("&Speak"));
|
||||
speak_menu->AppendSeparator();
|
||||
speak_menu->Append(MENU_SPEAK_FILE, _("Speak &file..."));
|
||||
@@ -105,7 +106,9 @@ wxMenuBar *MakeMenu(int type)
|
||||
|
||||
option_menu = new wxMenu;
|
||||
option_menu->Append(MENU_PATHS, _("Set &paths"), paths_menu);
|
||||
option_menu->Append(MENU_PARAMS, _("Speed..."));
|
||||
option_menu->Append(MENU_OPT_SPEED, _("Speed..."));
|
||||
option_menu->Append(MENU_OPT_PUNCT, _("Speak punctiation"));
|
||||
option_menu->Append(MENU_OPT_SPELL, _("Speak character names"));
|
||||
|
||||
// TOOLS
|
||||
vowelchart_menu = new wxMenu;
|
||||
|
||||
+23
-29
@@ -498,12 +498,12 @@ void LookupAccentedLetter(Translator *tr, unsigned int letter, char *ph_buf)
|
||||
|
||||
|
||||
|
||||
void LookupLetter(Translator *tr, unsigned int letter, int next_byte, char *ph_buf1)
|
||||
{//=================================================================================
|
||||
void LookupLetter(Translator *tr, unsigned int letter, int next_byte, char *ph_buf1, int control)
|
||||
{//==============================================================================================
|
||||
// control, bit 0: not the first letter of a word
|
||||
|
||||
int len;
|
||||
unsigned char *p;
|
||||
static char single_letter[10] = {0,0};
|
||||
char ph_stress[2];
|
||||
unsigned int dict_flags[2];
|
||||
char ph_buf3[40];
|
||||
char *ptr;
|
||||
@@ -568,27 +568,17 @@ void LookupLetter(Translator *tr, unsigned int letter, int next_byte, char *ph_b
|
||||
LookupAccentedLetter(tr, letter, ph_buf3);
|
||||
}
|
||||
|
||||
if(ph_buf3[0] == 0)
|
||||
strcpy(ph_buf1, ph_buf3);
|
||||
if((ph_buf1[0] == 0) || (ph_buf1[0] == phonSWITCH))
|
||||
{
|
||||
ph_buf1[0] = 0;
|
||||
return;
|
||||
}
|
||||
if(ph_buf3[0] == phonSWITCH)
|
||||
{
|
||||
strcpy(ph_buf1,ph_buf3);
|
||||
return;
|
||||
}
|
||||
// at a stress marker at the start of the letter name, unless one is already marked
|
||||
ph_stress[0] = phonSTRESS_P;
|
||||
ph_stress[1] = 0;
|
||||
|
||||
for(p=(unsigned char *)ph_buf3; (*p != 0) && (phoneme_tab[*p] != NULL); p++)
|
||||
{
|
||||
if(phoneme_tab[*p]->type == phSTRESS)
|
||||
ph_stress[0] = 0; // stress is already marked
|
||||
}
|
||||
sprintf(ph_buf1,"%s%s",ph_stress,ph_buf3);
|
||||
}
|
||||
dict_flags[0] = 0;
|
||||
dict_flags[1] = 0;
|
||||
SetWordStress(tr, ph_buf1, dict_flags, -1, control & 1);
|
||||
|
||||
} // end of LookupLetter
|
||||
|
||||
|
||||
|
||||
@@ -596,7 +586,9 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control)
|
||||
{//=========================================================================
|
||||
// get pronunciation for an isolated letter
|
||||
// return number of bytes used by the letter
|
||||
// control 2=say-as glyphs, 3-say-as chars
|
||||
// control bit 0: a non-initial letter in a word
|
||||
// bit 1: say 'capital'
|
||||
|
||||
int n_bytes;
|
||||
int letter;
|
||||
int len;
|
||||
@@ -618,7 +610,7 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control)
|
||||
letter &= 0xff; // uncode private usage area
|
||||
}
|
||||
|
||||
if(control > 2)
|
||||
if(control & 2)
|
||||
{
|
||||
// include CAPITAL information
|
||||
if(iswupper(letter))
|
||||
@@ -628,7 +620,7 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control)
|
||||
}
|
||||
letter = towlower2(letter);
|
||||
|
||||
LookupLetter(tr, letter, word[n_bytes], ph_buf);
|
||||
LookupLetter(tr, letter, word[n_bytes], ph_buf, control & 1);
|
||||
|
||||
if(ph_buf[0] == phonSWITCH)
|
||||
{
|
||||
@@ -642,7 +634,7 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control)
|
||||
SetTranslator2("en");
|
||||
save_option_phonemes = option_phonemes;
|
||||
option_phonemes = 0;
|
||||
LookupLetter(translator2, letter, word[n_bytes], ph_buf);
|
||||
LookupLetter(translator2, letter, word[n_bytes], ph_buf, control & 1);
|
||||
SelectPhonemeTable(voice->phoneme_tab_ix); // revert to original phoneme table
|
||||
option_phonemes = save_option_phonemes;
|
||||
|
||||
@@ -671,7 +663,7 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control)
|
||||
{
|
||||
pbuf += strlen(pbuf);
|
||||
*pbuf++ = phonPAUSE_VSHORT;
|
||||
LookupLetter(tr, *p2, 0, pbuf);
|
||||
LookupLetter(tr, *p2, 0, pbuf, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -740,9 +732,11 @@ void SetSpellingStress(Translator *tr, char *phonemes, int control, int n_chars)
|
||||
if(control == 4)
|
||||
c = phonPAUSE; // pause after each character
|
||||
if(((count % 3) == 0) || (control > 2))
|
||||
c = phonPAUSE_SHORT; // pause following a primary stress
|
||||
c = phonPAUSE_NOLINK; // pause following a primary stress
|
||||
else
|
||||
continue; // remove marker
|
||||
c = phonPAUSE_VSHORT;
|
||||
// else
|
||||
// continue; // remove marker
|
||||
}
|
||||
*phonemes++ = c;
|
||||
}
|
||||
@@ -1593,7 +1587,7 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned
|
||||
hyphen = 1;
|
||||
ix++;
|
||||
}
|
||||
while((word[ix] != 0) && (word[ix] != ' ') && (ix < int(sizeof(suffix)-1)))
|
||||
while((word[ix] != 0) && (word[ix] != ' ') && (ix < (int)(sizeof(suffix)-1)))
|
||||
{
|
||||
*p++ = word[ix++];
|
||||
}
|
||||
|
||||
@@ -380,9 +380,12 @@ void ProsodyDisplay::DrawEnv(wxDC& dc, int x1, int y1, int width, PHONEME_LIST *
|
||||
{
|
||||
// the envelope is given by a Tone phoneme acting on this vowel
|
||||
InterpretPhoneme2(ph->tone_ph, &phdata_tone);
|
||||
env = LookupEnvelope(phdata_tone.pitch_env);
|
||||
env = GetEnvelope(phdata_tone.pitch_env);
|
||||
}
|
||||
|
||||
if(env == NULL)
|
||||
return;
|
||||
|
||||
for(ix=0; ix<=width; ix+=4)
|
||||
{
|
||||
x = int((ix * 127.9)/width);
|
||||
|
||||
+6
-6
@@ -121,17 +121,17 @@ static const unsigned int punct_attributes [] = { 0,
|
||||
CLAUSE_COMMA, CLAUSE_PERIOD, CLAUSE_QUESTION, CLAUSE_EXCLAMATION, CLAUSE_COLON, CLAUSE_SEMICOLON,
|
||||
CLAUSE_SEMICOLON, // en-dash
|
||||
CLAUSE_SEMICOLON, // em-dash
|
||||
CLAUSE_SEMICOLON + PUNCT_SAY_NAME | 0x8000, // elipsis
|
||||
CLAUSE_SEMICOLON | PUNCT_SAY_NAME | 0x8000, // elipsis
|
||||
|
||||
CLAUSE_QUESTION, // Greek question mark
|
||||
CLAUSE_SEMICOLON, // Greek semicolon
|
||||
CLAUSE_PERIOD+0x8000, // Devanagari Danda (fullstop)
|
||||
CLAUSE_PERIOD | 0x8000, // Devanagari Danda (fullstop)
|
||||
|
||||
CLAUSE_PERIOD+0x8000, // Armenian period
|
||||
CLAUSE_PERIOD | 0x8000, // Armenian period
|
||||
CLAUSE_COMMA, // Armenian comma
|
||||
CLAUSE_EXCLAMATION + PUNCT_IN_WORD, // Armenian exclamation
|
||||
CLAUSE_QUESTION + PUNCT_IN_WORD, // Armenian question
|
||||
CLAUSE_PERIOD + PUNCT_IN_WORD, // Armenian emphasis mark
|
||||
CLAUSE_EXCLAMATION | PUNCT_IN_WORD, // Armenian exclamation
|
||||
CLAUSE_QUESTION | PUNCT_IN_WORD, // Armenian question
|
||||
CLAUSE_PERIOD | PUNCT_IN_WORD, // Armenian emphasis mark
|
||||
|
||||
CLAUSE_SEMICOLON, // Arabic ;
|
||||
CLAUSE_QUESTION, // Arabic question mark
|
||||
|
||||
+10
-4
@@ -360,14 +360,14 @@ void SetParameter(int parameter, int value, int relative)
|
||||
|
||||
|
||||
|
||||
static void DoEmbedded2(int &embix)
|
||||
static void DoEmbedded2(int *embix)
|
||||
{//================================
|
||||
// There were embedded commands in the text at this point
|
||||
|
||||
unsigned int word;
|
||||
|
||||
do {
|
||||
word = embedded_list[embix++];
|
||||
word = embedded_list[(*embix)++];
|
||||
|
||||
if((word & 0x1f) == EMBED_S)
|
||||
{
|
||||
@@ -420,7 +420,7 @@ void CalcLengths(Translator *tr)
|
||||
|
||||
if(p->synthflags & SFLAG_EMBEDDED)
|
||||
{
|
||||
DoEmbedded2(embedded_ix);
|
||||
DoEmbedded2(&embedded_ix);
|
||||
}
|
||||
|
||||
type = p->type;
|
||||
@@ -734,6 +734,12 @@ if(p->type != phVOWEL)
|
||||
}
|
||||
p->length = length_mod;
|
||||
|
||||
if(p->env >= (N_ENVELOPE_DATA-1))
|
||||
{
|
||||
fprintf(stderr,"espeak: Bad intonation data\n");
|
||||
p->env = 0;
|
||||
}
|
||||
|
||||
// pre-vocalic part
|
||||
// set last-pitch
|
||||
env2 = p->env + 1; // version for use with preceding semi-vowel
|
||||
@@ -741,7 +747,7 @@ if(p->type != phVOWEL)
|
||||
if(p->tone_ph != 0)
|
||||
{
|
||||
InterpretPhoneme2(p->tone_ph, &phdata_tone);
|
||||
pitch_env = LookupEnvelope(phdata_tone.pitch_env);
|
||||
pitch_env = GetEnvelope(phdata_tone.pitch_env);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+17
-12
@@ -75,44 +75,44 @@ static const char *help_text =
|
||||
"\t Amplitude, 0 to 200, default is 100\n"
|
||||
"-g <integer>\n"
|
||||
"\t Word gap. Pause between words, units of 10mS at the default speed\n"
|
||||
"-k <integer>\n"
|
||||
"\t Indicate capital letters with: 1=sound, 2=the word \"capitals\",\n"
|
||||
"\t higher values indicate a pitch increase (try -k20).\n"
|
||||
"-l <integer>\n"
|
||||
"\t Line length. If not zero (which is the default), consider\n"
|
||||
"\t lines less than this length as end-of-clause\n"
|
||||
"-p <integer>\n"
|
||||
"\t Pitch adjustment, 0 to 99, default is 50\n"
|
||||
"-s <integer>\n"
|
||||
"\t Speed in words per minute 80 to 450, default is 175\n"
|
||||
"\t Speed in words per minute, 80 to 450, default is 175\n"
|
||||
"-v <voice name>\n"
|
||||
"\t Use voice file of this name from espeak-data/voices\n"
|
||||
"-w <wave file name>\n"
|
||||
"\t Write output to this WAV file, rather than speaking it directly\n"
|
||||
"\t Write speech to this WAV file, rather than speaking it directly\n"
|
||||
"-b\t Input text encoding, 1=UTF8, 2=8 bit, 4=16 bit \n"
|
||||
"-m\t Interpret SSML markup, and ignore other < > tags\n"
|
||||
"-q\t Quiet, don't produce any speech (may be useful with -x)\n"
|
||||
"-x\t Write phoneme mnemonics to stdout\n"
|
||||
"-X\t Write phonemes mnemonics and translation trace to stdout\n"
|
||||
"-z\t No final sentence pause at the end of the text\n"
|
||||
"--stdout Write speech output to stdout\n"
|
||||
"--compile=<voice name>\n"
|
||||
"\t Compile the pronunciation rules and dictionary in the current\n"
|
||||
"\t Compile pronunciation rules and dictionary from the current\n"
|
||||
"\t directory. <voice name> specifies the language\n"
|
||||
"--ipa Write phonemes to stdout using International Phonetic Alphabet\n"
|
||||
"--path=\"<path>\"\n"
|
||||
"\t Specifies the directory containing the espeak-data directory\n"
|
||||
"--pho\n"
|
||||
"\t Write mbrola phoneme data (.pho) to stdout, or to the file in --phonout\n"
|
||||
"--pho Write mbrola phoneme data (.pho) to stdout or to the file in --phonout\n"
|
||||
"--phonout=\"<filename>\"\n"
|
||||
"\t Write phoneme output from -x -X and --pho to this file\n"
|
||||
"\t Write phoneme output from -x -X --ipa and --pho to this file\n"
|
||||
"--punct=\"<characters>\"\n"
|
||||
"\t Speak the names of punctuation characters during speaking. If\n"
|
||||
"\t =<characters> is omitted, all punctuation is spoken.\n"
|
||||
"--split=\"<minutes>\"\n"
|
||||
"\t Starts a new WAV file every <minutes>. Used with -w\n"
|
||||
"--stdout Write speech output to stdout\n"
|
||||
"--voices=<language>\n"
|
||||
"\t List the available voices for the specified language.\n"
|
||||
"\t If <language> is omitted, then list all voices.\n"
|
||||
"-k <integer>\n"
|
||||
"\t Indicate capital letters with: 1=sound, 2=the word \"capitals\",\n"
|
||||
"\t higher values indicate a pitch increase (try -k20).\n";
|
||||
"\t If <language> is omitted, then list all voices.\n";
|
||||
|
||||
|
||||
void DisplayVoices(FILE *f_out, char *language);
|
||||
@@ -478,6 +478,7 @@ int main (int argc, char **argv)
|
||||
{"path", required_argument, 0, 0x107},
|
||||
{"phonout", required_argument, 0, 0x108},
|
||||
{"pho", no_argument, 0, 0x109},
|
||||
{"ipa", no_argument, 0, 0x10a},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -708,7 +709,11 @@ int main (int argc, char **argv)
|
||||
break;
|
||||
|
||||
case 0x109: // --pho
|
||||
option_mbrola_phonemes = 8;
|
||||
option_mbrola_phonemes = 16;
|
||||
break;
|
||||
|
||||
case 0x10a: // --ipa
|
||||
option_phonemes = 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
+7
-5
@@ -1120,13 +1120,15 @@ ESPEAK_API void espeak_SetPhonemeTrace(int value, FILE *stream)
|
||||
{//============================================================
|
||||
ENTER("espeak_SetPhonemes");
|
||||
/* Controls the output of phoneme symbols for the text
|
||||
value=0 No phoneme output (default)
|
||||
value=1 Output the translated phoneme symbols for the text
|
||||
value=2 as (1), but also output a trace of how the translation was done (matching rules and list entries)
|
||||
bit 3: produce mbrola pho data
|
||||
bits 0-3:
|
||||
value=0 No phoneme output (default)
|
||||
value=1 Output the translated phoneme symbols for the text
|
||||
value=2 as (1), but also output a trace of how the translation was done (matching rules and list entries)
|
||||
value=3 as (1), but produces IPA phoneme names rather than ascii
|
||||
bit 4: produce mbrola pho data
|
||||
*/
|
||||
option_phonemes = value & 3;
|
||||
option_mbrola_phonemes = value & 8;
|
||||
option_mbrola_phonemes = value & 16;
|
||||
f_trans = stream;
|
||||
if(stream == NULL)
|
||||
f_trans = stderr;
|
||||
|
||||
@@ -444,6 +444,7 @@ void espeak_SetPhonemeTrace(int value, FILE *stream);
|
||||
value=0 No phoneme output (default)
|
||||
value=1 Output the translated phoneme symbols for the text
|
||||
value=2 as (1), but also output a trace of how the translation was done (matching rules and list entries)
|
||||
value=3 as (1), but produces IPA rather than ascii phoneme names
|
||||
|
||||
stream output stream for the phoneme symbols (and trace). If stream=NULL then it uses stdout.
|
||||
*/
|
||||
|
||||
+18
-20
@@ -386,7 +386,7 @@ int MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, int resume, FILE *f_mbr
|
||||
int done;
|
||||
int len_percent;
|
||||
const char *final_pitch;
|
||||
char buf[80];
|
||||
char *ptr;
|
||||
char mbr_buf[120];
|
||||
|
||||
static int phix;
|
||||
@@ -404,7 +404,7 @@ int MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, int resume, FILE *f_mbr
|
||||
if (WcmdqFree() < MIN_WCMDQ)
|
||||
return 1;
|
||||
|
||||
mbr_buf[0] = 0;
|
||||
ptr = mbr_buf;
|
||||
|
||||
p = &plist[phix];
|
||||
next = &plist[phix+1];
|
||||
@@ -415,7 +415,7 @@ int MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, int resume, FILE *f_mbr
|
||||
|
||||
if(p->synthflags & SFLAG_EMBEDDED)
|
||||
{
|
||||
DoEmbedded(embedded_ix, p->sourceix);
|
||||
DoEmbedded(&embedded_ix, p->sourceix);
|
||||
}
|
||||
|
||||
if(p->newword & 4)
|
||||
@@ -446,13 +446,12 @@ int MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, int resume, FILE *f_mbr
|
||||
|
||||
DoMarker(espeakEVENT_PHONEME, (p->sourceix & 0x7ff) + clause_start_char, 0, ph->mnemonic);
|
||||
|
||||
sprintf(buf,"%s\t",WordToString(name));
|
||||
strcat(mbr_buf,buf);
|
||||
ptr += sprintf(ptr,"%s\t",WordToString(name));
|
||||
|
||||
if(name2 == '_')
|
||||
{
|
||||
// add a pause after this phoneme
|
||||
pause = PauseLength(len_percent,0);
|
||||
pause = len_percent;
|
||||
name2 = 0;
|
||||
}
|
||||
|
||||
@@ -472,17 +471,19 @@ int MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, int resume, FILE *f_mbr
|
||||
|
||||
if(name2 == 0)
|
||||
{
|
||||
sprintf(buf,"%d\t%s", len, WritePitch(p->env,p->pitch1,p->pitch2,0,0));
|
||||
strcat(mbr_buf,buf);
|
||||
char *pitch = WritePitch(p->env,p->pitch1,p->pitch2,0,0);
|
||||
ptr += sprintf(ptr,"%d\t%s", len, pitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
len1 = (len * len_percent)/100;
|
||||
sprintf(buf,"%d\t%s", len1, WritePitch(p->env,p->pitch1,p->pitch2,len_percent,0));
|
||||
strcat(mbr_buf,buf);
|
||||
char *pitch;
|
||||
|
||||
sprintf(buf,"%s\t%d\t%s", WordToString(name2), len-len1, WritePitch(p->env,p->pitch1,p->pitch2,-len_percent,0));
|
||||
strcat(mbr_buf,buf);
|
||||
pitch = WritePitch(p->env,p->pitch1,p->pitch2,len_percent,0);
|
||||
len1 = (len * len_percent)/100;
|
||||
ptr += sprintf(ptr,"%d\t%s", len1, pitch);
|
||||
|
||||
pitch = WritePitch(p->env,p->pitch1,p->pitch2,-len_percent,0);
|
||||
ptr += sprintf(ptr,"%s\t%d\t%s", WordToString(name2), len-len1, pitch);
|
||||
}
|
||||
done = 1;
|
||||
break;
|
||||
@@ -545,25 +546,22 @@ int MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, int resume, FILE *f_mbr
|
||||
if(name2 != 0)
|
||||
{
|
||||
len1 = (len * len_percent)/100;
|
||||
sprintf(buf,"%d\n%s\t",len1,WordToString(name2));
|
||||
strcat(mbr_buf,buf);
|
||||
ptr += sprintf(ptr,"%d\n%s\t",len1,WordToString(name2));
|
||||
len -= len1;
|
||||
}
|
||||
sprintf(buf,"%d%s\n",len,final_pitch);
|
||||
strcat(mbr_buf,buf);
|
||||
ptr += sprintf(ptr,"%d%s\n",len,final_pitch);
|
||||
}
|
||||
|
||||
if(pause)
|
||||
{
|
||||
len += PauseLength(pause,0);
|
||||
sprintf(buf,"_ \t%d\n",PauseLength(pause,0));
|
||||
strcat(mbr_buf,buf);
|
||||
ptr += sprintf(ptr,"_ \t%d\n",PauseLength(pause,0));
|
||||
pause = 0;
|
||||
}
|
||||
|
||||
if(f_mbrola)
|
||||
{
|
||||
fwrite(mbr_buf,1,strlen(mbr_buf),f_mbrola); // write .pho to a file
|
||||
fwrite(mbr_buf,1,(ptr-mbr_buf),f_mbrola); // write .pho to a file
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+22
-7
@@ -35,8 +35,8 @@
|
||||
#include "translate.h"
|
||||
#include "wave.h"
|
||||
|
||||
const char *version_string = "1.43.48 28.Jun.10";
|
||||
const int version_phdata = 0x014342;
|
||||
const char *version_string = "1.43.52 04.Jul.10";
|
||||
const int version_phdata = 0x014351;
|
||||
|
||||
int option_device_number = -1;
|
||||
FILE *f_logespeak = NULL;
|
||||
@@ -364,11 +364,14 @@ frameref_t *LookupSpect(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params,
|
||||
|
||||
|
||||
|
||||
unsigned char *LookupEnvelope(int ix)
|
||||
{//================================
|
||||
if(ix==0)
|
||||
return(NULL);
|
||||
return((unsigned char *)&spects_data[ix]);
|
||||
unsigned char *GetEnvelope(int index)
|
||||
{//==================================
|
||||
if(index==0)
|
||||
{
|
||||
fprintf(stderr,"espeak: No envelope\n");
|
||||
return(envelope_data[0]); // not found, use a default envelope
|
||||
}
|
||||
return((unsigned char *)&spects_data[index]);
|
||||
}
|
||||
|
||||
|
||||
@@ -877,6 +880,18 @@ void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_
|
||||
phdata->pd_param[i_APPEND_PHONEME] = data;
|
||||
}
|
||||
else
|
||||
if(instn2 == i_IPA_NAME)
|
||||
{
|
||||
// followed by utf-8 characters, 2 per instn word
|
||||
for(ix=0; (ix < data) && (ix < 16); ix += 2)
|
||||
{
|
||||
prog++;
|
||||
phdata->ipa_string[ix] = prog[0] >> 8;
|
||||
phdata->ipa_string[ix+1] = prog[0] & 0xff;
|
||||
}
|
||||
phdata->ipa_string[ix] = 0;
|
||||
}
|
||||
else
|
||||
if(instn2 < N_PHONEME_DATA_PARAM)
|
||||
{
|
||||
if(instn2 == i_CHANGE_PHONEME2)
|
||||
|
||||
+19
-16
@@ -1198,7 +1198,7 @@ void DoVoiceChange(voice_t *v)
|
||||
}
|
||||
|
||||
|
||||
void DoEmbedded(int &embix, int sourceix)
|
||||
void DoEmbedded(int *embix, int sourceix)
|
||||
{//======================================
|
||||
// There were embedded commands in the text at this point
|
||||
unsigned int word; // bit 7=last command for this word, bits 5,6 sign, bits 0-4 command
|
||||
@@ -1206,7 +1206,7 @@ void DoEmbedded(int &embix, int sourceix)
|
||||
int command;
|
||||
|
||||
do {
|
||||
word = embedded_list[embix++];
|
||||
word = embedded_list[(*embix)++];
|
||||
value = word >> 8;
|
||||
command = word & 0x7f;
|
||||
|
||||
@@ -1323,7 +1323,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
|
||||
|
||||
if(p->synthflags & SFLAG_EMBEDDED)
|
||||
{
|
||||
DoEmbedded(embedded_ix, p->sourceix);
|
||||
DoEmbedded(&embedded_ix, p->sourceix);
|
||||
}
|
||||
|
||||
if(p->newword)
|
||||
@@ -1627,8 +1627,8 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
|
||||
if(p->tone_ph != 0)
|
||||
{
|
||||
InterpretPhoneme2(p->tone_ph, &phdata_tone);
|
||||
pitch_env = LookupEnvelope(phdata_tone.pitch_env);
|
||||
amp_env = LookupEnvelope(phdata_tone.amp_env);
|
||||
pitch_env = GetEnvelope(phdata_tone.pitch_env);
|
||||
amp_env = GetEnvelope(phdata_tone.amp_env);
|
||||
}
|
||||
|
||||
StartSyllable();
|
||||
@@ -1848,20 +1848,23 @@ int SpeakNextClause(FILE *f_in, const void *text_in, int control)
|
||||
CalcPitches(translator, clause_tone);
|
||||
CalcLengths(translator);
|
||||
|
||||
GetTranslatedPhonemeString(translator->phon_out,sizeof(translator->phon_out));
|
||||
if(option_phonemes > 0)
|
||||
if((option_phonemes > 0) || (phoneme_callback != NULL))
|
||||
{
|
||||
fprintf(f_trans,"%s\n",translator->phon_out);
|
||||
|
||||
if(!iswalpha(0x010d))
|
||||
GetTranslatedPhonemeString(translator->phon_out,sizeof(translator->phon_out));
|
||||
if(option_phonemes > 0)
|
||||
{
|
||||
// check that c-caron is recognized as an alphabetic character
|
||||
fprintf(stderr,"Warning: Accented letters are not recognized, eg: U+010D\nSet LC_CTYPE to a UTF-8 locale\n");
|
||||
fprintf(f_trans,"%s\n",translator->phon_out);
|
||||
|
||||
if(!iswalpha(0x010d))
|
||||
{
|
||||
// check that c-caron is recognized as an alphabetic character
|
||||
fprintf(stderr,"Warning: Accented letters are not recognized, eg: U+010D\nSet LC_CTYPE to a UTF-8 locale\n");
|
||||
}
|
||||
}
|
||||
if(phoneme_callback != NULL)
|
||||
{
|
||||
phoneme_callback(translator->phon_out);
|
||||
}
|
||||
}
|
||||
if(phoneme_callback != NULL)
|
||||
{
|
||||
phoneme_callback(translator->phon_out);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+8
-3
@@ -266,6 +266,7 @@ typedef struct {
|
||||
int vowel_transition[4];
|
||||
int pitch_env;
|
||||
int amp_env;
|
||||
char ipa_string[18];
|
||||
} PHONEME_DATA;
|
||||
|
||||
|
||||
@@ -289,7 +290,7 @@ typedef struct {
|
||||
#define i_RETURN 0x0001
|
||||
#define i_CONTINUE 0x0002
|
||||
|
||||
// Group 0 instrcutions with 8 bit operand. These value go into bits 8-15 if the instruction
|
||||
// Group 0 instrcutions with 8 bit operand. These values go into bits 8-15 of the instruction
|
||||
#define i_CHANGE_PHONEME 0x01
|
||||
#define i_REPLACE_NEXT_PHONEME 0x02
|
||||
#define i_INSERT_PHONEME 0x03
|
||||
@@ -302,6 +303,8 @@ typedef struct {
|
||||
#define i_SET_LENGTH 0x0a
|
||||
#define i_LONG_LENGTH 0x0b
|
||||
#define i_CHANGE_PHONEME2 0x0c // not yet used
|
||||
#define i_IPA_NAME 0x0d
|
||||
|
||||
#define i_CHANGE_IF 0x10 // 0x10 to 0x14
|
||||
|
||||
#define i_ADD_LENGTH 0x0c
|
||||
@@ -532,7 +535,8 @@ int CompileDictionary(const char *dsource, const char *dict_name, FILE *log, cha
|
||||
#define ENV_LEN 128 // length of pitch envelopes
|
||||
#define PITCHfall 0 // standard pitch envelopes
|
||||
#define PITCHrise 2
|
||||
extern unsigned char *envelope_data[20];
|
||||
#define N_ENVELOPE_DATA 20
|
||||
extern unsigned char *envelope_data[N_ENVELOPE_DATA];
|
||||
|
||||
extern int formant_rate[]; // max rate of change of each formant
|
||||
extern SPEED_FACTORS speed;
|
||||
@@ -562,13 +566,14 @@ int MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, int resume, FILE *f_mbr
|
||||
int MbrolaGenerate(PHONEME_LIST *phoneme_list, int *n_ph, int resume);
|
||||
int MbrolaFill(int length, int resume);
|
||||
void MbrolaReset(void);
|
||||
void DoEmbedded(int &embix, int sourceix);
|
||||
void DoEmbedded(int *embix, int sourceix);
|
||||
void DoMarker(int type, int char_posn, int length, int value);
|
||||
//int DoSample(PHONEME_TAB *ph1, PHONEME_TAB *ph2, int which, int length_mod, int amp);
|
||||
int DoSample3(PHONEME_DATA *phdata, int length_mod, int amp);
|
||||
int DoSpect2(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, PHONEME_LIST *plist, int modulation);
|
||||
int PauseLength(int pause, int control);
|
||||
int LookupPhonemeTable(const char *name);
|
||||
unsigned char *GetEnvelope(int index);
|
||||
|
||||
void InitBreath(void);
|
||||
|
||||
|
||||
+15
-4
@@ -418,7 +418,7 @@ Translator *SelectTranslator(const char *name)
|
||||
|
||||
case L('d','a'): // Danish
|
||||
{
|
||||
static const short stress_lengths_da[8] = {160,140, 200,200, 0,0, 220,210};
|
||||
static const short stress_lengths_da[8] = {160,140, 200,200, 0,0, 220,230};
|
||||
SetupTranslator(tr,stress_lengths_da,NULL);
|
||||
|
||||
tr->transpose_min = 'a';
|
||||
@@ -605,16 +605,18 @@ Translator *SelectTranslator(const char *name)
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case L('f','r'): // french
|
||||
{
|
||||
static const short stress_lengths_fr[8] = {190, 170, 190, 200, 0, 0, 235, 240};
|
||||
static const unsigned char stress_amps_fr[8] = {18,16, 20,20, 20,22, 22,21 };
|
||||
static const short stress_lengths_fr[8] = {190, 170, 190, 200, 0, 0, 190, 240};
|
||||
static const unsigned char stress_amps_fr[8] = {18,16, 20,20, 20,22, 18,18 };
|
||||
|
||||
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.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.
|
||||
tr->langopts.vowel_pause = 0;
|
||||
|
||||
tr->langopts.numbers = NUM_SINGLE_STRESS | NUM_DECIMAL_COMMA | NUM_ALLOW_SPACE | NUM_OMIT_1_HUNDRED | NUM_NOPAUSE | NUM_ROMAN | NUM_VIGESIMAL | NUM_DFRACTION_4;
|
||||
SetLetterVowel(tr,'y');
|
||||
@@ -678,6 +680,15 @@ Translator *SelectTranslator(const char *name)
|
||||
break;
|
||||
|
||||
|
||||
case L('h','t'): // Haitian Creole
|
||||
// static const short stress_lengths_fr[8] = {190, 170, 190, 200, 0, 0, 235, 240};
|
||||
// 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.numbers = NUM_SINGLE_STRESS | NUM_OMIT_1_HUNDRED | NUM_NOPAUSE | NUM_ROMAN | NUM_VIGESIMAL | NUM_DFRACTION_4;
|
||||
break;
|
||||
|
||||
|
||||
case L('h','u'): // Hungarian
|
||||
{
|
||||
static const unsigned char stress_amps_hu[8] = {17,17, 19,19, 20,22, 22,21 };
|
||||
|
||||
+24
-12
@@ -577,11 +577,17 @@ char *strchr_w(const char *s, int c)
|
||||
static char *SpeakIndividualLetters(Translator *tr, char *word, char *phonemes, int spell_word)
|
||||
{//============================================================================================
|
||||
int posn = 0;
|
||||
int capitals = 0;
|
||||
int non_initial = 0;
|
||||
|
||||
if (spell_word > 2)
|
||||
capitals = 2;
|
||||
|
||||
while((*word != ' ') && (*word != 0))
|
||||
{
|
||||
word += TranslateLetter(tr, word, phonemes, spell_word);
|
||||
word += TranslateLetter(tr, word, phonemes, capitals | non_initial);
|
||||
posn++;
|
||||
non_initial = 1;
|
||||
if(phonemes[0] == phonSWITCH)
|
||||
{
|
||||
// change to another language in order to translate this word
|
||||
@@ -666,10 +672,8 @@ int TranslateWord(Translator *tr, char *word1, int next_pause, WORD_TAB *wtab)
|
||||
{//===========================================================================
|
||||
// word1 is terminated by space (0x20) character
|
||||
|
||||
int length;
|
||||
int word_length;
|
||||
int ix;
|
||||
int posn;
|
||||
int pfix;
|
||||
int n_chars;
|
||||
unsigned int dictionary_flags[2];
|
||||
@@ -898,10 +902,14 @@ if((wmark > 0) && (wmark < 8))
|
||||
else
|
||||
if(found == 0)
|
||||
{
|
||||
int posn;
|
||||
int non_initial;
|
||||
int length;
|
||||
// word's pronunciation is not given in the dictionary list, although
|
||||
// dictionary_flags may have ben set there
|
||||
|
||||
posn = 0;
|
||||
non_initial = 0;
|
||||
length = 999;
|
||||
wordx = word1;
|
||||
|
||||
@@ -911,7 +919,11 @@ if((wmark > 0) && (wmark < 8))
|
||||
// This word looks "unpronouncable", so speak letters individually until we
|
||||
// find a remainder that we can pronounce.
|
||||
emphasize_allcaps = 0;
|
||||
wordx += TranslateLetter(tr, wordx, unpron_phonemes, 0);
|
||||
|
||||
if(posn > 0)
|
||||
non_initial = 1;
|
||||
|
||||
wordx += TranslateLetter(tr, wordx, unpron_phonemes, non_initial);
|
||||
posn++;
|
||||
if(unpron_phonemes[0] == phonSWITCH)
|
||||
{
|
||||
@@ -1234,13 +1246,13 @@ strcpy(phonemes2,phonemes);
|
||||
snprintf(word_phonemes, sizeof(word_phonemes), "%s%s%s", unpron_phonemes, prefix_phonemes, phonemes);
|
||||
#endif
|
||||
word_phonemes[N_WORD_PHONEMES-1] = 0;
|
||||
SetWordStress(tr, word_phonemes, dictionary_flags, -1, tr->prev_last_stress);
|
||||
SetWordStress(tr, word_phonemes, dictionary_flags, -1, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(prefix_phonemes[0] == 0)
|
||||
SetWordStress(tr, phonemes, dictionary_flags, -1, tr->prev_last_stress);
|
||||
SetWordStress(tr, phonemes, dictionary_flags, -1, 0);
|
||||
else
|
||||
SetWordStress(tr, phonemes, dictionary_flags, -1, 0);
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
@@ -2334,6 +2346,12 @@ void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *t
|
||||
}
|
||||
next_in_nbytes = utf8_in(&next_in,&source[source_index]);
|
||||
|
||||
if(c == 0)
|
||||
{
|
||||
finished = 1;
|
||||
c = ' ';
|
||||
}
|
||||
|
||||
if((c == CTRL_EMBEDDED) || (c == ctrl_embedded))
|
||||
{
|
||||
// start of embedded command in the text
|
||||
@@ -2486,12 +2504,6 @@ if((c == '/') && (tr->langopts.testing & 2) && IsDigit09(next_in) && IsAlpha(pre
|
||||
}
|
||||
}
|
||||
|
||||
if(c == 0)
|
||||
{
|
||||
finished = 1;
|
||||
c = ' ';
|
||||
}
|
||||
else
|
||||
if(IsAlpha(c))
|
||||
{
|
||||
if(!IsAlpha(prev_out) || (tr->langopts.ideographs && ((c > 0x3040) || (prev_out > 0x3040))))
|
||||
|
||||
+4
-4
@@ -469,8 +469,8 @@ typedef struct {
|
||||
#define NUM_SEP_SPACE 0x1000 // allow space as thousands separator (in addition to langopts.thousands_sep)
|
||||
#define NUM_DEC_IT 0x2000 // (LANG=it) speak post-decimal-point digits as a combined number not as single digits
|
||||
|
||||
struct Translator
|
||||
{//=============
|
||||
typedef struct
|
||||
{//===========
|
||||
|
||||
LANGUAGE_OPTIONS langopts;
|
||||
int translator_name;
|
||||
@@ -535,7 +535,7 @@ struct Translator
|
||||
int end_stressed_vowel; // word ends with stressed vowel
|
||||
int prev_dict_flags; // dictionary flags from previous word
|
||||
int clause_terminator;
|
||||
}; // end of class Translator
|
||||
} Translator;
|
||||
|
||||
|
||||
extern int option_tone2;
|
||||
@@ -624,7 +624,7 @@ int TranslateRoman(Translator *tr, char *word, char *ph_out, WORD_TAB *wtab);
|
||||
void ChangeWordStress(Translator *tr, char *word, int new_stress);
|
||||
void SetSpellingStress(Translator *tr, char *phonemes, int control, int n_chars);
|
||||
int TranslateLetter(Translator *tr, char *letter, char *phonemes, int control);
|
||||
void LookupLetter(Translator *tr, unsigned int letter, int next_byte, char *ph_buf);
|
||||
void LookupLetter(Translator *tr, unsigned int letter, int next_byte, char *ph_buf, int control);
|
||||
void LookupAccentedLetter(Translator *tr, unsigned int letter, char *ph_buf);
|
||||
|
||||
int LoadDictionary(Translator *tr, const char *name, int no_error);
|
||||
|
||||
+56
-40
@@ -48,6 +48,7 @@
|
||||
#define T_TRANSLATE 503
|
||||
#define T_PROCESS 504
|
||||
#define T_RULES 505
|
||||
#define T_TRANSLATE_IPA 506
|
||||
|
||||
TranslDlg *transldlg = NULL;
|
||||
extern char *speech_to_phonemes(char *data, char *phout);
|
||||
@@ -58,12 +59,19 @@ BEGIN_EVENT_TABLE(TranslDlg, wxPanel)
|
||||
EVT_BUTTON(T_TRANSLATE,TranslDlg::OnCommand)
|
||||
EVT_BUTTON(T_PROCESS,TranslDlg::OnCommand)
|
||||
EVT_BUTTON(T_RULES,TranslDlg::OnCommand)
|
||||
EVT_BUTTON(T_TRANSLATE_IPA,TranslDlg::OnCommand)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
|
||||
FILE *f_wave = NULL;
|
||||
wxFont font_phonetic;
|
||||
wxTextAttr style_phonetic;
|
||||
wxFont font_phonetic_large;
|
||||
wxTextAttr style_phonetic_large;
|
||||
|
||||
|
||||
#ifdef deleted
|
||||
|
||||
class IPATextCtrl : public wxTextCtrl
|
||||
{
|
||||
public:
|
||||
@@ -78,27 +86,6 @@ BEGIN_EVENT_TABLE(IPATextCtrl, wxTextCtrl)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
|
||||
// using Kirschenbaum scheme to enter IPA from the keyboard
|
||||
wchar_t ipa1[256] = {
|
||||
0,0x250,32,32,32,32,32,32,32,32,0xa,0xb,0xc,0x26f,0x272,0x275,
|
||||
32,32,0x25a,32,32,32,32,0x28d,32,32,32,32,32,32,32,32,
|
||||
0x20,0x21,0x22,0x23,0x24,0x25,0x0e6,0x27,0x28,0x27e,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
|
||||
0x252,0x31,0x32,0x25c,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x294,
|
||||
0x259,0x251,0x3b2,0xe7,0xf0,0x25b,0x46,0x262,0x127,0x26a,0x25f,0x4b,0x26c,0x271,0x14b,0x254,
|
||||
0x3a6,0x263,0x280,0x283,0x3b8,0x28a,0x28c,0x153,0x3c7,0xf8,0x292,0x32a,0x5c,0x5d,0x5e,0x5f,
|
||||
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
|
||||
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x303,0x7f,
|
||||
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
|
||||
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,
|
||||
0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,
|
||||
0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,
|
||||
0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,
|
||||
0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf,
|
||||
0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,
|
||||
0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
|
||||
};
|
||||
|
||||
|
||||
IPATextCtrl::IPATextCtrl(wxWindow *parent,wxWindowID id,const wxPoint& pos,const wxSize& size) :
|
||||
wxTextCtrl(parent,id,_T(""),pos,size,wxTE_MULTILINE)
|
||||
{
|
||||
@@ -132,7 +119,7 @@ void IPATextCtrl::OnKey(wxKeyEvent& event)
|
||||
else
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -280,8 +267,10 @@ TranslDlg::TranslDlg(wxWindow *parent) : wxPanel(parent)
|
||||
int height;
|
||||
int width;
|
||||
int x,y;
|
||||
int font_size;
|
||||
int height_ph = 350;
|
||||
|
||||
|
||||
wxTextAttr attr;
|
||||
wxFont font = wxFont(12,wxFONTFAMILY_ROMAN,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_LIGHT,false,_T(""),wxFONTENCODING_SYSTEM);
|
||||
|
||||
@@ -305,9 +294,18 @@ TranslDlg::TranslDlg(wxWindow *parent) : wxPanel(parent)
|
||||
t_phonetic = new wxTextCtrl(this,T_PHONETIC,_T(""),wxPoint(0,262),
|
||||
wxSize(298,height_ph),wxTE_MULTILINE | wxTE_READONLY,wxDefaultValidator,_T("Phoneme translation window"));
|
||||
|
||||
style_phonetic = t_phonetic->GetDefaultStyle();
|
||||
font_phonetic = style_phonetic.GetFont();
|
||||
font_size = font_phonetic.GetPointSize();
|
||||
font_phonetic_large = font_phonetic;
|
||||
style_phonetic_large = style_phonetic;
|
||||
font_phonetic_large.SetPointSize(font_size+1);
|
||||
style_phonetic_large.SetFont(font_phonetic_large);
|
||||
|
||||
y = height_ph + 270;
|
||||
t_translate = new wxButton(this,T_TRANSLATE,_T("Translate"),wxPoint(4,y));
|
||||
t_translate = new wxButton(this,T_RULES,_T("Show Rules"),wxPoint(4,y+32));
|
||||
t_translate = new wxButton(this,T_TRANSLATE_IPA,_T("Show IPA"),wxPoint(100,y+32));
|
||||
t_process = new wxButton(this,T_PROCESS,_T("Speak"),wxPoint(100,y));
|
||||
|
||||
t_source->SetFocus();
|
||||
@@ -399,6 +397,7 @@ void TranslDlg::OnCommand(wxCommandEvent& event)
|
||||
#define N_PH_LIST N_PHONEME_LIST
|
||||
|
||||
void *vp;
|
||||
int translate_text = 0;
|
||||
char buf[1000];
|
||||
char phon_out[N_PH_LIST*2];
|
||||
int clause_tone;
|
||||
@@ -415,8 +414,6 @@ void TranslDlg::OnCommand(wxCommandEvent& event)
|
||||
{
|
||||
case T_RULES:
|
||||
case MENU_SPEAK_RULES:
|
||||
option_phonemes = 2;
|
||||
|
||||
#ifdef PLATFORM_POSIX
|
||||
strcpy(fname_temp,"/tmp/espeakXXXXXX");
|
||||
if((fd_temp = mkstemp(fname_temp)) >= 0)
|
||||
@@ -435,8 +432,41 @@ void TranslDlg::OnCommand(wxCommandEvent& event)
|
||||
f_trans = f; // write translation rule trace to a temp file
|
||||
}
|
||||
#endif
|
||||
t_phonetic->SetDefaultStyle(style_phonetic);
|
||||
translate_text = 2;
|
||||
break;
|
||||
|
||||
case T_TRANSLATE:
|
||||
case MENU_SPEAK_TRANSLATE:
|
||||
t_phonetic->SetDefaultStyle(style_phonetic);
|
||||
translate_text = 1;
|
||||
break;
|
||||
|
||||
case T_TRANSLATE_IPA:
|
||||
case MENU_SPEAK_IPA:
|
||||
t_phonetic->SetDefaultStyle(style_phonetic_large);
|
||||
|
||||
translate_text = 3;
|
||||
break;
|
||||
|
||||
case T_PROCESS:
|
||||
case MENU_SPEAK_TEXT:
|
||||
if(prosodycanvas == NULL)
|
||||
{
|
||||
myframe->OnProsody(event);
|
||||
}
|
||||
prosodycanvas->LayoutData(ph_list,n_ph_list);
|
||||
option_phoneme_events = 1;
|
||||
option_log_frames = 1;
|
||||
MakeWave2(ph_list,n_ph_list);
|
||||
option_log_frames = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if(translate_text)
|
||||
{
|
||||
option_phonemes = translate_text;
|
||||
|
||||
option_multibyte = espeakCHARS_AUTO;
|
||||
SpeakNextClause(NULL,NULL,2); // stop speaking file
|
||||
|
||||
@@ -457,7 +487,7 @@ void TranslDlg::OnCommand(wxCommandEvent& event)
|
||||
if(clause_count++ > 0)
|
||||
strcat(phon_out," ||");
|
||||
strcat(phon_out,translator->phon_out);
|
||||
t_phonetic->SetValue(wxString(translator->phon_out,wxConvLocal));
|
||||
t_phonetic->SetValue(wxString(translator->phon_out,wxConvUTF8));
|
||||
|
||||
if((n_ph_list + n_phoneme_list) >= N_PH_LIST)
|
||||
{
|
||||
@@ -482,20 +512,6 @@ void TranslDlg::OnCommand(wxCommandEvent& event)
|
||||
fclose(f_trans);
|
||||
remove(fname_temp);
|
||||
}
|
||||
t_phonetic->AppendText(wxString(phon_out,wxConvLocal));
|
||||
break;
|
||||
|
||||
case T_PROCESS:
|
||||
case MENU_SPEAK_TEXT:
|
||||
if(prosodycanvas == NULL)
|
||||
{
|
||||
myframe->OnProsody(event);
|
||||
}
|
||||
prosodycanvas->LayoutData(ph_list,n_ph_list);
|
||||
option_phoneme_events = 1;
|
||||
option_log_frames = 1;
|
||||
MakeWave2(ph_list,n_ph_list);
|
||||
option_log_frames = 0;
|
||||
break;
|
||||
t_phonetic->AppendText(wxString(phon_out,wxConvUTF8));
|
||||
}
|
||||
} // end of TranslDlg::OnCommand
|
||||
|
||||
Reference in New Issue
Block a user