Browse Source

Merge remote-tracking branch 'jaacoppi/maintainability'

master
Reece H. Dunn 7 years ago
parent
commit
b8d5d96dea

+ 15
- 13
src/libespeak-ng/compiledata.c View File



{ "isVelar", 0, CONDITION_IS_PLACE_OF_ARTICULATION | phPLACE_VELAR }, { "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 }, { "isPause2", 0, CONDITION_IS_OTHER | isBreak },
{ "isWordStart", 0, CONDITION_IS_OTHER | isWordStart }, { "isWordStart", 0, CONDITION_IS_OTHER | isWordStart },
{ "InsertPhoneme", tINSTRN1, i_INSERT_PHONEME }, { "InsertPhoneme", tINSTRN1, i_INSERT_PHONEME },
{ "AppendPhoneme", tINSTRN1, i_APPEND_PHONEME }, { "AppendPhoneme", tINSTRN1, i_APPEND_PHONEME },
{ "IfNextVowelAppend", tINSTRN1, i_APPEND_IFNEXTVOWEL }, { "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 }, { "PauseBefore", tINSTRN1, i_PAUSE_BEFORE },
{ "PauseAfter", tINSTRN1, i_PAUSE_AFTER }, { "PauseAfter", tINSTRN1, i_PAUSE_AFTER },
case i_INSERT_PHONEME: case i_INSERT_PHONEME:
case i_REPLACE_NEXT_PHONEME: case i_REPLACE_NEXT_PHONEME:
case i_VOICING_SWITCH: 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); value = NextItemBrackets(tPHONEMEMNEM, 0);
*prog_out++ = (keyword << 8) + value; *prog_out++ = (keyword << 8) + value;
DecThenCount(); DecThenCount();

+ 109
- 117
src/libespeak-ng/dictionary.c View File

if (plist->synthflags & SFLAG_SYLLABLE) { if (plist->synthflags & SFLAG_SYLLABLE) {
if ((stress = plist->stresslevel) > 1) { if ((stress = plist->stresslevel) > 1) {
c = 0; c = 0;
if (stress > 5) stress = 5;
if (stress > STRESS_IS_PRIORITY) stress = STRESS_IS_PRIORITY;


if (use_ipa) { if (use_ipa) {
c = 0x2cc; // ipa, secondary stress c = 0x2cc; // ipa, secondary stress
if (stress > 3)
if (stress > STRESS_IS_SECONDARY)
c = 0x02c8; // ipa, primary stress c = 0x02c8; // ipa, primary stress
} else } else
c = stress_chars[stress]; c = stress_chars[stress];
int stress = -1; int stress = -1;
int primary_posn = 0; int primary_posn = 0;


vowel_stress[0] = 1;
vowel_stress[0] = STRESS_IS_UNSTRESSED;
while (((phcode = *phonemes++) != 0) && (count < (N_WORD_PHONEMES/2)-1)) { while (((phcode = *phonemes++) != 0) && (count < (N_WORD_PHONEMES/2)-1)) {
if ((ph = phoneme_tab[phcode]) == NULL) if ((ph = phoneme_tab[phcode]) == NULL)
continue; continue;
if (phcode == phonSTRESS_PREV) { if (phcode == phonSTRESS_PREV) {
// primary stress on preceeding vowel // primary stress on preceeding vowel
j = count - 1; 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 // 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; primary_posn = j;
} }


/* reduce any preceding primary stress markers */ /* reduce any preceding primary stress markers */
for (ix = 1; ix < j; ix++) { 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; break;
} }


if ((ph->type == phVOWEL) && !(ph->phflags & phNONSYLLABIC)) { if ((ph->type == phVOWEL) && !(ph->phflags & phNONSYLLABIC)) {
vowel_stress[count] = (char)stress; vowel_stress[count] = (char)stress;
if ((stress >= 4) && (stress >= max_stress)) {
if ((stress >= STRESS_IS_PRIMARY) && (stress >= max_stress)) {
primary_posn = count; primary_posn = count;
max_stress = stress; max_stress = stress;
} }


if ((stress < 0) && (control & 1) && (ph->phflags & phUNSTRESSED)) 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++; count++;
stress = -1; stress = -1;
// previous consonant phoneme is syllablic // previous consonant phoneme is syllablic
vowel_stress[count] = (char)stress; vowel_stress[count] = (char)stress;
if ((stress == 0) && (control & 1)) 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; *ph_out++ = phcode;
} }
vowel_stress[count] = 1;
vowel_stress[count] = STRESS_IS_UNSTRESSED;
*ph_out = 0; *ph_out = 0;


// has the position of the primary stress been specified by $1, $2, etc? // has the position of the primary stress been specified by $1, $2, etc?
if (*stressed_syllable >= count) if (*stressed_syllable >= count)
*stressed_syllable = count-1; // the final syllable *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; primary_posn = *stressed_syllable;
} }


if (max_stress == 5) {
if (max_stress == STRESS_IS_PRIORITY) {
// priority stress, replaces any other primary stress marker // priority stress, replaces any other primary stress marker
for (ix = 1; ix < count; ix++) { 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) if (tr->langopts.stress_flags & S_PRIORITY_STRESS)
vowel_stress[ix] = 1;
vowel_stress[ix] = STRESS_IS_UNSTRESSED;
else 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; primary_posn = ix;
} }
} }
max_stress = 4;
max_stress = STRESS_IS_PRIMARY;
} }


*stressed_syllable = primary_posn; *stressed_syllable = primary_posn;
strcpy((char *)phonetic, word); strcpy((char *)phonetic, word);
max_stress = GetVowelStress(tr, phonetic, vowel_stress, &vowel_count, &stressed_syllable, 0); 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 // promote to primary stress
for (ix = 1; ix < vowel_count; ix++) { for (ix = 1; ix < vowel_count; ix++) {
if (vowel_stress[ix] >= max_stress) { if (vowel_stress[ix] >= max_stress) {
p = phonetic; p = phonetic;
while (*p != 0) { while (*p != 0) {
if ((phoneme_tab[*p]->type == phVOWEL) && !(phoneme_tab[*p]->phflags & phNONSYLLABIC)) { 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]]; *word++ = stress_phonemes[(unsigned char)vowel_stress[ix]];


ix++; ix++;
int v_stress; int v_stress;
int stressed_syllable; // position of stressed syllable int stressed_syllable; // position of stressed syllable
int max_stress_posn; int max_stress_posn;
int unstressed_word = 0;
char *max_output; char *max_output;
int final_ph; int final_ph;
int final_ph2; int final_ph2;
int mnem; int mnem;
int opt_length; int opt_length;
int done;
int stressflags; int stressflags;
int dflags = 0; int dflags = 0;
int first_primary; int first_primary;


static char consonant_types[16] = { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 }; 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; stressflags = tr->langopts.stress_flags;


if (dictionary_flags != NULL) if (dictionary_flags != NULL)


max_output = output + (N_WORD_PHONEMES-3); // check for overrun max_output = output + (N_WORD_PHONEMES-3); // check for overrun



// any stress position marked in the xx_list dictionary ? // any stress position marked in the xx_list dictionary ?
bool unstressed_word = false;
stressed_syllable = dflags & 0x7; stressed_syllable = dflags & 0x7;
if (dflags & 0x8) { if (dflags & 0x8) {
// this indicates a word without a primary stress // this indicates a word without a primary stress
stressed_syllable = dflags & 0x3; stressed_syllable = dflags & 0x3;
unstressed_word = 1;
unstressed_word = true;
} }


max_stress = max_stress_input = GetVowelStress(tr, phonetic, vowel_stress, &vowel_count, &stressed_syllable, 1); max_stress = max_stress_input = GetVowelStress(tr, phonetic, vowel_stress, &vowel_count, &stressed_syllable, 1);
if ((max_stress < 0) && dictionary_flags) if ((max_stress < 0) && dictionary_flags)
max_stress = 0;
max_stress = STRESS_IS_DIMINISHED;


// heavy or light syllables // heavy or light syllables
ix = 1; ix = 1;
for (p = phonetic; *p != 0; p++) { for (p = phonetic; *p != 0; p++) {
if ((phoneme_tab[p[0]]->type == phVOWEL) && !(phoneme_tab[p[0]]->phflags & phNONSYLLABIC)) { if ((phoneme_tab[p[0]]->type == phVOWEL) && !(phoneme_tab[p[0]]->phflags & phNONSYLLABIC)) {
int weight = 0; int weight = 0;
int lengthened = 0;
bool lengthened = false;


if (phoneme_tab[p[1]]->code == phonLENGTHEN) if (phoneme_tab[p[1]]->code == phonLENGTHEN)
lengthened = 1;
lengthened = true;


if (lengthened || (phoneme_tab[p[0]]->phflags & phLONG)) { if (lengthened || (phoneme_tab[p[0]]->phflags & phLONG)) {
// long vowel, increase syllable weight // long vowel, increase syllable weight
// stress on second syllable // stress on second syllable
if ((stressed_syllable == 0) && (vowel_count > 2)) { if ((stressed_syllable == 0) && (vowel_count > 2)) {
stressed_syllable = 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; break;
case 10: // penultimate, but final if only 1 or 2 syllables case 10: // penultimate, but final if only 1 or 2 syllables
if (stressed_syllable == 0) { if (stressed_syllable == 0) {
if (vowel_count < 4) { 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; break;
} }
} }


if (stressed_syllable == 0) { if (stressed_syllable == 0) {
// no explicit stress - stress the penultimate vowel // no explicit stress - stress the penultimate vowel
max_stress = 4;
max_stress = STRESS_IS_PRIMARY;


if (vowel_count > 2) { if (vowel_count > 2) {
stressed_syllable = vowel_count - 2; stressed_syllable = vowel_count - 2;
stressed_syllable = vowel_count - 1; 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 // but this vowel is explicitly marked as unstressed
if (stressed_syllable > 1) if (stressed_syllable > 1)
stressed_syllable--; stressed_syllable--;
// only set the stress if it's not already marked explicitly // only set the stress if it's not already marked explicitly
if (vowel_stress[stressed_syllable] < 0) { if (vowel_stress[stressed_syllable] < 0) {
// don't stress if next and prev syllables are stressed // 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; vowel_stress[stressed_syllable] = max_stress;
} }
} }


while (stressed_syllable > 0) { while (stressed_syllable > 0) {
// find the last vowel which is not unstressed // 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; break;
} else } else
stressed_syllable--; stressed_syllable--;
} }
max_stress = 4;
max_stress = STRESS_IS_PRIMARY;
} }
break; break;
case 4: // stress on antipenultimate vowel case 4: // stress on antipenultimate vowel
if (stressed_syllable < 1) if (stressed_syllable < 1)
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; break;
case 5: case 5:
else else
stressed_syllable = guess_ru[vowel_count]; 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; break;
case 6: // LANG=hi stress on the last heaviest syllable case 6: // LANG=hi stress on the last heaviest syllable


// find the heaviest syllable, excluding the final syllable // find the heaviest syllable, excluding the final syllable
for (ix = 1; ix < (vowel_count-1); ix++) { 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) { if ((wt = syllable_weight[ix]) >= max_weight) {
max_weight = wt; max_weight = wt;
stressed_syllable = ix; stressed_syllable = ix;
stressed_syllable = 1; stressed_syllable = 1;
} }


vowel_stress[stressed_syllable] = 4;
max_stress = 4;
vowel_stress[stressed_syllable] = STRESS_IS_PRIMARY;
max_stress = STRESS_IS_PRIMARY;
} }
break; break;
case 7: // LANG=tr, the last syllable for any vowel marked explicitly as unstressed case 7: // LANG=tr, the last syllable for any vowel marked explicitly as unstressed
if (stressed_syllable == 0) { if (stressed_syllable == 0) {
stressed_syllable = vowel_count - 1; stressed_syllable = vowel_count - 1;
for (ix = 1; ix < vowel_count; ix++) { for (ix = 1; ix < vowel_count; ix++) {
if (vowel_stress[ix] == 1) {
if (vowel_stress[ix] == STRESS_IS_UNSTRESSED) {
stressed_syllable = ix-1; stressed_syllable = ix-1;
break; break;
} }
} }
vowel_stress[stressed_syllable] = 4;
max_stress = 4;
vowel_stress[stressed_syllable] = STRESS_IS_PRIMARY;
max_stress = STRESS_IS_PRIMARY;
} }
break; break;
case 9: // mark all as stressed case 9: // mark all as stressed
for (ix = 1; ix < vowel_count; ix++) { 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; break;
case 12: // LANG=kl (Greenlandic) case 12: // LANG=kl (Greenlandic)
long_vowel = 0; long_vowel = 0;
for (ix = 1; ix < vowel_count; ix++) { 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) { if (vowel_length[ix] > 0) {
long_vowel = ix; 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
} }
} }


stressed_syllable = vowel_count - 1; 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; break;
case 13: // LANG=ml, 1st unless 1st vowel is short and 2nd is long case 13: // LANG=ml, 1st unless 1st vowel is short and 2nd is long
if (stressed_syllable == 0) { if (stressed_syllable == 0) {
stressed_syllable = 1; stressed_syllable = 1;
if ((vowel_length[1] == 0) && (vowel_count > 2) && (vowel_length[2] > 0)) if ((vowel_length[1] == 0) && (vowel_count > 2) && (vowel_length[2] > 0))
stressed_syllable = 2; stressed_syllable = 2;
vowel_stress[stressed_syllable] = 4;
max_stress = 4;
vowel_stress[stressed_syllable] = STRESS_IS_PRIMARY;
max_stress = STRESS_IS_PRIMARY;
} }
break; 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 // 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 // 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) { 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 // 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 else
stress = 3;
stress = STRESS_IS_SECONDARY;


if (unstressed_word == 0) {
if (unstressed_word == false) {
if ((stressflags & S_2_SYL_2) && (vowel_count == 3)) { if ((stressflags & S_2_SYL_2) && (vowel_count == 3)) {
// Two syllable word, if one syllable has primary stress, then give the other secondary stress // 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 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;
} }
} }


done = 0;
bool done = false;
first_primary = 0; first_primary = 0;
for (v = 1; v < vowel_count; v++) { 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 // flag: don't give secondary stress to final vowel
} else if ((stressflags & 0x8000) && (done == 0)) {
} else if ((stressflags & 0x8000) && (done == false)) {
vowel_stress[v] = (char)stress; vowel_stress[v] = (char)stress;
done = 1;
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)))) {
done = true;
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 // 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 continue; // don't use secondary stress


// don't put secondary stress on a light syllable if the rest of the word (excluding last syllable) contains a heavy syllable
// 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)) { if ((v > 1) && (stressflags & S_2_TO_HEAVY) && (syllable_weight[v] == 0)) {
bool skip = false; bool skip = false;
for (int i = v; i < vowel_count - 1; i++) { for (int i = v; i < vowel_count - 1; i++) {
// should start with secondary stress on the first syllable, or should it count back from // 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? // the primary stress and put secondary stress on alternate syllables?
vowel_stress[v] = (char)stress; vowel_stress[v] = (char)stress;
done = 1;
stress = 3; // use secondary stress for remaining syllables
done = true;
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) if (first_primary == 0)
first_primary = v; first_primary = v;
else if (stressflags & S_FIRST_PRIMARY) { else if (stressflags & S_FIRST_PRIMARY) {
// reduce primary stresses after the first to secondary // reduce primary stresses after the first to secondary
vowel_stress[v] = 3;
vowel_stress[v] = STRESS_IS_SECONDARY;
} }
} }
} }
tonic = tr->langopts.unstressed_wd2; // more than one syllable, used secondary stress as the main stress 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; max_stress_posn = 0;
for (v = 1; v < vowel_count; v++) { for (v = 1; v < vowel_count; v++) {
if (vowel_stress[v] >= max_stress) { if (vowel_stress[v] >= max_stress) {
// find position of highest stress, and replace it by 'tonic' // find position of highest stress, and replace it by 'tonic'


// don't disturb an explicitly set stress by 'unstress-at-end' flag // 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; vowel_stress[max_stress_posn] = (char)tonic;
max_stress = tonic; max_stress = tonic;
} }
if ((tr->langopts.vowel_pause & 0x30) && (ph->type == phVOWEL)) { if ((tr->langopts.vowel_pause & 0x30) && (ph->type == phVOWEL)) {
// word starts with a vowel // 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 *output++ = phonPAUSE_NOLINK; // not to be replaced by link
else else
*output++ = phonPAUSE_VSHORT; // break, but no pause *output++ = phonPAUSE_VSHORT; // break, but no pause
v_stress = vowel_stress[v]; v_stress = vowel_stress[v];
tr->prev_last_stress = v_stress; 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))) { if ((v > 1) && (max_stress >= 2) && (stressflags & S_FINAL_DIM) && (v == (vowel_count-1))) {
// option: mark unstressed final syllable as diminished // 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))) { } else if ((stressflags & S_NO_DIM) || (v == 1) || (v == (vowel_count-1))) {
// first or last syllable, or option 'don't set diminished stress' // 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 // penultimate syllable, followed by an unstressed final syllable
v_stress = 1;
v_stress = STRESS_IS_UNSTRESSED;
} else { } else {
// unstressed syllable within a word // 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; 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) *output++ = stress_phonemes[v_stress]; // mark stress of all vowels except 1 (unstressed)


if (vowel_stress[v] > max_stress) if (vowel_stress[v] > max_stress)


if ((*p == phonLENGTHEN) && ((opt_length = tr->langopts.param[LOPT_IT_LENGTHEN]) & 1)) { if ((*p == phonLENGTHEN) && ((opt_length = tr->langopts.param[LOPT_IT_LENGTHEN]) & 1)) {
// remove lengthen indicator from non-stressed syllables // remove lengthen indicator from non-stressed syllables
int shorten = 0;
bool shorten = false;


if (opt_length & 0x10) { if (opt_length & 0x10) {
// only allow lengthen indicator on the highest stress syllable in the word // only allow lengthen indicator on the highest stress syllable in the word
if (v != max_stress_posn) if (v != max_stress_posn)
shorten = 1;
} else if (v_stress < 4) {
// only allow lengthen indicator if stress >= 4.
shorten = 1;
shorten = true;
} else if (v_stress < STRESS_IS_PRIMARY) {
// only allow lengthen indicator if stress >= STRESS_IS_PRIMARY.
shorten = true;
} }


if (shorten) if (shorten)


const char *p; const char *p;
unsigned char c; unsigned char c;
int unstress_mark;
int length; int length;


length = strlen(ph) + strlen(string); length = strlen(ph) + strlen(string);
return; return;


// any stressable vowel ? // any stressable vowel ?
unstress_mark = 0;
bool unstress_mark = false;
p = ph; p = ph;
while ((c = *p++) != 0) { while ((c = *p++) != 0) {
if (c >= n_phoneme_tab) continue; if (c >= n_phoneme_tab) continue;


if (phoneme_tab[c]->type == phSTRESS) { if (phoneme_tab[c]->type == phSTRESS) {
if (phoneme_tab[c]->std_length < 4) if (phoneme_tab[c]->std_length < 4)
unstress_mark = 1;
unstress_mark = true;
} else { } else {
if (phoneme_tab[c]->type == phVOWEL) { if (phoneme_tab[c]->type == phVOWEL) {
if (((phoneme_tab[c]->phflags & phUNSTRESSED) == 0) && if (((phoneme_tab[c]->phflags & phUNSTRESSED) == 0) &&
(unstress_mark == 0)) {
(unstress_mark == false)) {
tr->word_stressed_count++; tr->word_stressed_count++;
} }
unstress_mark = 0;
unstress_mark = false;
tr->word_vowel_count++; tr->word_vowel_count++;
} }
} }

+ 9
- 9
src/libespeak-ng/synthdata.c View File



if ((tr->langopts.param[LOPT_REDUCE] & 0x2) && (stress_level >= pl->wordstress)) { if ((tr->langopts.param[LOPT_REDUCE] & 0x2) && (stress_level >= pl->wordstress)) {
// treat the most stressed syllable in an unstressed word as stressed // 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; 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; return true;
} else { } else {
if (stress_level < condition_level[condition]) if (stress_level < condition_level[condition])
case CONDITION_IS_OTHER: case CONDITION_IS_OTHER:
switch (data) 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); return StressCondition(tr, plist, data, 0);
case isBreak: case isBreak:
return (ph->type == phPAUSE) || (plist_this->synthflags & SFLAG_NEXT_PAUSE); return (ph->type == phPAUSE) || (plist_this->synthflags & SFLAG_NEXT_PAUSE);

+ 10
- 8
src/libespeak-ng/synthesize.h View File

#define CONDITION_IS_OTHER 0x80 #define CONDITION_IS_OTHER 0x80


// other conditions (stress) // 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 // 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 isAfterStress 9
#define isNotVowel 10 #define isNotVowel 10
#define isFinalVowel 11 #define isFinalVowel 11
#define isFirstVowel 13 #define isFirstVowel 13
#define isSecondVowel 14 #define isSecondVowel 14
#define isTranslationGiven 16 // phoneme translation given in **_list or as [[...]] #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 #define i_StressLevel 0x800



Loading…
Cancel
Save