Fix an error where vowels start too loud (too strong attack). Added command-line option --compile-debug, which is like --compile but it includes source line information from the *_rules file, which is displayed with the -X option. espeakedit: Added Compile->Compile_dictionary(debug), Fixed <emphasis> which was broken in the previous version(s). <emphasis> now reduces the previous stressed syllable to secondary stress. git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@119 d46cf337-b52f-0410-862d-fd96e6ae7743master
rea (C% r,i:@ | rea (C% r,i:@ | ||||
_) rea (dC r,i:@ | _) rea (dC r,i:@ | ||||
rea (gen rI2eI | rea (gen rI2eI | ||||
_) re (au@P2 ,ri: | |||||
re (ck rE | re (ck rE | ||||
reckon rEk@n | reckon rEk@n | ||||
reco (g rEk@ | reco (g rEk@ |
<head> | <head> | ||||
<title>eSpeak Speech Synthesizer</title> | <title>eSpeak Speech Synthesizer</title> | ||||
<meta name="GENERATOR" content="Quanta Plus"> | |||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||||
</head> | </head> | ||||
<body> | <body> | ||||
<strong>--stdout</strong><br> | <strong>--stdout</strong><br> | ||||
<dd>Writes the speech output to stdout as it is produced, rather than speaking it. The data starts with a WAV file header which indicates the sample rate and format of the data. The length field is set to zero because the length of the data is unknown when the header is produced. | <dd>Writes the speech output to stdout as it is produced, rather than speaking it. The data starts with a WAV file header which indicates the sample rate and format of the data. The length field is set to zero because the length of the data is unknown when the header is produced. | ||||
<p> | <p> | ||||
<dt><strong>--compile[=<voice name>]</strong><br> | |||||
<dt><strong>--compile [=<voice name>]</strong><br> | |||||
<dd> | <dd> | ||||
Compile the pronunciation rule and dictionary lookup data from their source files in the current directory. The Voice determines which language's files are compiled. For example, if it's an English voice, then <em>en_rules</em>, <em>en_list</em>, and <em>en_extra</em> (if present), are compiled to replace <em>en_dict</em> in the <em>speak-data</em> directory. If no Voice is specified then the default Voice is used. | Compile the pronunciation rule and dictionary lookup data from their source files in the current directory. The Voice determines which language's files are compiled. For example, if it's an English voice, then <em>en_rules</em>, <em>en_list</em>, and <em>en_extra</em> (if present), are compiled to replace <em>en_dict</em> in the <em>speak-data</em> directory. If no Voice is specified then the default Voice is used. | ||||
<p> | <p> | ||||
<dt><strong>--punct[="<characters>"]</strong><br> | |||||
<dt><strong>--compile-debug [=<voice name>]</strong><br> | |||||
<dd> | |||||
The same as <strong>--compile</strong>, but source line numbers from the *_rules file are included. These are included in the rules trace when the <strong>-X</strong> option is used. | |||||
<p> | |||||
<dt><strong>--punct [="<characters>"]</strong><br> | |||||
<dd> | <dd> | ||||
Speaks the names of punctuation characters when they are encountered in the text. If <characters> are given, then only those listed punctuation characters are spoken, eg. <code> --punct=".,;?"</code> | Speaks the names of punctuation characters when they are encountered in the text. If <characters> are given, then only those listed punctuation characters are spoken, eg. <code> --punct=".,;?"</code> | ||||
<p> | <p> | ||||
<dt> | <dt> | ||||
<strong>--voices[=<language code>]</strong><br> | |||||
<strong>--voices [=<language code>]</strong><br> | |||||
<dd>Lists the available voices.<br> | <dd>Lists the available voices.<br> | ||||
If =<language code> is present then only those voices which are suitable for that language are listed.<br> | If =<language code> is present then only those voices which are suitable for that language are listed.<br> | ||||
<code>--voices=variant</code> lists the voice variants (voice modifiers). | <code>--voices=variant</code> lists the voice variants (voice modifiers). |
sprintf(fname,"%s/",path_install); | sprintf(fname,"%s/",path_install); | ||||
espeak_SetVoiceByName(voice); | espeak_SetVoiceByName(voice); | ||||
espeak_CompileDictionary(fname,f_log3); | |||||
espeak_CompileDictionary(fname,f_log3,0); | |||||
fclose(f_log3); | fclose(f_log3); | ||||
return(0); | return(0); |
extern void MakeVowelLists(void); | extern void MakeVowelLists(void); | ||||
extern void FindPhonemesUsed(void); | extern void FindPhonemesUsed(void); | ||||
extern void DrawEnvelopes(); | extern void DrawEnvelopes(); | ||||
extern int CompileDictionary(const char *dsource, const char *dict_name, FILE *log, char *fname); | |||||
extern int CompileDictionary(const char *dsource, const char *dict_name, FILE *log, char *fname, int flags); | |||||
static int markers_used[8]; | static int markers_used[8]; | ||||
fprintf(f_report," [%s] %s",WordToString(prev_mnemonic = list[ix]->ph_mnemonic), phoneme_tab_list2[prev_table = list[ix]->ph_table].name); | fprintf(f_report," [%s] %s",WordToString(prev_mnemonic = list[ix]->ph_mnemonic), phoneme_tab_list2[prev_table = list[ix]->ph_table].name); | ||||
fputc('\n',f_report); | fputc('\n',f_report); | ||||
} | |||||
for(ix=0; ix<n; ix++) | |||||
{ | |||||
free(list[ix]); | free(list[ix]); | ||||
list[ix] = NULL; | |||||
} | } | ||||
free(list); | free(list); | ||||
list = NULL; | |||||
fclose(f_report); | fclose(f_report); | ||||
} | } | ||||
LoadVoice(voicename,0); | LoadVoice(voicename,0); | ||||
if((err = CompileDictionary(path_dsource, dictname,log,NULL)) > 0) | |||||
if((err = CompileDictionary(path_dsource, dictname,log,NULL,0)) > 0) | |||||
{ | { | ||||
report = report + dictstr + wxString::Format(_T(" %d, "),err); | report = report + dictstr + wxString::Format(_T(" %d, "),err); | ||||
errors += err; | errors += err; |
static int transpose_min; | static int transpose_min; | ||||
static int transpose_max; | static int transpose_max; | ||||
static int text_mode = 0; | static int text_mode = 0; | ||||
static int debug_flag = 0; | |||||
int hash_counts[N_HASH_DICT]; | int hash_counts[N_HASH_DICT]; | ||||
char *hash_chains[N_HASH_DICT]; | char *hash_chains[N_HASH_DICT]; | ||||
} | } | ||||
strcpy(&output[len],rule_match); | strcpy(&output[len],rule_match); | ||||
len += strlen(rule_match); | len += strlen(rule_match); | ||||
if(debug_flag) | |||||
{ | |||||
output[len] = RULE_LINENUM; | |||||
output[len+1] = (linenum % 255) + 1; | |||||
output[len+2] = (linenum / 255) + 1; | |||||
len+=3; | |||||
} | |||||
if(rule_cond[0] != 0) | if(rule_cond[0] != 0) | ||||
{ | { | ||||
ix = -1; | ix = -1; | ||||
int CompileDictionary(const char *dsource, const char *dict_name, FILE *log, char *fname_err) | |||||
{//========================================================================================== | |||||
int CompileDictionary(const char *dsource, const char *dict_name, FILE *log, char *fname_err, int flags) | |||||
{//===================================================================================================== | |||||
// fname: space to write the filename in case of error | // fname: space to write the filename in case of error | ||||
// flags: bit 0: include source line number information, for debug purposes. | |||||
FILE *f_in; | FILE *f_in; | ||||
FILE *f_out; | FILE *f_out; | ||||
char path[sizeof(path_home)+40]; // path_dsource+20 | char path[sizeof(path_home)+40]; // path_dsource+20 | ||||
error_count = 0; | error_count = 0; | ||||
debug_flag = flags & 1; | |||||
if(dsource == NULL) | if(dsource == NULL) | ||||
dsource = ""; | dsource = ""; |
int match_type; | int match_type; | ||||
int finished=0; | int finished=0; | ||||
int value; | int value; | ||||
int linenum=0; | |||||
int flags; | int flags; | ||||
int suffix_char; | int suffix_char; | ||||
int condition_num=0; | int condition_num=0; | ||||
{ | { | ||||
rb = *rule++; | rb = *rule++; | ||||
if(rb <= 5) | |||||
if(rb <= RULE_LINENUM) | |||||
{ | { | ||||
switch(rb) | switch(rb) | ||||
{ | { | ||||
/* conditional rule, next byte gives condition number */ | /* conditional rule, next byte gives condition number */ | ||||
condition_num = *rule++; | condition_num = *rule++; | ||||
break; | break; | ||||
case RULE_LINENUM: | |||||
value = (rule[1] & 0xff) - 1; | |||||
linenum = (rule[0] & 0xff) - 1 + (value * 255); | |||||
rule+=2; | |||||
break; | |||||
} | } | ||||
continue; | continue; | ||||
} | } | ||||
*p = 0; | *p = 0; | ||||
p = output; | p = output; | ||||
if(linenum > 0) | |||||
{ | |||||
sprintf(p,"%5d:\t",linenum); | |||||
p += 7; | |||||
} | |||||
if(condition_num > 0) | if(condition_num > 0) | ||||
{ | { | ||||
sprintf(output,"?%d ",condition_num); | |||||
p = &output[strlen(output)]; | |||||
sprintf(p,"?%d ",condition_num); | |||||
p = &p[strlen(p)]; | |||||
} | } | ||||
if((ix = strlen(buf_pre)) > 0) | if((ix = strlen(buf_pre)) > 0) | ||||
{ | { | ||||
{ | { | ||||
rb = *rule++; | rb = *rule++; | ||||
if(rb <= 5) | |||||
if(rb <= RULE_LINENUM) | |||||
{ | { | ||||
switch(rb) | switch(rb) | ||||
{ | { | ||||
if(!failed) | if(!failed) | ||||
match.points++; // add one point for a matched conditional rule | match.points++; // add one point for a matched conditional rule | ||||
break; | break; | ||||
case RULE_LINENUM: | |||||
rule+=2; | |||||
break; | |||||
} | } | ||||
continue; | continue; | ||||
} | } | ||||
if(group_length > 1) | if(group_length > 1) | ||||
pts += 35; // to account for an extra letter matching | pts += 35; // to account for an extra letter matching | ||||
DecodePhonemes(match.phonemes,decoded_phonemes); | DecodePhonemes(match.phonemes,decoded_phonemes); | ||||
fprintf(f_trans,"%3d %s [%s]\n",pts,DecodeRule(group,rule_start),decoded_phonemes); | |||||
fprintf(f_trans,"%3d\t%s [%s]\n",pts,DecodeRule(group,rule_start),decoded_phonemes); | |||||
} | } | ||||
#endif | #endif | ||||
We distinguish them by their indices. */ | We distinguish them by their indices. */ | ||||
{"help", no_argument, 0, 'h'}, | {"help", no_argument, 0, 'h'}, | ||||
{"stdin", no_argument, 0, 0x100}, | {"stdin", no_argument, 0, 0x100}, | ||||
{"stdout", no_argument, 0, 0x101}, | |||||
{"compile-debug", optional_argument, 0, 0x101}, | |||||
{"compile", optional_argument, 0, 0x102}, | {"compile", optional_argument, 0, 0x102}, | ||||
{"punct", optional_argument, 0, 0x103}, | {"punct", optional_argument, 0, 0x103}, | ||||
{"voices", optional_argument, 0, 0x104}, | {"voices", optional_argument, 0, 0x104}, | ||||
{"stdout", no_argument, 0, 0x105}, | |||||
{0, 0, 0, 0} | {0, 0, 0, 0} | ||||
}; | }; | ||||
flag_stdin = 1; | flag_stdin = 1; | ||||
break; | break; | ||||
case 0x101: // --stdout | |||||
case 0x105: // --stdout | |||||
option_waveout = 1; | option_waveout = 1; | ||||
strcpy(wavefile,"stdout"); | strcpy(wavefile,"stdout"); | ||||
break; | break; | ||||
case 0x101: // --compile-debug | |||||
case 0x102: // --compile | case 0x102: // --compile | ||||
strncpy0(voicename,optarg,sizeof(voicename)); | strncpy0(voicename,optarg,sizeof(voicename)); | ||||
flag_compile = 1; | |||||
flag_compile = c; | |||||
quiet = 1; | quiet = 1; | ||||
break; | break; | ||||
if(flag_compile) | if(flag_compile) | ||||
{ | { | ||||
// This must be done after the voice is set | // This must be done after the voice is set | ||||
espeak_CompileDictionary("",stderr); | |||||
espeak_CompileDictionary("", stderr, flag_compile & 0x1); | |||||
exit(0); | exit(0); | ||||
} | } | ||||
EVT_MENU(MENU_PATH4, MyFrame::OnOptions) | EVT_MENU(MENU_PATH4, MyFrame::OnOptions) | ||||
EVT_MENU(MENU_COMPILE_PH, MyFrame::OnTools) | EVT_MENU(MENU_COMPILE_PH, MyFrame::OnTools) | ||||
EVT_MENU(MENU_COMPILE_DICT, MyFrame::OnTools) | EVT_MENU(MENU_COMPILE_DICT, MyFrame::OnTools) | ||||
EVT_MENU(MENU_COMPILE_DICT_DEBUG, MyFrame::OnTools) | |||||
EVT_MENU(MENU_COMPILE_MBROLA, MyFrame::OnTools) | EVT_MENU(MENU_COMPILE_MBROLA, MyFrame::OnTools) | ||||
EVT_MENU(MENU_CLOSE_ALL, MyFrame::OnQuit) | EVT_MENU(MENU_CLOSE_ALL, MyFrame::OnQuit) | ||||
EVT_MENU(MENU_QUIT, MyFrame::OnQuit) | EVT_MENU(MENU_QUIT, MyFrame::OnQuit) | ||||
{//========================================= | {//========================================= | ||||
int err; | int err; | ||||
FILE *log; | FILE *log; | ||||
int debug_flag=0; | |||||
char fname_log[sizeof(path_dsource)+12]; | char fname_log[sizeof(path_dsource)+12]; | ||||
char err_fname[sizeof(path_home)+15]; | char err_fname[sizeof(path_home)+15]; | ||||
CompileMbrola(); | CompileMbrola(); | ||||
break; | break; | ||||
case MENU_COMPILE_DICT_DEBUG: | |||||
debug_flag =1; // and drop through to next case | |||||
case MENU_COMPILE_DICT: | case MENU_COMPILE_DICT: | ||||
sprintf(fname_log,"%s%s",path_dsource,"dict_log"); | sprintf(fname_log,"%s%s",path_dsource,"dict_log"); | ||||
log = fopen(fname_log,"w"); | log = fopen(fname_log,"w"); | ||||
if((err = CompileDictionary(path_dsource,dictionary_name,log,err_fname)) < 0) | |||||
if((err = CompileDictionary(path_dsource,dictionary_name,log,err_fname,debug_flag)) < 0) | |||||
{ | { | ||||
wxLogError(_T("Can't access file:\n")+wxString(err_fname,wxConvLocal)); | wxLogError(_T("Can't access file:\n")+wxString(err_fname,wxConvLocal)); | ||||
option = langopts.intonation_group; | option = langopts.intonation_group; | ||||
if(option > INTONATION_TYPES) | |||||
if(option >= INTONATION_TYPES) | |||||
option = 0; | option = 0; | ||||
group_tone = punct_to_tone[option][clause_type]; | group_tone = punct_to_tone[option][clause_type]; | ||||
if(syl->stress == 6) | if(syl->stress == 6) | ||||
{ | { | ||||
// reduce the stress of the previous stressed syllable | |||||
for(ix=st_ix-1; ix>=st_start && ix>=(st_ix-3); ix--) | |||||
{ | |||||
if(syllable_tab[ix].stress == 6) | |||||
break; | |||||
if(syllable_tab[ix].stress == 4) | |||||
{ | |||||
syllable_tab[ix].stress = 3; | |||||
break; | |||||
} | |||||
} | |||||
// are the next primary syllables also emphasized ? | // are the next primary syllables also emphasized ? | ||||
for(ix=st_ix+1; ix<n_st; ix++) | for(ix=st_ix+1; ix<n_st; ix++) | ||||
{ | { |
MENU_PROSODY, | MENU_PROSODY, | ||||
MENU_COMPILE_PH, | MENU_COMPILE_PH, | ||||
MENU_COMPILE_DICT, | MENU_COMPILE_DICT, | ||||
MENU_COMPILE_DICT_DEBUG, | |||||
MENU_COMPILE_MBROLA, | MENU_COMPILE_MBROLA, | ||||
MENU_SPEAK_TRANSLATE, | MENU_SPEAK_TRANSLATE, |
data_menu = new wxMenu; | data_menu = new wxMenu; | ||||
data_menu->Append(MENU_COMPILE_PH, _("Compile &phoneme data")); | data_menu->Append(MENU_COMPILE_PH, _("Compile &phoneme data")); | ||||
data_menu->Append(MENU_COMPILE_DICT, _("Compile &dictionary")); | data_menu->Append(MENU_COMPILE_DICT, _("Compile &dictionary")); | ||||
data_menu->Append(MENU_COMPILE_DICT_DEBUG, _("Compile dictionary (&debug)")); | |||||
data_menu->Append(MENU_COMPILE_MBROLA, _("Compile &mbrola phonemes list")); | data_menu->Append(MENU_COMPILE_MBROLA, _("Compile &mbrola phonemes list")); | ||||
// OPTIONS MENU | // OPTIONS MENU |
{//===================================== | {//===================================== | ||||
// A phoneme has been selected | // A phoneme has been selected | ||||
PHONEME_LIST *p; | PHONEME_LIST *p; | ||||
const char *emphasized; | |||||
char buf[120]; | char buf[120]; | ||||
if(index < 0) return; | if(index < 0) return; | ||||
p = &phlist[index]; | p = &phlist[index]; | ||||
if((p == NULL) || (p->ph == NULL)) return; | if((p == NULL) || (p->ph == NULL)) return; | ||||
sprintf(buf,"Stress %d Amp %2d LenMod %2d Pitch %3d %3d [env=%d] Flags %.2x ", | |||||
p->tone,p->amp,p->length,p->pitch1,p->pitch2,p->env,p->ph->phflags); | |||||
emphasized = ""; | |||||
if(p->tone & 8) | |||||
emphasized = "*"; | |||||
sprintf(buf,"Stress %s%d Amp %2d LenMod %2d Pitch %3d %3d [env=%d] Flags %.2x ", | |||||
emphasized,p->tone&0x7,p->amp,p->length,p->pitch1,p->pitch2,p->env,p->ph->phflags); | |||||
wxLogStatus(wxString(buf,wxConvLocal)); | wxLogStatus(wxString(buf,wxConvLocal)); | ||||
} | } | ||||
int value; | int value; | ||||
char buf[20]; | char buf[20]; | ||||
int new_parameters[N_SPEECH_PARAM]; | int new_parameters[N_SPEECH_PARAM]; | ||||
static char cmd_letter[N_SPEECH_PARAM] = {0, 'S','A','P','R', 0, 0, 'F'}; // embedded command letters | |||||
static char cmd_letter[N_SPEECH_PARAM] = {0, 'S','A','P','R', 0, 0, 0, 0, 0, 0, 0, 'F'}; // embedded command letters | |||||
for(param=0; param<N_SPEECH_PARAM; param++) | for(param=0; param<N_SPEECH_PARAM; param++) |
We distinguish them by their indices. */ | We distinguish them by their indices. */ | ||||
{"help", no_argument, 0, 'h'}, | {"help", no_argument, 0, 'h'}, | ||||
{"stdin", no_argument, 0, 0x100}, | {"stdin", no_argument, 0, 0x100}, | ||||
{"stdout", no_argument, 0, 0x101}, | |||||
{"compile-debug", optional_argument, 0, 0x101}, | |||||
{"compile", optional_argument, 0, 0x102}, | {"compile", optional_argument, 0, 0x102}, | ||||
{"punct", optional_argument, 0, 0x103}, | {"punct", optional_argument, 0, 0x103}, | ||||
{"voices", optional_argument, 0, 0x104}, | {"voices", optional_argument, 0, 0x104}, | ||||
{"stdout", no_argument, 0, 0x105}, | |||||
{0, 0, 0, 0} | {0, 0, 0, 0} | ||||
}; | }; | ||||
flag_stdin = 1; | flag_stdin = 1; | ||||
break; | break; | ||||
case 0x101: // --stdout | |||||
case 0x105: // --stdout | |||||
option_waveout = 1; | option_waveout = 1; | ||||
strcpy(wavefile,"stdout"); | strcpy(wavefile,"stdout"); | ||||
break; | break; | ||||
case 0x101: // --compile-debug | |||||
case 0x102: // --compile | case 0x102: // --compile | ||||
if(optarg2 != NULL) | if(optarg2 != NULL) | ||||
strncpy0(voicename,optarg2,sizeof(voicename)); | strncpy0(voicename,optarg2,sizeof(voicename)); | ||||
flag_compile = 1; | |||||
flag_compile = c; | |||||
break; | break; | ||||
case 0x103: // --punct | case 0x103: // --punct | ||||
strcpy(path_dsource,path_home); | strcpy(path_dsource,path_home); | ||||
path_dsource[strlen(path_home)-11] = 0; // remove "espeak-data" from the end | path_dsource[strlen(path_home)-11] = 0; // remove "espeak-data" from the end | ||||
strcat(path_dsource,"dictsource\\"); | strcat(path_dsource,"dictsource\\"); | ||||
CompileDictionary(path_dsource,dictionary_name,NULL,NULL); | |||||
CompileDictionary(path_dsource,dictionary_name,NULL,NULL, flag_compile & 0x1); | |||||
#else | #else | ||||
#ifdef PLATFORM_WINDOWS | #ifdef PLATFORM_WINDOWS | ||||
char path_dsource[sizeof(path_home)+20]; | char path_dsource[sizeof(path_home)+20]; | ||||
strcpy(path_dsource,path_home); | strcpy(path_dsource,path_home); | ||||
path_dsource[strlen(path_home)-11] = 0; // remove "espeak-data" from the end | path_dsource[strlen(path_home)-11] = 0; // remove "espeak-data" from the end | ||||
strcat(path_dsource,"dictsource\\"); | strcat(path_dsource,"dictsource\\"); | ||||
CompileDictionary(path_dsource,dictionary_name,NULL,NULL); | |||||
CompileDictionary(path_dsource,dictionary_name,NULL,NULL, flag_compile & 0x1); | |||||
#else | #else | ||||
CompileDictionary(NULL,dictionary_name,NULL,NULL); | |||||
CompileDictionary(NULL,dictionary_name,NULL,NULL, flag_compile & 0x1); | |||||
#endif | #endif | ||||
#endif | #endif | ||||
exit(0); | exit(0); |
} // end of espeak_SetPhonemes | } // end of espeak_SetPhonemes | ||||
ESPEAK_API void espeak_CompileDictionary(const char *path, FILE *log) | |||||
{//================================================================== | |||||
ESPEAK_API void espeak_CompileDictionary(const char *path, FILE *log, int flags) | |||||
{//============================================================================= | |||||
ENTER("espeak_CompileDictionary"); | ENTER("espeak_CompileDictionary"); | ||||
CompileDictionary(path,dictionary_name,log,NULL); | |||||
CompileDictionary(path, dictionary_name, log, NULL, flags); | |||||
} // end of espeak_CompileDirectory | } // end of espeak_CompileDirectory | ||||
Revision 3 | Revision 3 | ||||
Added espeakWORDGAP to espeak_PARAMETER | Added espeakWORDGAP to espeak_PARAMETER | ||||
Revision 4 | |||||
Added flags parameter to espeak_CompileDictionary() | |||||
*/ | */ | ||||
/********************/ | /********************/ | ||||
/* Initialization */ | /* Initialization */ | ||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
extern "C" | extern "C" | ||||
#endif | #endif | ||||
void espeak_CompileDictionary(const char *path, FILE *log); | |||||
void espeak_CompileDictionary(const char *path, FILE *log, int flags); | |||||
/* Compile pronunciation dictionary for a language which corresponds to the currently | /* Compile pronunciation dictionary for a language which corresponds to the currently | ||||
selected voice. The required voice should be selected before calling this function. | selected voice. The required voice should be selected before calling this function. | ||||
path: The directory which contains the language's '_rules' and '_list' files. | path: The directory which contains the language's '_rules' and '_list' files. | ||||
'path' should end with a path separator character ('/'). | 'path' should end with a path separator character ('/'). | ||||
log: Stream for error reports and statistics information. If log=NULL then stderr will be used. | log: Stream for error reports and statistics information. If log=NULL then stderr will be used. | ||||
flags: Bit 0: include source line information for debug purposes (This is displayed with the | |||||
-X command line option). | |||||
*/ | */ | ||||
/***********************/ | /***********************/ | ||||
/* Voice Selection */ | /* Voice Selection */ |
strncpy0(command,param_string(&p),sizeof(command)); | strncpy0(command,param_string(&p),sizeof(command)); | ||||
if(memcmp(command,"compile=",8)==0) | if(memcmp(command,"compile=",8)==0) | ||||
{ | { | ||||
CompileDictionary(NULL,&command[8],NULL,NULL); | |||||
CompileDictionary(NULL,&command[8],NULL,NULL,0); | |||||
return; | return; | ||||
} | } | ||||
else | else |
{ | { | ||||
total += ((htab[h] * htab[h]) >> 10); | total += ((htab[h] * htab[h]) >> 10); | ||||
} | } | ||||
rms = sqrt(total) / 14.5; | |||||
rms = sqrt(total) / 7.25; | |||||
// DrawPeaks(NULL,0,0,amp); | // DrawPeaks(NULL,0,0,amp); | ||||
return(rms); | return(rms); | ||||
} | } |
#include "translate.h" | #include "translate.h" | ||||
#include "wave.h" | #include "wave.h" | ||||
const char *version_string = "1.30.04 07.Jan.08"; | |||||
const int version_phdata = 0x013000; | |||||
const char *version_string = "1.30.05 07.Jan.08"; | |||||
const int version_phdata = 0x013005; | |||||
int option_device_number = -1; | int option_device_number = -1; | ||||
} | } | ||||
} | } | ||||
if((wflags & FLAG_ALL_UPPER) && (word_length > 1) && (clause_lower_count > 3) && iswalpha(first_char)) | |||||
if((wflags & FLAG_ALL_UPPER) && (word_length > 1)&& iswalpha(first_char)) | |||||
{ | { | ||||
if((option_tone_flags & OPTION_EMPHASIZE_ALLCAPS) && !(dictionary_flags[0] & FLAG_ABBREV)) | if((option_tone_flags & OPTION_EMPHASIZE_ALLCAPS) && !(dictionary_flags[0] & FLAG_ABBREV)) | ||||
{ | { | ||||
emphasize_allcaps = FLAG_EMPHASIZED; | emphasize_allcaps = FLAG_EMPHASIZED; | ||||
} | } | ||||
else | else | ||||
if(!found && !(dictionary_flags[0] & FLAG_SKIPWORDS) && (word_length<4) && (clause_upper_count <= clause_lower_count)) | |||||
if(!found && !(dictionary_flags[0] & FLAG_SKIPWORDS) && (word_length<4) && (clause_lower_count > 3) && (clause_upper_count <= clause_lower_count)) | |||||
{ | { | ||||
// An upper case word in a lower case clause. This could be an abbreviation. | // An upper case word in a lower case clause. This could be an abbreviation. | ||||
spell_word = 1; | spell_word = 1; | ||||
strcat(word_phonemes,end_phonemes); | strcat(word_phonemes,end_phonemes); | ||||
} | } | ||||
if(wflags & FLAG_LAST_WORD) | |||||
{ | |||||
// don't use $brk pause before the last word of a sentence | |||||
// (but allow it for emphasis, see below | |||||
dictionary_flags[0] &= ~FLAG_PAUSE1; | |||||
} | |||||
if(wflags & FLAG_EMPHASIZED) | if(wflags & FLAG_EMPHASIZED) | ||||
{ | { | ||||
// A word is indicated in the source text as stressed | // A word is indicated in the source text as stressed | ||||
// Give it stress level 6 (for the intonation module) | // Give it stress level 6 (for the intonation module) | ||||
ChangeWordStress(this,word_phonemes,6); | ChangeWordStress(this,word_phonemes,6); | ||||
dictionary_flags[0] |= FLAG_PAUSE1; // precede by short pause | |||||
// if(!(wflags & FLAG_LAST_WORD)) // ?? omit pre-pause if it's the last word in the sentence? | |||||
dictionary_flags[0] |= FLAG_PAUSE1; // precede by short pause | |||||
} | } | ||||
else | else | ||||
if(wtab[dictionary_skipwords].flags & FLAG_LAST_WORD) | if(wtab[dictionary_skipwords].flags & FLAG_LAST_WORD) | ||||
} | } | ||||
} | } | ||||
if(!(word_flags & FLAG_LAST_WORD) && !(word_flags & FLAG_HYPHEN)) | |||||
if(!(word_flags & FLAG_HYPHEN)) | |||||
{ | { | ||||
if(flags & FLAG_PAUSE1) | if(flags & FLAG_PAUSE1) | ||||
{ | { |
#define RULE_CONDITION 5 // followed by condition number (byte) | #define RULE_CONDITION 5 // followed by condition number (byte) | ||||
#define RULE_GROUP_START 6 | #define RULE_GROUP_START 6 | ||||
#define RULE_GROUP_END 7 | #define RULE_GROUP_END 7 | ||||
#define RULE_LINENUM 8 // next 2 bytes give a line number, for debugging purposes | |||||
#define RULE_SPACE 32 // ascii space | #define RULE_SPACE 32 // ascii space | ||||
#define RULE_SYLLABLE 9 | #define RULE_SYLLABLE 9 | ||||
extern void SetLengthMods(Translator *tr, int value); | extern void SetLengthMods(Translator *tr, int value); | ||||
Translator *SelectTranslator(const char *name); | Translator *SelectTranslator(const char *name); | ||||
int CompileDictionary(const char *dsource, const char *dict_name, FILE *log, char *err_name); | |||||
int CompileDictionary(const char *dsource, const char *dict_name, FILE *log, char *err_name,int flags); | |||||
void LoadConfig(void); | void LoadConfig(void); | ||||
int PhonemeCode(unsigned int mnem); | int PhonemeCode(unsigned int mnem); | ||||
void ChangeWordStress(Translator *tr, char *word, int new_stress); | void ChangeWordStress(Translator *tr, char *word, int new_stress); |
{ | { | ||||
if(*p == RULE_CONDITION) | if(*p == RULE_CONDITION) | ||||
p+=2; | p+=2; | ||||
if(*p == RULE_LINENUM) | |||||
p+=3; | |||||
if(*p == RULE_GROUP_END) | if(*p == RULE_GROUP_END) | ||||
{ | { | ||||
p++; | p++; |