TranslateWord2 uses phonemes in ph_list2. Apart from the breakable loops, it
may statically require up to 7 phonemes. Then TranslateClause always
uses 2 phonemes. We thus have to keep these margins along the loops to
avoid any overflow.
Fixes #1073
Valgrind reports:
==3642987== Conditional jump or move depends on uninitialised value(s)
==3642987== at 0x491F268: TranslateNumber_1 (numbers.c:1785)
==3642987== by 0x4923C35: TranslateNumber (numbers.c:2080)
==3642987== by 0x49556DC: TranslateWord3 (translate.c:644)
==3642987== by 0x4957FCE: TranslateWord (translate.c:1100)
==3642987== by 0x4959344: TranslateWord2 (translate.c:1361)
==3642987== by 0x496116E: TranslateClause (translate.c:2613)
==3642987== by 0x494FF7A: SpeakNextClause (synthesize.c:1569)
==3642987== by 0x4939B9D: Synthesize (speech.c:457)
==3642987== by 0x493AE6A: sync_espeak_Synth (speech.c:570)
==3642987== by 0x493B286: espeak_ng_Synthesize (speech.c:678)
==3642987== by 0x4916925: espeak_Synth (espeak_api.c:90)
==3642987== by 0x10CF5D: main (espeak-ng.c:691)
==3642987== Uninitialised value was created by a stack allocation
==3642987== at 0x495BD9F: TranslateClause (translate.c:1941)
Indeed, TranslateNumber_1 looks back up to three bytes before, with
IsDigit09(word[-3])), so we have to increase the heading margin to three
spaces.
valgrind reports
==3632264== Conditional jump or move depends on uninitialised value(s)
==3632264== at 0x4846688: strcmp (vg_replace_strmem.c:924)
==3632264== by 0x490EC12: LookupDictList (dictionary.c:2889)
==3632264== by 0x49554C6: TranslateWord3 (translate.c:588)
==3632264== by 0x4957FCE: TranslateWord (translate.c:1100)
==3632264== by 0x4959344: TranslateWord2 (translate.c:1361)
==3632264== by 0x4961390: TranslateClause (translate.c:2621)
==3632264== by 0x494FF7A: SpeakNextClause (synthesize.c:1569)
==3632264== by 0x4939B9D: Synthesize (speech.c:457)
==3632264== by 0x493AE6A: sync_espeak_Synth (speech.c:570)
==3632264== by 0x493B286: espeak_ng_Synthesize (speech.c:678)
==3632264== by 0x4916925: espeak_Synth (espeak_api.c:90)
==3632264== by 0x10CF5D: main (espeak-ng.c:691)
And indeed tr->phonemes_repeat may not necessarily be initialized.
shifting negative integers has an undefined behavior, so we have to
avoid it entirely. Using * 256 and / 256 provides the expected behavior
while being correctly optimized by the compiler.
event_notify currently introduces an arbitrary 50ms delay between speech
requests. This is usually unnoticed since it's small. But when
cancelling a long series of events, they add up to potentially seconds
of delays, while the user was precisely requesting to just cancel
everything as fast as possible.
This 50ms delay was probably meant to work around some issues elsewhere.
If they are still there, they should be fixed, not worked around.
compiledict.c: change 'temp' to "${dict}temp" temporary file
This way we can compile multiple dictionaries at a time without
stepping on 'temp' file from different compilation steps:
$ make -j8 -B
...
make[1]: *** [Makefile:3082: espeak-ng-data/an_dict] Segmentation fault (core dumped)
make[1]: *** Deleting file 'espeak-ng-data/an_dict'
make[1]: *** [Makefile:3082: espeak-ng-data/az_dict] Segmentation fault (core dumped)
make[1]: *** Deleting file 'espeak-ng-data/az_dict'
Use ESPEAKNG_DEFAULT_VOICE instead of hard coded "en".
This will make it easier to set a default voice other than
English. This is important for cases when a language will fall back to
the default voice.
Some references to L('e', 'n') still need to be changed.
Found by parsing the results from this bash script:
for define in $(grep define *.h | awk'{print $2}');
do if ! grep -q $define *.c
then
echo "$define not found";
fi
done
code cleanup: don't add a \0 to voices_language in LoadVoice().
This is unnecessary since the string is already null terminated in the
V_LANGUAGE switch case. sscanf creates a null terminated string in
language_name, which is then copied to voice_language by strcpy (keeping
the \0).
It's probably unnecessary code and could be removed. However, it would
break tests. This is a temporary solution.
The solution is to do it once in VoiceReset() and then if the "formant"
keyword changes voice->width.
When a language or voice file in espeak-ng-data is loaded the keyword
"translator" must be set so that other language options can modify the
values in struct Translator.
CheckTranslator() provides standardized error for all switch cases that
modify a value in struct Translator.
code cleanup: move stressLength, stressAdd and stressAmp handling in LoadVoice()
From now on, stressLength must be set before stressAdd because
stressLength will overwrite any previous value. Usually stressLength is
set in a language file and stressAdd in a voice file.
Previously the order of the two commands didn't matter.
code cleanup: remove unnecessary new_translator in LoadVoice()
It looks like this was used in situations where both "language" and
"translator" voice options were found. Since bda8b6f76a "translator"
hasn't been supported.