| @@ -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 | |||