mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-11-08 15:41:16 +00:00
[1.29.07] Reduce clicks at very low pitches due to numerical overflow in wave generation.
Treat echo-delay = 0 as "no echo", even if ech-amplitude is set. lang=ru, fix crash for "words" which has produce no phonemes (wg. ":"). git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@88 d46cf337-b52f-0410-862d-fd96e6ae7743
This commit is contained in:
+1
-48
@@ -931,7 +931,6 @@ void Translator::SetWordStress(char *output, unsigned int dictionary_flags, int
|
||||
int ix;
|
||||
int v;
|
||||
int v_stress;
|
||||
int reduce_level;
|
||||
int stressed_syllable; // position of stressed syllable
|
||||
int max_stress_posn;
|
||||
int unstressed_word = 0;
|
||||
@@ -966,6 +965,7 @@ void Translator::SetWordStress(char *output, unsigned int dictionary_flags, int
|
||||
if(phonetic[ix] == 0)
|
||||
break;
|
||||
}
|
||||
if(ix == 0) return;
|
||||
final_ph = phonetic[ix-1];
|
||||
|
||||
max_output = output + (N_WORD_PHONEMES-3); /* check for overrun */
|
||||
@@ -1360,53 +1360,6 @@ void Translator::SetWordStress(char *output, unsigned int dictionary_flags, int
|
||||
if(v_stress > 0)
|
||||
*output++ = stress_phonemes[v_stress]; // mark stress of all vowels except 0 (unstressed)
|
||||
|
||||
while((ph->reduce_to != 0) && (((dictionary_flags & FLAG_FOUND)==0) || (langopts.param[LOPT_REDUCE] & 1)))
|
||||
{
|
||||
// this vowel can be reduced to another if the stress is below a specified value
|
||||
int reduce = 0;
|
||||
|
||||
switch(reduce_level = (ph->phflags >> 28) & 7)
|
||||
{
|
||||
case 0:
|
||||
/* reduce unstressed-diminished to schwa */
|
||||
if((vowel_stress[v+1] <= 1) && (v >= (vowel_count-2)))
|
||||
{
|
||||
/* not if followed by another, terminating, unstessed syllable */
|
||||
break;
|
||||
} // drop through to next case
|
||||
case 1:
|
||||
if(v_stress == 1) // diminished stress only
|
||||
reduce = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
if(v_stress < reduce_level)
|
||||
reduce = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if(max_stress == 1) max_stress = 0;
|
||||
if(unstressed_word && (langopts.param[LOPT_REDUCE] & 0x2) && (v_stress >= max_stress))
|
||||
{
|
||||
// don't reduce the most stressed syllable in an unstressed word
|
||||
reduce = 0;
|
||||
}
|
||||
|
||||
if(reduce)
|
||||
{
|
||||
phcode = ph->reduce_to;
|
||||
ph = phoneme_tab[phcode];
|
||||
#ifdef deleted
|
||||
if(*p == phonLENGTHEN)
|
||||
{
|
||||
/* delete length indicator after vowel now that it has been reduced */
|
||||
p++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if(vowel_stress[v] > max_stress)
|
||||
{
|
||||
|
||||
+52
-20
@@ -35,10 +35,6 @@
|
||||
int Translator::ChangePhonemes(PHONEME_LIST2 *phlist, int n_ph, int index, PHONEME_TAB *ph, CHANGEPH *ch)
|
||||
{//======================================================================================================
|
||||
// Called for each phoneme in the phoneme list, to allow a language to make changes
|
||||
// flags: bit 0=1 last phoneme in a word
|
||||
// bit 1=1 this is the highest stressed vowel in the current word
|
||||
// bit 2=1 after the highest stressed vowel in the current word
|
||||
// bit 3=1 the phonemes were specified explicitly, or found from an entry in the xx_list dictionary
|
||||
// ph The current phoneme
|
||||
return(0);
|
||||
}
|
||||
@@ -184,7 +180,7 @@ void Translator::MakePhonemeList(int post_pause, int start_sentence)
|
||||
PHONEME_TAB *ph;
|
||||
PHONEME_TAB *prev, *next, *next2;
|
||||
int unstress_count = 0;
|
||||
int word_has_stress = 0;
|
||||
int word_stress = 0;
|
||||
int switched_language = 0;
|
||||
int max_stress;
|
||||
int voicing;
|
||||
@@ -338,7 +334,21 @@ void Translator::MakePhonemeList(int post_pause, int start_sentence)
|
||||
}
|
||||
|
||||
if(plist2->sourceix)
|
||||
word_has_stress = 0; // start of a word
|
||||
{
|
||||
// start of a word
|
||||
int k;
|
||||
word_stress = 0;
|
||||
|
||||
// find the highest stress level in this word
|
||||
for(k=j+1; k < n_ph_list2; k++)
|
||||
{
|
||||
if(ph_list3[k].sourceix)
|
||||
break; // start of the next word
|
||||
|
||||
if(ph_list3[k].stress > word_stress)
|
||||
word_stress = ph_list3[k].stress;
|
||||
}
|
||||
}
|
||||
|
||||
if(ph == NULL) continue;
|
||||
|
||||
@@ -353,7 +363,7 @@ void Translator::MakePhonemeList(int post_pause, int start_sentence)
|
||||
{
|
||||
// in a sequence of unstressed syllables, reduce alternate syllables to 'diminished'
|
||||
// stress. But not for the last phoneme of a stressed word
|
||||
if((langopts.stress_flags & 0x2) || (word_has_stress && ((plist2+1)->sourceix!=0)))
|
||||
if((langopts.stress_flags & 0x2) || ((word_stress > 3) && ((plist2+1)->sourceix!=0)))
|
||||
{
|
||||
// An unstressed final vowel of a stressed word
|
||||
unstress_count=1; // try again for next syllable
|
||||
@@ -367,8 +377,6 @@ void Translator::MakePhonemeList(int post_pause, int start_sentence)
|
||||
else
|
||||
{
|
||||
unstress_count = 0;
|
||||
if(plist2->stress > 3)
|
||||
word_has_stress = 1; // word has a primary or a secondary stress
|
||||
}
|
||||
}
|
||||
|
||||
@@ -426,20 +434,44 @@ void Translator::MakePhonemeList(int post_pause, int start_sentence)
|
||||
}
|
||||
}
|
||||
|
||||
if((ph->reduce_to != 0) && (ph->type != phVOWEL) && !(plist2->synthflags & SFLAG_DICTIONARY))
|
||||
{
|
||||
// reduction for vowels has already been done in SetWordStress
|
||||
int reduce_level;
|
||||
|
||||
if(next->type == phVOWEL)
|
||||
while((ph->reduce_to != 0) && (!(plist2->synthflags & SFLAG_DICTIONARY) || (langopts.param[LOPT_REDUCE] & 1)))
|
||||
{
|
||||
int reduce_level;
|
||||
int stress_level;
|
||||
int reduce = 0;
|
||||
|
||||
reduce_level = (ph->phflags >> 28) & 7;
|
||||
|
||||
if(ph->type == phVOWEL)
|
||||
{
|
||||
reduce_level = (ph->phflags >> 28) & 7;
|
||||
if((&plist2[1])->stress < reduce_level)
|
||||
{
|
||||
// look at the stress of the following vowel
|
||||
ph = phoneme_tab[ph->reduce_to];
|
||||
}
|
||||
stress_level = plist2->stress;
|
||||
}
|
||||
else
|
||||
{
|
||||
// consonant, get stress from the following vowel
|
||||
if(next->type == phVOWEL)
|
||||
stress_level = (plist2+1)->stress;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if(stress_level == 1)
|
||||
reduce = 1; // stress = 'reduced'
|
||||
|
||||
if(stress_level < reduce_level)
|
||||
reduce =1;
|
||||
|
||||
if((word_stress < 4) && (langopts.param[LOPT_REDUCE] & 0x2) && (stress_level >= word_stress))
|
||||
{
|
||||
// don't reduce the most stressed syllable in an unstressed word
|
||||
reduce = 0;
|
||||
}
|
||||
|
||||
if(reduce)
|
||||
ph = phoneme_tab[ph->reduce_to];
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if((plist2+1)->synthflags & SFLAG_LENGTHEN)
|
||||
|
||||
@@ -744,11 +744,6 @@ typedef struct {
|
||||
int Translator_Russian::ChangePhonemes(PHONEME_LIST2 *phlist, int n_ph, int index, PHONEME_TAB *ph, CHANGEPH *ch)
|
||||
{//==============================================================================================================
|
||||
// Called for each phoneme in the phoneme list, to allow a language to make changes
|
||||
// flags: bit 0=1 last phoneme in a word
|
||||
// bit 1=1 this is the highest stressed vowel in the current word
|
||||
// bit 2=1 after the highest stressed vowel in the current word
|
||||
// bit 3=1 the phonemes were specified explicitly, or found from an entry in the xx_list dictionary
|
||||
// bits 8-15 syllable number, 1=first syllable, etc.
|
||||
// ph The current phoneme
|
||||
|
||||
int variant;
|
||||
|
||||
+1
-1
@@ -923,7 +923,7 @@ strcpy(phonemes2,phonemes);
|
||||
if(last_char == 'f')
|
||||
TranslateRules(&word_ss[1], phonemes, N_WORD_PHONEMES, NULL, 0, 0);
|
||||
else
|
||||
if(strchr_w("hsx",last_char)==NULL)
|
||||
if((last_char==0) || (strchr_w("hsx",last_char)==NULL))
|
||||
TranslateRules(&word_zz[1], phonemes, N_WORD_PHONEMES, NULL, 0, 0);
|
||||
else
|
||||
TranslateRules(&word_iz[1], phonemes, N_WORD_PHONEMES, NULL, 0, 0);
|
||||
|
||||
+4
-4
@@ -396,9 +396,9 @@ static void VoiceFormant(char *p)
|
||||
// Set parameters for a formant
|
||||
int ix;
|
||||
int formant;
|
||||
int freq = -1;
|
||||
int height = -1;
|
||||
int width = -1;
|
||||
int freq = 100;
|
||||
int height = 100;
|
||||
int width = 100;
|
||||
|
||||
ix = sscanf(p,"%d %d %d %d",&formant,&freq,&height,&width);
|
||||
if(ix < 2)
|
||||
@@ -713,7 +713,7 @@ voice_t *LoadVoice(const char *vname, int control)
|
||||
{
|
||||
while(isspace(*p)) p++;
|
||||
n = -1;
|
||||
if((n = atoi(p)) > 0)
|
||||
if(((n = atoi(p)) > 0) && (n < 32))
|
||||
{
|
||||
p++;
|
||||
conditional_rules |= (1 << n);
|
||||
|
||||
+7
-4
@@ -817,6 +817,9 @@ static void WavegenSetEcho(void)
|
||||
amp = embedded_value[EMBED_H];
|
||||
delay = 130;
|
||||
}
|
||||
|
||||
if(delay == 0)
|
||||
amp = 0;
|
||||
echo_head = (delay * samplerate)/1000;
|
||||
echo_amp = amp;
|
||||
// compensate (partially) for increase in amplitude due to echo
|
||||
@@ -893,7 +896,7 @@ int PeaksToHarmspect(wavegen_peaks_t *peaks, int pitch, int *htab, int control)
|
||||
{
|
||||
peak_harmonic[pk] = peaks[pk].freq / pitch;
|
||||
x = peaks[pk].height >> 14;
|
||||
peak_height[pk] = x * x * 5;
|
||||
peak_height[pk] = (x * x * 5)/2;
|
||||
|
||||
// only use harmonics up to half the samplerate
|
||||
if(peak_harmonic[pk] >= hmax_samplerate)
|
||||
@@ -905,7 +908,7 @@ int PeaksToHarmspect(wavegen_peaks_t *peaks, int pitch, int *htab, int control)
|
||||
for(h=0; h<=hmax; h++, f+=pitch)
|
||||
{
|
||||
x = htab[h] >> 15;
|
||||
htab[h] = (x * x) >> 7;
|
||||
htab[h] = (x * x) >> 8;
|
||||
|
||||
if((ix = (f >> 19)) < N_TONE_ADJUST)
|
||||
{
|
||||
@@ -1134,7 +1137,7 @@ static int Wavegen()
|
||||
maxh2 = PeaksToHarmspect(peaks,pitch<<4,hspect[0],0);
|
||||
|
||||
// adjust amplitude to compensate for fewer harmonics at higher pitch
|
||||
amplitude2 = (amplitude * pitch)/(100 << 12);
|
||||
amplitude2 = (amplitude * pitch)/(100 << 11);
|
||||
|
||||
// switch sign of harmonics above about 900Hz, to reduce max peak amplitude
|
||||
h_switch_sign = 890 / (pitch >> 12);
|
||||
@@ -1181,7 +1184,7 @@ static int Wavegen()
|
||||
cycle_count++;
|
||||
|
||||
// adjust amplitude to compensate for fewer harmonics at higher pitch
|
||||
amplitude2 = (amplitude * pitch)/(100 << 12);
|
||||
amplitude2 = (amplitude * pitch)/(100 << 11);
|
||||
|
||||
if(glottal_flag > 0)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user