Bug fixes. git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@166 d46cf337-b52f-0410-862d-fd96e6ae7743master
hmm h@m | hmm h@m | ||||
(http ://) eItSti:ti:'pi:_ | (http ://) eItSti:ti:'pi:_ | ||||
ibm $abbrev | ibm $abbrev | ||||
ie aIi:_! $pause | |||||
ie aIi:_! $pause $only | |||||
i.e aIi:_! $pause | i.e aIi:_! $pause | ||||
irc $abbrev | irc $abbrev | ||||
lbs paUndz | lbs paUndz | ||||
heroin hEroUIn | heroin hEroUIn | ||||
heroism hEroUIz@m | heroism hEroUIz@m | ||||
heroine hEroUIn | heroine hEroUIn | ||||
heron hEr@n | |||||
herpes h3:pi:z | herpes h3:pi:z | ||||
hideout haIdaUt | hideout haIdaUt | ||||
hindu hIndu: | hindu hIndu: |
// 2006-11-18 Gilles Casse <[email protected]> | // 2006-11-18 Gilles Casse <[email protected]> | ||||
// | // | ||||
// Updated: 2008-03-05 Michel Such <[email protected]> | |||||
// Updated: 2008-03-10 Michel Such <[email protected]> | |||||
// | // | ||||
// * The rules are based on Cicero TTS. | // * The rules are based on Cicero TTS. | ||||
// Y | // Y | ||||
ontin) en (t_ A~ // continent, incontinent | ontin) en (t_ A~ // continent, incontinent | ||||
erm) en (t_ A~ // ferment, serment | erm) en (t_ A~ // ferment, serment | ||||
Vferm) en (t_ // ferment, referment (verbe) | Vferm) en (t_ // ferment, referment (verbe) | ||||
Arp) en (t_ A~ // arpent, serpent | |||||
XArp) en (t_ A~ // arpent, serpent | |||||
CArr) en (t_ A~ // conncurrent, torrent | CArr) en (t_ A~ // conncurrent, torrent | ||||
_appar) en (t_ A~ // apparent | _appar) en (t_ A~ // apparent | ||||
spar) en (t_ A~ // transparent | spar) en (t_ A~ // transparent | ||||
xcell) en (t_ A~ // excellent | xcell) en (t_ A~ // excellent | ||||
nn) en (t_ t2 // prennent, viennent, sonnent | nn) en (t_ t2 // prennent, viennent, sonnent | ||||
iCam) en (t_ A~ | |||||
mm) en (t_ A~ | mm) en (t_ A~ | ||||
em) en (t_ A~ // vitement | em) en (t_ A~ // vitement | ||||
mom) en (t_ A~ // moment | mom) en (t_ A~ // moment | ||||
Caim) en (t_ A~ | Caim) en (t_ A~ | ||||
dum) en (t_ A~ | dum) en (t_ A~ | ||||
gum) en (t_ A~ | gum) en (t_ A~ | ||||
jum) en (t_ A~ | |||||
oCum) en (t_ A~ | oCum) en (t_ A~ | ||||
rum) en (t_ A~ | rum) en (t_ A~ | ||||
.group j | .group j | ||||
j Z // adjoint joujoux | j Z // adjoint joujoux | ||||
// group j: English section | |||||
ject (_ _^_en | |||||
.group k | .group k | ||||
k k // kafka | k k // kafka | ||||
// group k: English section | // group k: English section | ||||
AC) k _^_en // blank, black, dark | |||||
ke (X _^_en // basket, make, take | ke (X _^_en // basket, make, take | ||||
key _^_en | key _^_en | ||||
ky (_ _^_en | ky (_ _^_en | ||||
// group t: English section | // group t: English section | ||||
C) th (_ _^_en // month | C) th (_ _^_en // month | ||||
_) th (eX _^_en // the, then | |||||
_) th (aX _^_en // than, that | |||||
_) th (As _^_en // these those there | |||||
_) time _^_en | _) time _^_en | ||||
tle (_ _^_en | tle (_ _^_en | ||||
too _^_en | too _^_en | ||||
?1 _1 'um | ?1 _1 'um | ||||
?2 _1 'uN | ?2 _1 'uN | ||||
_2 d'oIs# | _2 d'oIs# | ||||
_3 tr'es# | |||||
_3 tR'es# | |||||
?1 _4 kw'atru | ?1 _4 kw'atru | ||||
?2 _4 kw'atRu | ?2 _4 kw'atRu | ||||
_5 s'iNku | _5 s'iNku | ||||
?2_19 dezen'Ovi | ?2_19 dezen'Ovi | ||||
?1_2X v'iNty | ?1_2X v'iNty | ||||
?2_2X v'iNtSi | ?2_2X v'iNtSi | ||||
_3X tr'iNt& | |||||
_3X tR'iNt& | |||||
?1_4X kw&*'eNt& | ?1_4X kw&*'eNt& | ||||
?2_4X kwa*'eINt& | ?2_4X kwa*'eINt& |
#define M_IMPLOSIVE M_HOOK | #define M_IMPLOSIVE M_HOOK | ||||
typedef struct { | typedef struct { | ||||
char *name; | |||||
const char *name; | |||||
int flags; | int flags; | ||||
} ACCENTS; | } ACCENTS; | ||||
char *p_textinput; | char *p_textinput; | ||||
wchar_t *p_wchar_input; | wchar_t *p_wchar_input; | ||||
int ungot_char; | int ungot_char; | ||||
char *ungot_word = NULL; | |||||
const char *ungot_word = NULL; | |||||
int end_of_input; | int end_of_input; | ||||
int ignore_text=0; // set during <sub> ... </sub> to ignore text which has been replaced by an alias | int ignore_text=0; // set during <sub> ... </sub> to ignore text which has been replaced by an alias | ||||
char single_letter[24]; | char single_letter[24]; | ||||
char phonemes[60]; | char phonemes[60]; | ||||
char phonemes2[60]; | char phonemes2[60]; | ||||
char *lang_name = NULL; | |||||
const char *lang_name = NULL; | |||||
char *string; | char *string; | ||||
static char buf[60]; | static char buf[60]; | ||||
#include "translate.h" | #include "translate.h" | ||||
#include "wave.h" | #include "wave.h" | ||||
const char *version_string = "1.36 09.Mar.08"; | |||||
const char *version_string = "1.36.01 11.Mar.08"; | |||||
const int version_phdata = 0x013400; | const int version_phdata = 0x013400; | ||||
int option_device_number = -1; | int option_device_number = -1; |
int stress; | int stress; | ||||
int modulation; | int modulation; | ||||
int pre_voiced; | int pre_voiced; | ||||
int free_min; | |||||
unsigned char *pitch_env=NULL; | unsigned char *pitch_env=NULL; | ||||
unsigned char *amp_env; | unsigned char *amp_env; | ||||
PHONEME_TAB *ph; | PHONEME_TAB *ph; | ||||
while(ix < (*n_ph)) | while(ix < (*n_ph)) | ||||
{ | { | ||||
if(WcmdqFree() <= MIN_WCMDQ) | |||||
p = &phoneme_list[ix]; | |||||
if(p->type == phPAUSE) | |||||
free_min = 5; | |||||
else | |||||
if(p->type != phVOWEL) | |||||
free_min = 10; // we need less Q space for non-vowels, and we need to generate phonemes after a vowel so that the pitch_length is filled in | |||||
else | |||||
free_min = MIN_WCMDQ; // 22 | |||||
if(WcmdqFree() <= free_min) | |||||
return(1); // wait | return(1); // wait | ||||
prev = &phoneme_list[ix-1]; | prev = &phoneme_list[ix-1]; | ||||
p = &phoneme_list[ix]; | |||||
next = &phoneme_list[ix+1]; | next = &phoneme_list[ix+1]; | ||||
next2 = &phoneme_list[ix+2]; | next2 = &phoneme_list[ix+2]; | ||||
#define N_WCMDQ 160 | #define N_WCMDQ 160 | ||||
#define MIN_WCMDQ 20 // need this many free entries before adding new phoneme | |||||
#define MIN_WCMDQ 22 // need this many free entries before adding new phoneme | |||||
extern long wcmdq[N_WCMDQ][4]; | extern long wcmdq[N_WCMDQ][4]; | ||||
extern int wcmdq_head; | extern int wcmdq_head; |
if((word_length == 1) && IsAlpha(wc)) | if((word_length == 1) && IsAlpha(wc)) | ||||
{ | { | ||||
posn = 0; | posn = 0; | ||||
while(*wordx != ' ') | |||||
while((*wordx != ' ') && (*wordx != 0)) | |||||
{ | { | ||||
wordx += TranslateLetter(wordx, phonemes, 4, word_length); | wordx += TranslateLetter(wordx, phonemes, 4, word_length); | ||||
posn++; | posn++; | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
int c2; | |||||
ix = 0; | ix = 0; | ||||
while((word_copy[ix] = word[ix]) != ' ') ix++; | |||||
while(((c2 = word_copy[ix] = word[ix]) != ' ') && (c2 != 0)) ix++; | |||||
word_copy_len = ix; | word_copy_len = ix; | ||||
flags = translator->TranslateWord(word, next_pause, wtab); | flags = translator->TranslateWord(word, next_pause, wtab); | ||||
ok =0; | ok =0; | ||||
} | } | ||||
if(sylimit & 0x100) | |||||
if(ok != 0) | |||||
{ | { | ||||
// only if the second word has $alt attribute | |||||
strcpy(ph_buf,word_phonemes); | |||||
flags2 = translator->TranslateWord(p2+1, 0, wtab+1); | |||||
if((flags2 & FLAG_ALT_TRANS) == 0) | |||||
if(sylimit & 0x100) | |||||
{ | { | ||||
// only if the second word has $alt attribute | |||||
strcpy(ph_buf,word_phonemes); | |||||
flags2 = translator->TranslateWord(p2+1, 0, wtab+1); | |||||
if((flags2 & FLAG_ALT_TRANS) == 0) | |||||
{ | |||||
ok = 0; | |||||
strcpy(word_phonemes,ph_buf); | |||||
} | |||||
} | |||||
if((sylimit & 0x200) && ((wtab+1)->flags & FLAG_LAST_WORD)) | |||||
{ | |||||
// not if the next word is end-of-sentence | |||||
ok = 0; | ok = 0; | ||||
strcpy(word_phonemes,ph_buf); | |||||
} | } | ||||
} | } | ||||
if((sylimit & 0x200) && ((wtab+1)->flags & FLAG_LAST_WORD)) | |||||
{ | |||||
// not if the next word is end-of-sentence | |||||
ok = 0; | |||||
} | |||||
if(ok) | if(ok) | ||||
{ | { | ||||
*p2 = '-'; // replace next space by hyphen | *p2 = '-'; // replace next space by hyphen | ||||
} | } | ||||
} | } | ||||
memset(&ph_list2[0],0,sizeof(ph_list2[0])); | |||||
ph_list2[0].phcode = phonPAUSE_SHORT; | ph_list2[0].phcode = phonPAUSE_SHORT; | ||||
ph_list2[0].stress = 0; | |||||
ph_list2[0].tone_number = 0; | |||||
ph_list2[0].sourceix = 0; | |||||
n_ph_list2 = 1; | n_ph_list2 = 1; | ||||
prev_last_stress = 0; | prev_last_stress = 0; | ||||
prepause_timeout = 0; | prepause_timeout = 0; |