Fixes #1528 Now, `klatt` and `breath`-enabled variants may be added to testsmaster
| "-x\t Write phoneme mnemonics to stdout\n" | "-x\t Write phoneme mnemonics to stdout\n" | ||||
| "-X\t Write phonemes mnemonics and translation trace to stdout\n" | "-X\t Write phonemes mnemonics and translation trace to stdout\n" | ||||
| "-z\t No final sentence pause at the end of the text\n" | "-z\t No final sentence pause at the end of the text\n" | ||||
| "-D\t Enable deterministic random mode\n" | |||||
| "--compile=<voice name>\n" | "--compile=<voice name>\n" | ||||
| "\t Compile pronunciation rules and dictionary from the current\n" | "\t Compile pronunciation rules and dictionary from the current\n" | ||||
| "\t directory. <voice name> specifies the language\n" | "\t directory. <voice name> specifies the language\n" | ||||
| int phoneme_options = 0; | int phoneme_options = 0; | ||||
| int option_linelength = 0; | int option_linelength = 0; | ||||
| int option_waveout = 0; | int option_waveout = 0; | ||||
| bool deterministic = 0; | |||||
| espeak_VOICE voice_select; | espeak_VOICE voice_select; | ||||
| char filename[200]; | char filename[200]; | ||||
| option_punctlist[0] = 0; | option_punctlist[0] = 0; | ||||
| while (true) { | while (true) { | ||||
| c = getopt_long(argc, argv, "a:b:d:f:g:hk:l:mp:qs:v:w:xXz", | |||||
| c = getopt_long(argc, argv, "a:b:Dd:f:g:hk:l:mp:qs:v:w:xXz", | |||||
| long_options, &option_index); | long_options, &option_index); | ||||
| // Detect the end of the options. | // Detect the end of the options. | ||||
| case 'd': | case 'd': | ||||
| strncpy0(devicename, optarg2, sizeof(devicename)); | strncpy0(devicename, optarg2, sizeof(devicename)); | ||||
| break; | break; | ||||
| case 'D': | |||||
| deterministic = 1; | |||||
| break; | |||||
| case 'h': | case 'h': | ||||
| printf("\n"); | printf("\n"); | ||||
| PrintVersion(); | PrintVersion(); | ||||
| exit(1); | exit(1); | ||||
| } | } | ||||
| if (deterministic) { | |||||
| // Set random generator state to well-known | |||||
| espeak_ng_SetRandSeed(1); | |||||
| } | |||||
| if (option_waveout || quiet) { | if (option_waveout || quiet) { | ||||
| // writing to a file (or no output), we can use synchronous mode | // writing to a file (or no output), we can use synchronous mode | ||||
| result = espeak_ng_InitializeOutput(ENOUTPUT_MODE_SYNCHRONOUS, 0, devicename[0] ? devicename : NULL); | result = espeak_ng_InitializeOutput(ENOUTPUT_MODE_SYNCHRONOUS, 0, devicename[0] ? devicename : NULL); |
| ESPEAK_NG_API espeak_ng_STATUS | ESPEAK_NG_API espeak_ng_STATUS | ||||
| espeak_ng_SetConstF0(int f0); | espeak_ng_SetConstF0(int f0); | ||||
| ESPEAK_NG_API espeak_ng_STATUS | |||||
| espeak_ng_SetRandSeed(long seed); | |||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||
| } | } |
| return ucd_tolower(c); | return ucd_tolower(c); | ||||
| } | } | ||||
| static uint32_t espeak_rand_state = 0; | |||||
| long espeak_rand(long min, long max) { | |||||
| // Ref: https://github.com/bminor/glibc/blob/glibc-2.36/stdlib/random_r.c#L364 | |||||
| espeak_rand_state = (((uint64_t)espeak_rand_state * 1103515245) + 12345) % 0x7fffffff; | |||||
| long res = (long)espeak_rand_state; | |||||
| return (res % (max-min+1))-min; | |||||
| } | |||||
| void espeak_srand(long seed) { | |||||
| espeak_rand_state = (uint32_t)(seed); | |||||
| (void)espeak_rand(0, 1); // Dummy flush a generator | |||||
| } | |||||
| #pragma GCC visibility push(default) | |||||
| ESPEAK_NG_API espeak_ng_STATUS | |||||
| espeak_ng_SetRandSeed(long seed) { | |||||
| espeak_srand(seed); | |||||
| return ENS_OK; | |||||
| } | |||||
| #pragma GCC visibility pop |
| extern ESPEAK_NG_API int GetFileLength(const char *filename); | extern ESPEAK_NG_API int GetFileLength(const char *filename); | ||||
| extern ESPEAK_NG_API void strncpy0(char *to, const char *from, int size); | extern ESPEAK_NG_API void strncpy0(char *to, const char *from, int size); | ||||
| void espeak_srand(long seed); | |||||
| long espeak_rand(long min, long max); | |||||
| int IsAlpha(unsigned int c); | int IsAlpha(unsigned int c); | ||||
| int IsBracket(int c); | int IsBracket(int c); | ||||
| int IsDigit(unsigned int c); | int IsDigit(unsigned int c); |
| #include <espeak-ng/speak_lib.h> | #include <espeak-ng/speak_lib.h> | ||||
| #include "klatt.h" | #include "klatt.h" | ||||
| #include "common.h" // for espeak_rand | |||||
| #include "synthesize.h" // for frame_t, WGEN_DATA, STEPSIZE, N_KLATTP, echo... | #include "synthesize.h" // for frame_t, WGEN_DATA, STEPSIZE, N_KLATTP, echo... | ||||
| #include "voice.h" // for voice_t, N_PEAKS | #include "voice.h" // for voice_t, N_PEAKS | ||||
| #ifdef INCLUDE_SPEECHPLAYER | #ifdef INCLUDE_SPEECHPLAYER | ||||
| static int nsamples; | static int nsamples; | ||||
| static int sample_count; | static int sample_count; | ||||
| #ifdef _MSC_VER | |||||
| #define getrandom(min, max) ((rand()%(int)(((max)+1)-(min)))+(min)) | |||||
| #else | |||||
| #define getrandom(min, max) ((rand()%(long)(((max)+1)-(min)))+(min)) | |||||
| #endif | |||||
| #define getrandom(min, max) espeak_rand((min), (max)) | |||||
| // function prototypes for functions private to this file | // function prototypes for functions private to this file | ||||
| temp_diff = ftemp - (double)itemp; | temp_diff = ftemp - (double)itemp; | ||||
| current_value = samples[itemp]; | |||||
| next_value = samples[itemp+1]; | |||||
| current_value = samples[(itemp) % kt_globals.num_samples]; | |||||
| next_value = samples[(itemp+1) % kt_globals.num_samples]; | |||||
| diff_value = (double)next_value - (double)current_value; | diff_value = (double)next_value - (double)current_value; | ||||
| diff_value = diff_value * temp_diff; | diff_value = diff_value * temp_diff; | ||||
| result = samples[itemp] + diff_value; | |||||
| result = samples[(itemp) % kt_globals.num_samples] + diff_value; | |||||
| result = result * kt_globals.sample_factor; | result = result * kt_globals.sample_factor; | ||||
| } else | } else | ||||
| result = 0; | result = 0; | ||||
| } | } | ||||
| for (ix = 0; ix < N_KLATTP; ix++) { | for (ix = 0; ix < N_KLATTP; ix++) { | ||||
| if ((ix >= 5) && ((fr1->frflags & FRFLAG_KLATT) == 0)) { | |||||
| if ((ix >= 5) || ((fr1->frflags & FRFLAG_KLATT) == 0)) { | |||||
| klattp1[ix] = klattp[ix] = 0; | klattp1[ix] = klattp[ix] = 0; | ||||
| klattp_inc[ix] = 0; | klattp_inc[ix] = 0; | ||||
| } else { | } else { |
| option_phonemes = 0; | option_phonemes = 0; | ||||
| option_phoneme_events = 0; | option_phoneme_events = 0; | ||||
| // Seed random generator | |||||
| espeak_srand(time(NULL)); | |||||
| return ENS_OK; | return ENS_OK; | ||||
| } | } | ||||
| #include <espeak-ng/speak_lib.h> | #include <espeak-ng/speak_lib.h> | ||||
| #include "wavegen.h" | #include "wavegen.h" | ||||
| #include "common.h" // for espeak_rand | |||||
| #include "synthesize.h" // for WGEN_DATA, RESONATOR, frame_t | #include "synthesize.h" // for WGEN_DATA, RESONATOR, frame_t | ||||
| #include "mbrola.h" // for MbrolaFill, MbrolaReset, mbrola... | #include "mbrola.h" // for MbrolaFill, MbrolaReset, mbrola... | ||||
| int ix; | int ix; | ||||
| // use two random numbers, for alternate formants | // use two random numbers, for alternate formants | ||||
| noise = (rand() & 0x3fff) - 0x2000; | |||||
| noise = espeak_rand(-0x2000, 0x1fff); | |||||
| for (ix = 1; ix < N_PEAKS; ix++) { | for (ix = 1; ix < N_PEAKS; ix++) { | ||||
| int amp; | int amp; |
| # Test some common commands to find the correct one for the system being tested on. | # Test some common commands to find the correct one for the system being tested on. | ||||
| } | } | ||||
| # test if Klatt synthesizer is installed | |||||
| is_klatt() { | |||||
| echo -n "checking if klatt is installed ... " | |||||
| if [ "`which klatt`" != "" ]; then | |||||
| echo "yes" | |||||
| else | |||||
| echo "no" | |||||
| exit | |||||
| fi | |||||
| } | |||||
| # test if MBROLA synthesizer is installed | # test if MBROLA synthesizer is installed | ||||
| is_mbrola() { | is_mbrola() { | ||||
| echo -n "checking if MBROLA is installed ... " | echo -n "checking if MBROLA is installed ... " | ||||
| echo "testing ${VOICE}${MESSAGE}" | echo "testing ${VOICE}${MESSAGE}" | ||||
| ESPEAK_DATA_PATH=`pwd` LD_LIBRARY_PATH=src:${LD_LIBRARY_PATH} \ | ESPEAK_DATA_PATH=`pwd` LD_LIBRARY_PATH=src:${LD_LIBRARY_PATH} \ | ||||
| $VALGRIND src/espeak-ng --stdout -v ${VOICE} "${TEST_TEXT}" \ | |||||
| $VALGRIND src/espeak-ng -D --stdout -v ${VOICE} "${TEST_TEXT}" \ | |||||
| > actual.txt || exit 1 | > actual.txt || exit 1 | ||||
| < actual.txt $sha1sum | awk '{ print $1 }' > sum.txt | < actual.txt $sha1sum | awk '{ print $1 }' > sum.txt | ||||
| echo "${EXPECTED}" > expected.txt | echo "${EXPECTED}" > expected.txt | ||||
| MESSAGE=$4 | MESSAGE=$4 | ||||
| echo "testing ${VOICE}${MESSAGE}" | echo "testing ${VOICE}${MESSAGE}" | ||||
| ESPEAK_DATA_PATH=`pwd` LD_LIBRARY_PATH=src:${LD_LIBRARY_PATH} \ | ESPEAK_DATA_PATH=`pwd` LD_LIBRARY_PATH=src:${LD_LIBRARY_PATH} \ | ||||
| $VALGRIND src/espeak-ng --stdout -v ${VOICE} "${TEST_TEXT}" \ | |||||
| $VALGRIND src/espeak-ng -D --stdout -v ${VOICE} "${TEST_TEXT}" \ | |||||
| > actual.txt || exit 1 | > actual.txt || exit 1 | ||||
| < actual.txt $sha1sum | awk '{ print $1 }' > sum.txt | < actual.txt $sha1sum | awk '{ print $1 }' > sum.txt | ||||
| if [ "$MESSAGE" = "Ignore" ] ; then | if [ "$MESSAGE" = "Ignore" ] ; then | ||||
| cat sum.txt | grep -E "$EXPECTED" || (echo "... ignoring error" && true) | cat sum.txt | grep -E "$EXPECTED" || (echo "... ignoring error" && true) | ||||
| else | else | ||||
| cat sum.txt | grep -E "$EXPECTED" || { printf "wrong hash: "; cat actual.txt; exit 1; } | |||||
| cat sum.txt | grep -E "$EXPECTED" || { printf "wrong hash: "; cat sum.txt; exit 1; } | |||||
| fi | fi | ||||
| } | } | ||||
| . "`dirname $0`/common" | . "`dirname $0`/common" | ||||
| # and run needed checks before | # and run needed checks before | ||||
| is_hash | is_hash | ||||
| is_klatt | |||||
| # call actual test functions | # call actual test functions | ||||
| test_wav_grep en+klatt "4b91f47e4be93993e53bbc04cbee7378118f990a" "The quick brown fox jumps over the lazy dog" | |||||
| test_wav_grep en+klatt2 "bc99291590ff83b1e877688633adf3c20a65cd9c" "The quick brown fox jumps over the lazy dog" | |||||
| test_wav_grep en+klatt3 "b6e89f4027d173166f49e4d933361651b43f4ca8|2bcc5a6e6c2fc4cd43f41c6a4bdf026c370a1fe9" "The quick brown fox jumps over the lazy dog" | |||||
| # this voice seems to make random sound/hashes | |||||
| #test_wav en+klatt4 "377767780368115863cde5cc11c0203cfdd48476" "The quick brown fox jumps over the lazy dog" | |||||
| test_wav_grep en+klatt5 "6665329b413244b9846533ce207f0ee3d6e55094" "The quick brown fox jumps over the lazy dog" | |||||
| test_wav en+klatt "8155a2249db8f6fe5f3b1d4fd00c35d09ceb6c82" "The quick brown fox jumps over the lazy dog" | |||||
| test_wav en+klatt2 "90559a2ff9973c3ccf1eb7e71579fedfedbd3c67" "The quick brown fox jumps over the lazy dog" | |||||
| test_wav en+klatt3 "a636bc97d68fbec753c7cecc718b539c87627095" "The quick brown fox jumps over the lazy dog" | |||||
| test_wav en+klatt4 "653e243019c9462c7a9a90f4b03326d45b45f41c" "The quick brown fox jumps over the lazy dog" | |||||
| test_wav en+klatt5 "6665329b413244b9846533ce207f0ee3d6e55094" "The quick brown fox jumps over the lazy dog" |
| test_wav "en+nonexisting" 029983e9084e04384af8a0816fb667e5c5e06389 "Testing variants" | test_wav "en+nonexisting" 029983e9084e04384af8a0816fb667e5c5e06389 "Testing variants" | ||||
| test_wav "en+f1" dba359ac75ec33cc9cd4bd2af5031a3dbd84427c "Testing variants" | test_wav "en+f1" dba359ac75ec33cc9cd4bd2af5031a3dbd84427c "Testing variants" | ||||
| test_wav "en+anikaRobot" d56012d8f4cfb4c36fdad31ad9ad7abda40ef474 "Testing variants" | test_wav "en+anikaRobot" d56012d8f4cfb4c36fdad31ad9ad7abda40ef474 "Testing variants" | ||||
| test_wav "en+Demonic" cc24431d23ce6d0a36f6a46df374f995beeb2863 "Testing variants" | |||||
| test_wav "en+klatt4" e03e3c6204de48d3e5b172cca4cca1ff09461ee1 "Testing variants" |