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); |