These are global arrays reused several times. When using them msan and
valgrind thus believe they are always initialized, which reduces their
capacity to detect uninitialized values. We can however explicitly tell them
when they are reused, and thus to be considered as uninitialized.
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.
Soundicons are used for external audio with SSML <audio> tag and for
replacing punctuation names with sound files in LoadConfig().
Currently there's a bug wih soundicon slots: if both LoadConfig and
<audio> are used, the punctuation reserves all slots and no sound from
<audio> is played.
Espeak-ng uses bitrate 16 internally. If the input inside <audio> has a
different bitrate the audio will not play correctly unless converted to
16 bits.
Closes #885.
It is supposed to be used with SSML for reading < (<) and & (&)
when invoking espeak-ng --punct -m.
However, it looks like the code is dead since removing it doesn't fail
the ssml reference test.
code cleanup: remove unnecessary current_voice_id in readclause.c
Instead of passing a temporary variable current_voice_id to SSML
processing logic and then copying the value to voice_change, pass
voice_change directly. GetVoiceAttributes() both sets voice_change and
retuns CLAUSE_TYPE_VOICE_CHANGE that is used by TranslateClause() for
error checking.
tests/ssml/language-switch.ssml covers the intended behavior of language
switching and will fail when either voice_change or CLAUSE_TYPE_VOICE_CHANGE
is not set correctly.
code cleanup: reorganize check for u.s.a.'s in int ReadClause()
This approach reduces the amount of nested if statements and doesn't
require the temporary variable int c_next_2.
A test already exists for this case in tests/translate.test
code cleanup: move check for SSML comments and declarations to
ProcessSsmlTag()
Note the line in readclause.c:
if ((c2 == '/') || iswalpha(c2) || c2 == '!' || c2 == '?') {
It might be enough to pass everything to ProcessSsmlTag. What are the
cases that are skipped because of this?
code cleanup: Move self_closing checks to ProcessSsmlTag()
This is a bit slower since we don't pass n_xml_buf as an argument but
rather get it with a call to wcslen. It is much cleaner though, since
the name ProcessSsmlTag() implies that all processing should be done
there.
code cleanup: Check all local includes with include-what-you-use
Going through files in src/libespeak-ng/, include-what-you-use removed a
few unnecessary includes and included explanations on why a certain
header should be included. This makes tracking globals and dependencies easier.
Running the codebase through IWYU should be repeated after each major
code restIncludes to standard c library weren't checked to avoid
breaking builds with other platforms.
See https://github.com/include-what-you-use/include-what-you-use
SetVoiceStack looks for "!v" in variant_name and skips the first
three characters if "!v" is found. The problem here is that it
does not check that the third character is the path separator, so
may advance into unknown memory if variant_name is exactly "!v".
This fixes that problem by checking for the path separator. It
also simplifies the logic by checking the bytes explicitly.
NOTE: This is not strictly needed, as the only code paths this is
relevant for is in espeak_ng_SetVoiceByName, and the variant name
comes from ExtractVoiceVariantName, which sets up the variant name
correctly.
Compare variant_name with "!v" only if long enough
Various places call SetVoiceStack with "" for the variant_name. This
causes -fsanitize=address to fail with an overflow as the call to
memcmp is checking the first 2 bytes, and there is only 1 byte
available.