Add short pause between [*] and a fricative. git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@44 d46cf337-b52f-0410-862d-fd96e6ae7743master
| // This file is UTF-8 encoded | // This file is UTF-8 encoded | ||||
| // all words lower case | // all words lower case | ||||
| // Alphabet | |||||
| // Α α, Β β, Γ γ, Δ δ, Ε ε, Ζ ζ, Η η, Θ θ, Ι ι, Κ κ, Λ λ, Μ μ, Ν ν, Ξ ξ, | // Α α, Β β, Γ γ, Δ δ, Ε ε, Ζ ζ, Η η, Θ θ, Ι ι, Κ κ, Λ λ, Μ μ, Ν ν, Ξ ξ, | ||||
| // Ο ο, Π π, Ρ ρ, Σ σ ς (word-final form), Τ τ, Υ υ, Φ φ, Χ χ, Ψ ψ, Ω ω. | // Ο ο, Π π, Ρ ρ, Σ σ ς (word-final form), Τ τ, Υ υ, Φ φ, Χ χ, Ψ ψ, Ω ω. | ||||
| // Letter group B: θ κ ξ π ς σ τ φ χ (voiceless consonants) | // Letter group B: θ κ ξ π ς σ τ φ χ (voiceless consonants) | ||||
| // Letter group Y: ε η ι υ έ ή ί ύ (front vowels). | // Letter group Y: ε η ι υ έ ή ί ύ (front vowels). | ||||
| .L01 αι ε ι η υ οι ει αί έ ί ή ύ οί εί | |||||
| .group α | .group α | ||||
| α a | α a | ||||
| A) γγ Ng | A) γγ Ng | ||||
| A) γκ Ng | A) γκ Ng | ||||
| γ (χ N | γ (χ N | ||||
| γ (L01 j | |||||
| γαι (A j | γαι (A j | ||||
| γε (A j | γε (A j | ||||
| γει (A j | |||||
| γη (A j | |||||
| γι (A j | γι (A j | ||||
| γη (A j | |||||
| γυ (A j | γυ (A j | ||||
| γοι (A j | γοι (A j | ||||
| γει (A j | |||||
| .group δ | .group δ | ||||
| δ D | δ D |
| phoneme * // flap | phoneme * // flap | ||||
| vcd alv flp | vcd alv flp | ||||
| brkafter | |||||
| vowelout f1=3 f2=1500 -400 300 f3=-200 80 rms=35 len=50 | vowelout f1=3 f2=1500 -400 300 f3=-200 80 rms=35 len=50 | ||||
| vowelin f1=0 f2=1500 -300 300 f3=-200 80 rms=20 | vowelin f1=0 f2=1500 -300 300 f3=-200 80 rms=20 | ||||
| formants d/tap3+r3/rx%200 | formants d/tap3+r3/rx%200 |
| {"vowel2", 0x2000000+phVOWEL2}, | {"vowel2", 0x2000000+phVOWEL2}, | ||||
| {"palatal", 0x2000000+phPALATAL}, | {"palatal", 0x2000000+phPALATAL}, | ||||
| {"long", 0x2000000+phLONG}, | {"long", 0x2000000+phLONG}, | ||||
| {"brkafter", 0x2000000+phBRKAFTER}, | |||||
| // voiced / unvoiced | // voiced / unvoiced | ||||
| {"vcd", 0x2000000+phVOICED}, | {"vcd", 0x2000000+phVOICED}, |
| int GetVowelStress(unsigned char *phonemes, unsigned char *vowel_stress, int &vowel_count, int &stressed_syllable) | |||||
| {//=============================================================================================================== | |||||
| static int GetVowelStress(Translator *tr, unsigned char *phonemes, unsigned char *vowel_stress, int &vowel_count, int &stressed_syllable) | |||||
| {//====================================================================================================================================== | |||||
| unsigned char phcode; | unsigned char phcode; | ||||
| PHONEME_TAB *ph; | PHONEME_TAB *ph; | ||||
| for(ix=1; ix<count; ix++) | for(ix=1; ix<count; ix++) | ||||
| { | { | ||||
| if(vowel_stress[ix] == 4) | if(vowel_stress[ix] == 4) | ||||
| vowel_stress[ix] = 0; | |||||
| { | |||||
| if(tr->langopts.stress_flags & 0x20000) | |||||
| vowel_stress[ix] = 0; | |||||
| else | |||||
| vowel_stress[ix] = 3; | |||||
| } | |||||
| if(vowel_stress[ix] == 5) | if(vowel_stress[ix] == 5) | ||||
| { | { | ||||
| phonSTRESS_P, phonSTRESS_TONIC, phonSTRESS_TONIC}; | phonSTRESS_P, phonSTRESS_TONIC, phonSTRESS_TONIC}; | ||||
| void ChangeWordStress(char *word, int new_stress) | |||||
| {//============================================== | |||||
| void ChangeWordStress(Translator *tr, char *word, int new_stress) | |||||
| {//============================================================== | |||||
| int ix; | int ix; | ||||
| unsigned char *p; | unsigned char *p; | ||||
| int max_stress; | int max_stress; | ||||
| unsigned char vowel_stress[N_WORD_PHONEMES/2]; | unsigned char vowel_stress[N_WORD_PHONEMES/2]; | ||||
| strcpy((char *)phonetic,word); | strcpy((char *)phonetic,word); | ||||
| max_stress = GetVowelStress(phonetic,vowel_stress,vowel_count,stressed_syllable); | |||||
| max_stress = GetVowelStress(tr, phonetic,vowel_stress,vowel_count,stressed_syllable); | |||||
| if(new_stress >= 4) | if(new_stress >= 4) | ||||
| { | { | ||||
| unstressed_word = 1; | unstressed_word = 1; | ||||
| } | } | ||||
| max_stress = GetVowelStress(phonetic,vowel_stress,vowel_count,stressed_syllable); | |||||
| max_stress = GetVowelStress(this,phonetic,vowel_stress,vowel_count,stressed_syllable); | |||||
| // heavy or light syllables | // heavy or light syllables | ||||
| ix = 1; | ix = 1; | ||||
| int Translator::TranslateRules(char *p, char *phonemes, int ph_size, char *end_phonemes, int word_flags, int dict_flags) | |||||
| {//===================================================================================================================== | |||||
| int Translator::TranslateRules(char *p_start, char *phonemes, int ph_size, char *end_phonemes, int word_flags, int dict_flags) | |||||
| {//=========================================================================================================================== | |||||
| /* Translate a word bounded by space characters | /* Translate a word bounded by space characters | ||||
| Append the result to 'phonemes' and any standard prefix/suffix in 'end_phonemes' */ | Append the result to 'phonemes' and any standard prefix/suffix in 'end_phonemes' */ | ||||
| int g1; /* first group for this letter */ | int g1; /* first group for this letter */ | ||||
| int n; | int n; | ||||
| int letter; | int letter; | ||||
| int ix; | |||||
| int digit_count=0; | int digit_count=0; | ||||
| char *p_start; | |||||
| char *p; | |||||
| MatchRecord match1; | MatchRecord match1; | ||||
| MatchRecord match2; | MatchRecord match2; | ||||
| char ph_buf[40]; | char ph_buf[40]; | ||||
| char word_copy[N_WORD_BYTES]; | |||||
| static const char str_pause[2] = {phonPAUSE_NOLINK,0}; | static const char str_pause[2] = {phonPAUSE_NOLINK,0}; | ||||
| char group_name[4]; | char group_name[4]; | ||||
| if(data_dictrules == NULL) | if(data_dictrules == NULL) | ||||
| return(0); | return(0); | ||||
| for(ix=0; ix<(N_WORD_BYTES-1);) | |||||
| { | |||||
| c = p_start[ix]; | |||||
| word_copy[ix++] = c; | |||||
| } | |||||
| word_copy[ix] = 0; | |||||
| #ifdef LOG_TRANSLATE | #ifdef LOG_TRANSLATE | ||||
| if((option_phonemes == 2) && ((word_flags & FLAG_NO_TRACE)==0)) | if((option_phonemes == 2) && ((word_flags & FLAG_NO_TRACE)==0)) | ||||
| { | { | ||||
| char wordbuf[120]; | char wordbuf[120]; | ||||
| int ix; | int ix; | ||||
| for(ix=0; ((c = p[ix]) != ' ') && (c != 0); ix++) | |||||
| for(ix=0; ((c = p_start[ix]) != ' ') && (c != 0); ix++) | |||||
| { | { | ||||
| wordbuf[ix] = c; | wordbuf[ix] = c; | ||||
| } | } | ||||
| } | } | ||||
| #endif | #endif | ||||
| p_start = p; | |||||
| p = p_start; | |||||
| word_vowel_count = 0; | word_vowel_count = 0; | ||||
| word_stressed_count = 0; | word_stressed_count = 0; | ||||
| match1.end_type |= p - p_start; | match1.end_type |= p - p_start; | ||||
| } | } | ||||
| strcpy(end_phonemes,match1.phonemes); | strcpy(end_phonemes,match1.phonemes); | ||||
| memcpy(p_start,word_copy,strlen(word_copy)); | |||||
| return(match1.end_type); | return(match1.end_type); | ||||
| } | } | ||||
| } | } | ||||
| // any language specific changes ? | // any language specific changes ? | ||||
| ApplySpecialAttribute(phonemes,dict_flags); | ApplySpecialAttribute(phonemes,dict_flags); | ||||
| memcpy(p_start,word_copy,strlen(word_copy)); | |||||
| return(0); | return(0); | ||||
| } /* end of TranslateRules */ | } /* end of TranslateRules */ | ||||
| #define phPALATAL 0x200 | #define phPALATAL 0x200 | ||||
| #define phLONG 0x1000 | #define phLONG 0x1000 | ||||
| #define phAPPENDPH 0x2000 // always insert another phoneme (link_out) after this one | #define phAPPENDPH 0x2000 // always insert another phoneme (link_out) after this one | ||||
| #define phBRKAFTER 0x4000 // [*] add a post-pause | |||||
| #define phALTERNATIVE 0x0c00 // bits 10,11 specifying use of alternative_ph | #define phALTERNATIVE 0x0c00 // bits 10,11 specifying use of alternative_ph | ||||
| #define phBEFOREVOWEL 0x0000 | #define phBEFOREVOWEL 0x0000 |
| if(next->type==phVOWEL) | if(next->type==phVOWEL) | ||||
| { | { | ||||
| pre_voiced = 1; | pre_voiced = 1; | ||||
| } | |||||
| } // drop through | |||||
| case phFRICATIVE: | case phFRICATIVE: | ||||
| if(p->newword) | if(p->newword) | ||||
| p->prepause = 15; | p->prepause = 15; | ||||
| if(next->type==phPAUSE && prev->type==phNASAL && !(p->ph->phflags&phFORTIS)) | if(next->type==phPAUSE && prev->type==phNASAL && !(p->ph->phflags&phFORTIS)) | ||||
| p->prepause = 25; | p->prepause = 25; | ||||
| if(prev->ph->phflags & phBRKAFTER) | |||||
| p->prepause = 30; | |||||
| if((p->ph->phflags & phSIBILANT) && next->type==phSTOP && !next->newword) | if((p->ph->phflags & phSIBILANT) && next->type==phSTOP && !next->newword) | ||||
| { | { | ||||
| if(prev->type == phVOWEL) | if(prev->type == phVOWEL) |
| #include "translate.h" | #include "translate.h" | ||||
| #include "wave.h" | #include "wave.h" | ||||
| const char *version_string = "1.26.02 11.Jun.07"; | |||||
| const char *version_string = "1.26.03 12.Jun.07"; | |||||
| const int version_phdata = 0x012601; | const int version_phdata = 0x012601; | ||||
| int option_device_number = -1; | int option_device_number = -1; |
| // tr->langopts.vowel_pause = 1; | // tr->langopts.vowel_pause = 1; | ||||
| tr->langopts.stress_rule = 3; // stress on final syllable | tr->langopts.stress_rule = 3; // stress on final syllable | ||||
| tr->langopts.stress_flags = 0x6 | 0x10; | |||||
| tr->langopts.stress_flags = 0x6 | 0x10 | 0x20000; | |||||
| tr->langopts.numbers = 0xa69 + 0x2000; | tr->langopts.numbers = 0xa69 + 0x2000; | ||||
| tr->punct_to_tone[0][3] = 2; // use exclamation intonation | tr->punct_to_tone[0][3] = 2; // use exclamation intonation | ||||
| SetLetterVowel(tr,'y'); | SetLetterVowel(tr,'y'); |
| { | { | ||||
| // the word has attribute to stress or unstress when at end of clause | // the word has attribute to stress or unstress when at end of clause | ||||
| if(dictionary_flags & (FLAG_STRESS_END | FLAG_STRESS_END2)) | if(dictionary_flags & (FLAG_STRESS_END | FLAG_STRESS_END2)) | ||||
| ChangeWordStress(word_phonemes,4); | |||||
| ChangeWordStress(this,word_phonemes,4); | |||||
| // SetWordStress(word_phonemes,0,4,prev_last_stress); | // SetWordStress(word_phonemes,0,4,prev_last_stress); | ||||
| else | else | ||||
| if(dictionary_flags & FLAG_UNSTRESS_END) | if(dictionary_flags & FLAG_UNSTRESS_END) | ||||
| ChangeWordStress(word_phonemes,3); | |||||
| ChangeWordStress(this,word_phonemes,3); | |||||
| // SetWordStress(word_phonemes,0,3,prev_last_stress); | // SetWordStress(word_phonemes,0,3,prev_last_stress); | ||||
| } | } | ||||
| if(wflags & FLAG_STRESSED_WORD) | if(wflags & FLAG_STRESSED_WORD) |
| // bit13= If there is only one syllable before the primary stress, give it a secondary stress | // bit13= If there is only one syllable before the primary stress, give it a secondary stress | ||||
| // bit15= Give stress to the first unstressed syllable | // bit15= Give stress to the first unstressed syllable | ||||
| // bit16= Don't diminish consecutive syllables within a word. | // bit16= Don't diminish consecutive syllables within a word. | ||||
| // bit17= "priority" stress reduces other primary stress to "unstressed" not "secondary" | |||||
| int stress_flags; | int stress_flags; | ||||
| int unstressed_wd1; // stress for $u word of 1 syllable | int unstressed_wd1; // stress for $u word of 1 syllable | ||||
| 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); | ||||
| void LoadConfig(void); | void LoadConfig(void); | ||||
| int PhonemeCode(unsigned int mnem); | int PhonemeCode(unsigned int mnem); | ||||
| void ChangeWordStress(char *word, int new_stress); | |||||
| void ChangeWordStress(Translator *tr, char *word, int new_stress); | |||||
| int TransposeAlphabet(char *text, int offset, int min, int max); | int TransposeAlphabet(char *text, int offset, int min, int max); | ||||
| int utf8_in(int *c, char *buf, int backwards); | int utf8_in(int *c, char *buf, int backwards); | ||||
| int utf8_out(unsigned int c, char *buf); | int utf8_out(unsigned int c, char *buf); |