From 4cbe26b711f5d8bc48e5488bcac01734cf8b07ad Mon Sep 17 00:00:00 2001 From: Juho Hiltunen Date: Wed, 9 Nov 2022 21:04:34 +0200 Subject: [PATCH] cleanup: refactor check for LOPT_REGRESSIVE_VOICING to SetRegressiveVoicing() --- src/libespeak-ng/phonemelist.c | 162 +++++++++++++++++---------------- 1 file changed, 84 insertions(+), 78 deletions(-) diff --git a/src/libespeak-ng/phonemelist.c b/src/libespeak-ng/phonemelist.c index e350d87d..d661cf9c 100644 --- a/src/libespeak-ng/phonemelist.c +++ b/src/libespeak-ng/phonemelist.c @@ -40,6 +40,8 @@ #include "translate.h" #include "speech.h" +static void SetRegressiveVoicing(int regression, PHONEME_LIST2 *plist2, PHONEME_TAB *ph, Translator *tr); + static const unsigned char pause_phonemes[8] = { 0, phonPAUSE_VSHORT, phonPAUSE_SHORT, phonPAUSE, phonPAUSE_LONG, phonGLOTTALSTOP, phonPAUSE_LONG, phonPAUSE_LONG }; @@ -122,13 +124,12 @@ void MakePhonemeList(Translator *tr, int post_pause, bool start_sentence) int j; int insert_ph = 0; PHONEME_LIST *phlist; - PHONEME_TAB *ph; + PHONEME_TAB *ph = NULL; PHONEME_TAB *next, *next2; int unstress_count = 0; int word_stress = 0; int current_phoneme_tab; int max_stress; - int regression; int end_sourceix; int alternative; int delete_count; @@ -209,83 +210,9 @@ void MakePhonemeList(Translator *tr, int post_pause, bool start_sentence) SelectPhonemeTable(current_phoneme_tab); + int regression; if ((regression = tr->langopts.param[LOPT_REGRESSIVE_VOICING]) != 0) { - // set consonant clusters to all voiced or all unvoiced - // Regressive - int type; - bool stop_propagation = false; - int voicing = 0; - - for (j = n_ph_list2-1; j >= 0; j--) { - if (plist2[j].phcode == phonSWITCH) { - /* Find previous phonSWITCH to determine language we're switching back to */ - int k; - for (k = j-1; k >= 0; k--) - if (plist2[k].phcode == phonSWITCH) - break; - if (k >= 0) - SelectPhonemeTable(plist2[k].tone_ph); - else - SelectPhonemeTable(tr->phoneme_tab_ix); - } - ph = phoneme_tab[plist2[j].phcode]; - if (ph == NULL) - continue; - - if (plist2[j].synthflags & SFLAG_SWITCHED_LANG) { - stop_propagation = false; - voicing = 0; - if (regression & 0x100) - voicing = 1; // word-end devoicing - continue; - } - - type = ph->type; - - if (regression & 0x2) { - // [v] amd [v;] don't cause regression, or [R^] - if (((ph->mnemonic & 0xff) == 'v') || ((ph->mnemonic & 0xff) == 'R')) { - stop_propagation = true; - if (regression & 0x10) - voicing = 0; - } - } - - if ((type == phSTOP) || type == (phFRICATIVE)) { - if ((voicing == 0) && (regression & 0xf)) - voicing = 1; - else if ((voicing == 2) && (ph->end_type != 0)) // use end_type field for voicing_switch for consonants - plist2[j].phcode = ph->end_type; // change to voiced equivalent - } else if ((type == phVSTOP) || type == (phVFRICATIVE)) { - if ((voicing == 0) && (regression & 0xf)) - voicing = 2; - else if ((voicing == 1) && (ph->end_type != 0)) - plist2[j].phcode = ph->end_type; // change to unvoiced equivalent - } else { - if (regression & 0x8) { - // LANG=Polish, propagate through liquids and nasals - if ((type == phPAUSE) || (type == phVOWEL)) - voicing = 0; - } else - voicing = 0; - } - if (stop_propagation) { - voicing = 0; - stop_propagation = false; - } - - if (plist2[j].sourceix) { - if (regression & 0x04) { - // stop propagation at a word boundary - voicing = 0; - } - if (regression & 0x100) { - // devoice word-final consonants, unless propagating voiced - if (voicing == 0) - voicing = 1; - } - } - } + SetRegressiveVoicing(regression, plist2, ph, tr); } SelectPhonemeTable(tr->phoneme_tab_ix); @@ -590,3 +517,82 @@ void MakePhonemeList(Translator *tr, int post_pause, bool start_sentence) SelectPhonemeTable(tr->phoneme_tab_ix); } + +static void SetRegressiveVoicing(int regression, PHONEME_LIST2 *plist2, PHONEME_TAB *ph, Translator *tr) { + // set consonant clusters to all voiced or all unvoiced + // Regressive + int type; + bool stop_propagation = false; + int voicing = 0; + + for (int j = n_ph_list2-1; j >= 0; j--) { + if (plist2[j].phcode == phonSWITCH) { + /* Find previous phonSWITCH to determine language we're switching back to */ + int k; + for (k = j-1; k >= 0; k--) + if (plist2[k].phcode == phonSWITCH) + break; + if (k >= 0) + SelectPhonemeTable(plist2[k].tone_ph); + else + SelectPhonemeTable(tr->phoneme_tab_ix); + } + ph = phoneme_tab[plist2[j].phcode]; + if (ph == NULL) + continue; + + if (plist2[j].synthflags & SFLAG_SWITCHED_LANG) { + stop_propagation = false; + voicing = 0; + if (regression & 0x100) + voicing = 1; // word-end devoicing + continue; + } + + type = ph->type; + + if (regression & 0x2) { + // [v] amd [v;] don't cause regression, or [R^] + if (((ph->mnemonic & 0xff) == 'v') || ((ph->mnemonic & 0xff) == 'R')) { + stop_propagation = true; + if (regression & 0x10) + voicing = 0; + } + } + + if ((type == phSTOP) || type == (phFRICATIVE)) { + if ((voicing == 0) && (regression & 0xf)) + voicing = 1; + else if ((voicing == 2) && (ph->end_type != 0)) // use end_type field for voicing_switch for consonants + plist2[j].phcode = ph->end_type; // change to voiced equivalent + } else if ((type == phVSTOP) || type == (phVFRICATIVE)) { + if ((voicing == 0) && (regression & 0xf)) + voicing = 2; + else if ((voicing == 1) && (ph->end_type != 0)) + plist2[j].phcode = ph->end_type; // change to unvoiced equivalent + } else { + if (regression & 0x8) { + // LANG=Polish, propagate through liquids and nasals + if ((type == phPAUSE) || (type == phVOWEL)) + voicing = 0; + } else + voicing = 0; + } + if (stop_propagation) { + voicing = 0; + stop_propagation = false; + } + + if (plist2[j].sourceix) { + if (regression & 0x04) { + // stop propagation at a word boundary + voicing = 0; + } + if (regression & 0x100) { + // devoice word-final consonants, unless propagating voiced + if (voicing == 0) + voicing = 1; + } + } + } + } \ No newline at end of file