@@ -468,7 +468,7 @@ char *WritePhMnemonic(char *phon_out, PHONEME_TAB *ph, PHONEME_LIST *plist, int | |||
if (plist == NULL) | |||
InterpretPhoneme2(ph->code, &phdata); | |||
else | |||
InterpretPhoneme(NULL, 0, plist, &phdata, NULL); | |||
InterpretPhoneme(NULL, 0, plist, plist, &phdata, NULL); | |||
p = phdata.ipa_string; | |||
if (*p == 0x20) { |
@@ -41,7 +41,7 @@ | |||
#include "speech.h" | |||
static void SetRegressiveVoicing(int regression, PHONEME_LIST2 *plist2, PHONEME_TAB *ph, Translator *tr); | |||
static void ReInterpretPhoneme(PHONEME_TAB *ph, PHONEME_TAB *ph2, PHONEME_LIST *plist3, Translator *tr, PHONEME_DATA *phdata, WORD_PH_DATA *worddata); | |||
static void ReInterpretPhoneme(PHONEME_TAB *ph, PHONEME_TAB *ph2, PHONEME_LIST *plist3, PHONEME_LIST *plist3_start, Translator *tr, PHONEME_DATA *phdata, WORD_PH_DATA *worddata); | |||
static const unsigned char pause_phonemes[8] = { | |||
0, phonPAUSE_VSHORT, phonPAUSE_SHORT, phonPAUSE, phonPAUSE_LONG, phonGLOTTALSTOP, phonPAUSE_LONG, phonPAUSE_LONG | |||
@@ -296,7 +296,7 @@ void MakePhonemeList(Translator *tr, int post_pause, bool start_sentence) | |||
if (ph == NULL) continue; | |||
InterpretPhoneme(tr, 0x100, plist3, &phdata, &worddata); | |||
InterpretPhoneme(tr, 0x100, plist3, ph_list3, &phdata, &worddata); | |||
if ((alternative = phdata.pd_param[pd_CHANGE_NEXTPHONEME]) > 0) { | |||
ph_list3[j+1].ph = phoneme_tab[alternative]; | |||
@@ -315,7 +315,7 @@ void MakePhonemeList(Translator *tr, int post_pause, bool start_sentence) | |||
plist3->ph = ph; | |||
plist3->phcode = alternative; | |||
ReInterpretPhoneme(ph, ph2, plist3, tr, &phdata, &worddata); | |||
ReInterpretPhoneme(ph, ph2, plist3, ph_list3, tr, &phdata, &worddata); | |||
} | |||
if ((alternative = phdata.pd_param[pd_CHANGEPHONEME]) > 0) { | |||
@@ -328,7 +328,7 @@ void MakePhonemeList(Translator *tr, int post_pause, bool start_sentence) | |||
if (alternative == 1) | |||
deleted = true; // NULL phoneme, discard | |||
else { | |||
ReInterpretPhoneme(ph, ph2, plist3, tr, &phdata, &worddata); | |||
ReInterpretPhoneme(ph, ph2, plist3, ph_list3, tr, &phdata, &worddata); | |||
} | |||
} | |||
@@ -579,7 +579,7 @@ static void SetRegressiveVoicing(int regression, PHONEME_LIST2 *plist2, PHONEME_ | |||
} | |||
} | |||
static void ReInterpretPhoneme(PHONEME_TAB *ph, PHONEME_TAB *ph2, PHONEME_LIST *plist3, Translator *tr, PHONEME_DATA *phdata, WORD_PH_DATA *worddata) { | |||
static void ReInterpretPhoneme(PHONEME_TAB *ph, PHONEME_TAB *ph2, PHONEME_LIST *plist3, PHONEME_LIST *plist3_start, Translator *tr, PHONEME_DATA *phdata, WORD_PH_DATA *worddata) { | |||
if (ph->type == phVOWEL) { | |||
plist3->synthflags |= SFLAG_SYLLABLE; | |||
if (ph2->type != phVOWEL) | |||
@@ -589,5 +589,5 @@ if (ph->type == phVOWEL) { | |||
// re-interpret the changed phoneme | |||
// But it doesn't obey a second ChangePhoneme() | |||
InterpretPhoneme(tr, 0x100, plist3, phdata, worddata); | |||
InterpretPhoneme(tr, 0x100, plist3, plist3_start, phdata, worddata); | |||
} |
@@ -479,7 +479,7 @@ int MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, bool resume, FILE *f_mb | |||
if (released == false) | |||
p->synthflags |= SFLAG_NEXT_PAUSE; | |||
InterpretPhoneme(NULL, 0, p, &phdata, NULL); | |||
InterpretPhoneme(NULL, 0, p, plist, &phdata, NULL); | |||
len = DoSample3(&phdata, 0, -1); | |||
len = (len * 1000)/samplerate; // convert to mS | |||
@@ -490,7 +490,7 @@ int MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, bool resume, FILE *f_mb | |||
break; | |||
case phFRICATIVE: | |||
len = 0; | |||
InterpretPhoneme(NULL, 0, p, &phdata, NULL); | |||
InterpretPhoneme(NULL, 0, p, plist, &phdata, NULL); | |||
if (p->synthflags & SFLAG_LENGTHEN) | |||
len = DoSample3(&phdata, p->length, -1); // play it twice for [s:] etc. | |||
len += DoSample3(&phdata, p->length, -1); | |||
@@ -500,7 +500,7 @@ int MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, bool resume, FILE *f_mb | |||
case phNASAL: | |||
if (next->type != phVOWEL) { | |||
memset(&fmtp, 0, sizeof(fmtp)); | |||
InterpretPhoneme(NULL, 0, p, &phdata, NULL); | |||
InterpretPhoneme(NULL, 0, p, plist, &phdata, NULL); | |||
fmtp.fmt_addr = phdata.sound_addr[pd_FMT]; | |||
len = DoSpect2(p->ph, 0, &fmtp, p, -1); | |||
len = (len * 1000)/samplerate; |
@@ -451,21 +451,21 @@ static bool StressCondition(Translator *tr, PHONEME_LIST *plist, int condition, | |||
} | |||
static int CountVowelPosition(PHONEME_LIST *plist) | |||
static int CountVowelPosition(PHONEME_LIST *plist, PHONEME_LIST *plist_start) | |||
{ | |||
int count = 0; | |||
for (;;) { | |||
if (plist->ph->type == phVOWEL) | |||
count++; | |||
if (plist->sourceix != 0) | |||
if (plist->sourceix != 0 || plist == plist_start) | |||
break; | |||
plist--; | |||
} | |||
return count; | |||
} | |||
static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist, unsigned short *p_prog, WORD_PH_DATA *worddata) | |||
static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_LIST *plist_start, unsigned short *p_prog, WORD_PH_DATA *worddata) | |||
{ | |||
unsigned int data; | |||
int instn; | |||
@@ -515,6 +515,8 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist, | |||
{ | |||
case 0: // prevPh | |||
case 5: // prevPhW | |||
if (plist < plist_start+1) | |||
return false; | |||
plist--; | |||
check_endtype = true; | |||
break; | |||
@@ -553,6 +555,8 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist, | |||
plist = &plist[3]; | |||
break; | |||
case 10: // prev2PhW | |||
if (plist < plist_start + 2) | |||
return false; | |||
if ((plist[0].sourceix) || (plist[-1].sourceix)) | |||
return false; | |||
plist -= 2; | |||
@@ -562,6 +566,8 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist, | |||
if ((which == 0) || (which == 5)) { | |||
if (plist->phcode == 1) { | |||
if (plist <= plist_start) | |||
return false; | |||
// This is a NULL phoneme, a phoneme has been deleted so look at the previous phoneme | |||
plist--; | |||
} | |||
@@ -614,6 +620,8 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist, | |||
if (plist->sourceix != 0) | |||
return false; | |||
do { | |||
if (plist <= plist_start) | |||
return false; | |||
plist--; | |||
if ((plist->stresslevel & 0xf) >= 4) | |||
return true; | |||
@@ -633,9 +641,9 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist, | |||
case isVoiced: | |||
return (ph->type == phVOWEL) || (ph->type == phLIQUID) || (ph->phflags & phVOICED); | |||
case isFirstVowel: | |||
return CountVowelPosition(plist) == 1; | |||
return CountVowelPosition(plist, plist_start) == 1; | |||
case isSecondVowel: | |||
return CountVowelPosition(plist) == 2; | |||
return CountVowelPosition(plist, plist_start) == 2; | |||
case isTranslationGiven: | |||
return (plist->synthflags & SFLAG_DICTIONARY) != 0; | |||
} | |||
@@ -733,7 +741,7 @@ static int NumInstnWords(unsigned short *prog) | |||
} | |||
} | |||
void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_DATA *phdata, WORD_PH_DATA *worddata) | |||
void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_LIST *plist_start, PHONEME_DATA *phdata, WORD_PH_DATA *worddata) | |||
{ | |||
// control: | |||
// bit 0: PreVoicing | |||
@@ -839,7 +847,7 @@ void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_ | |||
truth = true; | |||
while ((instn & 0xe000) == 0x2000) { | |||
// process a sequence of conditions, using boolean accumulator | |||
truth2 = InterpretCondition(tr, control, plist, prog, worddata); | |||
truth2 = InterpretCondition(tr, control, plist, plist_start, prog, worddata); | |||
prog += NumInstnWords(prog); | |||
if (*prog == i_NOT) { | |||
truth2 = truth2 ^ 1; | |||
@@ -986,5 +994,5 @@ void InterpretPhoneme2(int phcode, PHONEME_DATA *phdata) | |||
plist[1].ph = phoneme_tab[phcode]; | |||
plist[2].sourceix = 1; | |||
InterpretPhoneme(NULL, 0, &plist[1], phdata, NULL); | |||
InterpretPhoneme(NULL, 0, &plist[1], plist, phdata, NULL); | |||
} |
@@ -34,6 +34,7 @@ extern "C" | |||
void InterpretPhoneme(Translator *tr, | |||
int control, | |||
PHONEME_LIST *plist, | |||
PHONEME_LIST *plist_start, | |||
PHONEME_DATA *phdata, | |||
WORD_PH_DATA *worddata); | |||
@@ -1256,7 +1256,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, bool resume) | |||
if (ph->phflags & phPREVOICE) { | |||
// a period of voicing before the release | |||
memset(&fmtp, 0, sizeof(fmtp)); | |||
InterpretPhoneme(NULL, 0x01, p, &phdata, &worddata); | |||
InterpretPhoneme(NULL, 0x01, p, phoneme_list, &phdata, &worddata); | |||
fmtp.fmt_addr = phdata.sound_addr[pd_FMT]; | |||
fmtp.fmt_amp = phdata.sound_param[pd_FMT]; | |||
@@ -1268,12 +1268,12 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, bool resume) | |||
DoSpect2(ph, 0, &fmtp, p, 0); | |||
} | |||
InterpretPhoneme(NULL, 0, p, &phdata, &worddata); | |||
InterpretPhoneme(NULL, 0, p, phoneme_list, &phdata, &worddata); | |||
phdata.pd_control |= pd_DONTLENGTHEN; | |||
DoSample3(&phdata, 0, 0); | |||
break; | |||
case phFRICATIVE: | |||
InterpretPhoneme(NULL, 0, p, &phdata, &worddata); | |||
InterpretPhoneme(NULL, 0, p, phoneme_list, &phdata, &worddata); | |||
if (p->synthflags & SFLAG_LENGTHEN) | |||
DoSample3(&phdata, p->length, 0); // play it twice for [s:] etc. | |||
@@ -1302,7 +1302,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, bool resume) | |||
if ((prev->type == phVOWEL) || (ph->phflags & phPREVOICE)) { | |||
// a period of voicing before the release | |||
InterpretPhoneme(NULL, 0x01, p, &phdata, &worddata); | |||
InterpretPhoneme(NULL, 0x01, p, phoneme_list, &phdata, &worddata); | |||
fmtp.fmt_addr = phdata.sound_addr[pd_FMT]; | |||
fmtp.fmt_amp = phdata.sound_param[pd_FMT]; | |||
@@ -1321,7 +1321,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, bool resume) | |||
StartSyllable(); | |||
} else | |||
p->synthflags |= SFLAG_NEXT_PAUSE; | |||
InterpretPhoneme(NULL, 0, p, &phdata, &worddata); | |||
InterpretPhoneme(NULL, 0, p, phoneme_list, &phdata, &worddata); | |||
fmtp.fmt_addr = phdata.sound_addr[pd_FMT]; | |||
fmtp.fmt_amp = phdata.sound_param[pd_FMT]; | |||
fmtp.wav_addr = phdata.sound_addr[pd_ADDWAV]; | |||
@@ -1353,7 +1353,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, bool resume) | |||
StartSyllable(); | |||
else | |||
p->synthflags |= SFLAG_NEXT_PAUSE; | |||
InterpretPhoneme(NULL, 0, p, &phdata, &worddata); | |||
InterpretPhoneme(NULL, 0, p, phoneme_list, &phdata, &worddata); | |||
memset(&fmtp, 0, sizeof(fmtp)); | |||
fmtp.std_length = phdata.pd_param[i_SET_LENGTH]*2; | |||
fmtp.fmt_addr = phdata.sound_addr[pd_FMT]; | |||
@@ -1375,7 +1375,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, bool resume) | |||
if (prev->type == phNASAL) | |||
last_frame = NULL; | |||
InterpretPhoneme(NULL, 0, p, &phdata, &worddata); | |||
InterpretPhoneme(NULL, 0, p, phoneme_list, &phdata, &worddata); | |||
fmtp.std_length = phdata.pd_param[i_SET_LENGTH]*2; | |||
fmtp.fmt_addr = phdata.sound_addr[pd_FMT]; | |||
fmtp.fmt_amp = phdata.sound_param[pd_FMT]; | |||
@@ -1408,7 +1408,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, bool resume) | |||
if (next->type == phVOWEL) | |||
StartSyllable(); | |||
InterpretPhoneme(NULL, 0, p, &phdata, &worddata); | |||
InterpretPhoneme(NULL, 0, p, phoneme_list, &phdata, &worddata); | |||
if ((value = (phdata.pd_param[i_PAUSE_BEFORE] - p->prepause)) > 0) | |||
DoPause(value, 1); | |||
@@ -1425,7 +1425,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, bool resume) | |||
memset(&fmtp, 0, sizeof(fmtp)); | |||
InterpretPhoneme(NULL, 0, p, &phdata, &worddata); | |||
InterpretPhoneme(NULL, 0, p, phoneme_list, &phdata, &worddata); | |||
fmtp.std_length = phdata.pd_param[i_SET_LENGTH] * 2; | |||
vowelstart_prev = 0; | |||
@@ -1434,7 +1434,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, bool resume) | |||
fmtp.fmt_length = phdata.sound_param[pd_VWLSTART]; | |||
} else if (prev->type != phPAUSE) { | |||
// check the previous phoneme | |||
InterpretPhoneme(NULL, 0, prev, &phdata_prev, NULL); | |||
InterpretPhoneme(NULL, 0, prev, phoneme_list, &phdata_prev, NULL); | |||
if (((fmtp.fmt_addr = phdata_prev.sound_addr[pd_VWLSTART]) != 0) && (phdata_prev.pd_control & pd_FORNEXTPH)) { | |||
// a vowel start has been specified by the previous phoneme | |||
vowelstart_prev = 1; | |||
@@ -1509,7 +1509,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, bool resume) | |||
fmtp.fmt2_lenadj = phdata.sound_param[pd_VWLEND]; | |||
else if (next->type != phPAUSE) { | |||
fmtp.fmt2_lenadj = 0; | |||
InterpretPhoneme(NULL, 0, next, &phdata_next, NULL); | |||
InterpretPhoneme(NULL, 0, next, phoneme_list, &phdata_next, NULL); | |||
fmtp.use_vowelin = 1; | |||
fmtp.transition0 = phdata_next.vowel_transition[2]; // always do vowel_transition, even if ph_VWLEND ?? consider [N] |
@@ -1 +1 @@ | |||
kəmpˈa͡ɪl ænd flˈæʃ lˈɪnɪɪd͡ʒ ˈændɹɔ͡ɪd ˌo͡ʊˈɛs | |||
kəmpˈa͡ɪl ænd flˈæʃ lˈɪnɪʲɪd͡ʒ ˈændɹɔ͡ɪd ˌo͡ʊˈɛs |
@@ -3,7 +3,7 @@ | |||
juː hæv fˈɔː͡ɹ nˈuː mˈɛsɪd͡ʒᵻz | |||
ðə fˈɜːst ɪz fɹʌm stˈɛfəni wˈɪljəmz ænd ɚɹˈa͡ɪvd æt | |||
θɹˈiː fˈɔː͡ɹɾi fˈa͡ɪv pˌiːˈɛm | |||
θɹˈiː fˈɔː͡ɹɾi fˈa͡ɪv pˌiːʲˈɛm | |||
ðə sˈʌbd͡ʒɛkt ɪz skˈiː tɹˈɪp | |||