[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:
jonsd
2007-10-01 09:26:33 +00:00
parent 5671a4bd93
commit ca61663045
28 changed files with 128 additions and 137 deletions
+1 -48
View File
@@ -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
View File
@@ -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)
-5
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
{