@@ -16,27 +16,27 @@ jobs: | |||
strategy: | |||
fail-fast: false | |||
matrix: | |||
arch: [x86-32, x86-64] | |||
arch: [x86-64, x86-32] | |||
sanitizer: [no, address, leak, memory, thread, undefined, valgrind] | |||
include: | |||
- sanitizer: "no" | |||
deps: "" | |||
configflags: "" | |||
configflags: "-g -Og -fno-omit-frame-pointer" | |||
config: "" | |||
build_env: "" | |||
check_env: "" | |||
- sanitizer: "address" | |||
deps: "" | |||
configflags: "-fsanitize=address -g -Og" | |||
configflags: "-fsanitize=address -g -Og -fno-omit-frame-pointer" | |||
config: "" | |||
build_env: "ASAN_OPTIONS=detect_leaks=0" | |||
check_env: "ASAN_OPTIONS=detect_leaks=0" | |||
- sanitizer: "leak" | |||
deps: "" | |||
configflags: '-fsanitize=leak -g -Og' | |||
configflags: '-fsanitize=leak -g -Og -fno-omit-frame-pointer' | |||
config: "" | |||
build_env: "LSAN_OPTIONS=fast_unwind_on_malloc=0" | |||
check_env: "LSAN_OPTIONS=fast_unwind_on_malloc=0" | |||
@@ -44,28 +44,28 @@ jobs: | |||
- sanitizer: "memory" | |||
deps: "clang" | |||
configenv: "CC=clang CXX=clang++" | |||
configflags: "-fsanitize=memory -fsanitize-memory-track-origins=2 -g -Og" | |||
configflags: "-fsanitize=memory -fsanitize-memory-track-origins=2 -g -Og -fno-omit-frame-pointer" | |||
config: "--without-pcaudiolib" | |||
build_env: "MSAN_OPTIONS=exitcode=42" | |||
check_env: "MSAN_OPTIONS=exitcode=42" | |||
- sanitizer: "thread" | |||
deps: "" | |||
configflags: "-fsanitize=thread -g -Og" | |||
configflags: "-fsanitize=thread -g -Og -fno-omit-frame-pointer" | |||
config: "" | |||
build_env: "" | |||
check_env: "" | |||
- sanitizer: "undefined" | |||
deps: "" | |||
configflags: "-fsanitize=undefined -g -Og" | |||
configflags: "-fsanitize=undefined -g -Og -fno-omit-frame-pointer" | |||
config: "" | |||
build_env: "UBSAN_OPTIONS=halt_on_error=1" | |||
check_env: "UBSAN_OPTIONS=halt_on_error=1" | |||
- sanitizer: "valgrind" | |||
deps: "libtool-bin valgrind" | |||
configflags: '' | |||
configflags: '-g -Og -fno-omit-frame-pointer' | |||
config: "" | |||
build_env: 'VALGRIND="libtool --mode=execute valgrind --track-origins=yes --leak-check=full --error-exitcode=1" ' | |||
check_env: 'VALGRIND="libtool --mode=execute valgrind --track-origins=yes --leak-check=full --error-exitcode=1" ' | |||
@@ -119,7 +119,7 @@ jobs: | |||
strategy: | |||
fail-fast: false | |||
matrix: | |||
arch: [x86-32, x86-64] | |||
arch: [x86-64, x86-32] | |||
include: | |||
- arch: x86-32 | |||
@@ -140,7 +140,7 @@ jobs: | |||
- name: autoconf | |||
run: ./autogen.sh ; chmod -x INSTALL m4/*.m4 | |||
- name: run | |||
run: reprotest 'CFLAGS="${{ matrix.archconfigflags }}" CXXFLAGS="${{ matrix.archconfigflags }}" ./configure && make clean && make && make check && touch success' success | |||
run: reprotest 'CFLAGS="${{ matrix.archconfigflags }}" CXXFLAGS="${{ matrix.archconfigflags }}" ./configure --without-gradle && make clean && make && make check && touch success' success | |||
distcheck: | |||
@@ -0,0 +1,64 @@ | |||
name: fuzzing | |||
on: | |||
workflow_dispatch: | |||
schedule: | |||
- cron: "0 4 * * 1" | |||
jobs: | |||
fuzzing: | |||
runs-on: ubuntu-latest | |||
name: Fuzz synth_espeak on ${{ matrix.arch }} for ${{ matrix.lang }} | |||
strategy: | |||
fail-fast: false | |||
matrix: | |||
arch: [x86-64, x86-32] | |||
lang: [af, am, an, ar, as, az, ba, be, bg, bn, bpy, bs, ca, chr, cmn, cs, cv, cy, da, de, el, en, eo, es, et, eu, fa, fi, fr, ga, gd, gn, grc, gu, hak, haw, he, hi, hr, ht, hu, hy, ia, id, io, is, it, ja, jbo, ka, kk, kl, kn, ko, kok, ku, ky, la, lb, lfn, lt, lv, mi, mk, ml, mr, ms, mt, my, nci, ne, nl, no, nog, om, or, pa, pap, piqd, pl, pt, py, qdb, qu, quc, qya, ro, ru, sd, shn, si, sjn, sk, sl, smj, sq, sr, sv, sw, ta, te, th, tk, tn, tr, tt, ug, uk, ur, uz, vi, yue] | |||
include: | |||
- arch: x86-32 | |||
archdeps: "gcc-multilib g++-multilib libpcaudio-dev:i386 libsonic-dev:i386 libc6-dbg:i386" | |||
archconfigflags: "-m32" | |||
- arch: x86-64 | |||
archdeps: "" | |||
archconfigflags: '' | |||
steps: | |||
- uses: actions/checkout@v2 | |||
- name: enable 32bit architecture | |||
run: sudo dpkg --add-architecture i386 | |||
if: matrix.arch == 'x86-32' | |||
- name: dependencies | |||
run: sudo apt-get update && sudo apt-get install libpcaudio-dev libsonic-dev ronn kramdown clang llvm ${{ matrix.archdeps }} | |||
- name: autoconf | |||
run: ./autogen.sh ; chmod -x INSTALL m4/*.m4 | |||
- name: configure | |||
run: CC=clang CXX=clang++ | |||
CFLAGS="${{ matrix.archconfigflags }} -fsanitize=address,undefined -fstack-protector-strong -g -Og -fno-omit-frame-pointer" | |||
CXXFLAGS="${{ matrix.archconfigflags }} -fsanitize=address,undefined -fstack-protector-strong -g -Og -fno-omit-frame-pointer" | |||
LDFLAGS="-fsanitize=address,undefined -lubsan" | |||
./configure --with-libfuzzer | |||
- name: Store the fuzzer config | |||
if: ${{ failure() }} | |||
uses: actions/upload-artifact@v2 | |||
with: | |||
name: config-${{ matrix.arch }}-${{ matrix.lang }}.log | |||
path: config.log | |||
- name: make | |||
run: make -j | |||
- name: Fuzz function synth_espeak() | |||
run: mkdir tests/fuzzing/CORPUS_DIR ; FUZZ_VOICE=${{ matrix.lang }} tests/fuzzing/synth_fuzzer.test -seed=1 -runs=10000 -max_len=4096 tests/fuzzing/CORPUS_DIR | |||
- name: Store the crash POC | |||
if: ${{ failure() }} | |||
uses: actions/upload-artifact@v2 | |||
with: | |||
name: crash-${{ matrix.arch }}-${{ matrix.lang }}.1 | |||
path: crash-* | |||
- name: Fuzz function synth_espeak() with language-specific input | |||
run: cp dictsource/${{ matrix.lang }}_* tests/fuzzing/CORPUS_DIR/ ; FUZZ_VOICE=${{ matrix.lang }} tests/fuzzing/synth_fuzzer.test -seed=1 -runs=10000 -max_len=4096 tests/fuzzing/CORPUS_DIR | |||
- name: Store the crash POC | |||
if: ${{ failure() }} | |||
uses: actions/upload-artifact@v2 | |||
with: | |||
name: crash-${{ matrix.arch }}-${{ matrix.lang }}.2 | |||
path: crash-* |
@@ -123,10 +123,19 @@ espeak-ng.pc | |||
espeak-ng-*.tar.gz | |||
espeak-ng-*.*/ | |||
# /tests/fuzzing/ | |||
/tests/fuzzing/crash-* | |||
/tests/fuzzing/oom-* | |||
/tests/fuzzing/leak-* | |||
/tests/fuzzing/fuzz-*.log | |||
/tests/fuzzing/*.profdata | |||
/tests/fuzzing/*.profraw | |||
/tests/fuzzing/.deps/*.Po | |||
/tests/fuzzing/.dirstamp | |||
!tests/fuzzing/CORPUS*/*.txt | |||
# Windows builds | |||
src/pcaudiolib/ | |||
!src/windows/config.h | |||
*.obj |
@@ -10,9 +10,20 @@ The espeak-ng project is a fork of the espeak project. | |||
### 1.52 (In Development) | |||
updated languages: | |||
* ba (Bashkir) -- Andiv06 | |||
* be (Belarusian) -- Andiv06 | |||
* en (English) -- Bill Dengler | |||
* es (Spanish) -- Sukil Etxenike | |||
* fa (Persian) -- MH | |||
* he (Hebrew) -- Omer I.S | |||
* it (Italian) -- Christian Leo Mameli | |||
* ro (Romanian) -- Andiv06 | |||
* be (Belarusian) -- Andiv06 | |||
* en (English) -- Bill Dengler | |||
* es (Spanish) -- Sukil Etxenike | |||
* kl (Greenlandic) -- Andiv06 | |||
* qdb (Lang Belta) -- Andiv06 | |||
* quc (K'iche') -- Andiv06 | |||
### 1.51 | |||
@@ -18,6 +18,12 @@ MKDIR=mkdir -p | |||
AM_CFLAGS = \ | |||
-Isrc/include -Isrc/include/compat -I$(srcdir)/src/speechPlayer/include -I$(srcdir)/src/ucd-tools/src/include \ | |||
-D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112L | |||
AM_CXXFLAGS = | |||
if USE_COVERAGE | |||
AM_CFLAGS += -fprofile-instr-generate -fcoverage-mapping | |||
AM_CXXFLAGS += -fprofile-instr-generate -fcoverage-mapping | |||
endif | |||
EXTRA_DIST= | |||
CLEANFILES = dictsource/ru_listx dictsource/cmn_listx dictsource/yue_listx | |||
@@ -321,6 +327,8 @@ tests_libfuzzrunner_la_CFLAGS = -Isrc/libespeak-ng ${AM_CFLAGS} | |||
tests_libfuzzrunner_la_SOURCES = tests/fuzzrunner.c | |||
endif | |||
check_PROGRAMS += tests/ssml-fuzzer.test | |||
tests_ssml_fuzzer_test_CFLAGS = ${AM_CFLAGS} | |||
tests_ssml_fuzzer_test_SOURCES = tests/ssml-fuzzer.c | |||
@@ -333,9 +341,16 @@ tests_readclause_test_SOURCES += tests/dummy.cpp | |||
tests_ssml_fuzzer_test_SOURCES += tests/dummy.cpp | |||
endif | |||
if HAVE_LIBFUZZER | |||
tests_ssml_fuzzer_test_CFLAGS += -fsanitize=fuzzer | |||
tests_ssml_fuzzer_test_LDFLAGS = -fsanitize=fuzzer | |||
noinst_PROGRAMS = tests/fuzzing/synth_fuzzer.test | |||
tests_fuzzing_synth_fuzzer_test_SOURCES = tests/fuzzing/synth_fuzzer.c | |||
tests_fuzzing_synth_fuzzer_test_LDADD = src/libespeak-ng.la | |||
tests_fuzzing_synth_fuzzer_test_CFLAGS= ${AM_CFLAGS} -fsanitize=fuzzer -DPATH_ESPEAK_DATA=\"$(abs_top_srcdir)/espeak-ng-data\" -Isrc/libespeak-ng | |||
tests_fuzzing_synth_fuzzer_test_LDFLAGS= ${AM_LDFLAGS} -fsanitize=fuzzer -static -lm -Wl,-z,relro ${PCAUDIOLIB_LIBS} | |||
else | |||
tests_ssml_fuzzer_test_LDADD += tests/libfuzzrunner.la | |||
endif | |||
@@ -488,6 +503,7 @@ dictionaries: \ | |||
espeak-ng-data/mr_dict \ | |||
espeak-ng-data/ms_dict \ | |||
espeak-ng-data/mt_dict \ | |||
espeak-ng-data/mto_dict \ | |||
espeak-ng-data/my_dict \ | |||
espeak-ng-data/nci_dict \ | |||
espeak-ng-data/ne_dict \ | |||
@@ -750,6 +766,9 @@ espeak-ng-data/ms_dict: dictsource/ms_list dictsource/ms_rules dictsource/ms_ext | |||
mt: espeak-ng-data/mt_dict | |||
espeak-ng-data/mt_dict: dictsource/mt_list dictsource/mt_rules dictsource/mt_extra | |||
mto: espeak-ng-data/mto_dict | |||
espeak-ng-data/mto_dict: dictsource/mto_list dictsource/mto_rules | |||
my: espeak-ng-data/my_dict | |||
espeak-ng-data/my_dict: dictsource/my_list dictsource/my_rules dictsource/my_extra dictsource/my_emoji | |||
@@ -70,7 +70,7 @@ android { | |||
defaultConfig { | |||
minSdkVersion 14 | |||
targetSdkVersion 26 | |||
versionCode 20 | |||
versionCode 22 | |||
versionName "1.52-dev" | |||
} | |||
@@ -64,6 +64,10 @@ AC_ARG_WITH([libfuzzer], | |||
[AS_HELP_STRING([--with-libfuzzer], [enable libFuzzer in the fuzzer tests @<:@default=no@:>@])], | |||
[]) | |||
AC_ARG_WITH([coverage], | |||
[AS_HELP_STRING([--with-coverage], [enable clang coverage in the fuzzer tests (also add coverage to lib sources) @<:@default=no@:>@])], | |||
[]) | |||
dnl ================================================================ | |||
dnl Program checks. | |||
dnl ================================================================ | |||
@@ -79,13 +83,13 @@ dnl gradle checks. | |||
dnl ================================================================ | |||
AC_MSG_CHECKING([for gradle]) | |||
if test -e ${GRADLE} ; then | |||
AC_MSG_RESULT([${GRADLE}]) | |||
AM_CONDITIONAL(HAVE_GRADLE, [test 1 = 1]) | |||
if command -v "$GRADLE" >/dev/null; then | |||
AC_MSG_RESULT([$GRADLE]) | |||
else | |||
GRADLE= | |||
AC_MSG_RESULT([no]) | |||
AM_CONDITIONAL(HAVE_GRADLE, [test 1 = 0]) | |||
fi | |||
AM_CONDITIONAL(HAVE_GRADLE, [test x"$GRADLE" != x]) | |||
AC_SUBST(GRADLE) | |||
@@ -131,6 +135,19 @@ else | |||
AC_MSG_ERROR([C99 is not supported by $CC.]) | |||
fi | |||
AC_LANG_PUSH(C) | |||
TEMP_CFLAGS="$CFLAGS" | |||
CFLAGS="$CFLAGS -fsanitize=fuzzer" | |||
AC_MSG_CHECKING([if $CC supports fuzzer with the -fsanitize=fuzzer flag]) | |||
AC_COMPILE_IFELSE( | |||
[AC_LANG_PROGRAM( [[]], [[]])], | |||
[have_fuzzer_fuzzer=yes], | |||
[have_fuzzer_fuzzer=no]) | |||
AC_MSG_RESULT($have_fuzzer_fuzzer) | |||
CFLAGS="$TEMP_CFLAGS" | |||
AC_LANG_POP(C) | |||
dnl ================================================================ | |||
dnl FreeBSD check. | |||
dnl ================================================================ | |||
@@ -330,7 +347,19 @@ else | |||
have_libfuzzer=no | |||
fi | |||
AM_CONDITIONAL(HAVE_LIBFUZZER, [test x"$have_libfuzzer" = xyes]) | |||
AM_CONDITIONAL(HAVE_LIBFUZZER, [test x"$have_libfuzzer" = xyes -a x"$have_fuzzer_fuzzer" = xyes]) | |||
dnl ================================================================ | |||
dnl clang-coverage checks. | |||
dnl ================================================================ | |||
if test "$with_coverage" = "yes" ; then | |||
use_coverage=yes | |||
else | |||
use_coverage=no | |||
fi | |||
AM_CONDITIONAL(USE_COVERAGE, [test x"$use_coverage" = xyes]) | |||
dnl ================================================================ | |||
dnl Generate output. |
@@ -49,32 +49,23 @@ | |||
_0 n'ul? | |||
_1 b'er | |||
_2 ik'e | |||
_3 'WS; | |||
_3 'Ws | |||
_4 d'yrt | |||
_5 b'iS | |||
_6 Alt'V | |||
_7 Z;id'e | |||
_8 sig'ez | |||
_9 tug'Vz | |||
_10 'un | |||
_11 unb'er | |||
_12 unik'e | |||
_13 un'WS; | |||
_14 und'yrt | |||
_15 unb'iS | |||
_16 unAlt'V | |||
_17 unZ;id'e | |||
_18 unsig'ez | |||
_19 untug'Vz | |||
_7 et'e | |||
_8 hig'eD | |||
_9 tug'VD | |||
_1X 'un | |||
_2X egerm'e | |||
_3X ut'Vz | |||
_4X kVr'Vk | |||
_3X ut'VD | |||
_4X qVr'q | |||
_5X ill'e | |||
_6X Altm'VS | |||
_7X Z;itm'eS | |||
_8X siks'&n | |||
_9X tuks'An | |||
_0C j'Wz | |||
_7X etm'eS | |||
_8X hikh'&n | |||
_9X tukh'An | |||
_0C j'WD | |||
_0M1 m'eN | |||
_0M2 milli'on | |||
_1M2 milli'on |
@@ -45,10 +45,10 @@ _4 ts.ati"ri" | |||
_5 p;at; | |||
_6 s.Es;t; | |||
_7 s;Em | |||
_8 vOs;jEm | |||
_9 dz;Ev;at; | |||
_10 dz;Es;at; | |||
_11 adz;inats:at; | |||
_8 vOs;E2m | |||
_9 d;Ev;at; | |||
_10 d;Es;at; | |||
_11 ad;inats:at; | |||
_12 dvanats:at; | |||
_13 tri"nats:at; | |||
_14 ts.ati"rnats:at; | |||
@@ -56,7 +56,7 @@ _15 p;atnats:at; | |||
_16 s.asnats:at; | |||
_17 s;amnats:at; | |||
_18 vas;amnats:at; | |||
_19 dz;Ev;atnats:at; | |||
_19 d;Ev;atnats:at; | |||
_2X dvats:at; | |||
_3X tri"ts:at; | |||
_4X sorak |
@@ -1129,6 +1129,7 @@ blurry bl3:ri | |||
boardmember $1 | |||
bobsled $alt1 | |||
boing bOIN | |||
boise 'bOIsi $only | |||
bologna b@loUni | |||
bolognese b0l@n'eIz | |||
bombard $2 | |||
@@ -2295,6 +2296,7 @@ irises aIrIsI#z | |||
iron aI3n | |||
isochronous aIs'0kr@n@s | |||
isosceles aIs'0s@li:z | |||
issaquah 'Is@kwA: | |||
?3 issuance ISu:@ns | |||
invalidity I2nv@lIdI#ti | |||
@@ -3034,6 +3036,7 @@ psychosis saIk'oUsIs | |||
psychotic saIk'0tIk | |||
pud pUd // and pudding | |||
pueblo pwEbloU | |||
puget pju:dZIt | |||
punative pju:n@tIv | |||
puny pju:ni | |||
purist pjU@Ist | |||
@@ -3258,6 +3261,7 @@ saliva s@laIv@ | |||
salmon sam@n | |||
?3 salon $alt3 | |||
saloon $alt3 | |||
sammamish s@'m'amIS | |||
san ,san $only | |||
sanguine $alt2 | |||
santoor $alt3 | |||
@@ -3403,6 +3407,7 @@ slough slVf $verb | |||
slugabed slVg@bEd | |||
snafu snafu: | |||
snafus snafu:z | |||
snohomish snoU'hoUmIS | |||
snooker snu:k3 | |||
sociopath soUsI@paT | |||
sofa soUf@ |
@@ -335,7 +335,7 @@ Uds ustedes $text $capital $dot | |||
// pronunciation exceptions | |||
ser s'e@-* $only // it's not a abbrev | |||
vilmente $1 | |||
deprimente $3 | |||
depri $u $stem | |||
// Proper Names and countries | |||
amsterdam $3 | |||
bardem $2 |
@@ -3,32 +3,47 @@ | |||
בּ bet | |||
ב vet | |||
ג 'gimel | |||
גּ 'gimel | |||
ד 'dalet | |||
דּ 'dalet | |||
ה he | |||
ו vav | |||
ז 'zajin | |||
זּ 'zajin | |||
ח Xet | |||
ט tet | |||
טּ tet | |||
י jod | |||
יּ jod | |||
כּ kaf | |||
כ Xaf | |||
ךּ kaf sofit | |||
ך Xaf sofit | |||
ךּ kaf so'fit | |||
ך kaf so'fit | |||
ל 'lamed | |||
לּ 'lamed | |||
מ mem | |||
ם mem sofit | |||
מּ mem | |||
ם mem so'fit | |||
נ nun | |||
ן nun sofit | |||
נּ nun | |||
ן nun so'fit | |||
ס 'sameX | |||
סּ 'sameX | |||
ע ?ajin | |||
פּ pe | |||
פ fe | |||
ף pe sofit | |||
צ 'tsadi | |||
צּ 'tsadi | |||
ץ 'tsadi sofit | |||
ק kof | |||
ר Q"eS | |||
ק kof | |||
קּ kof | |||
ר Q"ejS | |||
ש Sin | |||
שּ Sin | |||
שׁ Sin | |||
שּׁ Sin | |||
שׂ sin | |||
שּׂ sin | |||
תּ tav | |||
ת Tav | |||
ת tav |
@@ -9,8 +9,8 @@ | |||
בדיקה bdi'ka | |||
אנגלית ang'lit | |||
אני a'ni | |||
הוא hu | |||
היא hi | |||
הוא hu | |||
הם hem | |||
(את רוצה) at||Q"o'tsa | |||
באנגלית be?ang'lit | |||
@@ -135,3 +135,6 @@ | |||
אמת e'met | |||
נכון na'Xon | |||
ישר ja'SaQ" | |||
בה ba | |||
תה te | |||
שה se |
@@ -17,6 +17,7 @@ | |||
אוּי ui | |||
אָ o | |||
אָ a | |||
אה a | |||
.group ב | |||
ב v | |||
@@ -41,19 +42,34 @@ | |||
בּוּ bu | |||
בׇּ bo | |||
בָּ ba | |||
בה va | |||
.group ג | |||
ג g | |||
גּ g | |||
גַ ga | |||
גַּ ga | |||
גֵ ge | |||
גֵּ ge | |||
גֶ ge | |||
גֶּ ge | |||
גְ g | |||
גְּ g | |||
גִ gi | |||
גִּ gi | |||
גוֹ go | |||
גּוֹ go | |||
גי gi | |||
גִּי gi | |||
גוּ gu | |||
גּוּ gu | |||
גֻ gu | |||
גֻּ gu | |||
גׇ go | |||
גׇּ go | |||
גָ ga | |||
גָּ ga | |||
גה ga | |||
ג' dZ | |||
גַ' dZa | |||
גֵ' dZe | |||
@@ -76,6 +92,8 @@ | |||
דוֹ do | |||
די di | |||
דוּ du | |||
דו du | |||
דה da | |||
דׇ do | |||
דָ da | |||
דּ d | |||
@@ -92,17 +110,19 @@ | |||
דָ' Da | |||
.group ה | |||
ה ? | |||
הַ a | |||
הֵ e | |||
הֶ e | |||
ה h | |||
הַ ha | |||
הֵ he | |||
הֶ he | |||
הֱ he | |||
הְ h | |||
הִ i | |||
הוֹ o | |||
הי i | |||
הוּ u | |||
הׇ o | |||
הָ a | |||
הִ hi | |||
הוֹ ho | |||
הי hi | |||
הוּ hu | |||
הׇ ho | |||
הָ ha | |||
הּ h | |||
.group ו | |||
ו v | |||
@@ -148,6 +168,7 @@ | |||
חוּ Xu | |||
חׇ Xo | |||
חָ Xa | |||
חה Xa | |||
.group ט | |||
ט t | |||
@@ -161,6 +182,7 @@ | |||
טוּ tu | |||
טׇ to | |||
טָ ta | |||
טה ta | |||
.group י | |||
י j | |||
@@ -195,6 +217,8 @@ | |||
ך X | |||
ךָ Xa | |||
ךְ X | |||
ךָּ ka | |||
ךְּ k | |||
.group ל | |||
ל l | |||
@@ -208,6 +232,7 @@ | |||
לוּ lu | |||
לׇ lo | |||
לָ la | |||
לה la | |||
.group מ | |||
מ m | |||
@@ -221,6 +246,7 @@ | |||
מוּ mu | |||
מׇ mo | |||
מָ ma | |||
מה ma | |||
.group ם | |||
ם m | |||
@@ -237,6 +263,7 @@ | |||
נוּ nu | |||
נׇ no | |||
נָ na | |||
נה na | |||
נג N | |||
.group ן | |||
@@ -254,11 +281,13 @@ | |||
סוּ su | |||
סׇ so | |||
סָ sa | |||
סה sa | |||
.group ע | |||
ע ? | |||
עַ aa | |||
עַי ai | |||
עיי ai | |||
עֵ e | |||
עֶ e | |||
עֶי ei | |||
@@ -271,6 +300,7 @@ | |||
עוּי ui | |||
עָ o | |||
עָ a | |||
עה a | |||
.group פ | |||
פ f | |||
@@ -298,6 +328,7 @@ | |||
.group ף | |||
ף f | |||
ףּ p | |||
.group צ | |||
צ ts | |||
@@ -309,6 +340,7 @@ | |||
צוֹ tso | |||
צי tsi | |||
צוּ tsu | |||
צה tsa | |||
צׇ tso | |||
צָ tsa | |||
צ' tS | |||
@@ -322,6 +354,7 @@ | |||
צ'וּ tSu | |||
צׇ' tSo | |||
צָ' tSa | |||
צ'ה tSa | |||
.group ץ | |||
ץ ts | |||
@@ -339,6 +372,7 @@ | |||
קוּ ku | |||
קׇ ko | |||
קָ ka | |||
קה ka | |||
.group ר | |||
ר Q" | |||
@@ -352,6 +386,7 @@ | |||
רוּ Q"u | |||
רׇ Q"o | |||
רָ Q"a | |||
רה Q"a | |||
.group ש | |||
ש S | |||
@@ -377,6 +412,7 @@ | |||
שׂוּ su | |||
שׇׂ so | |||
שָׂ sa | |||
שה Sa | |||
.group ת | |||
ת t | |||
@@ -402,6 +438,7 @@ | |||
ת'וּ Tu | |||
תׇ' To | |||
תָ' Ta | |||
תה ta | |||
.group ׇ | |||
ׇ o |
@@ -1,6 +1,6 @@ | |||
// This file is UTF-8 encoded | |||
// Updated 2021 December 22 by Christian Leo M, <llajta2012@gmail.com> | |||
// Updated 2022 april 30 by Christian Leo Mameli, <llajta2012ATgmail.com> | |||
// $alt change [e] or [o] in the stressed syllable to [E] or [O] | |||
// $alt2 change [E] or [O] in the stressed syllable to [e] or [o] | |||
@@ -740,7 +740,7 @@ abbiamo $u+ $verbf | |||
abbiate $u+ | |||
abbiano $1 $verbf | |||
avessi av'es:i $verbf | |||
avesse av'es:i $verbf | |||
avesse av'es:e $verbf | |||
avessimo $u+ $verbf | |||
aveste av'este $verbf | |||
avessero $u+ $verbf | |||
@@ -2343,6 +2343,7 @@ beatle b'i:tol | |||
beccaria $3 | |||
beethoven be:t'o:ven | |||
benetton $3 | |||
benjamin $1 | |||
bergomi $1 | |||
behringer b'e:RiNg,E@-* | |||
bertold $alt | |||
@@ -2367,6 +2368,7 @@ carey _^_en | |||
carmel $2 | |||
cassano $2 | |||
casula $2 | |||
catherine _^_EN | |||
catia k'a:tia | |||
celentano $3 | |||
cesare $1 | |||
@@ -2696,6 +2698,7 @@ vainer v'aIne@-* $only | |||
valeria $2 $alt2 | |||
valter $1 $onlys | |||
van $u $capital $only | |||
vanzetti vandz'Et:i | |||
vazquez vask'Ets | |||
vedder $1 $onlys | |||
vermouth v'E@-*mut | |||
@@ -3022,6 +3025,7 @@ avvalere $3 | |||
avvantaggiano $3 | |||
avvantaggino $3 | |||
avvelenino $3 | |||
avventurano $3 | |||
avver $2 | |||
avverano $2 | |||
avverino $2 | |||
@@ -3068,7 +3072,7 @@ boccino $1 | |||
boicottino $3 | |||
bombardano $2 | |||
bombardino $2 | |||
brahmano $1 | |||
bramano $1 | |||
bramino $1 | |||
brancolano $1 | |||
brancolino $1 | |||
@@ -4111,6 +4115,7 @@ preoccupano $2 | |||
preoccupino $2 | |||
preordin $2 | |||
preparano $2 | |||
prescegliere $2 | |||
presentino $2 | |||
presenziano $2 | |||
pressino $1 | |||
@@ -4132,9 +4137,10 @@ producano $2 | |||
profilano $2 | |||
programmano $2 | |||
proiettino $3 | |||
prolunghino $2 | |||
pronuncino $2 | |||
propinino $2 | |||
proponere $3 $alt | |||
proponere $3 $alt | |||
propugnano $2 | |||
prorogano $1 | |||
prosciughino $2 | |||
@@ -4194,7 +4200,7 @@ ravvedere $3 | |||
ravvisano $2 | |||
ravvisino $2 | |||
razziano $1 | |||
razziavano $3 | |||
razziavano $2 | |||
reagii @-*eadZ'i:j | |||
realizzino $3 | |||
recano $1 | |||
@@ -4442,6 +4448,8 @@ scannino $1 | |||
scantono $2 | |||
scappano $1 | |||
scappino $1 | |||
scarcer $1 | |||
scarcerano $1 | |||
scardin $1 | |||
scaricano $1 | |||
scarichino $1 | |||
@@ -5041,6 +5049,7 @@ dirigiti $2 | |||
disabilital $3 | |||
disconnettiti $3 | |||
disegnaci $2 | |||
dissolversi $2 | |||
distintasi $2 | |||
distintosi $2 | |||
domandatel $3 |
@@ -3783,6 +3783,7 @@ stereotip $3 | |||
stesicor $2 | |||
stigmate $1 | |||
stilobate $2 | |||
stipiti $1 | |||
stom $alt | |||
stomaci $1 | |||
stop $alt | |||
@@ -4045,6 +4046,7 @@ travesi $alt | |||
tre t@-*'e | |||
trenta $alt2 | |||
trebaseleghe $3 $alt2 | |||
treccine $2 | |||
tredicesim $alt | |||
tredici $alt2 | |||
tremil $2 |
@@ -28,10 +28,10 @@ z zE | |||
// ø | |||
// å | |||
// Native numbers 0-10 | |||
// Native numbers 0-20 | |||
_0n n'u:lu | |||
_1n at'a:sEq | |||
_2n m'arluk | |||
_1n at'a:s@q | |||
_2n m'arl#uk | |||
_3n p'iNasut | |||
_4n s'isamat | |||
_5n t'al#imat | |||
@@ -40,6 +40,16 @@ _7n arfinEqm'arluk | |||
_8n arfinEqp'iNasut | |||
_9n quliNil'uat | |||
_10n q'ulit | |||
_11n aqqanEq | |||
_12n aqqanEqm'arl#uk | |||
_13n aqqanEqp'iNasut | |||
_14n aqqanEqs'isamat | |||
_15n aqqanEqt'al#imat | |||
_16n arfErs'anil#it | |||
_17n arfErsanEqm'arl#uk | |||
_18n arfErsanEqp'iNasut | |||
_19n arfErsanEqs'isamat | |||
_20n inukn'a:l#uQu | |||
// Danish numbers | |||
_0 'nOl |
@@ -0,0 +1,214 @@ | |||
// This file is UTF8 encoded | |||
// letters | |||
_cap m'aJ^us | |||
_?? s'imbolo | |||
_#32 Esp'aTjo | |||
// accent names | |||
_lig liQaD'ura | |||
_acu aQ'uDo | |||
_ac2 d'oble||aQ'uDo | |||
_brv br'eBe | |||
_ced seD'iJ^a | |||
_cir sirkumfl'exo | |||
_dia dj'Eresis | |||
_dac d'oble||aQ'uDo | |||
_dot p'unto | |||
_grv gr'aBe | |||
_hac kar'on | |||
_mcn makr'on | |||
_ogo kol'ita | |||
_rng an'iJ^o | |||
_stk b'aRR2a | |||
_tld t'ilde | |||
_sup supE**'indiTe | |||
_sub suB'indiTe | |||
// names of symbols | |||
° grados | |||
_. punto | |||
_, koma | |||
_; p,untoik'oma | |||
_: d,osp'untos | |||
_! TERR2'araDmiraTj'on | |||
_? TERR2'arintERR2,oQaTj'on | |||
_¡ aBr'iraDmiraTj'on | |||
_¿ aBr'irintERR2,oQaTj'on | |||
_< men'orke | |||
_> maJ^'orke | |||
_' apostr'ofo | |||
ꞌ salt'il^o $only | |||
_" kom'iJ^as | |||
_- gJ^on | |||
__ suBraJ^'aDo | |||
_/ baRR2a | |||
_\ b'aRR2aimbErt'iDa | |||
_` aT'Ento||gr'aBe | |||
_´ aT'Ento||aQ'uDo | |||
_( ,aBrepar'Entesis | |||
_) Tj,ERR2apar'Entesis | |||
_[ ,aBrekortS'ete | |||
_] Tj,ERR2akortS'ete | |||
_{ ,aBreJ^'aBe | |||
_} Tj,ERR2aJ^'aBe | |||
_« kom'iJ^as||iTkJ^'ErDas | |||
_» kom'iJ^as||dEr'EtSas | |||
= iQw'al | |||
+ m'as | |||
# almoaD'iJ^a | |||
* astEr'isko | |||
. punto | |||
^ Tirkumfl'exo | |||
₠ 'eU*o | |||
€ eUro | |||
% porTj'Ento | |||
& ampErs'ant | |||
@ aRR2'oBa | |||
/ baRR2a | |||
© kopiRR2'aIt | |||
£ liBras | |||
¶ p'aRR2afo | |||
§ sEkTj'on | |||
¬ n'ot | |||
· p'unto||m'edjo | |||
// Language names | |||
_cyr Ti*'iliko_ | |||
_hy arm'enjo | |||
_he eB@-*'Eo | |||
_ar 'a*aBe | |||
_hi 'i:ndi | |||
_bn beNg,al'i_ | |||
_ta t'amil | |||
_te tel'ugu | |||
_si TiNgal'es | |||
_th t'a:i | |||
_my birm'ano | |||
_ja x,apon'Es | |||
_zh tS'ino | |||
// numbers | |||
_0 nitija | |||
_1 toU?k# | |||
_2 mahtsk# | |||
_3 toUoUhk# | |||
_4 mAktAAz.k# | |||
_5 mugooz.k# | |||
_6 toUht8k# | |||
_7 vuz.toUht8k# | |||
_8 toUtoUht8k# | |||
_9 tAz.toUht8k# | |||
_1X mAhk# | |||
_2x ii?p | |||
_3X mAhk#ii?p | |||
_4X v8htkup | |||
_5X v8htkupmAhk# | |||
_6X toUoUhk#ii?p | |||
_7X toUoUhk#ii?pmAhk# | |||
_8X mAktAAz.k#ii?p | |||
_9X mAktAAz.k#ii?pmAhk# | |||
_0C mugooz.k#ii?p | |||
_dpt koma | |||
_roman Rom'ano | |||
// ordinal numbers | |||
_#º o | |||
_#ª a | |||
_ord mu | |||
ºc gr'ados||T'e | |||
ºf gr'ados||'Efe | |||
ºk gr'ados||k'a | |||
// Letters (names taken from Spanish) | |||
// If a letter has a "word" pronunciation which is different from its | |||
// "letter" name, then include the letter name here, with the letter | |||
// prefixed by a _ character. | |||
_b be | |||
_c Te | |||
_d de | |||
_f Efe | |||
_g xe | |||
_h atSe | |||
_j xota | |||
_k ka | |||
_l Ele | |||
_m Eme | |||
_n Ene | |||
_ñ En^e | |||
_p pe | |||
_q ku | |||
_r Ere | |||
_s Ese | |||
_t te | |||
_v uBe | |||
_w uBe||d'oBle | |||
_x Ekis | |||
_z TEta | |||
_a a | |||
_e e | |||
_o o | |||
_y igri'eQa | |||
_á 'a||aTEntw'aDa | |||
_é 'e||aTEntw'aDa | |||
_í 'i||aTEntw'aDa | |||
_ó 'o||aTEntw'aDa | |||
_ú 'u||aTEntw'aDa | |||
_ü 'u||kon||dj'ErEsis | |||
_ç $accent | |||
// Proper Names and countries | |||
amsterdam $3 | |||
bardem $2 | |||
jerusalem $4 | |||
méxico m'Exiko | |||
vietnam $2 | |||
// foreign words | |||
android 'androId | |||
apple 'ap@l | |||
copyright k'opiRR2,aIt | |||
chrome kr'owm | |||
curriculum $2 | |||
diem d'i:em $only | |||
eloquence 'elokwens | |||
english ínglish $text | |||
espeak 'isp'ik | |||
eyes 'aIs | |||
facebook f'eIsbuk | |||
firefox f'aIrfoks | |||
free fr'i | |||
google g'ug@l | |||
hardware h'ardwer | |||
iphone 'aIfon | |||
ipod 'aIpod | |||
jaws dZ'os | |||
jazz dZ'as | |||
linux $1 | |||
live l'aIB | |||
messenger m'esendZer | |||
microsoft m'aIkrosoft | |||
mozilla moT'ila | |||
office 'ofis | |||
platform pl'atfom | |||
power p'awer | |||
service s'erBis | |||
skype sk'aIp | |||
snapshot sn'apS,ot // _^_en | |||
software s'oftwer | |||
spanish sp'aniS | |||
speech sp'itS | |||
thunderbird t'anderbird | |||
twit tw'it | |||
twitter tw'iter | |||
window w'indow | |||
(e speak) 'isp'ik | |||
(i phone) 'aIfon | |||
(i pod) 'aIpod |
@@ -0,0 +1,107 @@ | |||
// Translation rules for mto | |||
// This file is UTF-8 encoded | |||
.L01 a e i o u ä ë ï ö ü | |||
.L02 m n | |||
.group a | |||
a a | |||
.group ä | |||
ä A | |||
.group e | |||
e e | |||
.group ë | |||
ë @ | |||
.group i | |||
i i | |||
.group ï | |||
ï 8 | |||
.group o | |||
o o | |||
.group ö | |||
ö oU | |||
.group u | |||
u u | |||
.group v | |||
v(_ f | |||
_)v(o b | |||
j)v vj | |||
v(j vj | |||
v v | |||
.group s | |||
s s | |||
.group x | |||
L01)x z. | |||
L02)x z. | |||
j)x s.j | |||
x(j s.j | |||
x s. | |||
.group j | |||
j h | |||
.group ts | |||
%L01)ts dz | |||
L02)ts dz | |||
j)ts tsj | |||
ts(j tsj | |||
ts ts | |||
.group p | |||
L01)p(L01 b | |||
L02)p(L01 b | |||
p(_ p# | |||
j)p pj | |||
p(j pj | |||
p p | |||
.group t | |||
L01)t(L01 d | |||
L02)t(L01 d | |||
j)t tj | |||
t(j tj | |||
t(_ t# | |||
t t | |||
.group k | |||
L01)k(L01 g | |||
L02)k(L01 g | |||
k(_ k# | |||
j)k kj | |||
k(j kj | |||
k k | |||
.group ꞌ | |||
ꞌ ? | |||
.group m | |||
j)m mj | |||
m(j mj | |||
m m | |||
.group n | |||
n(p m | |||
n(k N | |||
j)n nj | |||
n(j nj | |||
n n | |||
.group r | |||
r r | |||
.group l | |||
l l | |||
.group y | |||
y j |
@@ -1,11 +1,11 @@ | |||
// numbers | |||
_1 jun | |||
_2 keb' | |||
_3 oxib' | |||
_4 kajib' | |||
_5 job' | |||
_6 waqib' | |||
_7 wuqub' | |||
_8 wajxaqib' | |||
_9 b'elejeb' | |||
_10 lajuj | |||
// Native numbers 1-10 | |||
_1n jun | |||
_2n keb' | |||
_3n oxib' | |||
_4n kajib' | |||
_5n job' | |||
_6n waqib' | |||
_7n wuqub' | |||
_8n wajxaqib' | |||
_9n b'elejeb' | |||
_10n lajuj |
@@ -1,4 +1,4 @@ | |||
name Lang_Belta | |||
name Lang Belta | |||
language qdb | |||
numbers 4 3 |
@@ -0,0 +1,8 @@ | |||
name Totontepec Mixe | |||
language mto | |||
maintainer Bill Dengler <[email protected]> and Elizabeth Resendiz <[email protected]> | |||
status testing | |||
lowercaseSentence | |||
tunes s6 c6 q6 e6 |
@@ -0,0 +1,216 @@ | |||
//==================================================== | |||
// Totontepec Mixe | |||
//==================================================== | |||
phoneme a | |||
ipa a | |||
vwl starttype #a endtype #a | |||
length 190 | |||
FMT(vowel/a_4) | |||
endphoneme | |||
phoneme A | |||
ipa ɑ | |||
vwl starttype #a endtype #a | |||
length 220 | |||
unr bck low | |||
FMT(vowel/aa_8) | |||
endphoneme | |||
phoneme e | |||
ipa e | |||
vwl starttype #e endtype #e | |||
length 190 | |||
FMT(vowel/e_mid2) | |||
endphoneme | |||
phoneme @ | |||
ipa ə | |||
vwl starttype #@ endtype #@ | |||
unstressed | |||
length 140 | |||
unr cnt mid | |||
IF thisPh(isWordEnd) THEN | |||
FMT(vowel/@_6, 90) | |||
ENDIF | |||
FMT(vowel/@) | |||
endphoneme | |||
phoneme i | |||
ipa i | |||
vwl starttype #i endtype #i | |||
length 190 | |||
IfNextVowelAppend(;) | |||
FMT(vowel/i) | |||
endphoneme | |||
phoneme 8 | |||
ipa ɘ | |||
vwl starttype #@ endtype #@ | |||
length 165 | |||
FMT(vowel/8_7) | |||
endphoneme | |||
phoneme o | |||
ipa o | |||
vwl starttype #o endtype #o | |||
length 195 | |||
FMT(vowel/oo) | |||
endphoneme | |||
phoneme oU | |||
ipa əʊ | |||
vwl starttype #@ endtype #u | |||
length 220 | |||
FMT(vdiph/@u_en) | |||
endphoneme | |||
phoneme u | |||
vwl starttype #u endtype #u | |||
length 200 | |||
FMT(vowel/u_bck2) | |||
endphoneme | |||
phoneme k | |||
import_phoneme consonants/k- | |||
endphoneme | |||
phoneme k# | |||
import_phoneme consonants/k# | |||
endphoneme | |||
phoneme g | |||
ipa g | |||
vcd vel stp | |||
lengthmod 5 | |||
voicingswitch k | |||
Vowelin f1=2 f2=2300 200 300 f3=-300 80 | |||
Vowelout f1=2 f2=2300 250 300 f3=-300 80 brk | |||
FMT(g/g) addWav(x/g2) // weaker [g] | |||
endphoneme | |||
phoneme t | |||
import_phoneme base1/t[ | |||
endphoneme | |||
phoneme T // Used in Spanish words | |||
import_phoneme base1/T | |||
endphoneme | |||
phoneme t# | |||
ipa tʰ | |||
vls dnt stp | |||
lengthmod 2 | |||
voicingswitch d | |||
Vowelin f1=0 f2=1500 -300 300 f3=-100 80 amp=16 | |||
Vowelout f1=0 f2=1500 -300 250 f3=-100 80 rms=20 | |||
IF nextPh(isPause2) THEN | |||
WAV(ustop/t_dnt, 35) | |||
ENDIF | |||
WAV(ustop/t_dnt, 50) | |||
endphoneme | |||
phoneme d | |||
import_phoneme base2/d | |||
endphoneme | |||
phoneme p | |||
import_phoneme consonants/p- | |||
endphoneme | |||
phoneme p# | |||
import_phoneme consonants/ph | |||
endphoneme | |||
phoneme b | |||
import_phoneme base1/b | |||
endphoneme | |||
phoneme v | |||
ipa v | |||
vcd lbd frc | |||
FMT(voc/v) addWav(vocw/v, 90) | |||
endphoneme | |||
phoneme f | |||
ipa f | |||
vls lbd frc | |||
WAV(ufric/f, 80) | |||
endphoneme | |||
phoneme s | |||
ipa s | |||
vls alv frc sib | |||
lengthmod 3 | |||
voicingswitch z | |||
Vowelin f1=0 f2=1700 -300 300 f3=-100 80 | |||
Vowelout f1=0 f2=1700 -300 250 f3=-100 80 rms=20 | |||
IF nextPh(isPause) THEN | |||
WAV(ufric/s_, 60) // quieter 's' at end of word | |||
ELIF nextPh(p) OR nextPh(t) OR nextPh(k) THEN | |||
WAV(ufric/s!) | |||
ENDIF | |||
WAV(ufric/s, 80) | |||
endphoneme | |||
phoneme s. | |||
import_phoneme base1/s. | |||
endphoneme | |||
phoneme z. | |||
import_phoneme base1/z. | |||
endphoneme | |||
phoneme ts | |||
import_phoneme consonants/ts | |||
endphoneme | |||
phoneme dz | |||
import_phoneme consonants/dz | |||
endphoneme | |||
phoneme m | |||
import_phoneme base1/m- | |||
endphoneme | |||
phoneme n | |||
import_phoneme base1/n- | |||
endphoneme | |||
phoneme N | |||
import_phoneme base1/N- | |||
endphoneme | |||
phoneme r | |||
import_phoneme base1/* | |||
endphoneme | |||
phoneme l | |||
import_phoneme base1/l | |||
endphoneme | |||
phoneme j | |||
import_phoneme base1/j | |||
endphoneme | |||
phoneme C | |||
import_phoneme base1/C | |||
endphoneme | |||
phoneme ? | |||
ipa ʔ | |||
vls glt stp | |||
lengthmod 1 // 5? longer preceding vowel | |||
nolink | |||
Vowelin glstop | |||
Vowelout glstop | |||
WAV(ustop/null) | |||
endphoneme | |||
phoneme h | |||
import_phoneme base1/h | |||
endphoneme |
@@ -150,7 +150,8 @@ endphoneme | |||
phoneme r | |||
liquid trl | |||
lengthmod 7 | |||
lengthmod 6 | |||
IF nextPh(isNotVowel) THEN | |||
ChangePhoneme(r/) | |||
ENDIF | |||
@@ -172,6 +173,9 @@ phoneme r | |||
FMT(r/trr) | |||
ENDIF | |||
FMT(r/rr) | |||
Vowelin f1=0 f2=1600 -300 300 f3=-200 80 | |||
Vowelout f1=2 f2=1600 -300 300 f3=-200 80 brk | |||
FMT(r3/r_trill2) addWav(r3/r_trill2.wav, 65) | |||
endphoneme | |||
@@ -1852,6 +1852,9 @@ include ph_kurdish | |||
phonemetable mi base2 | |||
include ph_maori | |||
phonemetable mto base2 | |||
include ph_mixe_mto | |||
phonemetable nci base2 | |||
include ph_nahuatl | |||
@@ -2058,3 +2061,5 @@ include ph_langbelta | |||
phonemetable be ru | |||
include ph_belarusian | |||
phonemetable ms id |
@@ -143,7 +143,7 @@ static void DisplayVoices(FILE *f_out, char *language) | |||
const espeak_VOICE **voices; | |||
espeak_VOICE voice_select; | |||
static char genders[4] = { '-', 'M', 'F', '-' }; | |||
static const char genders[4] = { '-', 'M', 'F', '-' }; | |||
if ((language != NULL) && (language[0] != 0)) { | |||
// display only voices for the specified language, in order of priority | |||
@@ -201,7 +201,7 @@ static void Write4Bytes(FILE *f, int value) | |||
static int OpenWavFile(char *path, int rate) | |||
{ | |||
static unsigned char wave_hdr[44] = { | |||
static const unsigned char wave_hdr[44] = { | |||
'R', 'I', 'F', 'F', 0x24, 0xf0, 0xff, 0x7f, 'W', 'A', 'V', 'E', 'f', 'm', 't', ' ', | |||
0x10, 0, 0, 0, 1, 0, 1, 0, 9, 0x3d, 0, 0, 0x12, 0x7a, 0, 0, | |||
2, 0, 0x10, 0, 'd', 'a', 't', 'a', 0x00, 0xf0, 0xff, 0x7f | |||
@@ -304,7 +304,7 @@ static void PrintVersion() | |||
int main(int argc, char **argv) | |||
{ | |||
static struct option long_options[] = { | |||
static const struct option long_options[] = { | |||
{ "help", no_argument, 0, 'h' }, | |||
{ "stdin", no_argument, 0, 0x100 }, | |||
{ "compile-debug", optional_argument, 0, 0x101 }, |
@@ -1559,7 +1559,7 @@ static void CompileSound(int keyword, int isvowel) | |||
int addr = 0; | |||
int value = 0; | |||
char path[N_ITEM_STRING]; | |||
static int sound_instns[] = { i_FMT, i_WAV, i_VWLSTART, i_VWLENDING, i_WAVADD }; | |||
static const int sound_instns[] = { i_FMT, i_WAV, i_VWLSTART, i_VWLENDING, i_WAVADD }; | |||
NextItemBrackets(tSTRING, 2); | |||
strcpy(path, item_string); |
@@ -223,14 +223,16 @@ char *DecodeRule(const char *group_chars, int group_length, char *rule, int cont | |||
char suffix[20]; | |||
static char output[80]; | |||
static char symbols[] = { | |||
MAKE_MEM_UNDEFINED(&output, sizeof(output)); | |||
static const char symbols[] = { | |||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', | |||
'&', '%', '+', '#', 'S', 'D', 'Z', 'A', 'L', '!', | |||
' ', '@', '?', 'J', 'N', 'K', 'V', '?', 'T', 'X', | |||
'?', 'W' | |||
}; | |||
static char symbols_lg[] = { 'A', 'B', 'C', 'H', 'F', 'G', 'Y' }; | |||
static const char symbols_lg[] = { 'A', 'B', 'C', 'H', 'F', 'G', 'Y' }; | |||
match_type = 0; | |||
buf_pre[0] = 0; | |||
@@ -766,8 +768,8 @@ static int isHexDigit(int c) | |||
static void copy_rule_string(char *string, int *state_out) | |||
{ | |||
// state 0: conditional, 1=pre, 2=match, 3=post, 4=phonemes | |||
static char *outbuf[5] = { rule_cond, rule_pre, rule_match, rule_post, rule_phonemes }; | |||
static int next_state[5] = { 2, 2, 4, 4, 4 }; | |||
static char * const outbuf[5] = { rule_cond, rule_pre, rule_match, rule_post, rule_phonemes }; | |||
static const int next_state[5] = { 2, 2, 4, 4, 4 }; | |||
char *output; | |||
char *p; | |||
int ix; |
@@ -26,6 +26,7 @@ | |||
#include <string.h> | |||
#include <wctype.h> | |||
#include <wchar.h> | |||
#include <assert.h> | |||
#include <espeak-ng/espeak_ng.h> | |||
#include <espeak-ng/speak_lib.h> | |||
@@ -1060,7 +1061,7 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags, | |||
char vowel_length[N_WORD_PHONEMES/2]; | |||
unsigned char phonetic[N_WORD_PHONEMES]; | |||
static char consonant_types[16] = { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 }; | |||
static const char consonant_types[16] = { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 }; | |||
stressflags = tr->langopts.stress_flags; | |||
@@ -1226,9 +1227,9 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags, | |||
// LANG=Russian | |||
if (stressed_syllable == 0) { | |||
// no explicit stress - guess the stress from the number of syllables | |||
static char guess_ru[16] = { 0, 0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 9, 10, 11 }; | |||
static char guess_ru_v[16] = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 7, 8, 9, 10 }; // for final phoneme is a vowel | |||
static char guess_ru_t[16] = { 0, 0, 1, 2, 3, 3, 3, 4, 5, 6, 7, 7, 7, 8, 9, 10 }; // for final phoneme is an unvoiced stop | |||
static const char guess_ru[16] = { 0, 0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 9, 10, 11 }; | |||
static const char guess_ru_v[16] = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 7, 8, 9, 10 }; // for final phoneme is a vowel | |||
static const char guess_ru_t[16] = { 0, 0, 1, 2, 3, 3, 3, 4, 5, 6, 7, 7, 7, 8, 9, 10 }; // for final phoneme is an unvoiced stop | |||
stressed_syllable = vowel_count - 3; | |||
if (vowel_count < 16) { | |||
@@ -2228,7 +2229,7 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c | |||
int dict_flags0 = 0; | |||
MatchRecord match1; | |||
MatchRecord match2; | |||
char ph_buf[40]; | |||
char ph_buf[N_PHONEME_BYTES]; | |||
char word_copy[N_WORD_BYTES]; | |||
static const char str_pause[2] = { phonPAUSE_NOLINK, 0 }; | |||
@@ -2660,8 +2661,9 @@ static const char *LookupDict2(Translator *tr, const char *word, const char *wor | |||
phonetic[0] = 0; | |||
phoneme_len = 0; | |||
} else { | |||
strcpy(phonetic, p); | |||
phoneme_len = strlen(p); | |||
assert(phoneme_len < N_PHONEME_BYTES); | |||
strcpy(phonetic, p); | |||
p += (phoneme_len + 1); | |||
} | |||
@@ -2875,6 +2877,8 @@ int LookupDictList(Translator *tr, char **wordptr, char *ph_out, unsigned int *f | |||
char word[N_WORD_BYTES]; | |||
static char word_replacement[N_WORD_BYTES]; | |||
MAKE_MEM_UNDEFINED(&word_replacement, sizeof(word_replacement)); | |||
length = 0; | |||
word2 = word1 = *wordptr; | |||
@@ -3008,12 +3012,14 @@ int Lookup(Translator *tr, const char *word, char *ph_out) | |||
if (flags[0] & FLAG_TEXTMODE) { | |||
say_as = option_sayas; | |||
option_sayas = 0; // don't speak replacement word as letter names | |||
// NOTE: TranslateRoman checks text[-2], so pad the start of text to prevent | |||
// NOTE: TranslateRoman checks text[-2] and IsLetterGroup looks | |||
// for a heading \0, so pad the start of text to prevent | |||
// it reading data on the stack. | |||
text[0] = ' '; | |||
text[0] = 0; | |||
text[1] = ' '; | |||
strncpy0(text+2, word1, sizeof(text)-2); | |||
flags0 = TranslateWord(tr, text+2, NULL, NULL); | |||
text[2] = ' '; | |||
strncpy0(text+3, word1, sizeof(text)-3); | |||
flags0 = TranslateWord(tr, text+3, NULL, NULL); | |||
strcpy(ph_out, word_phonemes); | |||
option_sayas = say_as; | |||
} | |||
@@ -3052,11 +3058,11 @@ int RemoveEnding(Translator *tr, char *word, int end_type, char *word_copy) | |||
char ending[50] = {0}; | |||
// these lists are language specific, but are only relevant if the 'e' suffix flag is used | |||
static const char *add_e_exceptions[] = { | |||
static const char * const add_e_exceptions[] = { | |||
"ion", NULL | |||
}; | |||
static const char *add_e_additions[] = { | |||
static const char * const add_e_additions[] = { | |||
"c", "rs", "ir", "ur", "ath", "ns", "u", | |||
"spong", // sponge | |||
"rang", // strange |
@@ -539,10 +539,10 @@ static int calc_pitch_segment(SYLLABLE *syllable_tab, int ix, int end_ix, TONE_H | |||
int pitch_range; | |||
int pitch_range_abs; | |||
int *drops; | |||
signed char *overflow_tab; | |||
const signed char *overflow_tab; | |||
SYLLABLE *syl; | |||
static signed char continue_tab[5] = { -26, 32, 20, 8, 0 }; | |||
static const signed char continue_tab[5] = { -26, 32, 20, 8, 0 }; | |||
drops = th->body_drops; | |||
pitch_range = (th->body_end - th->body_start) * 256; |
@@ -483,7 +483,7 @@ void KlattFini(void) | |||
static void frame_init(klatt_frame_ptr frame) | |||
{ | |||
double amp_par[7]; | |||
static double amp_par_factor[7] = { 0.6, 0.4, 0.15, 0.06, 0.04, 0.022, 0.03 }; | |||
static const double amp_par_factor[7] = { 0.6, 0.4, 0.15, 0.06, 0.04, 0.022, 0.03 }; | |||
long Gain0_tmp; | |||
int ix; | |||
@@ -552,7 +552,7 @@ static void frame_init(klatt_frame_ptr frame) | |||
static double impulsive_source() | |||
{ | |||
static double doublet[] = { 0.0, 13000000.0, -13000000.0 }; | |||
static const double doublet[] = { 0.0, 13000000.0, -13000000.0 }; | |||
static double vwave; | |||
if (kt_globals.nper < 3) | |||
@@ -623,7 +623,7 @@ static void pitch_synch_par_reset(klatt_frame_ptr frame) | |||
long temp; | |||
double temp1; | |||
static long skew; | |||
static short B0[224] = { | |||
static const short B0[224] = { | |||
1200, 1142, 1088, 1038, 991, 948, 907, 869, 833, 799, 768, 738, 710, 683, 658, | |||
634, 612, 590, 570, 551, 533, 515, 499, 483, 468, 454, 440, 427, 415, 403, | |||
391, 380, 370, 360, 350, 341, 332, 323, 315, 307, 300, 292, 285, 278, 272, | |||
@@ -836,7 +836,7 @@ static double gen_noise(double noise) | |||
static double DBtoLIN(long dB) | |||
{ | |||
static short amptable[88] = { | |||
static const short amptable[88] = { | |||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, | |||
8, 9, 10, 11, 13, 14, 16, 18, 20, 22, 25, 28, 32, | |||
35, 40, 45, 51, 57, 64, 71, 80, 90, 101, 114, 128, | |||
@@ -1076,10 +1076,10 @@ static void SetSynth_Klatt(int length, frame_t *fr1, frame_t *fr2, voice_t *wvoi | |||
void KlattInit() | |||
{ | |||
static short formant_hz[10] = { 280, 688, 1064, 2806, 3260, 3700, 6500, 7000, 8000, 280 }; | |||
static short bandwidth[10] = { 89, 160, 70, 160, 200, 200, 500, 500, 500, 89 }; | |||
static short parallel_amp[10] = { 0, 59, 59, 59, 59, 59, 59, 0, 0, 0 }; | |||
static short parallel_bw[10] = { 59, 59, 89, 149, 200, 200, 500, 0, 0, 0 }; | |||
static const short formant_hz[10] = { 280, 688, 1064, 2806, 3260, 3700, 6500, 7000, 8000, 280 }; | |||
static const short bandwidth[10] = { 89, 160, 70, 160, 200, 200, 500, 500, 500, 89 }; | |||
static const short parallel_amp[10] = { 0, 59, 59, 59, 59, 59, 59, 0, 0, 0 }; | |||
static const short parallel_bw[10] = { 59, 59, 89, 149, 200, 200, 500, 0, 0, 0 }; | |||
int ix; | |||
@@ -479,7 +479,7 @@ void LookupLetter(Translator *tr, unsigned int letter, int next_byte, char *ph_b | |||
// control, bit 0: not the first letter of a word | |||
int len; | |||
static char single_letter[10] = { 0, 0 }; | |||
char single_letter[10] = { 0, 0 }; | |||
unsigned int dict_flags[2]; | |||
char ph_buf3[40]; | |||
@@ -500,8 +500,8 @@ void LookupLetter(Translator *tr, unsigned int letter, int next_byte, char *ph_b | |||
if (tr->translator_name == L('e', 'n')) | |||
return; // we are already using English | |||
SetTranslator2(ESPEAKNG_DEFAULT_VOICE); | |||
if (Lookup(translator2, &single_letter[2], ph_buf3) != 0) { | |||
SetTranslator3(ESPEAKNG_DEFAULT_VOICE); | |||
if (Lookup(translator3, &single_letter[2], ph_buf3) != 0) { | |||
// yes, switch to English and re-translate the word | |||
sprintf(ph_buf1, "%c", phonSWITCH); | |||
} | |||
@@ -691,7 +691,7 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control, ALP | |||
char ph_buf2[80]; | |||
char ph_alphabet[80]; | |||
char hexbuf[12]; | |||
static char pause_string[] = { phonPAUSE, 0 }; | |||
static const char pause_string[] = { phonPAUSE, 0 }; | |||
ph_buf[0] = 0; | |||
ph_alphabet[0] = 0; | |||
@@ -719,8 +719,8 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control, ALP | |||
// don't say "superscript" during normal text reading | |||
Lookup(tr, modifier, capital); | |||
if (capital[0] == 0) { | |||
capital[2] = SetTranslator2(ESPEAKNG_DEFAULT_VOICE); // overwrites previous contents of translator2 | |||
Lookup(translator2, modifier, &capital[3]); | |||
capital[2] = SetTranslator3(ESPEAKNG_DEFAULT_VOICE); // overwrites previous contents of translator3 | |||
Lookup(translator3, modifier, &capital[3]); | |||
if (capital[3] != 0) { | |||
capital[0] = phonPAUSE; | |||
capital[1] = phonSWITCH; | |||
@@ -763,8 +763,8 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control, ALP | |||
ph_buf2[0] = 0; | |||
if (Lookup(translator, alphabet->name, ph_alphabet) == 0) { // the original language for the current voice | |||
// Can't find the local name for this alphabet, use the English name | |||
ph_alphabet[2] = SetTranslator2(ESPEAKNG_DEFAULT_VOICE); // overwrites previous contents of translator2 | |||
Lookup(translator2, alphabet->name, ph_buf2); | |||
ph_alphabet[2] = SetTranslator3(ESPEAKNG_DEFAULT_VOICE); // overwrites previous contents of translator3 | |||
Lookup(translator3, alphabet->name, ph_buf2); | |||
} else if (translator != tr) { | |||
phontab_1 = tr->phoneme_tab_ix; | |||
strcpy(ph_buf2, ph_alphabet); | |||
@@ -801,9 +801,9 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control, ALP | |||
char hangul_buf[12]; | |||
// speak in the language for this alphabet (or English) | |||
ph_buf[2] = SetTranslator2(WordToString2(language)); | |||
ph_buf[2] = SetTranslator3(WordToString2(language)); | |||
if (translator2 != NULL) { | |||
if (translator3 != NULL) { | |||
if (((code = letter - 0xac00) >= 0) && (letter <= 0xd7af)) { | |||
// Special case for Korean letters. | |||
// break a syllable hangul into 2 or 3 individual jamo | |||
@@ -818,15 +818,15 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control, ALP | |||
p3[6] = ' '; | |||
p3[7] = 0; | |||
ph_buf[3] = 0; | |||
TranslateRules(translator2, &hangul_buf[1], &ph_buf[3], sizeof(ph_buf)-3, NULL, 0, NULL); | |||
SetWordStress(translator2, &ph_buf[3], NULL, -1, 0); | |||
TranslateRules(translator3, &hangul_buf[1], &ph_buf[3], sizeof(ph_buf)-3, NULL, 0, NULL); | |||
SetWordStress(translator3, &ph_buf[3], NULL, -1, 0); | |||
} else | |||
LookupLetter(translator2, letter, word[n_bytes], &ph_buf[3], control & 1); | |||
LookupLetter(translator3, letter, word[n_bytes], &ph_buf[3], control & 1); | |||
if (ph_buf[3] == phonSWITCH) { | |||
// another level of language change | |||
ph_buf[2] = SetTranslator2(&ph_buf[4]); | |||
LookupLetter(translator2, letter, word[n_bytes], &ph_buf[3], control & 1); | |||
ph_buf[2] = SetTranslator3(&ph_buf[4]); | |||
LookupLetter(translator3, letter, word[n_bytes], &ph_buf[3], control & 1); | |||
} | |||
SelectPhonemeTable(voice->phoneme_tab_ix); // revert to original phoneme table | |||
@@ -1039,7 +1039,7 @@ int TranslateRoman(Translator *tr, char *word, char *ph_out, WORD_TAB *wtab) | |||
char number_chars[N_WORD_BYTES]; | |||
static const char *roman_numbers = "ixcmvld"; | |||
static int roman_values[] = { 1, 10, 100, 1000, 5, 50, 500 }; | |||
static const int roman_values[] = { 1, 10, 100, 1000, 5, 50, 500 }; | |||
acc = 0; | |||
prev = 0; |
@@ -291,6 +291,7 @@ void MakePhonemeList(Translator *tr, int post_pause, bool start_sentence) | |||
} | |||
} | |||
SelectPhonemeTable(tr->phoneme_tab_ix); | |||
n_ph_list3 = SubstitutePhonemes(ph_list3) - 2; | |||
for (j = 0; (j < n_ph_list3) && (ix < N_PHONEME_LIST-3);) { | |||
@@ -321,6 +322,7 @@ void MakePhonemeList(Translator *tr, int post_pause, bool start_sentence) | |||
ph_list3[0].ph = ph; | |||
word_start = 1; | |||
SelectPhonemeTable(tr->phoneme_tab_ix); | |||
for (j = 0; insert_ph || ((j < n_ph_list3) && (ix < N_PHONEME_LIST-3)); j++) { | |||
plist3 = &ph_list3[j]; | |||
@@ -461,7 +463,7 @@ void MakePhonemeList(Translator *tr, int post_pause, bool start_sentence) | |||
} | |||
if ((plist3+1)->synthflags & SFLAG_LENGTHEN) { | |||
static char types_double[] = { phFRICATIVE, phVFRICATIVE, phNASAL, phLIQUID, 0 }; | |||
static const char types_double[] = { phFRICATIVE, phVFRICATIVE, phNASAL, phLIQUID, 0 }; | |||
if ((j > 0) && (strchr(types_double, next->type))) { | |||
// lengthen this consonant by doubling it | |||
// BUT, can't insert a phoneme at position plist3[0] because it crashes PrevPh() | |||
@@ -589,4 +591,6 @@ void MakePhonemeList(Translator *tr, int post_pause, bool start_sentence) | |||
phlist[ix++].ph = phoneme_tab[phonPAUSE_SHORT]; | |||
n_phoneme_list = ix; | |||
SelectPhonemeTable(tr->phoneme_tab_ix); | |||
} |
@@ -187,6 +187,8 @@ const char *WordToString2(unsigned int word) | |||
static char buf[5]; | |||
char *p; | |||
MAKE_MEM_UNDEFINED(&buf, sizeof(buf)); | |||
p = buf; | |||
for (ix = 3; ix >= 0; ix--) { | |||
if ((*p = word >> (ix*8)) != 0) | |||
@@ -227,6 +229,8 @@ static const char *LookupCharName(Translator *tr, int c, int only) | |||
char *string; | |||
static char buf[60]; | |||
MAKE_MEM_UNDEFINED(&buf, sizeof(buf)); | |||
buf[0] = 0; | |||
flags[0] = 0; | |||
flags[1] = 0; | |||
@@ -335,7 +339,7 @@ static int AnnouncePunctuation(Translator *tr, int c1, int *c2_ptr, char *output | |||
if ((*bufix == 0) || (end_clause == 0) || (tr->langopts.param[LOPT_ANNOUNCE_PUNCT] & 2)) { | |||
punct_count = 1; | |||
while ((c2 == c1) && (c1 != '<')) { // don't eat extra '<', it can miss XML tags | |||
while (!Eof() && (c2 == c1) && (c1 != '<')) { // don't eat extra '<', it can miss XML tags | |||
punct_count++; | |||
c2 = GetC(); | |||
} | |||
@@ -541,8 +545,10 @@ int ReadClause(Translator *tr, char *buf, short *charix, int *charix_top, int n_ | |||
c1 = c2; | |||
if (ungot_string_ix >= 0) { | |||
if (ungot_string[ungot_string_ix] == 0) | |||
if (ungot_string[ungot_string_ix] == 0) { | |||
MAKE_MEM_UNDEFINED(&ungot_string, sizeof(ungot_string)); | |||
ungot_string_ix = -1; | |||
} | |||
} | |||
if ((ungot_string_ix == 0) && (ungot_char2 == 0)) | |||
@@ -647,7 +653,7 @@ int ReadClause(Translator *tr, char *buf, short *charix, int *charix_top, int n_ | |||
// an embedded command. If it's a voice change, end the clause | |||
if (c2 == 'V') { | |||
buf[ix++] = 0; // end the clause at this point | |||
while (!iswspace(c1 = GetC()) && !Eof() && (ix < (n_buf-1))) | |||
while (!Eof() && !iswspace(c1 = GetC()) && (ix < (n_buf-1))) | |||
buf[ix++] = c1; // add voice name to end of buffer, after the text | |||
buf[ix++] = 0; | |||
return CLAUSE_VOICE; | |||
@@ -657,7 +663,7 @@ int ReadClause(Translator *tr, char *buf, short *charix, int *charix_top, int n_ | |||
strcpy(&buf[ix], " "); | |||
ix += 3; | |||
if ((c2 = GetC()) == '0') | |||
if (!Eof() && (c2 = GetC()) == '0') | |||
option_punctuation = 0; | |||
else { | |||
option_punctuation = 1; | |||
@@ -665,7 +671,7 @@ int ReadClause(Translator *tr, char *buf, short *charix, int *charix_top, int n_ | |||
if (c2 != '1') { | |||
// a list of punctuation characters to be spoken, terminated by space | |||
j = 0; | |||
while (!iswspace(c2) && !Eof()) { | |||
while (!Eof() && !iswspace(c2)) { | |||
option_punctlist[j++] = c2; | |||
c2 = GetC(); | |||
buf[ix++] = ' '; | |||
@@ -674,7 +680,8 @@ int ReadClause(Translator *tr, char *buf, short *charix, int *charix_top, int n_ | |||
option_punctuation = 2; | |||
} | |||
} | |||
c2 = GetC(); | |||
if (!Eof()) | |||
c2 = GetC(); | |||
continue; | |||
} | |||
} | |||
@@ -791,7 +798,7 @@ int ReadClause(Translator *tr, char *buf, short *charix, int *charix_top, int n_ | |||
} | |||
if ((c1 == '.') && (c2 == '.')) { | |||
while ((c_next = GetC()) == '.') { | |||
while (!Eof() && (c_next = GetC()) == '.') { | |||
// 3 or more dots, replace by elipsis | |||
c1 = 0x2026; | |||
c2 = ' '; | |||
@@ -808,7 +815,7 @@ int ReadClause(Translator *tr, char *buf, short *charix, int *charix_top, int n_ | |||
// Handling of sequences of ? and ! like ??!?, !!??!, ?!! etc | |||
// Use only first char as determinant | |||
if(punct_data & (CLAUSE_QUESTION | CLAUSE_EXCLAMATION)) { | |||
while(clause_type_from_codepoint(c2) & (CLAUSE_QUESTION | CLAUSE_EXCLAMATION)) { | |||
while(!Eof() && clause_type_from_codepoint(c2) & (CLAUSE_QUESTION | CLAUSE_EXCLAMATION)) { | |||
c_next = GetC(); | |||
c2 = c_next; | |||
} |
@@ -35,7 +35,7 @@ | |||
# include <valgrind/memcheck.h> | |||
# define MAKE_MEM_UNDEFINED(addr, len) VALGRIND_MAKE_MEM_UNDEFINED(addr, len) | |||
# else | |||
# define MAKE_MEM_UNDEFINED(addr, len) ((void) (addr, len)) | |||
# define MAKE_MEM_UNDEFINED(addr, len) ((void) ((void) addr, len)) | |||
# endif | |||
#endif | |||
@@ -47,6 +47,7 @@ | |||
#include "synthesize.h" // for SPEED_FACTORS, speed | |||
#include "translate.h" // for CTRL_EMBEDDED, IsDigit09, utf8_out | |||
#include "voice.h" // for SelectVoice, SelectVoiceByName | |||
#include "speech.h" // for MAKE_MEM_UNDEFINED | |||
static const MNEM_TAB ssmltags[] = { | |||
{ "speak", SSML_SPEAK }, | |||
@@ -214,6 +215,8 @@ static const char *VoiceFromStack(SSML_STACK *ssml_stack, int n_ssml_stack, espe | |||
char language[40]; | |||
char buf[80]; | |||
MAKE_MEM_UNDEFINED(&voice_name, sizeof(voice_name)); | |||
strcpy(voice_name, ssml_stack[0].voice_name); | |||
strcpy(language, ssml_stack[0].language); | |||
voice_select.age = ssml_stack[0].voice_age; | |||
@@ -275,13 +278,13 @@ static const char *VoiceFromStack(SSML_STACK *ssml_stack, int n_ssml_stack, espe | |||
} | |||
static wchar_t *GetSsmlAttribute(wchar_t *pw, const char *name) | |||
static const wchar_t *GetSsmlAttribute(wchar_t *pw, const char *name) | |||
{ | |||
// Gets the value string for an attribute. | |||
// Returns NULL if the attribute is not present | |||
int ix; | |||
static wchar_t empty[1] = { 0 }; | |||
static const wchar_t empty[1] = { 0 }; | |||
while (*pw != 0) { | |||
if (iswspace(pw[-1])) { | |||
@@ -315,11 +318,11 @@ static int GetVoiceAttributes(wchar_t *pw, int tag_type, SSML_STACK *ssml_sp, SS | |||
// a voice change. | |||
// Returns CLAUSE_TYPE_VOICE_CHANGE if there is a voice change | |||
wchar_t *lang; | |||
wchar_t *gender; | |||
wchar_t *name; | |||
wchar_t *age; | |||
wchar_t *variant; | |||
const wchar_t *lang; | |||
const wchar_t *gender; | |||
const wchar_t *name; | |||
const wchar_t *age; | |||
const wchar_t *variant; | |||
int value; | |||
const char *new_voice_id; | |||
@@ -384,7 +387,7 @@ static void ProcessParamStack(char *outbuf, int *outix, int n_param_stack, PARAM | |||
int value; | |||
char buf[20]; | |||
int new_parameters[N_SPEECH_PARAM]; | |||
static char cmd_letter[N_SPEECH_PARAM] = { 0, 'S', 'A', 'P', 'R', 0, 'C', 0, 0, 0, 0, 0, 'F' }; // embedded command letters | |||
static const char cmd_letter[N_SPEECH_PARAM] = { 0, 'S', 'A', 'P', 'R', 0, 'C', 0, 0, 0, 0, 0, 'F' }; // embedded command letters | |||
for (param = 0; param < N_SPEECH_PARAM; param++) | |||
new_parameters[param] = -1; | |||
@@ -482,7 +485,7 @@ static int ReplaceKeyName(char *outbuf, int index, int *outix) | |||
return 0; | |||
} | |||
static void SetProsodyParameter(int param_type, wchar_t *attr1, PARAM_STACK *sp, PARAM_STACK *param_stack, int *speech_parameters) | |||
static void SetProsodyParameter(int param_type, const wchar_t *attr1, PARAM_STACK *sp, PARAM_STACK *param_stack, int *speech_parameters) | |||
{ | |||
int value; | |||
int sign; | |||
@@ -528,7 +531,7 @@ static void SetProsodyParameter(int param_type, wchar_t *attr1, PARAM_STACK *sp, | |||
{ NULL, -1 } | |||
}; | |||
static const MNEM_TAB *mnem_tabs[5] = { | |||
static const MNEM_TAB * const mnem_tabs[5] = { | |||
NULL, mnem_rate, mnem_volume, mnem_pitch, mnem_range | |||
}; | |||
@@ -564,9 +567,9 @@ int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int *outix, int n_outbuf, con | |||
int value3; | |||
int voice_change_flag; | |||
wchar_t *px; | |||
wchar_t *attr1; | |||
wchar_t *attr2; | |||
wchar_t *attr3; | |||
const wchar_t *attr1; | |||
const wchar_t *attr2; | |||
const wchar_t *attr3; | |||
int terminator; | |||
char *uri; | |||
int param_type; | |||
@@ -581,7 +584,7 @@ int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int *outix, int n_outbuf, con | |||
} | |||
// these tags have no effect if they are self-closing, eg. <voice /> | |||
static char ignore_if_self_closing[] = { 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0 }; | |||
static const char ignore_if_self_closing[] = { 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0 }; | |||
bool self_closing = false; | |||
int len; | |||
@@ -645,7 +648,7 @@ int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int *outix, int n_outbuf, con | |||
{ NULL, -1 } | |||
}; | |||
static const char *prosody_attr[5] = { | |||
static const char * const prosody_attr[5] = { | |||
NULL, "rate", "volume", "pitch", "range" | |||
}; | |||
@@ -711,13 +714,13 @@ int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int *outix, int n_outbuf, con | |||
value = attrlookup(attr1, mnem_emphasis); | |||
if (translator->langopts.tone_language == 1) { | |||
static unsigned char emphasis_to_pitch_range[] = { 50, 50, 40, 70, 90, 100 }; | |||
static unsigned char emphasis_to_volume[] = { 100, 100, 70, 110, 135, 150 }; | |||
static const unsigned char emphasis_to_pitch_range[] = { 50, 50, 40, 70, 90, 100 }; | |||
static const unsigned char emphasis_to_volume[] = { 100, 100, 70, 110, 135, 150 }; | |||
// tone language (eg.Chinese) do emphasis by increasing the pitch range. | |||
sp->parameter[espeakRANGE] = emphasis_to_pitch_range[value]; | |||
sp->parameter[espeakVOLUME] = emphasis_to_volume[value]; | |||
} else { | |||
static unsigned char emphasis_to_volume2[] = { 100, 100, 75, 100, 120, 150 }; | |||
static const unsigned char emphasis_to_volume2[] = { 100, 100, 75, 100, 120, 150 }; | |||
sp->parameter[espeakVOLUME] = emphasis_to_volume2[value]; | |||
sp->parameter[espeakEMPHASIS] = value; | |||
} | |||
@@ -855,7 +858,7 @@ int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int *outix, int n_outbuf, con | |||
terminator = CLAUSE_NONE; | |||
if ((attr1 = GetSsmlAttribute(px, "strength")) != NULL) { | |||
static int break_value[6] = { 0, 7, 14, 21, 40, 80 }; // *10mS | |||
static const int break_value[6] = { 0, 7, 14, 21, 40, 80 }; // *10mS | |||
value = attrlookup(attr1, mnem_break); | |||
if (value < 3) { | |||
// adjust prepause on the following word |
@@ -253,6 +253,8 @@ static char *WritePitch(int env, int pitch1, int pitch2, int split, int final) | |||
char buf[50]; | |||
static char output[50]; | |||
MAKE_MEM_UNDEFINED(&output, sizeof(output)); | |||
output[0] = 0; | |||
pitch_env = envelope_data[env]; | |||
@@ -208,6 +208,8 @@ frameref_t *LookupSpect(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, | |||
frame_t *frame; | |||
static frameref_t frames_buf[N_SEQ_FRAMES]; | |||
MAKE_MEM_UNDEFINED(&frames_buf, sizeof(frames_buf)); | |||
seq = (SPECT_SEQ *)(&phondata_ptr[fmt_params->fmt_addr]); | |||
seqk = (SPECT_SEQK *)seq; | |||
nf = seq->n_frames; | |||
@@ -428,7 +430,7 @@ static bool StressCondition(Translator *tr, PHONEME_LIST *plist, int condition, | |||
{ | |||
int stress_level; | |||
PHONEME_LIST *pl; | |||
static int condition_level[4] = { 1, 2, 4, 15 }; | |||
static const int condition_level[4] = { 1, 2, 4, 15 }; | |||
if (phoneme_tab[plist[0].phcode]->type == phVOWEL) | |||
pl = plist; |
@@ -43,6 +43,7 @@ | |||
#include "translate.h" // for translator, LANGUAGE_OPTIONS, Trans... | |||
#include "voice.h" // for voice_t, voice, LoadVoiceVariant | |||
#include "wavegen.h" // for WcmdqInc, WcmdqFree, WcmdqStop | |||
#include "speech.h" // for MAKE_MEM_UNDEFINED | |||
static void SmoothSpect(void); | |||
@@ -77,6 +78,8 @@ const char *WordToString(unsigned int word) | |||
int ix; | |||
static char buf[5]; | |||
MAKE_MEM_UNDEFINED(&buf, sizeof(buf)); | |||
for (ix = 0; ix < 4; ix++) | |||
buf[ix] = word >> (ix*8); | |||
buf[4] = 0; | |||
@@ -388,6 +391,8 @@ static frame_t *AllocFrame() | |||
ix++; | |||
if (ix >= N_FRAME_POOL) | |||
ix = 0; | |||
MAKE_MEM_UNDEFINED(&frame_pool[ix], sizeof(frame_pool[ix])); | |||
return &frame_pool[ix]; | |||
} | |||
@@ -553,7 +558,7 @@ int FormantTransition2(frameref_t *seq, int *n_frames, unsigned int data1, unsig | |||
#define N_VCOLOUR 2 | |||
// percentage change for each formant in 256ths | |||
static short vcolouring[N_VCOLOUR][5] = { | |||
static const short vcolouring[N_VCOLOUR][5] = { | |||
{ 243, 272, 256, 256, 256 }, // palatal consonant follows | |||
{ 256, 256, 240, 240, 240 }, // retroflex | |||
}; |
@@ -1210,7 +1210,7 @@ Translator *SelectTranslator(const char *name) | |||
break; | |||
case L('m', 'k'): // Macedonian | |||
{ | |||
static wchar_t vowels_cyrillic[] = { | |||
static const wchar_t vowels_cyrillic[] = { | |||
// also include 'р' [R] | |||
0x440, 0x430, 0x435, 0x438, 0x439, 0x43e, 0x443, 0x44b, 0x44d, | |||
0x44e, 0x44f, 0x450, 0x451, 0x456, 0x457, 0x45d, 0x45e, 0 | |||
@@ -1558,7 +1558,7 @@ Translator *SelectTranslator(const char *name) | |||
{ | |||
static const short stress_lengths_vi[8] = { 150, 150, 180, 180, 210, 230, 230, 240 }; | |||
static const unsigned char stress_amps_vi[] = { 16, 16, 16, 16, 22, 22, 22, 22 }; | |||
static wchar_t vowels_vi[] = { | |||
static const wchar_t vowels_vi[] = { | |||
0x61, 0xe0, 0xe1, 0x1ea3, 0xe3, 0x1ea1, // a | |||
0x103, 0x1eb1, 0x1eaf, 0x1eb3, 0x1eb5, 0x1eb7, // ă | |||
0xe2, 0x1ea7, 0x1ea5, 0x1ea9, 0x1eab, 0x1ead, // â |
@@ -47,6 +47,8 @@ | |||
Translator *translator = NULL; // the main translator | |||
Translator *translator2 = NULL; // secondary translator for certain words | |||
static char translator2_language[20] = { 0 }; | |||
Translator *translator3 = NULL; // tertiary translator for certain words | |||
static char translator3_language[20] = { 0 }; | |||
FILE *f_trans = NULL; // phoneme output text | |||
int option_tone_flags = 0; // bit 8=emphasize allcaps, bit 9=emphasize penultimate stress | |||
@@ -342,7 +344,7 @@ int utf8_out(unsigned int c, char *buf) | |||
int n_bytes; | |||
int j; | |||
int shift; | |||
static char unsigned code[4] = { 0, 0xc0, 0xe0, 0xf0 }; | |||
static const char unsigned code[4] = { 0, 0xc0, 0xe0, 0xf0 }; | |||
if (c < 0x80) { | |||
buf[0] = c; | |||
@@ -1206,35 +1208,45 @@ static void Word_EmbeddedCmd() | |||
} while (((embedded_cmd & 0x80) == 0) && (embedded_read < embedded_ix)); | |||
} | |||
int SetTranslator2(const char *new_language) | |||
static int SetAlternateTranslator(const char *new_language, Translator **translator, char translator_language[20]) | |||
{ | |||
// Set translator2 to a second language | |||
// Set alternate translator to a second language | |||
int new_phoneme_tab; | |||
if ((new_phoneme_tab = SelectPhonemeTableName(new_language)) >= 0) { | |||
if ((translator2 != NULL) && (strcmp(new_language, translator2_language) != 0)) { | |||
if ((*translator != NULL) && (strcmp(new_language, translator_language) != 0)) { | |||
// we already have an alternative translator, but not for the required language, delete it | |||
DeleteTranslator(translator2); | |||
translator2 = NULL; | |||
DeleteTranslator(*translator); | |||
*translator = NULL; | |||
} | |||
if (translator2 == NULL) { | |||
translator2 = SelectTranslator(new_language); | |||
strcpy(translator2_language, new_language); | |||
if (*translator == NULL) { | |||
*translator = SelectTranslator(new_language); | |||
strcpy(translator_language, new_language); | |||
if (LoadDictionary(translator2, translator2->dictionary_name, 0) != 0) { | |||
if (LoadDictionary(*translator, (*translator)->dictionary_name, 0) != 0) { | |||
SelectPhonemeTable(voice->phoneme_tab_ix); // revert to original phoneme table | |||
new_phoneme_tab = -1; | |||
translator2_language[0] = 0; | |||
translator_language[0] = 0; | |||
} | |||
translator2->phoneme_tab_ix = new_phoneme_tab; | |||
(*translator)->phoneme_tab_ix = new_phoneme_tab; | |||
} | |||
} | |||
if (translator2 != NULL) | |||
translator2->phonemes_repeat[0] = 0; | |||
if (*translator != NULL) | |||
(*translator)->phonemes_repeat[0] = 0; | |||
return new_phoneme_tab; | |||
} | |||
int SetTranslator2(const char *new_language) | |||
{ | |||
return SetAlternateTranslator(new_language, &translator2, translator2_language); | |||
} | |||
int SetTranslator3(const char *new_language) | |||
{ | |||
return SetAlternateTranslator(new_language, &translator3, translator3_language); | |||
} | |||
static int TranslateWord2(Translator *tr, char *word, WORD_TAB *wtab, int pre_pause) | |||
{ | |||
int flags = 0; | |||
@@ -1574,6 +1586,7 @@ static int TranslateWord2(Translator *tr, char *word, WORD_TAB *wtab, int pre_pa | |||
if (ph_code == phonSWITCH) { | |||
ph_list2[n_ph_list2].phcode = ph_code; | |||
ph_list2[n_ph_list2].stresslevel = 0; | |||
ph_list2[n_ph_list2].sourceix = 0; | |||
ph_list2[n_ph_list2].synthflags = 0; | |||
ph_list2[n_ph_list2++].tone_ph = *p; | |||
@@ -1988,6 +2001,8 @@ void TranslateClause(Translator *tr, int *tone_out, char **voice_change) | |||
if (tr == NULL) | |||
return; | |||
MAKE_MEM_UNDEFINED(&voice_change_name, sizeof(voice_change_name)); | |||
embedded_ix = 0; | |||
embedded_read = 0; | |||
pre_pause = 0; |
@@ -39,6 +39,7 @@ extern "C" | |||
#define N_WORD_PHONEMES 200 // max phonemes in a word | |||
#define N_WORD_BYTES 160 // max bytes for the UTF8 characters in a word | |||
#define N_PHONEME_BYTES 160 // max bytes for a phoneme | |||
#define N_CLAUSE_WORDS 300 // max words in a clause | |||
#define N_TR_SOURCE 800 // the source text of a single clause (UTF8 bytes) | |||
@@ -649,6 +650,7 @@ extern wchar_t option_punctlist[N_PUNCTLIST]; // which punctuation characters t | |||
extern Translator *translator; | |||
extern Translator *translator2; | |||
extern Translator *translator3; | |||
extern char dictionary_name[40]; | |||
extern espeak_ng_TEXT_DECODER *p_decoder; | |||
extern int dictionary_skipwords; | |||
@@ -679,6 +681,7 @@ ALPHABET *AlphabetFromChar(int c); | |||
Translator *SelectTranslator(const char *name); | |||
int SetTranslator2(const char *name); | |||
int SetTranslator3(const char *name); | |||
void DeleteTranslator(Translator *tr); | |||
void ProcessLanguageOptions(LANGUAGE_OPTIONS *langopts); | |||
@@ -356,10 +356,10 @@ void VoiceReset(int tone_only) | |||
// Set voice to the default values | |||
int pk; | |||
static unsigned char default_heights[N_PEAKS] = { 130, 128, 120, 116, 100, 100, 128, 128, 128 }; // changed for v.1.47 | |||
static unsigned char default_widths[N_PEAKS] = { 140, 128, 128, 160, 171, 171, 128, 128, 128 }; | |||
static const unsigned char default_heights[N_PEAKS] = { 130, 128, 120, 116, 100, 100, 128, 128, 128 }; // changed for v.1.47 | |||
static const unsigned char default_widths[N_PEAKS] = { 140, 128, 128, 160, 171, 171, 128, 128, 128 }; | |||
static int breath_widths[N_PEAKS] = { 0, 200, 200, 400, 400, 400, 600, 600, 600 }; | |||
static const int breath_widths[N_PEAKS] = { 0, 200, 200, 400, 400, 400, 600, 600, 600 }; | |||
// default is: pitch 80,118 | |||
voice->pitch_base = 0x47000; | |||
@@ -554,6 +554,12 @@ voice_t *LoadVoice(const char *vname, int control) | |||
static char voice_name[40]; // voice name for current_voice_selected | |||
static char voice_languages[100]; // list of languages and priorities for current_voice_selected | |||
if (!tone_only) { | |||
MAKE_MEM_UNDEFINED(&voice_identifier, sizeof(voice_identifier)); | |||
MAKE_MEM_UNDEFINED(&voice_name, sizeof(voice_name)); | |||
MAKE_MEM_UNDEFINED(&voice_languages, sizeof(voice_languages)); | |||
} | |||
strncpy0(voicename, vname, sizeof(voicename)); | |||
if (control & 0x10) { | |||
strcpy(buf, vname); | |||
@@ -959,6 +965,9 @@ voice_t *LoadVoice(const char *vname, int control) | |||
return NULL; // no dictionary loaded | |||
} | |||
} | |||
/* Terminate languages list with a zero-priority entry */ | |||
voice_languages[langix] = 0; | |||
} | |||
return voice; | |||
@@ -973,6 +982,7 @@ static char *ExtractVoiceVariantName(char *vname, int variant_num, int add_dir) | |||
static char variant_name[40]; | |||
char variant_prefix[5]; | |||
MAKE_MEM_UNDEFINED(&variant_name, sizeof(variant_name)); | |||
variant_name[0] = 0; | |||
sprintf(variant_prefix, "!v%c", PATHSEP); | |||
if (add_dir == 0) | |||
@@ -1310,6 +1320,9 @@ char const *SelectVoice(espeak_VOICE *voice_select, int *found) | |||
static espeak_VOICE voice_variants[N_VOICE_VARIANTS]; | |||
static char voice_id[50]; | |||
MAKE_MEM_UNDEFINED(&voice_variants, sizeof(voice_variants)); | |||
MAKE_MEM_UNDEFINED(&voice_id, sizeof(voice_id)); | |||
*found = 1; | |||
memcpy(&voice_select2, voice_select, sizeof(voice_select2)); | |||
@@ -1320,6 +1333,8 @@ char const *SelectVoice(espeak_VOICE *voice_select, int *found) | |||
// no language is specified. Get language from the named voice | |||
static char buf[60]; | |||
MAKE_MEM_UNDEFINED(&buf, sizeof(buf)); | |||
if (voice_select2.name == NULL) { | |||
if ((voice_select2.name = voice_select2.identifier) == NULL) | |||
voice_select2.name = ESPEAKNG_DEFAULT_VOICE; | |||
@@ -1510,7 +1525,7 @@ ESPEAK_NG_API espeak_ng_STATUS espeak_ng_SetVoiceByFile(const char *filename) | |||
int ix; | |||
espeak_VOICE voice_selector; | |||
char *variant_name; | |||
static char buf[60]; | |||
char buf[60]; | |||
strncpy0(buf, filename, sizeof(buf)); | |||
@@ -1547,7 +1562,7 @@ ESPEAK_NG_API espeak_ng_STATUS espeak_ng_SetVoiceByName(const char *name) | |||
int ix; | |||
espeak_VOICE voice_selector; | |||
char *variant_name; | |||
static char buf[60]; | |||
char buf[60]; | |||
strncpy0(buf, name, sizeof(buf)); | |||
@@ -1172,8 +1172,8 @@ static void SetSynth(int length, int modn, frame_t *fr1, frame_t *fr2, voice_t * | |||
int length4; | |||
int qix; | |||
int cmd; | |||
static int glottal_reduce_tab1[4] = { 0x30, 0x30, 0x40, 0x50 }; // vowel before [?], amp * 1/256 | |||
static int glottal_reduce_tab2[4] = { 0x90, 0xa0, 0xb0, 0xc0 }; // vowel after [?], amp * 1/256 | |||
static const int glottal_reduce_tab1[4] = { 0x30, 0x30, 0x40, 0x50 }; // vowel before [?], amp * 1/256 | |||
static const int glottal_reduce_tab2[4] = { 0x90, 0xa0, 0xb0, 0xc0 }; // vowel after [?], amp * 1/256 | |||
end_wave = 1; | |||
@@ -0,0 +1,61 @@ | |||
All fuzzers here are run continously through OSS-fuzz. | |||
Link to OSS-fuzz integration: Pending | |||
# Translation fuzzers | |||
Currently, there is a fuzzer related to synthetizer, **synth_fuzzer** that will target **espak_Synth**. The following sections will explain how to configure the fuzzers, how to use them and how to get a coverage report of the fuzzing result. | |||
## Configure the project for fuzzing | |||
We have added some switchs to configure.ac for fuzzing and coverage. The `--with-fuzzer` switch will check if your are actually using clang and clang++ as compilers (by looking at CC and CXX) and allows generation of compilation instructions for fuzzer targets. The `--with-coverage` will add `-fprofile-instr-generate -fcoverage-mapping` to AM_CPPFLAGS in espeak/Makefile.am. | |||
To configure and build the project with coverage and fuzzer. | |||
```./autogen.sh | |||
CC=clang CXX=clang++ ./configure --with-coverage --with-fuzzer | |||
make -j8 | |||
``` | |||
## Run the fuzzers | |||
You are now able to run the fuzzer and will have to give 2 parameters to it. First, you need to choose a language to fuzz and set the `FUZZ_VOICE` environment variable to them. Then, you need to provide a corpus with files containing sample inputs that will be used by libfuzzer to craft the data passed to the fuzzing function (the idea is to keep corpus as minimal as possible). If you don't provide any corpus directory, libfuzzer just generates random inputs. | |||
Here is how you can start fuzzing `espeak_Synth` function. | |||
``` | |||
# first we move to tests/fuzzing directory | |||
cd tests/fuzzing | |||
#to have interesting file in the corpus , there is a simple python script that allows you to do that | |||
./create_dict_corpus_file.py -c CORPUS/ | |||
# we consider here you have added corpus files into tests/fuzzing/CORPUS directory | |||
FUZZ_VOICE=en ./synth_fuzzer CORPUS/ | |||
# to run the fuzzer using parallelization | |||
# you can even set more jobs than workers (the ones that just stopped will be instantly replaced by a new fuzzer process) | |||
FUZZ_VOICE=en ./synth_fuzzer CORPUS/ -workers=8 -jobs=8 | |||
``` | |||
After running the fuzzer multiple times with the same corpus directory, it might be possible that many corpus files added by the fuzzer explores the same paths. Hopefully, libfuzzer allows you to minimize a corpus. There is a simple bash script in tests/fuzzing that allows you to do that. | |||
``` | |||
./minimize-corpus.sh CORPUS/ | |||
# if you have added a POC file in the corpus directory and you want to keep it intact, change his extension to .txt and use --preserve-txt switch that keep .txt files intact in the directory | |||
./minimize-corpus.sh --preserve-txt CORPUS/ | |||
``` | |||
## Look at fuzzer coverage | |||
If you want to see what are the source code parts that are explored by the fuzzer, you can use clang coverage. So, you have to configure with coverage switch, run the fuzzer and show coverage data from the run with llvm tools. | |||
To be able to use the coverage data, you need first to compile the raw profile data file of the run. By default, this file is created after execution under the name of default.profraw but you can specify it with `LLVM_PROFILE_FILE`. | |||
Here is how to do that. | |||
``` | |||
LLVM_PROFILE_FILE=synth_fuzzer.profraw FUZZ_VOICE=en ./synth_fuzzer CORPUS/ -workers=8 -jobs=8 | |||
# wait for a bit and press CTRL+C | |||
# compile raw profile | |||
llvm-profdata merge -sparse synth_fuzzer.profraw -o synth_fuzzer.profdata | |||
# show coverage (redlines are the one wich are reached) | |||
llvm-cov show ./synth_fuzzer -instr-profile=synth_fuzzer.profdata | |||
``` |
@@ -0,0 +1,68 @@ | |||
#!/bin/python3 | |||
# /* | |||
# * Copyright (C) 2022 Anna Stan , Mamaodou Dramé Kalilou , Nicolas Morel | |||
# * | |||
# * This program is free software; you can redistribute it and/or modify | |||
# * it under the terms of the GNU General Public License as published by | |||
# * the Free Software Foundation; either version 3 of the License, or | |||
# * (at your option) any later version. | |||
# * | |||
# * This program is distributed in the hope that it will be useful, | |||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
# * GNU General Public License for more details. | |||
# * | |||
# * You should have received a copy of the GNU General Public License | |||
# * along with this program; if not, see: <http://www.gnu.org/licenses/>. | |||
# */ | |||
import sys | |||
import mmap | |||
import argparse | |||
import shutil | |||
import os | |||
from os import O_RDONLY, O_RDWR, O_WRONLY, O_TRUNC, O_CREAT, SEEK_END, SEEK_CUR, SEEK_SET | |||
def main(argc, argv): | |||
if argc < 2: | |||
print('Summary: add file to the corpus ', file=sys.stderr) | |||
print(f'Usage: {argv[0]} -c <corpus_dir>', file=sys.stderr) | |||
exit(1) | |||
ap = argparse.ArgumentParser() | |||
# Add the arguments to the parser | |||
ap.add_argument("-c", "--corpus_dir", required=True, | |||
help="corpus directory where to add the file") | |||
args = vars(ap.parse_args()) | |||
lang_list=os.getenv("FUZZ_VOICE") | |||
if(lang_list): | |||
list=lang_list+"_list" | |||
else: | |||
list="en_list" | |||
output_name = list+"_dict_corpus.txt" | |||
output_path=args['corpus_dir']+output_name | |||
output= open(output_path, "w") | |||
path="../../dictsource/"+list | |||
file = open( path, "r") | |||
lines=file.readlines() | |||
index=1 | |||
for line in lines: | |||
if line[0]=='/' and line[1]=='/': | |||
continue | |||
res = line.split() | |||
if len(res): | |||
output.write("kw") | |||
output.write(str(index)) | |||
index=index+1 | |||
output.write("=") | |||
output.write(res[0]) | |||
output.write('\n') | |||
file.close() | |||
output.close() | |||
if __name__ == "__main__": | |||
main(len(sys.argv), sys.argv) |
@@ -0,0 +1,36 @@ | |||
#!/bin/bash | |||
if [[ $# -lt 1 ]] | |||
then | |||
echo "Usage: $0 <corpus-dir>" | |||
echo "Usage: $0 --preserve-txt <corpus-dir> (minimize corpus but keep .txt files intact)" | |||
exit 1 | |||
fi | |||
preserve_txt=0 | |||
if [[ "$1" == "--preserve-txt" ]] | |||
then | |||
preserve_txt=1 | |||
CORPUS_DIR=$2 | |||
else | |||
CORPUS_DIR=$1 | |||
fi | |||
export FUZZ_VOICE=en | |||
FUZZER=./synth_fuzzer | |||
TMP_DIR=$(mktemp -d) | |||
echo "Merging..." | |||
`$FUZZER -merge=1 $TMP_DIR $CORPUS_DIR` | |||
echo "Removing old files..." | |||
if [[ $preserve_txt -eq 1 ]] | |||
then | |||
echo " => Preserve .txt files" | |||
rm -rvf $(find $CORPUS_DIR | grep -vE "*.txt|$CORPUS_DIR") 2>/dev/null | |||
else | |||
rm -rf $CORPUS_DIR/* 2>/dev/null | |||
fi | |||
cp $TMP_DIR/* $CORPUS_DIR 2>/dev/null | |||
rm -rf $TMP_DIR | |||
echo "Merging done !" |
@@ -0,0 +1,80 @@ | |||
/* | |||
* Copyright (C) 2018 Sascha Brawer | |||
* | |||
* This program is free software; you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation; either version 3 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program; if not, write see: | |||
* <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include "config.h" | |||
#include <stdint.h> | |||
#include <stdlib.h> | |||
#include <string.h> | |||
#include <libgen.h> | |||
#include <time.h> | |||
#include <espeak-ng/espeak_ng.h> | |||
#define BOLDRED(x) "\x1b[31m\x1b[1m" x "\x1b[0m" | |||
static int initialized = 0; | |||
static int | |||
espeak_callback(short *data, int samples, espeak_EVENT *events) | |||
{ | |||
(void)data; | |||
(void)samples; | |||
(void)events; | |||
return 0; | |||
} | |||
/* See http://llvm.org/docs/LibFuzzer.html */ | |||
extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); | |||
extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) | |||
{ | |||
int buflength = size+1; | |||
if (!initialized) | |||
{ | |||
int options = espeakINITIALIZE_DONT_EXIT; | |||
espeak_Initialize(AUDIO_OUTPUT_SYNCHRONOUS, buflength, PATH_ESPEAK_DATA, options); | |||
espeak_SetSynthCallback(espeak_callback); | |||
const char *lang = getenv("FUZZ_VOICE"); | |||
if (lang == NULL) | |||
{ | |||
fprintf(stderr, "\n" BOLDRED("[Please set up FUZZ_VOICE env var before starting fuzzer]") "\n\n"); | |||
exit(1); | |||
} | |||
if (espeak_SetVoiceByName(lang) != EE_OK) | |||
{ | |||
fprintf(stderr, "\n" BOLDRED("[Please supply a valid voice in FUZZ_VOICE]") "\n\n"); | |||
exit(1); | |||
} | |||
initialized = 1; | |||
fprintf(stderr, "VOICE FUZZED = %s\n", lang); | |||
} | |||
char *mutable_data = strndup((char *)data, size); | |||
if (!mutable_data) | |||
{ | |||
perror("malloc"); | |||
exit(1); | |||
} | |||
unsigned int position = 0, position_type = POS_CHARACTER, end_position = 0 , synth_flags = espeakCHARS_AUTO; | |||
espeak_Synth(mutable_data, buflength, position, position_type, end_position, | |||
synth_flags, NULL, NULL); | |||
free(mutable_data); | |||
return 0; | |||
} |
@@ -97,6 +97,7 @@ test_phwav mk 072d0a74acf54bea528e7dde427eb04808d38364 "ma na n^a Na pa ta xa k^ | |||
test_phwav mr 5238ba08fba349fea6c00bdd8f1672ede229b8ec "ma na n.a n^a pa t#a t.a tSa ka qa p#a t.#a c#a k#a ba d#a d.a dZa ga b#a d.#a J#a g#a fa sa Sa xa va za Za Qa Ha ra r.a la ja _:_ mI mU me m@ mo mE mV mO ma mi: mu: me: mo: mE: mO: ma: m&: mI~ mi~ mU~ mu~ mU~ me~ mo~ mE~ mV~ mO~ ma~ mAI maU" | |||
test_phwav ms 75a57a020af2b62e3448792d3f6a945a9b2c6b75 "ma na n^a Na pa ba ta da ka ga ?a tSa dZa fa va Ta Da sa za Sa xa Qa ha ja wa la Ra R2a _:_ ma mE mO m@ me mo mi mu maI meI mOI maU m@U" | |||
test_phwav mt 03231022bb750335042309d6d2acd55f214a8967 "ma na Na pa ta ka ?a ba da ga p\`a t\`a k\`a tSa dZa tS\`a Ba sa za Sa Za xa ha la ja wa ra _:_ mi me my ma m@ mo mu" | |||
test_phwav mto bd45ab06741222328c2068f5a14a08b052dbdaa6 "a A e @ i 8 o oU u k k# ga t T t# da p p# b v f s s. z. ts dz m n N ra la j C a?e ha" | |||
test_phwav my 77eeafb213bfd0756319b2766be8364a2bff46ad "na Na la ja pa pha fa ta tha ka kha tS;a tS;ha S;a s.a tsa tsha ts.a ts.ha N-a _:_ ma mA mai mAu m@ m@r mE mei mi mi[ mi. miA miAu miE mio miou mo mo- mou mong mu muA mua muai mu@ mei muo my myu my& myE my@ myi _:_ ma11 ma21 ma214 ma22 ma33 ma35 ma44 ma51 ma53 ma55" | |||
test_phwav nb adbf0b2e74a76ff7bd2463223f648d479515a314 "m#a ma n#a na n^#a n^a N#a Na pa ta ca ka fa va Ta Da sa Ca J^a xa Qa ha l#a la tl#a r#a ra _:_ mi mi: mI mI: mE mE: ma ma: mO mO: mu mu: my my: mW mW: maI maI: meI meI: maU maU: moU moU: mYy mOI myI" | |||
test_phwav nci 8c578e588c4f0a283359d62754fde039b14c8aef "ma na Na pa ta ka ba da ga fa Ta sa Sa xa ha va Da za Za tSa dZa la ra ja wa t2a t#a d#a z#a r-a z/2a w#a m- n- N- _:_ mI mE ma m0 mV mU mi: mA: mO: mu: m3: mA@ mO@ mo@ mU@ mi@3 mIR mVR mi@ me@ mi m@ m3 me# mI# mI2 meI maI mOI moU maU maa mO2 maI@ maI3 maU@" |
@@ -4,10 +4,12 @@ echo -n "testing files for executable bits that shouldn't be executable ... " | |||
find * -executable -type f | \ | |||
grep -vE "compile|config\.(guess|status|sub)|configure|depcomp|install-sh|libtool|missing" | # Ignore autotools output \ | |||
grep -vE "*\.test|tests/common|src(/\.libs)?/(e?speak-ng|.*\.so\..*)|src/\.libs/lt-espeak-ng|android" | # Ignore built programs and libraries \ | |||
grep -vE "*.\.sh|tools/emoji" | # Ignore helper scripts \ | |||
grep -vE ".*\.test|tests/common|src(/\.libs)?/(e?speak-ng|.*\.so\..*)|src/\.libs/lt-espeak-ng|android" | # Ignore built programs and libraries \ | |||
grep -vE ".*\.sh|tools/emoji" | # Ignore helper scripts \ | |||
grep -vE "src/ucd-tools/tools/(.*\.py|mkencodingtable)" | # Ignore ucd-tools helper scripts \ | |||
grep -vE "tests/.libs|src/ucd-tools/tests/print(ucd|c)data(_cpp)?" | # Ignore ucd-tools test programs \ | |||
grep -vE "tests/fuzzing/.*\.py" | #Ignore fuzzing python helper script | |||
grep -vE "tests/fuzzing/.*\.sh" | #Ignore fuzzing python helper script | |||
tee tests/non-executable-files-with-executable-bit.check > /dev/null | |||
if [ -s tests/non-executable-files-with-executable-bit.check ] ; then |