mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-10-31 05:35:35 +00:00
Unify terminology for stress
synthesize.h now contains the definitions STRESS_IS_... that should be used with code related to syllable stress. Note that isBreak and other defines were renumbered so that stress definitions could have values 0-6. Possible TODOs: 1. Unify with terms used with phonemes, i.e. keywords like isDiminished in compiledata.c and stress_type in phsource/phonemes 2. Add functionality and documentation about STRESS_IS_PRIORITY and STRESS_IS_EMPHASIZED
This commit is contained in:
@@ -119,11 +119,11 @@ static keywtab_t k_properties[] = {
|
||||
|
||||
{ "isVelar", 0, CONDITION_IS_PLACE_OF_ARTICULATION | phPLACE_VELAR },
|
||||
|
||||
{ "isDiminished", 0, CONDITION_IS_OTHER | isDiminished },
|
||||
{ "isUnstressed", 0, CONDITION_IS_OTHER | isUnstressed },
|
||||
{ "isNotStressed", 0, CONDITION_IS_OTHER | isNotStressed },
|
||||
{ "isStressed", 0, CONDITION_IS_OTHER | isStressed },
|
||||
{ "isMaxStress", 0, CONDITION_IS_OTHER | isMaxStress },
|
||||
{ "isDiminished", 0, CONDITION_IS_OTHER | STRESS_IS_DIMINISHED },
|
||||
{ "isUnstressed", 0, CONDITION_IS_OTHER | STRESS_IS_UNSTRESSED },
|
||||
{ "isNotStressed", 0, CONDITION_IS_OTHER | STRESS_IS_NOT_STRESSED },
|
||||
{ "isStressed", 0, CONDITION_IS_OTHER | STRESS_IS_SECONDARY },
|
||||
{ "isMaxStress", 0, CONDITION_IS_OTHER | STRESS_IS_PRIMARY },
|
||||
|
||||
{ "isPause2", 0, CONDITION_IS_OTHER | isBreak },
|
||||
{ "isWordStart", 0, CONDITION_IS_OTHER | isWordStart },
|
||||
@@ -260,10 +260,11 @@ static keywtab_t keywords[] = {
|
||||
{ "InsertPhoneme", tINSTRN1, i_INSERT_PHONEME },
|
||||
{ "AppendPhoneme", tINSTRN1, i_APPEND_PHONEME },
|
||||
{ "IfNextVowelAppend", tINSTRN1, i_APPEND_IFNEXTVOWEL },
|
||||
{ "ChangeIfDiminished", tINSTRN1, i_CHANGE_IF | isDiminished },
|
||||
{ "ChangeIfUnstressed", tINSTRN1, i_CHANGE_IF | isUnstressed },
|
||||
{ "ChangeIfNotStressed", tINSTRN1, i_CHANGE_IF | isNotStressed },
|
||||
{ "ChangeIfStressed", tINSTRN1, i_CHANGE_IF | isStressed },
|
||||
{ "ChangeIfDiminished", tINSTRN1, i_CHANGE_IF | STRESS_IS_DIMINISHED },
|
||||
{ "ChangeIfUnstressed", tINSTRN1, i_CHANGE_IF | STRESS_IS_UNSTRESSED },
|
||||
{ "ChangeIfNotStressed", tINSTRN1, i_CHANGE_IF | STRESS_IS_NOT_STRESSED },
|
||||
{ "ChangeIfStressed", tINSTRN1, i_CHANGE_IF | STRESS_IS_SECONDARY },
|
||||
{ "ChangeIfStressed", tINSTRN1, i_CHANGE_IF | STRESS_IS_PRIMARY },
|
||||
|
||||
{ "PauseBefore", tINSTRN1, i_PAUSE_BEFORE },
|
||||
{ "PauseAfter", tINSTRN1, i_PAUSE_AFTER },
|
||||
@@ -2045,10 +2046,11 @@ static int CompilePhoneme(int compile_phoneme)
|
||||
case i_INSERT_PHONEME:
|
||||
case i_REPLACE_NEXT_PHONEME:
|
||||
case i_VOICING_SWITCH:
|
||||
case i_CHANGE_IF | isDiminished:
|
||||
case i_CHANGE_IF | isUnstressed:
|
||||
case i_CHANGE_IF | isNotStressed:
|
||||
case i_CHANGE_IF | isStressed:
|
||||
case i_CHANGE_IF | STRESS_IS_DIMINISHED:
|
||||
case i_CHANGE_IF | STRESS_IS_UNSTRESSED:
|
||||
case i_CHANGE_IF | STRESS_IS_NOT_STRESSED:
|
||||
case i_CHANGE_IF | STRESS_IS_SECONDARY:
|
||||
case i_CHANGE_IF | STRESS_IS_PRIMARY:
|
||||
value = NextItemBrackets(tPHONEMEMNEM, 0);
|
||||
*prog_out++ = (keyword << 8) + value;
|
||||
DecThenCount();
|
||||
|
||||
+102
-101
@@ -584,11 +584,11 @@ const char *GetTranslatedPhonemeString(int phoneme_mode)
|
||||
if (plist->synthflags & SFLAG_SYLLABLE) {
|
||||
if ((stress = plist->stresslevel) > 1) {
|
||||
c = 0;
|
||||
if (stress > 5) stress = 5;
|
||||
if (stress > STRESS_IS_PRIORITY) stress = STRESS_IS_PRIORITY;
|
||||
|
||||
if (use_ipa) {
|
||||
c = 0x2cc; // ipa, secondary stress
|
||||
if (stress > 3)
|
||||
if (stress > STRESS_IS_SECONDARY)
|
||||
c = 0x02c8; // ipa, primary stress
|
||||
} else
|
||||
c = stress_chars[stress];
|
||||
@@ -853,7 +853,7 @@ static int GetVowelStress(Translator *tr, unsigned char *phonemes, signed char *
|
||||
int stress = -1;
|
||||
int primary_posn = 0;
|
||||
|
||||
vowel_stress[0] = 1;
|
||||
vowel_stress[0] = STRESS_IS_UNSTRESSED;
|
||||
while (((phcode = *phonemes++) != 0) && (count < (N_WORD_PHONEMES/2)-1)) {
|
||||
if ((ph = phoneme_tab[phcode]) == NULL)
|
||||
continue;
|
||||
@@ -864,20 +864,20 @@ static int GetVowelStress(Translator *tr, unsigned char *phonemes, signed char *
|
||||
if (phcode == phonSTRESS_PREV) {
|
||||
// primary stress on preceeding vowel
|
||||
j = count - 1;
|
||||
while ((j > 0) && (*stressed_syllable == 0) && (vowel_stress[j] < 4)) {
|
||||
if ((vowel_stress[j] != 0) && (vowel_stress[j] != 1)) {
|
||||
while ((j > 0) && (*stressed_syllable == 0) && (vowel_stress[j] < STRESS_IS_PRIMARY)) {
|
||||
if ((vowel_stress[j] != STRESS_IS_DIMINISHED) && (vowel_stress[j] != STRESS_IS_UNSTRESSED)) {
|
||||
// don't promote a phoneme which must be unstressed
|
||||
vowel_stress[j] = 4;
|
||||
vowel_stress[j] = STRESS_IS_PRIMARY;
|
||||
|
||||
if (max_stress < 4) {
|
||||
max_stress = 4;
|
||||
if (max_stress < STRESS_IS_PRIMARY) {
|
||||
max_stress = STRESS_IS_PRIMARY;
|
||||
primary_posn = j;
|
||||
}
|
||||
|
||||
/* reduce any preceding primary stress markers */
|
||||
for (ix = 1; ix < j; ix++) {
|
||||
if (vowel_stress[ix] == 4)
|
||||
vowel_stress[ix] = 3;
|
||||
if (vowel_stress[ix] == STRESS_IS_PRIMARY)
|
||||
vowel_stress[ix] = STRESS_IS_SECONDARY;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -896,13 +896,13 @@ static int GetVowelStress(Translator *tr, unsigned char *phonemes, signed char *
|
||||
|
||||
if ((ph->type == phVOWEL) && !(ph->phflags & phNONSYLLABIC)) {
|
||||
vowel_stress[count] = (char)stress;
|
||||
if ((stress >= 4) && (stress >= max_stress)) {
|
||||
if ((stress >= STRESS_IS_PRIMARY) && (stress >= max_stress)) {
|
||||
primary_posn = count;
|
||||
max_stress = stress;
|
||||
}
|
||||
|
||||
if ((stress < 0) && (control & 1) && (ph->phflags & phUNSTRESSED))
|
||||
vowel_stress[count] = 1; // weak vowel, must be unstressed
|
||||
vowel_stress[count] = STRESS_IS_UNSTRESSED; // weak vowel, must be unstressed
|
||||
|
||||
count++;
|
||||
stress = -1;
|
||||
@@ -910,12 +910,12 @@ static int GetVowelStress(Translator *tr, unsigned char *phonemes, signed char *
|
||||
// previous consonant phoneme is syllablic
|
||||
vowel_stress[count] = (char)stress;
|
||||
if ((stress == 0) && (control & 1))
|
||||
vowel_stress[count++] = 1; // syllabic consonant, usually unstressed
|
||||
vowel_stress[count++] = STRESS_IS_UNSTRESSED; // syllabic consonant, usually unstressed
|
||||
}
|
||||
|
||||
*ph_out++ = phcode;
|
||||
}
|
||||
vowel_stress[count] = 1;
|
||||
vowel_stress[count] = STRESS_IS_UNSTRESSED;
|
||||
*ph_out = 0;
|
||||
|
||||
// has the position of the primary stress been specified by $1, $2, etc?
|
||||
@@ -923,27 +923,27 @@ static int GetVowelStress(Translator *tr, unsigned char *phonemes, signed char *
|
||||
if (*stressed_syllable >= count)
|
||||
*stressed_syllable = count-1; // the final syllable
|
||||
|
||||
vowel_stress[*stressed_syllable] = 4;
|
||||
max_stress = 4;
|
||||
vowel_stress[*stressed_syllable] = STRESS_IS_PRIMARY;
|
||||
max_stress = STRESS_IS_PRIMARY;
|
||||
primary_posn = *stressed_syllable;
|
||||
}
|
||||
|
||||
if (max_stress == 5) {
|
||||
if (max_stress == STRESS_IS_PRIORITY) {
|
||||
// priority stress, replaces any other primary stress marker
|
||||
for (ix = 1; ix < count; ix++) {
|
||||
if (vowel_stress[ix] == 4) {
|
||||
if (vowel_stress[ix] == STRESS_IS_PRIMARY) {
|
||||
if (tr->langopts.stress_flags & S_PRIORITY_STRESS)
|
||||
vowel_stress[ix] = 1;
|
||||
vowel_stress[ix] = STRESS_IS_UNSTRESSED;
|
||||
else
|
||||
vowel_stress[ix] = 3;
|
||||
vowel_stress[ix] = STRESS_IS_SECONDARY;
|
||||
}
|
||||
|
||||
if (vowel_stress[ix] == 5) {
|
||||
vowel_stress[ix] = 4;
|
||||
if (vowel_stress[ix] == STRESS_IS_PRIORITY) {
|
||||
vowel_stress[ix] = STRESS_IS_PRIMARY;
|
||||
primary_posn = ix;
|
||||
}
|
||||
}
|
||||
max_stress = 4;
|
||||
max_stress = STRESS_IS_PRIMARY;
|
||||
}
|
||||
|
||||
*stressed_syllable = primary_posn;
|
||||
@@ -969,7 +969,7 @@ void ChangeWordStress(Translator *tr, char *word, int new_stress)
|
||||
strcpy((char *)phonetic, word);
|
||||
max_stress = GetVowelStress(tr, phonetic, vowel_stress, &vowel_count, &stressed_syllable, 0);
|
||||
|
||||
if (new_stress >= 4) {
|
||||
if (new_stress >= STRESS_IS_PRIMARY) {
|
||||
// promote to primary stress
|
||||
for (ix = 1; ix < vowel_count; ix++) {
|
||||
if (vowel_stress[ix] >= max_stress) {
|
||||
@@ -990,7 +990,7 @@ void ChangeWordStress(Translator *tr, char *word, int new_stress)
|
||||
p = phonetic;
|
||||
while (*p != 0) {
|
||||
if ((phoneme_tab[*p]->type == phVOWEL) && !(phoneme_tab[*p]->phflags & phNONSYLLABIC)) {
|
||||
if ((vowel_stress[ix] == 0) || (vowel_stress[ix] > 1))
|
||||
if ((vowel_stress[ix] == STRESS_IS_DIMINISHED) || (vowel_stress[ix] > STRESS_IS_UNSTRESSED))
|
||||
*word++ = stress_phonemes[(unsigned char)vowel_stress[ix]];
|
||||
|
||||
ix++;
|
||||
@@ -1045,13 +1045,6 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
|
||||
static char consonant_types[16] = { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
/* stress numbers STRESS_BASE +
|
||||
0 diminished, unstressed within a word
|
||||
1 unstressed, weak
|
||||
2
|
||||
3 secondary stress
|
||||
4 main stress */
|
||||
|
||||
stressflags = tr->langopts.stress_flags;
|
||||
|
||||
if (dictionary_flags != NULL)
|
||||
@@ -1084,7 +1077,7 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
|
||||
max_stress = max_stress_input = GetVowelStress(tr, phonetic, vowel_stress, &vowel_count, &stressed_syllable, 1);
|
||||
if ((max_stress < 0) && dictionary_flags)
|
||||
max_stress = 0;
|
||||
max_stress = STRESS_IS_DIMINISHED;
|
||||
|
||||
// heavy or light syllables
|
||||
ix = 1;
|
||||
@@ -1124,16 +1117,16 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
// stress on second syllable
|
||||
if ((stressed_syllable == 0) && (vowel_count > 2)) {
|
||||
stressed_syllable = 2;
|
||||
if (max_stress == 0)
|
||||
vowel_stress[stressed_syllable] = 4;
|
||||
max_stress = 4;
|
||||
if (max_stress == STRESS_IS_DIMINISHED)
|
||||
vowel_stress[stressed_syllable] = STRESS_IS_PRIMARY;
|
||||
max_stress = STRESS_IS_PRIMARY;
|
||||
}
|
||||
break;
|
||||
case 10: // penultimate, but final if only 1 or 2 syllables
|
||||
if (stressed_syllable == 0) {
|
||||
if (vowel_count < 4) {
|
||||
vowel_stress[vowel_count - 1] = 4;
|
||||
max_stress = 4;
|
||||
vowel_stress[vowel_count - 1] = STRESS_IS_PRIMARY;
|
||||
max_stress = STRESS_IS_PRIMARY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1143,7 +1136,7 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
|
||||
if (stressed_syllable == 0) {
|
||||
// no explicit stress - stress the penultimate vowel
|
||||
max_stress = 4;
|
||||
max_stress = STRESS_IS_PRIMARY;
|
||||
|
||||
if (vowel_count > 2) {
|
||||
stressed_syllable = vowel_count - 2;
|
||||
@@ -1174,7 +1167,7 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
stressed_syllable = vowel_count - 1;
|
||||
}
|
||||
|
||||
if ((vowel_stress[stressed_syllable] == 0) || (vowel_stress[stressed_syllable] == 1)) {
|
||||
if ((vowel_stress[stressed_syllable] == STRESS_IS_DIMINISHED) || (vowel_stress[stressed_syllable] == STRESS_IS_UNSTRESSED)) {
|
||||
// but this vowel is explicitly marked as unstressed
|
||||
if (stressed_syllable > 1)
|
||||
stressed_syllable--;
|
||||
@@ -1187,7 +1180,7 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
// only set the stress if it's not already marked explicitly
|
||||
if (vowel_stress[stressed_syllable] < 0) {
|
||||
// don't stress if next and prev syllables are stressed
|
||||
if ((vowel_stress[stressed_syllable-1] < 4) || (vowel_stress[stressed_syllable+1] < 4))
|
||||
if ((vowel_stress[stressed_syllable-1] < STRESS_IS_PRIMARY) || (vowel_stress[stressed_syllable+1] < STRESS_IS_PRIMARY))
|
||||
vowel_stress[stressed_syllable] = max_stress;
|
||||
}
|
||||
}
|
||||
@@ -1200,13 +1193,13 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
|
||||
while (stressed_syllable > 0) {
|
||||
// find the last vowel which is not unstressed
|
||||
if (vowel_stress[stressed_syllable] < 0) {
|
||||
vowel_stress[stressed_syllable] = 4;
|
||||
if (vowel_stress[stressed_syllable] < STRESS_IS_DIMINISHED) {
|
||||
vowel_stress[stressed_syllable] = STRESS_IS_PRIMARY;
|
||||
break;
|
||||
} else
|
||||
stressed_syllable--;
|
||||
}
|
||||
max_stress = 4;
|
||||
max_stress = STRESS_IS_PRIMARY;
|
||||
}
|
||||
break;
|
||||
case 4: // stress on antipenultimate vowel
|
||||
@@ -1215,9 +1208,9 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
if (stressed_syllable < 1)
|
||||
stressed_syllable = 1;
|
||||
|
||||
if (max_stress == 0)
|
||||
vowel_stress[stressed_syllable] = 4;
|
||||
max_stress = 4;
|
||||
if (max_stress == STRESS_IS_DIMINISHED)
|
||||
vowel_stress[stressed_syllable] = STRESS_IS_PRIMARY;
|
||||
max_stress = STRESS_IS_PRIMARY;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
@@ -1237,8 +1230,8 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
else
|
||||
stressed_syllable = guess_ru[vowel_count];
|
||||
}
|
||||
vowel_stress[stressed_syllable] = 4;
|
||||
max_stress = 4;
|
||||
vowel_stress[stressed_syllable] = STRESS_IS_PRIMARY;
|
||||
max_stress = STRESS_IS_PRIMARY;
|
||||
}
|
||||
break;
|
||||
case 6: // LANG=hi stress on the last heaviest syllable
|
||||
@@ -1248,7 +1241,7 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
|
||||
// find the heaviest syllable, excluding the final syllable
|
||||
for (ix = 1; ix < (vowel_count-1); ix++) {
|
||||
if (vowel_stress[ix] < 0) {
|
||||
if (vowel_stress[ix] < STRESS_IS_DIMINISHED) {
|
||||
if ((wt = syllable_weight[ix]) >= max_weight) {
|
||||
max_weight = wt;
|
||||
stressed_syllable = ix;
|
||||
@@ -1264,38 +1257,38 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
stressed_syllable = 1;
|
||||
}
|
||||
|
||||
vowel_stress[stressed_syllable] = 4;
|
||||
max_stress = 4;
|
||||
vowel_stress[stressed_syllable] = STRESS_IS_PRIMARY;
|
||||
max_stress = STRESS_IS_PRIMARY;
|
||||
}
|
||||
break;
|
||||
case 7: // LANG=tr, the last syllable for any vowel marked explicitly as unstressed
|
||||
if (stressed_syllable == 0) {
|
||||
stressed_syllable = vowel_count - 1;
|
||||
for (ix = 1; ix < vowel_count; ix++) {
|
||||
if (vowel_stress[ix] == 1) {
|
||||
if (vowel_stress[ix] == STRESS_IS_UNSTRESSED) {
|
||||
stressed_syllable = ix-1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
vowel_stress[stressed_syllable] = 4;
|
||||
max_stress = 4;
|
||||
vowel_stress[stressed_syllable] = STRESS_IS_PRIMARY;
|
||||
max_stress = STRESS_IS_PRIMARY;
|
||||
}
|
||||
break;
|
||||
case 9: // mark all as stressed
|
||||
for (ix = 1; ix < vowel_count; ix++) {
|
||||
if (vowel_stress[ix] < 0)
|
||||
vowel_stress[ix] = 4;
|
||||
if (vowel_stress[ix] < STRESS_IS_DIMINISHED)
|
||||
vowel_stress[ix] = STRESS_IS_PRIMARY;
|
||||
}
|
||||
break;
|
||||
case 12: // LANG=kl (Greenlandic)
|
||||
long_vowel = 0;
|
||||
for (ix = 1; ix < vowel_count; ix++) {
|
||||
if (vowel_stress[ix] == 4)
|
||||
vowel_stress[ix] = 3; // change marked stress (consonant clusters) to secondary (except the last)
|
||||
if (vowel_stress[ix] == STRESS_IS_PRIMARY)
|
||||
vowel_stress[ix] = STRESS_IS_SECONDARY; // change marked stress (consonant clusters) to secondary (except the last)
|
||||
|
||||
if (vowel_length[ix] > 0) {
|
||||
long_vowel = ix;
|
||||
vowel_stress[ix] = 3; // give secondary stress to all long vowels
|
||||
vowel_stress[ix] = STRESS_IS_SECONDARY; // give secondary stress to all long vowels
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1312,86 +1305,94 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
stressed_syllable = vowel_count - 1;
|
||||
}
|
||||
}
|
||||
vowel_stress[stressed_syllable] = 4;
|
||||
max_stress = 4;
|
||||
vowel_stress[stressed_syllable] = STRESS_IS_PRIMARY;
|
||||
max_stress = STRESS_IS_PRIMARY;
|
||||
break;
|
||||
case 13: // LANG=ml, 1st unless 1st vowel is short and 2nd is long
|
||||
if (stressed_syllable == 0) {
|
||||
stressed_syllable = 1;
|
||||
if ((vowel_length[1] == 0) && (vowel_count > 2) && (vowel_length[2] > 0))
|
||||
stressed_syllable = 2;
|
||||
vowel_stress[stressed_syllable] = 4;
|
||||
max_stress = 4;
|
||||
vowel_stress[stressed_syllable] = STRESS_IS_PRIMARY;
|
||||
max_stress = STRESS_IS_PRIMARY;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ((stressflags & S_FINAL_VOWEL_UNSTRESSED) && ((control & 2) == 0) && (vowel_count > 2) && (max_stress_input < 3) && (vowel_stress[vowel_count - 1] == 4)) {
|
||||
if ((stressflags & S_FINAL_VOWEL_UNSTRESSED) && ((control & 2) == 0) && (vowel_count > 2) && (max_stress_input < STRESS_IS_SECONDARY) && (vowel_stress[vowel_count - 1] == STRESS_IS_PRIMARY)) {
|
||||
// Don't allow stress on a word-final vowel
|
||||
// Only do this if there is no suffix phonemes to be added, and if a stress position was not given explicitly
|
||||
if (phoneme_tab[final_ph]->type == phVOWEL) {
|
||||
vowel_stress[vowel_count - 1] = 1;
|
||||
vowel_stress[vowel_count - 2] = 4;
|
||||
vowel_stress[vowel_count - 1] = STRESS_IS_UNSTRESSED;
|
||||
vowel_stress[vowel_count - 2] = STRESS_IS_PRIMARY;
|
||||
}
|
||||
}
|
||||
|
||||
// now guess the complete stress pattern
|
||||
if (max_stress < 4)
|
||||
stress = 4; // no primary stress marked, use for 1st syllable
|
||||
if (max_stress < STRESS_IS_PRIMARY)
|
||||
stress = STRESS_IS_PRIMARY; // no primary stress marked, use for 1st syllable
|
||||
else
|
||||
stress = 3;
|
||||
stress = STRESS_IS_SECONDARY;
|
||||
|
||||
if (unstressed_word == false) {
|
||||
if ((stressflags & S_2_SYL_2) && (vowel_count == 3)) {
|
||||
// Two syllable word, if one syllable has primary stress, then give the other secondary stress
|
||||
if (vowel_stress[1] == 4)
|
||||
vowel_stress[2] = 3;
|
||||
if (vowel_stress[2] == 4)
|
||||
vowel_stress[1] = 3;
|
||||
if (vowel_stress[1] == STRESS_IS_PRIMARY)
|
||||
vowel_stress[2] = STRESS_IS_SECONDARY;
|
||||
if (vowel_stress[2] == STRESS_IS_PRIMARY)
|
||||
vowel_stress[1] = STRESS_IS_SECONDARY;
|
||||
}
|
||||
|
||||
if ((stressflags & S_INITIAL_2) && (vowel_stress[1] < 0)) {
|
||||
if ((stressflags & S_INITIAL_2) && (vowel_stress[1] < STRESS_IS_DIMINISHED)) {
|
||||
// If there is only one syllable before the primary stress, give it a secondary stress
|
||||
if ((vowel_count > 3) && (vowel_stress[2] >= 4))
|
||||
vowel_stress[1] = 3;
|
||||
if ((vowel_count > 3) && (vowel_stress[2] >= STRESS_IS_PRIMARY))
|
||||
vowel_stress[1] = STRESS_IS_SECONDARY;
|
||||
}
|
||||
}
|
||||
|
||||
bool done = false;
|
||||
first_primary = 0;
|
||||
for (v = 1; v < vowel_count; v++) {
|
||||
if (vowel_stress[v] < 0) {
|
||||
if ((stressflags & S_FINAL_NO_2) && (stress < 4) && (v == vowel_count-1)) {
|
||||
if (vowel_stress[v] < STRESS_IS_DIMINISHED) {
|
||||
if ((stressflags & S_FINAL_NO_2) && (stress < STRESS_IS_PRIMARY) && (v == vowel_count-1)) {
|
||||
// flag: don't give secondary stress to final vowel
|
||||
} else if ((stressflags & 0x8000) && (done == false)) {
|
||||
vowel_stress[v] = (char)stress;
|
||||
done = true;
|
||||
stress = 3; // use secondary stress for remaining syllables
|
||||
} else if ((vowel_stress[v-1] <= 1) && ((vowel_stress[v+1] <= 1) || ((stress == 4) && (vowel_stress[v+1] <= 2)))) {
|
||||
stress = STRESS_IS_SECONDARY; // use secondary stress for remaining syllables
|
||||
} else if ((vowel_stress[v-1] <= STRESS_IS_UNSTRESSED) && ((vowel_stress[v+1] <= STRESS_IS_UNSTRESSED) || ((stress == STRESS_IS_PRIMARY) && (vowel_stress[v+1] <= STRESS_IS_NOT_STRESSED)))) {
|
||||
// trochaic: give stress to vowel surrounded by unstressed vowels
|
||||
|
||||
if ((stress == 3) && (stressflags & S_NO_AUTO_2))
|
||||
if ((stress == STRESS_IS_SECONDARY) && (stressflags & S_NO_AUTO_2))
|
||||
continue; // don't use secondary stress
|
||||
|
||||
if ((v > 1) && (stressflags & S_2_TO_HEAVY) && (syllable_weight[v] == 0) && (syllable_weight[v+1] > 0)) {
|
||||
// don't put secondary stress on a light syllable which is followed by a heavy syllable
|
||||
continue;
|
||||
// don't put secondary stress on a light syllable if the rest of the word (excluding last syllable) contains a heavy syllable
|
||||
if ((v > 1) && (stressflags & S_2_TO_HEAVY) && (syllable_weight[v] == 0)) {
|
||||
bool skip = false;
|
||||
for (int i = v; i < vowel_count - 1; i++) {
|
||||
if (syllable_weight[i] > 0) {
|
||||
skip = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (skip == true)
|
||||
continue;
|
||||
}
|
||||
|
||||
// should start with secondary stress on the first syllable, or should it count back from
|
||||
// the primary stress and put secondary stress on alternate syllables?
|
||||
vowel_stress[v] = (char)stress;
|
||||
done = true;
|
||||
stress = 3; // use secondary stress for remaining syllables
|
||||
stress = STRESS_IS_SECONDARY; // use secondary stress for remaining syllables
|
||||
}
|
||||
}
|
||||
|
||||
if (vowel_stress[v] >= 4) {
|
||||
if (vowel_stress[v] >= STRESS_IS_PRIMARY) {
|
||||
if (first_primary == 0)
|
||||
first_primary = v;
|
||||
else if (stressflags & S_FIRST_PRIMARY) {
|
||||
// reduce primary stresses after the first to secondary
|
||||
vowel_stress[v] = 3;
|
||||
vowel_stress[v] = STRESS_IS_SECONDARY;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1403,7 +1404,7 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
tonic = tr->langopts.unstressed_wd2; // more than one syllable, used secondary stress as the main stress
|
||||
}
|
||||
|
||||
max_stress = 0;
|
||||
max_stress = STRESS_IS_DIMINISHED;
|
||||
max_stress_posn = 0;
|
||||
for (v = 1; v < vowel_count; v++) {
|
||||
if (vowel_stress[v] >= max_stress) {
|
||||
@@ -1416,7 +1417,7 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
// find position of highest stress, and replace it by 'tonic'
|
||||
|
||||
// don't disturb an explicitly set stress by 'unstress-at-end' flag
|
||||
if ((tonic > max_stress) || (max_stress <= 4))
|
||||
if ((tonic > max_stress) || (max_stress <= STRESS_IS_PRIMARY))
|
||||
vowel_stress[max_stress_posn] = (char)tonic;
|
||||
max_stress = tonic;
|
||||
}
|
||||
@@ -1434,7 +1435,7 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
if ((tr->langopts.vowel_pause & 0x30) && (ph->type == phVOWEL)) {
|
||||
// word starts with a vowel
|
||||
|
||||
if ((tr->langopts.vowel_pause & 0x20) && (vowel_stress[1] >= 4))
|
||||
if ((tr->langopts.vowel_pause & 0x20) && (vowel_stress[1] >= STRESS_IS_PRIMARY))
|
||||
*output++ = phonPAUSE_NOLINK; // not to be replaced by link
|
||||
else
|
||||
*output++ = phonPAUSE_VSHORT; // break, but no pause
|
||||
@@ -1454,26 +1455,26 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
v_stress = vowel_stress[v];
|
||||
tr->prev_last_stress = v_stress;
|
||||
|
||||
if (v_stress <= 1) {
|
||||
if (v_stress <= STRESS_IS_UNSTRESSED) {
|
||||
if ((v > 1) && (max_stress >= 2) && (stressflags & S_FINAL_DIM) && (v == (vowel_count-1))) {
|
||||
// option: mark unstressed final syllable as diminished
|
||||
v_stress = 0;
|
||||
v_stress = STRESS_IS_DIMINISHED;
|
||||
} else if ((stressflags & S_NO_DIM) || (v == 1) || (v == (vowel_count-1))) {
|
||||
// first or last syllable, or option 'don't set diminished stress'
|
||||
v_stress = 1;
|
||||
} else if ((v == (vowel_count-2)) && (vowel_stress[vowel_count-1] <= 1)) {
|
||||
v_stress = STRESS_IS_UNSTRESSED;
|
||||
} else if ((v == (vowel_count-2)) && (vowel_stress[vowel_count-1] <= STRESS_IS_UNSTRESSED)) {
|
||||
// penultimate syllable, followed by an unstressed final syllable
|
||||
v_stress = 1;
|
||||
v_stress = STRESS_IS_UNSTRESSED;
|
||||
} else {
|
||||
// unstressed syllable within a word
|
||||
if ((vowel_stress[v-1] < 0) || ((stressflags & S_MID_DIM) == 0)) {
|
||||
v_stress = 0; // change to 0 (diminished stress)
|
||||
if ((vowel_stress[v-1] < STRESS_IS_DIMINISHED) || ((stressflags & S_MID_DIM) == 0)) {
|
||||
v_stress = STRESS_IS_DIMINISHED;
|
||||
vowel_stress[v] = v_stress;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((v_stress == 0) || (v_stress > 1))
|
||||
if ((v_stress == STRESS_IS_DIMINISHED) || (v_stress > STRESS_IS_UNSTRESSED))
|
||||
*output++ = stress_phonemes[v_stress]; // mark stress of all vowels except 1 (unstressed)
|
||||
|
||||
if (vowel_stress[v] > max_stress)
|
||||
@@ -1487,8 +1488,8 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
// only allow lengthen indicator on the highest stress syllable in the word
|
||||
if (v != max_stress_posn)
|
||||
shorten = true;
|
||||
} else if (v_stress < 4) {
|
||||
// only allow lengthen indicator if stress >= 4.
|
||||
} else if (v_stress < STRESS_IS_PRIMARY) {
|
||||
// only allow lengthen indicator if stress >= STRESS_IS_PRIMARY.
|
||||
shorten = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -466,15 +466,15 @@ static bool StressCondition(Translator *tr, PHONEME_LIST *plist, int condition,
|
||||
|
||||
if ((tr->langopts.param[LOPT_REDUCE] & 0x2) && (stress_level >= pl->wordstress)) {
|
||||
// treat the most stressed syllable in an unstressed word as stressed
|
||||
stress_level = 4;
|
||||
stress_level = STRESS_IS_PRIMARY;
|
||||
}
|
||||
}
|
||||
|
||||
if (condition == isMaxStress)
|
||||
if (condition == STRESS_IS_PRIMARY)
|
||||
return stress_level >= pl->wordstress;
|
||||
|
||||
if (condition == isStressed) {
|
||||
if (stress_level > 3)
|
||||
if (condition == STRESS_IS_SECONDARY) {
|
||||
if (stress_level > STRESS_IS_SECONDARY)
|
||||
return true;
|
||||
} else {
|
||||
if (stress_level < condition_level[condition])
|
||||
@@ -633,11 +633,11 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist,
|
||||
case CONDITION_IS_OTHER:
|
||||
switch (data)
|
||||
{
|
||||
case isDiminished:
|
||||
case isUnstressed:
|
||||
case isNotStressed:
|
||||
case isStressed:
|
||||
case isMaxStress:
|
||||
case STRESS_IS_DIMINISHED:
|
||||
case STRESS_IS_UNSTRESSED:
|
||||
case STRESS_IS_NOT_STRESSED:
|
||||
case STRESS_IS_SECONDARY:
|
||||
case STRESS_IS_PRIMARY:
|
||||
return StressCondition(tr, plist, data, 0);
|
||||
case isBreak:
|
||||
return (ph->type == phPAUSE) || (plist_this->synthflags & SFLAG_NEXT_PAUSE);
|
||||
|
||||
@@ -319,16 +319,15 @@ typedef struct {
|
||||
#define CONDITION_IS_OTHER 0x80
|
||||
|
||||
// other conditions (stress)
|
||||
#define isDiminished 0
|
||||
#define isUnstressed 1
|
||||
#define isNotStressed 2
|
||||
#define isStressed 3
|
||||
#define isMaxStress 4
|
||||
#define STRESS_IS_DIMINISHED 0 // diminished, unstressed within a word
|
||||
#define STRESS_IS_UNSTRESSED 1 // unstressed, weak
|
||||
#define STRESS_IS_NOT_STRESSED 2 // default, not stressed
|
||||
#define STRESS_IS_SECONDARY 3 // secondary stress
|
||||
#define STRESS_IS_PRIMARY 4 // primary (main) stress
|
||||
#define STRESS_IS_PRIORITY 5 // replaces primary markers
|
||||
#define STRESS_IS_EMPHASIZED 6 // emphasized
|
||||
|
||||
// other conditions
|
||||
#define isBreak 5 // pause phoneme or (stop/vstop/vfric not followed by vowel or (liquid in same word))
|
||||
#define isWordStart 6
|
||||
#define isWordEnd 8
|
||||
#define isAfterStress 9
|
||||
#define isNotVowel 10
|
||||
#define isFinalVowel 11
|
||||
@@ -336,6 +335,9 @@ typedef struct {
|
||||
#define isFirstVowel 13
|
||||
#define isSecondVowel 14
|
||||
#define isTranslationGiven 16 // phoneme translation given in **_list or as [[...]]
|
||||
#define isBreak 17 // pause phoneme or (stop/vstop/vfric not followed by vowel or (liquid in same word))
|
||||
#define isWordStart 18
|
||||
#define isWordEnd 19
|
||||
|
||||
#define i_StressLevel 0x800
|
||||
|
||||
|
||||
Reference in New Issue
Block a user