From 4a2890250b95f5d3f72a9fd468809fcf1685abe4 Mon Sep 17 00:00:00 2001 From: Juho Hiltunen Date: Sun, 2 Oct 2022 13:07:21 +0300 Subject: [PATCH 01/20] code cleanup: new file langopts.c for handling language options. The switch case in LoadVoice() currently mixes voice and language options. This change will start separating them into two functions. CheckTranslator will be moved to langopts.c. In the future there should be no need to use it in voices.c. There will be other temporary solutions also. --- Makefile.am | 2 + android/jni/Android.mk | 1 + src/libespeak-ng/langopts.c | 110 +++++++++++++++++++++++ src/libespeak-ng/voice.h | 4 + src/libespeak-ng/voices.c | 14 ++- src/windows/libespeak-ng.vcxproj | 4 +- src/windows/libespeak-ng.vcxproj.filters | 8 +- 7 files changed, 132 insertions(+), 11 deletions(-) create mode 100644 src/libespeak-ng/langopts.c diff --git a/Makefile.am b/Makefile.am index 462220d5..73f66f3a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -165,6 +165,7 @@ src_libespeak_ng_la_SOURCES = \ src/libespeak-ng/espeak_api.c \ src/libespeak-ng/ieee80.c \ src/libespeak-ng/intonation.c \ + src/libespeak-ng/langopts.c \ src/libespeak-ng/mnemonics.c \ src/libespeak-ng/numbers.c \ src/libespeak-ng/readclause.c \ @@ -195,6 +196,7 @@ noinst_HEADERS = \ src/libespeak-ng/ieee80.h \ src/libespeak-ng/intonation.h \ src/libespeak-ng/klatt.h \ + src/libespeak-ng/langopts.h \ src/libespeak-ng/mbrola.h \ src/libespeak-ng/mbrowrap.h \ src/libespeak-ng/mnemonics.h \ diff --git a/android/jni/Android.mk b/android/jni/Android.mk index c88f52f7..209641d1 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -30,6 +30,7 @@ ESPEAK_SOURCES := \ src/libespeak-ng/ieee80.c \ src/libespeak-ng/intonation.c \ src/libespeak-ng/klatt.c \ + src/libespeak-ng/langopts.c \ src/libespeak-ng/mnemonics.c \ src/libespeak-ng/numbers.c \ src/libespeak-ng/phoneme.c \ diff --git a/src/libespeak-ng/langopts.c b/src/libespeak-ng/langopts.c new file mode 100644 index 00000000..6b4dc6e6 --- /dev/null +++ b/src/libespeak-ng/langopts.c @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2005 to 2015 by Jonathan Duddington + * email: jonsd@users.sourceforge.net + * Copyright (C) 2015-2017 Reece H. Dunn + * Copyright (C) 2022 Juho Hiltunen + * + * 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: . + */ + +#include "config.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include "langopts.h" +#include "mnemonics.h" // for MNEM_TAB +#include "translate.h" // for Translator +#include "voice.h" // for CheckTranslator() + +enum { + V_NAME = 1, + V_LANGUAGE, + V_GENDER, + V_PHONEMES, + V_DICTIONARY, + V_VARIANTS, + + V_MAINTAINER, + V_STATUS, + + // these affect voice quality, are independent of language + V_FORMANT, + V_PITCH, + V_ECHO, + V_FLUTTER, + V_ROUGHNESS, + V_CLARITY, + V_TONE, + V_VOICING, + V_BREATH, + V_BREATHW, + + // these override defaults set by the translator + V_LOWERCASE_SENTENCE, + V_WORDGAP, + V_INTONATION, + V_TUNES, + V_STRESSLENGTH, + V_STRESSAMP, + V_STRESSADD, + V_DICTRULES, + V_STRESSRULE, + V_STRESSOPT, + V_NUMBERS, + + V_MBROLA, + V_KLATT, + V_FAST, + V_SPEED, + V_DICTMIN, + + // these need a phoneme table to have been specified + V_REPLACE, + V_CONSONANTS +}; + +static const MNEM_TAB langopts_tab[] = { + { "maintainer", V_MAINTAINER }, + { "status", V_STATUS }, + { "lowercaseSentence", V_LOWERCASE_SENTENCE }, + + { NULL, 0 } +}; + +extern int CheckTranslator(Translator *tr, const MNEM_TAB *keyword_tab, int key); + +void LoadLanguageOptions(Translator *translator, int key ) { + switch (key) + { + case V_LOWERCASE_SENTENCE: { + if (CheckTranslator(translator, langopts_tab, key) != 0) + break; + + translator->langopts.lowercase_sentence = true; + break; + } + + break; + case V_MAINTAINER: + case V_STATUS: + break; + } +} diff --git a/src/libespeak-ng/voice.h b/src/libespeak-ng/voice.h index 04f1e9e4..610e77ed 100644 --- a/src/libespeak-ng/voice.h +++ b/src/libespeak-ng/voice.h @@ -22,6 +22,9 @@ #include +#include "mnemonics.h" +#include "translate.h" + #ifdef __cplusplus extern "C" { @@ -81,6 +84,7 @@ extern espeak_VOICE current_voice_selected; extern voice_t *voice; extern int tone_points[12]; +int CheckTranslator(Translator *tr, const MNEM_TAB *keyword_tab, int key); const char *SelectVoice(espeak_VOICE *voice_select, int *found); espeak_VOICE *SelectVoiceByName(espeak_VOICE **voices, const char *name); voice_t *LoadVoice(const char *voice_name, int control); diff --git a/src/libespeak-ng/voices.c b/src/libespeak-ng/voices.c index fd2ad538..570fac0a 100644 --- a/src/libespeak-ng/voices.c +++ b/src/libespeak-ng/voices.c @@ -41,6 +41,7 @@ #include "voice.h" // for voice_t, DoVoiceChange, N_PEAKS #include "common.h" // for GetFileLength, strncpy0 #include "dictionary.h" // for LoadDictionary +#include "langopts.h" // for LoadLanguageOptions #include "mnemonics.h" // for LookupMnemName, MNEM_TAB #include "phoneme.h" // for REPLACE_PHONEMES, n_replace_pho... #include "speech.h" // for PATHSEP @@ -50,6 +51,8 @@ #include "translate.h" // for LANGUAGE_OPTIONS, DeleteTranslator #include "wavegen.h" // for InitBreath + + static const MNEM_TAB genders[] = { { "male", ENGENDER_MALE }, { "female", ENGENDER_FEMALE }, @@ -501,7 +504,7 @@ static void ReadNumbers(char *p, int *flags, int maxValue, const MNEM_TAB *keyw } } -static int CheckTranslator(Translator *tr, const MNEM_TAB *keyword_tab, int key) +int CheckTranslator(Translator *tr, const MNEM_TAB *keyword_tab, int key) { // Return 0 if translator is set. // Return 1 and print an error message for specified key if not @@ -629,6 +632,7 @@ voice_t *LoadVoice(const char *vname, int control) key = LookupMnem(keyword_tab, buf); + LoadLanguageOptions(translator, key); switch (key) { case V_LANGUAGE: @@ -693,14 +697,6 @@ voice_t *LoadVoice(const char *vname, int control) case V_FORMANT: VoiceFormant(p); break; - case V_LOWERCASE_SENTENCE: { - if (CheckTranslator(translator, keyword_tab, key) != 0) - break; - - translator->langopts.lowercase_sentence = true; - break; - } - case V_PITCH: // default is pitch 82 118 if (sscanf(p, "%d %d", &pitch1, &pitch2) == 2) { diff --git a/src/windows/libespeak-ng.vcxproj b/src/windows/libespeak-ng.vcxproj index 8812d016..1ea3935d 100644 --- a/src/windows/libespeak-ng.vcxproj +++ b/src/windows/libespeak-ng.vcxproj @@ -177,6 +177,7 @@ + @@ -210,6 +211,7 @@ + @@ -232,4 +234,4 @@ - \ No newline at end of file + diff --git a/src/windows/libespeak-ng.vcxproj.filters b/src/windows/libespeak-ng.vcxproj.filters index 74b04244..b60291ae 100644 --- a/src/windows/libespeak-ng.vcxproj.filters +++ b/src/windows/libespeak-ng.vcxproj.filters @@ -90,6 +90,9 @@ Source Files + + Source Files + Source Files @@ -197,6 +200,9 @@ Header Files + + Header Files + Header Files @@ -227,4 +233,4 @@ Source Files - \ No newline at end of file + From 77282aca34e9442e4f07b394de45415d386aa9c0 Mon Sep 17 00:00:00 2001 From: Juho Hiltunen Date: Mon, 3 Oct 2022 19:43:05 +0300 Subject: [PATCH 02/20] cleanup: move stressLength to LoadLanguageOptions() --- src/libespeak-ng/langopts.c | 30 ++++++++++++++++++++++-------- src/libespeak-ng/voice.h | 1 + src/libespeak-ng/voices.c | 21 +++++---------------- 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/libespeak-ng/langopts.c b/src/libespeak-ng/langopts.c index 6b4dc6e6..fb47186d 100644 --- a/src/libespeak-ng/langopts.c +++ b/src/libespeak-ng/langopts.c @@ -82,18 +82,19 @@ enum { }; static const MNEM_TAB langopts_tab[] = { - { "maintainer", V_MAINTAINER }, - { "status", V_STATUS }, { "lowercaseSentence", V_LOWERCASE_SENTENCE }, + { "stressLength", V_STRESSLENGTH }, - { NULL, 0 } + { "maintainer", V_MAINTAINER }, + { "status", V_STATUS }, + + { NULL, 0 } }; -extern int CheckTranslator(Translator *tr, const MNEM_TAB *keyword_tab, int key); +void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) { + int ix; -void LoadLanguageOptions(Translator *translator, int key ) { - switch (key) - { + switch (key) { case V_LOWERCASE_SENTENCE: { if (CheckTranslator(translator, langopts_tab, key) != 0) break; @@ -101,8 +102,21 @@ void LoadLanguageOptions(Translator *translator, int key ) { translator->langopts.lowercase_sentence = true; break; } + case V_STRESSLENGTH: { + if (CheckTranslator(translator, langopts_tab, key) != 0) + break; + + //printf("parsing: %s", keyValue); + int stress_lengths_set = 0; + int stress_lengths[8]; + stress_lengths_set = Read8Numbers(keyValue, stress_lengths); + + for (ix = 0; ix < stress_lengths_set; ix++) { + translator->stress_lengths[ix] = stress_lengths[ix]; + } + break; + } - break; case V_MAINTAINER: case V_STATUS: break; diff --git a/src/libespeak-ng/voice.h b/src/libespeak-ng/voice.h index 610e77ed..bf0517ac 100644 --- a/src/libespeak-ng/voice.h +++ b/src/libespeak-ng/voice.h @@ -91,6 +91,7 @@ voice_t *LoadVoice(const char *voice_name, int control); voice_t *LoadVoiceVariant(const char *voice_name, int variant); espeak_ng_STATUS DoVoiceChange(voice_t *v); void WavegenSetVoice(voice_t *v); +int Read8Numbers(char *data_in, int data[8]); void ReadTonePoints(char *string, int *tone_pts); void VoiceReset(int control); void FreeVoiceList(void); diff --git a/src/libespeak-ng/voices.c b/src/libespeak-ng/voices.c index 570fac0a..8f00db51 100644 --- a/src/libespeak-ng/voices.c +++ b/src/libespeak-ng/voices.c @@ -1,3 +1,4 @@ + /* * Copyright (C) 2005 to 2015 by Jonathan Duddington * email: jonsd@users.sourceforge.net @@ -134,9 +135,9 @@ static const MNEM_TAB keyword_tab[] = { { "pitch", V_PITCH }, { "phonemes", V_PHONEMES }, { "dictionary", V_DICTIONARY }, - { "stressLength", V_STRESSLENGTH }, { "stressAmp", V_STRESSAMP }, { "stressAdd", V_STRESSADD }, + { "stressLength", V_STRESSLENGTH }, { "intonation", V_INTONATION }, { "tunes", V_TUNES }, { "dictrules", V_DICTRULES }, @@ -476,7 +477,7 @@ static void PhonemeReplacement(char *p) replace_phonemes[n_replace_phonemes++].type = flags; } -static int Read8Numbers(char *data_in, int data[8]) +int Read8Numbers(char *data_in, int data[8]) { // Read 8 integer numbers memset(data, 0, 8*sizeof(int)); @@ -632,7 +633,8 @@ voice_t *LoadVoice(const char *vname, int control) key = LookupMnem(keyword_tab, buf); - LoadLanguageOptions(translator, key); + LoadLanguageOptions(translator, key, p); + switch (key) { case V_LANGUAGE: @@ -706,20 +708,7 @@ voice_t *LoadVoice(const char *vname, int control) voice->formant_factor = (int)((1+factor/4) * 256); // nominal formant shift for a different voice pitch } break; - case V_STRESSLENGTH: {// stressLength - if (CheckTranslator(translator, keyword_tab, key) != 0) - break; - int stress_lengths_set = 0; - int stress_lengths[8]; - stress_lengths_set = Read8Numbers(p, stress_lengths); - - for (ix = 0; ix < stress_lengths_set; ix++) { - translator->stress_lengths[ix] = stress_lengths[ix]; - } - - break; - } case V_STRESSAMP: { // stressAmp if (CheckTranslator(translator, keyword_tab, key) != 0) break; From db57230320b27c874e0629161c5bffe28cfb352f Mon Sep 17 00:00:00 2001 From: Juho Hiltunen Date: Mon, 3 Oct 2022 20:08:37 +0300 Subject: [PATCH 03/20] fixup error message for Bad Voice attribute. We currently have two switch statements. Every key should go to only one of them. --- src/libespeak-ng/langopts.c | 10 +- src/libespeak-ng/voices.c | 535 ++++++++++++++++++------------------ 2 files changed, 273 insertions(+), 272 deletions(-) diff --git a/src/libespeak-ng/langopts.c b/src/libespeak-ng/langopts.c index fb47186d..1ec8ba2c 100644 --- a/src/libespeak-ng/langopts.c +++ b/src/libespeak-ng/langopts.c @@ -81,15 +81,7 @@ enum { V_CONSONANTS }; -static const MNEM_TAB langopts_tab[] = { - { "lowercaseSentence", V_LOWERCASE_SENTENCE }, - { "stressLength", V_STRESSLENGTH }, - - { "maintainer", V_MAINTAINER }, - { "status", V_STATUS }, - - { NULL, 0 } -}; +extern const MNEM_TAB langopts_tab[]; void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) { int ix; diff --git a/src/libespeak-ng/voices.c b/src/libespeak-ng/voices.c index 8f00db51..748ae95f 100644 --- a/src/libespeak-ng/voices.c +++ b/src/libespeak-ng/voices.c @@ -120,16 +120,21 @@ enum { V_CONSONANTS }; +const MNEM_TAB langopts_tab[] = { + { "lowercaseSentence", V_LOWERCASE_SENTENCE }, + { "stressLength", V_STRESSLENGTH }, + + { "maintainer", V_MAINTAINER }, + { "status", V_STATUS }, + + { NULL, 0 } +}; + + static const MNEM_TAB keyword_tab[] = { { "name", V_NAME }, { "language", V_LANGUAGE }, { "gender", V_GENDER }, - - { "maintainer", V_MAINTAINER }, - { "status", V_STATUS }, - - - { "lowercaseSentence", V_LOWERCASE_SENTENCE }, { "variants", V_VARIANTS }, { "formant", V_FORMANT }, { "pitch", V_PITCH }, @@ -137,7 +142,6 @@ static const MNEM_TAB keyword_tab[] = { { "dictionary", V_DICTIONARY }, { "stressAmp", V_STRESSAMP }, { "stressAdd", V_STRESSADD }, - { "stressLength", V_STRESSLENGTH }, { "intonation", V_INTONATION }, { "tunes", V_TUNES }, { "dictrules", V_DICTRULES }, @@ -631,293 +635,298 @@ voice_t *LoadVoice(const char *vname, int control) if (buf[0] == 0) continue; - key = LookupMnem(keyword_tab, buf); + key = LookupMnem(langopts_tab, buf); - LoadLanguageOptions(translator, key, p); + if (key != 0) { + LoadLanguageOptions(translator, key, p); + } else { + key = LookupMnem(keyword_tab, buf); + switch (key) + { + case V_LANGUAGE: + { + unsigned int len; + int priority; - switch (key) - { - case V_LANGUAGE: - { - unsigned int len; - int priority; + if (tone_only) + break; - if (tone_only) - break; + priority = DEFAULT_LANGUAGE_PRIORITY; + language_name[0] = 0; - priority = DEFAULT_LANGUAGE_PRIORITY; - language_name[0] = 0; + sscanf(p, "%s %d", language_name, &priority); + if (strcmp(language_name, "variant") == 0) + break; - sscanf(p, "%s %d", language_name, &priority); - if (strcmp(language_name, "variant") == 0) - break; + len = strlen(language_name) + 2; + // check for space in languages[] + if (len < (sizeof(voice_languages)-langix-1)) { + voice_languages[langix] = priority; - len = strlen(language_name) + 2; - // check for space in languages[] - if (len < (sizeof(voice_languages)-langix-1)) { - voice_languages[langix] = priority; + strcpy(&voice_languages[langix+1], language_name); + langix += len; + } - strcpy(&voice_languages[langix+1], language_name); - langix += len; - } + // only act on the first language line + if (language_set == false) { + language_type = strtok(language_name, "-"); + language_set = true; + strcpy(translator_name, language_type); + strcpy(new_dictionary, language_type); + strcpy(phonemes_name, language_type); + SelectPhonemeTableName(phonemes_name); - // only act on the first language line - if (language_set == false) { - language_type = strtok(language_name, "-"); - language_set = true; - strcpy(translator_name, language_type); - strcpy(new_dictionary, language_type); - strcpy(phonemes_name, language_type); - SelectPhonemeTableName(phonemes_name); + translator = SelectTranslator(translator_name); + strncpy0(voice->language_name, language_name, sizeof(voice->language_name)); + } + } + break; + case V_NAME: + if (tone_only == 0) { + while (isspace(*p)) p++; + strncpy0(voice_name, p, sizeof(voice_name)); + } + break; + case V_GENDER: + { + int age = 0; + char vgender[80]; + sscanf(p, "%s %d", vgender, &age); + current_voice_selected.gender = LookupMnem(genders, vgender); + current_voice_selected.age = age; + } + break; + case V_DICTIONARY: // dictionary + sscanf(p, "%s", new_dictionary); + break; + case V_PHONEMES: // phoneme table + sscanf(p, "%s", phonemes_name); + break; + case V_FORMANT: + VoiceFormant(p); + break; + case V_PITCH: + // default is pitch 82 118 + if (sscanf(p, "%d %d", &pitch1, &pitch2) == 2) { + voice->pitch_base = (pitch1 - 9) << 12; + voice->pitch_range = (pitch2 - pitch1) * 108; + double factor = (double)(pitch1 - 82)/82; + voice->formant_factor = (int)((1+factor/4) * 256); // nominal formant shift for a different voice pitch + } + break; - translator = SelectTranslator(translator_name); - strncpy0(voice->language_name, language_name, sizeof(voice->language_name)); - } - } - break; - case V_NAME: - if (tone_only == 0) { - while (isspace(*p)) p++; - strncpy0(voice_name, p, sizeof(voice_name)); - } - break; - case V_GENDER: - { - int age = 0; - char vgender[80]; - sscanf(p, "%s %d", vgender, &age); - current_voice_selected.gender = LookupMnem(genders, vgender); - current_voice_selected.age = age; - } - break; - case V_DICTIONARY: // dictionary - sscanf(p, "%s", new_dictionary); - break; - case V_PHONEMES: // phoneme table - sscanf(p, "%s", phonemes_name); - break; - case V_FORMANT: - VoiceFormant(p); - break; - case V_PITCH: - // default is pitch 82 118 - if (sscanf(p, "%d %d", &pitch1, &pitch2) == 2) { - voice->pitch_base = (pitch1 - 9) << 12; - voice->pitch_range = (pitch2 - pitch1) * 108; - double factor = (double)(pitch1 - 82)/82; - voice->formant_factor = (int)((1+factor/4) * 256); // nominal formant shift for a different voice pitch - } - break; - case V_STRESSAMP: { // stressAmp - if (CheckTranslator(translator, keyword_tab, key) != 0) - break; + case V_STRESSAMP: { // stressAmp + if (CheckTranslator(translator, keyword_tab, key) != 0) + break; - int stress_amps_set = 0; - int stress_amps[8]; - stress_amps_set = Read8Numbers(p, stress_amps); - for (ix = 0; ix < stress_amps_set; ix++) { - translator->stress_amps[ix] = stress_amps[ix]; - } + int stress_amps_set = 0; + int stress_amps[8]; + stress_amps_set = Read8Numbers(p, stress_amps); + for (ix = 0; ix < stress_amps_set; ix++) { + translator->stress_amps[ix] = stress_amps[ix]; + } - break; - } - case V_STRESSADD: { // stressAdd - if (CheckTranslator(translator, keyword_tab, key) != 0) - break; + break; + } - int stress_add_set = 0; - stress_add_set = Read8Numbers(p, stress_add); + case V_STRESSADD: { // stressAdd + if (CheckTranslator(translator, keyword_tab, key) != 0) + break; - for (ix = 0; ix < stress_add_set; ix++) { - translator->stress_lengths[ix] += stress_add[ix]; - } + int stress_add_set = 0; + stress_add_set = Read8Numbers(p, stress_add); - break; - } - case V_INTONATION: // intonation - sscanf(p, "%d", &option_tone_flags); - if ((option_tone_flags & 0xff) != 0) { - if (CheckTranslator(translator, keyword_tab, key) != 0) - break; + for (ix = 0; ix < stress_add_set; ix++) { + translator->stress_lengths[ix] += stress_add[ix]; + } - translator->langopts.intonation_group = option_tone_flags & 0xff; - } - break; - case V_TUNES: - if (CheckTranslator(translator, keyword_tab, key) != 0) - break; + break; + } + case V_INTONATION: // intonation + sscanf(p, "%d", &option_tone_flags); + if ((option_tone_flags & 0xff) != 0) { + if (CheckTranslator(translator, keyword_tab, key) != 0) + break; - n = sscanf(p, "%s %s %s %s %s %s", names[0], names[1], names[2], names[3], names[4], names[5]); - translator->langopts.intonation_group = 0; + translator->langopts.intonation_group = option_tone_flags & 0xff; + } + break; + case V_TUNES: + if (CheckTranslator(translator, keyword_tab, key) != 0) + break; - for (ix = 0; ix < n; ix++) { - if (strcmp(names[ix], "NULL") == 0) - continue; + n = sscanf(p, "%s %s %s %s %s %s", names[0], names[1], names[2], names[3], names[4], names[5]); + translator->langopts.intonation_group = 0; - if ((value = LookupTune(names[ix])) < 0) - fprintf(stderr, "Unknown tune '%s'\n", names[ix]); - else - translator->langopts.tunes[ix] = value; - } - break; + for (ix = 0; ix < n; ix++) { + if (strcmp(names[ix], "NULL") == 0) + continue; - case V_DICTRULES: // conditional dictionary rules and list entries - if (CheckTranslator(translator, keyword_tab, key) != 0) - break; + if ((value = LookupTune(names[ix])) < 0) + fprintf(stderr, "Unknown tune '%s'\n", names[ix]); + else + translator->langopts.tunes[ix] = value; + } + break; - ReadNumbers(p, &translator->dict_condition, 32, keyword_tab, key); - break; - case V_STRESSOPT: - if (CheckTranslator(translator, keyword_tab, key) != 0) - break; + case V_DICTRULES: // conditional dictionary rules and list entries + if (CheckTranslator(translator, keyword_tab, key) != 0) + break; - ReadNumbers(p, &translator->langopts.stress_flags, 32, keyword_tab, key); - break; + ReadNumbers(p, &translator->dict_condition, 32, keyword_tab, key); + break; + case V_STRESSOPT: + if (CheckTranslator(translator, keyword_tab, key) != 0) + break; - case V_NUMBERS: - if (CheckTranslator(translator, keyword_tab, key) != 0) - break; + ReadNumbers(p, &translator->langopts.stress_flags, 32, keyword_tab, key); + break; - // expect a list of numbers - while (*p != 0) { - while (isspace(*p)) p++; - if ((n = atoi(p)) > 0) { - p++; - if (n < 32) { - translator->langopts.numbers |= (1 << n); - } else { - if (n < 64) - translator->langopts.numbers2 |= (1 << (n-32)); - else - fprintf(stderr, "numbers: Bad option number %d\n", n); } - } - while (isalnum(*p)) p++; - } - ProcessLanguageOptions(&(translator->langopts)); + case V_NUMBERS: + if (CheckTranslator(translator, keyword_tab, key) != 0) + break; - break; - case V_REPLACE: - if (phonemes_set == false) { - // must set up a phoneme table before we can lookup phoneme mnemonics - SelectPhonemeTableName(phonemes_name); - phonemes_set = true; - } - PhonemeReplacement(p); - break; - case V_WORDGAP: // words - if (CheckTranslator(translator, keyword_tab, key) != 0) - break; + // expect a list of numbers + while (*p != 0) { + while (isspace(*p)) p++; + if ((n = atoi(p)) > 0) { + p++; + if (n < 32) { + translator->langopts.numbers |= (1 << n); + } else { + if (n < 64) + translator->langopts.numbers2 |= (1 << (n-32)); + else + fprintf(stderr, "numbers: Bad option number %d\n", n); } + } + while (isalnum(*p)) p++; + } + ProcessLanguageOptions(&(translator->langopts)); - sscanf(p, "%d %d", &translator->langopts.word_gap, &translator->langopts.vowel_pause); - break; - case V_STRESSRULE: - if (CheckTranslator(translator, keyword_tab, key) != 0) - break; + break; + case V_REPLACE: + if (phonemes_set == false) { + // must set up a phoneme table before we can lookup phoneme mnemonics + SelectPhonemeTableName(phonemes_name); + phonemes_set = true; + } + PhonemeReplacement(p); + break; + case V_WORDGAP: // words + if (CheckTranslator(translator, keyword_tab, key) != 0) + break; - sscanf(p, "%d %d %d", &translator->langopts.stress_rule, - &translator->langopts.unstressed_wd1, - &translator->langopts.unstressed_wd2); + sscanf(p, "%d %d", &translator->langopts.word_gap, &translator->langopts.vowel_pause); + break; + case V_STRESSRULE: + if (CheckTranslator(translator, keyword_tab, key) != 0) + break; - break; - case V_ECHO: - // echo. suggest: 135mS 11% - value = 0; - voice->echo_amp = 0; - sscanf(p, "%d %d", &voice->echo_delay, &voice->echo_amp); - break; - case V_FLUTTER: // flutter - if (sscanf(p, "%d", &value) == 1) - voice->flutter = value * 32; - break; - case V_ROUGHNESS: // roughness - if (sscanf(p, "%d", &value) == 1) - voice->roughness = value; - break; - case V_CLARITY: // formantshape - if (sscanf(p, "%d", &value) == 1) { - if (value > 4) { - voice->peak_shape = 1; // squarer formant peaks - value = 4; - } - voice->n_harmonic_peaks = 1+value; - } - break; - case V_TONE: - { - int tone_data[12]; - ReadTonePoints(p, tone_data); - SetToneAdjust(voice, tone_data); - } - break; - case V_VOICING: - if (sscanf(p, "%d", &value) == 1) - voice->voicing = (value * 64)/100; - break; - case V_BREATH: - voice->breath[0] = Read8Numbers(p, &voice->breath[1]); - for (ix = 1; ix < 8; ix++) { - if (ix % 2) - voice->breath[ix] = -voice->breath[ix]; - } - break; - case V_BREATHW: - voice->breathw[0] = Read8Numbers(p, &voice->breathw[1]); - break; - case V_CONSONANTS: - value = sscanf(p, "%d %d", &voice->consonant_amp, &voice->consonant_ampv); - break; - case V_SPEED: - sscanf(p, "%d", &voice->speed_percent); - SetSpeed(3); - break; - case V_MBROLA: - { - int srate = 16000; + sscanf(p, "%d %d %d", &translator->langopts.stress_rule, + &translator->langopts.unstressed_wd1, + &translator->langopts.unstressed_wd2); - name2[0] = 0; - sscanf(p, "%s %s %d", name1, name2, &srate); - espeak_ng_STATUS status = LoadMbrolaTable(name1, name2, &srate); - if (status != ENS_OK) { - espeak_ng_PrintStatusCodeMessage(status, stderr, NULL); - fclose(f_voice); - return NULL; - } - else - voice->samplerate = srate; - } - break; - case V_KLATT: - voice->klattv[0] = 1; // default source: IMPULSIVE - Read8Numbers(p, voice->klattv); - voice->klattv[KLATT_Kopen] -= 40; - break; - case V_FAST: - sscanf(p, "%d", &speed.fast_settings); - SetSpeed(3); - break; - case V_DICTMIN: { - if (CheckTranslator(translator, keyword_tab, key) != 0) - break; + break; + case V_ECHO: + // echo. suggest: 135mS 11% + value = 0; + voice->echo_amp = 0; + sscanf(p, "%d %d", &voice->echo_delay, &voice->echo_amp); + break; + case V_FLUTTER: // flutter + if (sscanf(p, "%d", &value) == 1) + voice->flutter = value * 32; + break; + case V_ROUGHNESS: // roughness + if (sscanf(p, "%d", &value) == 1) + voice->roughness = value; + break; + case V_CLARITY: // formantshape + if (sscanf(p, "%d", &value) == 1) { + if (value > 4) { + voice->peak_shape = 1; // squarer formant peaks + value = 4; + } + voice->n_harmonic_peaks = 1+value; + } + break; + case V_TONE: + { + int tone_data[12]; + ReadTonePoints(p, tone_data); + SetToneAdjust(voice, tone_data); + } + break; + case V_VOICING: + if (sscanf(p, "%d", &value) == 1) + voice->voicing = (value * 64)/100; + break; + case V_BREATH: + voice->breath[0] = Read8Numbers(p, &voice->breath[1]); + for (ix = 1; ix < 8; ix++) { + if (ix % 2) + voice->breath[ix] = -voice->breath[ix]; + } + break; + case V_BREATHW: + voice->breathw[0] = Read8Numbers(p, &voice->breathw[1]); + break; + case V_CONSONANTS: + value = sscanf(p, "%d %d", &voice->consonant_amp, &voice->consonant_ampv); + break; + case V_SPEED: + sscanf(p, "%d", &voice->speed_percent); + SetSpeed(3); + break; + case V_MBROLA: + { + int srate = 16000; - if (sscanf(p, "%d", &value) == 1) - translator->dict_min_size = value; - break; - } + name2[0] = 0; + sscanf(p, "%s %s %d", name1, name2, &srate); + espeak_ng_STATUS status = LoadMbrolaTable(name1, name2, &srate); + if (status != ENS_OK) { + espeak_ng_PrintStatusCodeMessage(status, stderr, NULL); + fclose(f_voice); + return NULL; + } + else + voice->samplerate = srate; + } + break; + case V_KLATT: + voice->klattv[0] = 1; // default source: IMPULSIVE + Read8Numbers(p, voice->klattv); + voice->klattv[KLATT_Kopen] -= 40; + break; + case V_FAST: + sscanf(p, "%d", &speed.fast_settings); + SetSpeed(3); + break; + case V_DICTMIN: { + if (CheckTranslator(translator, keyword_tab, key) != 0) + break; - break; - case V_MAINTAINER: - case V_STATUS: - break; - default: - if ((key & 0xff00) == 0x100) { - if (CheckTranslator(translator, keyword_tab, key) != 0) - break; - sscanf(p, "%d", &translator->langopts.param[key &0xff]); - } else - fprintf(stderr, "Bad voice attribute: %s\n", buf); - break; - } + if (sscanf(p, "%d", &value) == 1) + translator->dict_min_size = value; + break; + } + + break; + case V_MAINTAINER: + case V_STATUS: + break; + default: + if ((key & 0xff00) == 0x100) { + if (CheckTranslator(translator, keyword_tab, key) != 0) + break; + sscanf(p, "%d", &translator->langopts.param[key &0xff]); + } else + fprintf(stderr, "Bad voice attribute: %s\n", buf); + break; + } + } } if (f_voice != NULL) fclose(f_voice); From 2a462e4afeb5cad3baf1779b9d5c58d457e3edff Mon Sep 17 00:00:00 2001 From: Juho Hiltunen Date: Sun, 9 Oct 2022 14:56:29 +0300 Subject: [PATCH 04/20] cleanup: move stressAdd to LoadLanguageOptions() --- src/libespeak-ng/langopts.c | 18 ++++++++++++++++++ src/libespeak-ng/voices.c | 15 +-------------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/libespeak-ng/langopts.c b/src/libespeak-ng/langopts.c index 1ec8ba2c..7a49f6ac 100644 --- a/src/libespeak-ng/langopts.c +++ b/src/libespeak-ng/langopts.c @@ -94,6 +94,24 @@ void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) { translator->langopts.lowercase_sentence = true; break; } + + case V_STRESSADD: { // stressAdd + if (CheckTranslator(translator, langopts_tab, key) != 0) + break; + + int stress_add_set = 0; + int stress_add[8]; + + stress_add_set = Read8Numbers(keyValue, stress_add); + + for (ix = 0; ix < stress_add_set; ix++) { + translator->stress_lengths[ix] += stress_add[ix]; + } + + break; + } + + case V_STRESSLENGTH: { if (CheckTranslator(translator, langopts_tab, key) != 0) break; diff --git a/src/libespeak-ng/voices.c b/src/libespeak-ng/voices.c index 748ae95f..ad203636 100644 --- a/src/libespeak-ng/voices.c +++ b/src/libespeak-ng/voices.c @@ -122,6 +122,7 @@ enum { const MNEM_TAB langopts_tab[] = { { "lowercaseSentence", V_LOWERCASE_SENTENCE }, + { "stressAdd", V_STRESSADD }, { "stressLength", V_STRESSLENGTH }, { "maintainer", V_MAINTAINER }, @@ -141,7 +142,6 @@ static const MNEM_TAB keyword_tab[] = { { "phonemes", V_PHONEMES }, { "dictionary", V_DICTIONARY }, { "stressAmp", V_STRESSAMP }, - { "stressAdd", V_STRESSADD }, { "intonation", V_INTONATION }, { "tunes", V_TUNES }, { "dictrules", V_DICTRULES }, @@ -551,7 +551,6 @@ voice_t *LoadVoice(const char *vname, int control) char buf[sizeof(path_home)+30]; char path_voices[sizeof(path_home)+12]; - int stress_add[8]; char names[8][40]; char name1[40]; char name2[80]; @@ -730,19 +729,7 @@ voice_t *LoadVoice(const char *vname, int control) break; } - case V_STRESSADD: { // stressAdd - if (CheckTranslator(translator, keyword_tab, key) != 0) - break; - int stress_add_set = 0; - stress_add_set = Read8Numbers(p, stress_add); - - for (ix = 0; ix < stress_add_set; ix++) { - translator->stress_lengths[ix] += stress_add[ix]; - } - - break; - } case V_INTONATION: // intonation sscanf(p, "%d", &option_tone_flags); if ((option_tone_flags & 0xff) != 0) { From 46bc25e173d0854ff322035719d9b18be4829f09 Mon Sep 17 00:00:00 2001 From: Juho Hiltunen Date: Mon, 3 Oct 2022 20:40:17 +0300 Subject: [PATCH 05/20] cleanup: move stressAmp to LoadLanguageOptions() --- src/libespeak-ng/langopts.c | 13 +++++++++++++ src/libespeak-ng/voices.c | 17 +---------------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/libespeak-ng/langopts.c b/src/libespeak-ng/langopts.c index 7a49f6ac..cd2f6fa9 100644 --- a/src/libespeak-ng/langopts.c +++ b/src/libespeak-ng/langopts.c @@ -110,8 +110,21 @@ void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) { break; } + case V_STRESSAMP: { + if (CheckTranslator(translator, langopts_tab, key) != 0) + break; + int stress_amps_set = 0; + int stress_amps[8]; + stress_amps_set = Read8Numbers(keyValue, stress_amps); + + for (ix = 0; ix < stress_amps_set; ix++) { + translator->stress_amps[ix] = stress_amps[ix]; + } + + break; + } case V_STRESSLENGTH: { if (CheckTranslator(translator, langopts_tab, key) != 0) break; diff --git a/src/libespeak-ng/voices.c b/src/libespeak-ng/voices.c index ad203636..75b8549f 100644 --- a/src/libespeak-ng/voices.c +++ b/src/libespeak-ng/voices.c @@ -123,6 +123,7 @@ enum { const MNEM_TAB langopts_tab[] = { { "lowercaseSentence", V_LOWERCASE_SENTENCE }, { "stressAdd", V_STRESSADD }, + { "stressAmp", V_STRESSAMP }, { "stressLength", V_STRESSLENGTH }, { "maintainer", V_MAINTAINER }, @@ -141,7 +142,6 @@ static const MNEM_TAB keyword_tab[] = { { "pitch", V_PITCH }, { "phonemes", V_PHONEMES }, { "dictionary", V_DICTIONARY }, - { "stressAmp", V_STRESSAMP }, { "intonation", V_INTONATION }, { "tunes", V_TUNES }, { "dictrules", V_DICTRULES }, @@ -715,21 +715,6 @@ voice_t *LoadVoice(const char *vname, int control) break; - case V_STRESSAMP: { // stressAmp - if (CheckTranslator(translator, keyword_tab, key) != 0) - break; - - int stress_amps_set = 0; - int stress_amps[8]; - stress_amps_set = Read8Numbers(p, stress_amps); - for (ix = 0; ix < stress_amps_set; ix++) { - translator->stress_amps[ix] = stress_amps[ix]; - } - - break; - } - - case V_INTONATION: // intonation sscanf(p, "%d", &option_tone_flags); if ((option_tone_flags & 0xff) != 0) { From 9caada3b31546a8480bcbb3b537daebce86e2a68 Mon Sep 17 00:00:00 2001 From: Juho Hiltunen Date: Mon, 3 Oct 2022 20:55:36 +0300 Subject: [PATCH 06/20] cleanup: move stressOpt to LoadLanguageOptions() --- src/libespeak-ng/langopts.c | 9 +++++++++ src/libespeak-ng/voice.h | 1 + src/libespeak-ng/voices.c | 10 ++-------- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/libespeak-ng/langopts.c b/src/libespeak-ng/langopts.c index cd2f6fa9..1e8bc930 100644 --- a/src/libespeak-ng/langopts.c +++ b/src/libespeak-ng/langopts.c @@ -140,6 +140,15 @@ void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) { break; } + case V_STRESSOPT: { + if (CheckTranslator(translator, langopts_tab, key) != 0) + break; + + ReadNumbers(keyValue, &translator->langopts.stress_flags, 32, langopts_tab, key); + break; + } + + case V_MAINTAINER: case V_STATUS: break; diff --git a/src/libespeak-ng/voice.h b/src/libespeak-ng/voice.h index bf0517ac..60fdf3af 100644 --- a/src/libespeak-ng/voice.h +++ b/src/libespeak-ng/voice.h @@ -91,6 +91,7 @@ voice_t *LoadVoice(const char *voice_name, int control); voice_t *LoadVoiceVariant(const char *voice_name, int variant); espeak_ng_STATUS DoVoiceChange(voice_t *v); void WavegenSetVoice(voice_t *v); +void ReadNumbers(char *p, int *flags, int maxValue, const MNEM_TAB *keyword_tab, int key); int Read8Numbers(char *data_in, int data[8]); void ReadTonePoints(char *string, int *tone_pts); void VoiceReset(int control); diff --git a/src/libespeak-ng/voices.c b/src/libespeak-ng/voices.c index 75b8549f..a2d69e40 100644 --- a/src/libespeak-ng/voices.c +++ b/src/libespeak-ng/voices.c @@ -125,6 +125,7 @@ const MNEM_TAB langopts_tab[] = { { "stressAdd", V_STRESSADD }, { "stressAmp", V_STRESSAMP }, { "stressLength", V_STRESSLENGTH }, + { "stressOpt", V_STRESSOPT }, { "maintainer", V_MAINTAINER }, { "status", V_STATUS }, @@ -146,7 +147,6 @@ static const MNEM_TAB keyword_tab[] = { { "tunes", V_TUNES }, { "dictrules", V_DICTRULES }, { "stressRule", V_STRESSRULE }, - { "stressOpt", V_STRESSOPT }, { "replace", V_REPLACE }, { "words", V_WORDGAP }, { "echo", V_ECHO }, @@ -489,7 +489,7 @@ int Read8Numbers(char *data_in, int data[8]) &data[0], &data[1], &data[2], &data[3], &data[4], &data[5], &data[6], &data[7]); } -static void ReadNumbers(char *p, int *flags, int maxValue, const MNEM_TAB *keyword_tab, int key) { +void ReadNumbers(char *p, int *flags, int maxValue, const MNEM_TAB *keyword_tab, int key) { // read a list of numbers from string p // store them as flags in *flags // the meaning of the numbers is bit ordinals, not integer values @@ -748,12 +748,6 @@ voice_t *LoadVoice(const char *vname, int control) ReadNumbers(p, &translator->dict_condition, 32, keyword_tab, key); break; - case V_STRESSOPT: - if (CheckTranslator(translator, keyword_tab, key) != 0) - break; - - ReadNumbers(p, &translator->langopts.stress_flags, 32, keyword_tab, key); - break; case V_NUMBERS: if (CheckTranslator(translator, keyword_tab, key) != 0) From 8e3399bb98fe03e5003d04fcae0bf4ec3ec6fe89 Mon Sep 17 00:00:00 2001 From: Juho Hiltunen Date: Mon, 3 Oct 2022 21:15:48 +0300 Subject: [PATCH 07/20] cleanup: move stressRule to LoadLanguageOptions() --- src/libespeak-ng/langopts.c | 10 +++++++++- src/libespeak-ng/voices.c | 11 +---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/libespeak-ng/langopts.c b/src/libespeak-ng/langopts.c index 1e8bc930..79b0124a 100644 --- a/src/libespeak-ng/langopts.c +++ b/src/libespeak-ng/langopts.c @@ -139,7 +139,6 @@ void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) { } break; } - case V_STRESSOPT: { if (CheckTranslator(translator, langopts_tab, key) != 0) break; @@ -147,7 +146,16 @@ void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) { ReadNumbers(keyValue, &translator->langopts.stress_flags, 32, langopts_tab, key); break; } + case V_STRESSRULE: { + if (CheckTranslator(translator, langopts_tab, key) != 0) + break; + sscanf(keyValue, "%d %d %d", &translator->langopts.stress_rule, + &translator->langopts.unstressed_wd1, + &translator->langopts.unstressed_wd2); + + break; + } case V_MAINTAINER: case V_STATUS: diff --git a/src/libespeak-ng/voices.c b/src/libespeak-ng/voices.c index a2d69e40..13cecfc3 100644 --- a/src/libespeak-ng/voices.c +++ b/src/libespeak-ng/voices.c @@ -126,6 +126,7 @@ const MNEM_TAB langopts_tab[] = { { "stressAmp", V_STRESSAMP }, { "stressLength", V_STRESSLENGTH }, { "stressOpt", V_STRESSOPT }, + { "stressRule", V_STRESSRULE }, { "maintainer", V_MAINTAINER }, { "status", V_STATUS }, @@ -146,7 +147,6 @@ static const MNEM_TAB keyword_tab[] = { { "intonation", V_INTONATION }, { "tunes", V_TUNES }, { "dictrules", V_DICTRULES }, - { "stressRule", V_STRESSRULE }, { "replace", V_REPLACE }, { "words", V_WORDGAP }, { "echo", V_ECHO }, @@ -784,15 +784,6 @@ voice_t *LoadVoice(const char *vname, int control) break; sscanf(p, "%d %d", &translator->langopts.word_gap, &translator->langopts.vowel_pause); - break; - case V_STRESSRULE: - if (CheckTranslator(translator, keyword_tab, key) != 0) - break; - - sscanf(p, "%d %d %d", &translator->langopts.stress_rule, - &translator->langopts.unstressed_wd1, - &translator->langopts.unstressed_wd2); - break; case V_ECHO: // echo. suggest: 135mS 11% From e38142acd16e985360f908a18b9e96482e1c0dc9 Mon Sep 17 00:00:00 2001 From: Juho Hiltunen Date: Mon, 3 Oct 2022 21:25:42 +0300 Subject: [PATCH 08/20] cleanup: moved intonation to LoadLanguageOptions() --- src/libespeak-ng/langopts.c | 11 ++++++++++- src/libespeak-ng/voices.c | 11 +---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/libespeak-ng/langopts.c b/src/libespeak-ng/langopts.c index 79b0124a..6cd2ae90 100644 --- a/src/libespeak-ng/langopts.c +++ b/src/libespeak-ng/langopts.c @@ -87,6 +87,16 @@ void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) { int ix; switch (key) { + case V_INTONATION: { + sscanf(keyValue, "%d", &option_tone_flags); + if ((option_tone_flags & 0xff) != 0) { + if (CheckTranslator(translator, langopts_tab, key) != 0) + break; + + translator->langopts.intonation_group = option_tone_flags & 0xff; + } + break; + } case V_LOWERCASE_SENTENCE: { if (CheckTranslator(translator, langopts_tab, key) != 0) break; @@ -94,7 +104,6 @@ void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) { translator->langopts.lowercase_sentence = true; break; } - case V_STRESSADD: { // stressAdd if (CheckTranslator(translator, langopts_tab, key) != 0) break; diff --git a/src/libespeak-ng/voices.c b/src/libespeak-ng/voices.c index 13cecfc3..fb4a3e16 100644 --- a/src/libespeak-ng/voices.c +++ b/src/libespeak-ng/voices.c @@ -121,6 +121,7 @@ enum { }; const MNEM_TAB langopts_tab[] = { + { "intonation", V_INTONATION }, { "lowercaseSentence", V_LOWERCASE_SENTENCE }, { "stressAdd", V_STRESSADD }, { "stressAmp", V_STRESSAMP }, @@ -144,7 +145,6 @@ static const MNEM_TAB keyword_tab[] = { { "pitch", V_PITCH }, { "phonemes", V_PHONEMES }, { "dictionary", V_DICTIONARY }, - { "intonation", V_INTONATION }, { "tunes", V_TUNES }, { "dictrules", V_DICTRULES }, { "replace", V_REPLACE }, @@ -715,15 +715,6 @@ voice_t *LoadVoice(const char *vname, int control) break; - case V_INTONATION: // intonation - sscanf(p, "%d", &option_tone_flags); - if ((option_tone_flags & 0xff) != 0) { - if (CheckTranslator(translator, keyword_tab, key) != 0) - break; - - translator->langopts.intonation_group = option_tone_flags & 0xff; - } - break; case V_TUNES: if (CheckTranslator(translator, keyword_tab, key) != 0) break; From ec897eff322e7dfb8a1b1f952a8b2f735e3cd89f Mon Sep 17 00:00:00 2001 From: Juho Hiltunen Date: Tue, 4 Oct 2022 17:54:04 +0300 Subject: [PATCH 09/20] fixup, add langopts.h to version control --- src/libespeak-ng/langopts.h | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/libespeak-ng/langopts.h diff --git a/src/libespeak-ng/langopts.h b/src/libespeak-ng/langopts.h new file mode 100644 index 00000000..4f3d3c5e --- /dev/null +++ b/src/libespeak-ng/langopts.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2005 to 2007 by Jonathan Duddington + * email: jonsd@users.sourceforge.net + * Copyright (C) 2015 Reece H. Dunn + * + * 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: . + */ + +#ifndef ESPEAK_NG_LANGOPTS_H +#define ESPEAK_NG_LANGOPTS_H + +#include +#include "translate.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +void LoadLanguageOptions(Translator *translator, int key, char *keyValue); + +#ifdef __cplusplus +} +#endif + +#endif From c92180f9184aa96d7fb74fa7f77b450b990ad0d2 Mon Sep 17 00:00:00 2001 From: Juho Hiltunen Date: Tue, 4 Oct 2022 17:55:38 +0300 Subject: [PATCH 10/20] cleanup: move n_tunes and tunes to where they are used --- src/libespeak-ng/intonation.c | 3 --- src/libespeak-ng/synthdata.c | 3 +++ src/libespeak-ng/synthdata.h | 3 +++ src/libespeak-ng/synthesize.h | 3 +-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/libespeak-ng/intonation.c b/src/libespeak-ng/intonation.c index d5e9092d..c1664218 100644 --- a/src/libespeak-ng/intonation.c +++ b/src/libespeak-ng/intonation.c @@ -287,9 +287,6 @@ static TONE_NUCLEUS tone_nucleus_table[N_TONE_NUCLEUS_TABLE] = { { PITCHfall, 70, 18, PITCHfall, 70, 24, NULL, 32, 20, 0 }, // 12 test }; -int n_tunes = 0; -TUNE *tunes = NULL; - #define SECONDARY 3 #define PRIMARY 4 #define PRIMARY_STRESSED 6 diff --git a/src/libespeak-ng/synthdata.c b/src/libespeak-ng/synthdata.c index a2d7ae10..7510cc2a 100644 --- a/src/libespeak-ng/synthdata.c +++ b/src/libespeak-ng/synthdata.c @@ -42,6 +42,9 @@ #include "translate.h" // for Translator, LANGUAGE_OPTIONS #include "voice.h" // for ReadTonePoints, tone_points, voice +int n_tunes = 0; +TUNE *tunes = NULL; + const int version_phdata = 0x014801; // copy the current phoneme table into here diff --git a/src/libespeak-ng/synthdata.h b/src/libespeak-ng/synthdata.h index 5607f056..3548e3c5 100644 --- a/src/libespeak-ng/synthdata.h +++ b/src/libespeak-ng/synthdata.h @@ -56,6 +56,9 @@ int PhonemeCode(unsigned int mnem); void SelectPhonemeTable(int number); int SelectPhonemeTableName(const char *name); +extern int n_tunes; +extern TUNE *tunes; + #ifdef __cplusplus } #endif diff --git a/src/libespeak-ng/synthesize.h b/src/libespeak-ng/synthesize.h index d78e35e1..f8b71a02 100644 --- a/src/libespeak-ng/synthesize.h +++ b/src/libespeak-ng/synthesize.h @@ -382,8 +382,7 @@ typedef struct { int spare2; // the struct length should be a multiple of 4 bytes } TUNE; -extern int n_tunes; -extern TUNE *tunes; + // phoneme table extern PHONEME_TAB *phoneme_tab[N_PHONEME_TAB]; From f28841162ffec8a03d5b0f5b29aa7c3b8ce51eb0 Mon Sep 17 00:00:00 2001 From: Juho Hiltunen Date: Tue, 4 Oct 2022 17:56:58 +0300 Subject: [PATCH 11/20] moved tunes to LoadLanguageOptions() --- src/libespeak-ng/langopts.c | 35 +++++++++++++++++++++++++++++++++++ src/libespeak-ng/voices.c | 32 ++------------------------------ 2 files changed, 37 insertions(+), 30 deletions(-) diff --git a/src/libespeak-ng/langopts.c b/src/libespeak-ng/langopts.c index 6cd2ae90..40bdf328 100644 --- a/src/libespeak-ng/langopts.c +++ b/src/libespeak-ng/langopts.c @@ -24,6 +24,9 @@ #include #include #include +#include + +static int LookupTune(const char *name); #include #include @@ -33,6 +36,7 @@ #include "mnemonics.h" // for MNEM_TAB #include "translate.h" // for Translator #include "voice.h" // for CheckTranslator() +#include "synthdata.h" // for n_tunes, tunes enum { V_NAME = 1, @@ -85,6 +89,7 @@ extern const MNEM_TAB langopts_tab[]; void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) { int ix; + int n; switch (key) { case V_INTONATION: { @@ -165,9 +170,39 @@ void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) { break; } + case V_TUNES: { + if (CheckTranslator(translator, langopts_tab, key) != 0) + break; + + char names[8][40]; + n = sscanf(keyValue, "%s %s %s %s %s %s", names[0], names[1], names[2], names[3], names[4], names[5]); + translator->langopts.intonation_group = 0; + + for (ix = 0; ix < n; ix++) { + if (strcmp(names[ix], "NULL") == 0) + continue; + + if ((n = LookupTune(names[ix])) < 0) + fprintf(stderr, "Unknown tune '%s'\n", names[ix]); + else + translator->langopts.tunes[ix] = n; + } + break; + } + case V_MAINTAINER: case V_STATUS: break; } } + +static int LookupTune(const char *name) { + int ix; + + for (ix = 0; ix < n_tunes; ix++) { + if (strcmp(name, tunes[ix].name) == 0) + return ix; + } + return -1; +} diff --git a/src/libespeak-ng/voices.c b/src/libespeak-ng/voices.c index fb4a3e16..6024ec58 100644 --- a/src/libespeak-ng/voices.c +++ b/src/libespeak-ng/voices.c @@ -128,6 +128,7 @@ const MNEM_TAB langopts_tab[] = { { "stressLength", V_STRESSLENGTH }, { "stressOpt", V_STRESSOPT }, { "stressRule", V_STRESSRULE }, + { "tunes", V_TUNES }, { "maintainer", V_MAINTAINER }, { "status", V_STATUS }, @@ -145,7 +146,6 @@ static const MNEM_TAB keyword_tab[] = { { "pitch", V_PITCH }, { "phonemes", V_PHONEMES }, { "dictionary", V_DICTIONARY }, - { "tunes", V_TUNES }, { "dictrules", V_DICTRULES }, { "replace", V_REPLACE }, { "words", V_WORDGAP }, @@ -211,17 +211,6 @@ static char *fgets_strip(char *buf, int size, FILE *f_in) return buf; } -static int LookupTune(const char *name) -{ - int ix; - - for (ix = 0; ix < n_tunes; ix++) { - if (strcmp(name, tunes[ix].name) == 0) - return ix; - } - return -1; -} - static void SetToneAdjust(voice_t *voice, int *tone_pts) { int ix; @@ -551,7 +540,7 @@ voice_t *LoadVoice(const char *vname, int control) char buf[sizeof(path_home)+30]; char path_voices[sizeof(path_home)+12]; - char names[8][40]; + char name1[40]; char name2[80]; @@ -715,23 +704,6 @@ voice_t *LoadVoice(const char *vname, int control) break; - case V_TUNES: - if (CheckTranslator(translator, keyword_tab, key) != 0) - break; - - n = sscanf(p, "%s %s %s %s %s %s", names[0], names[1], names[2], names[3], names[4], names[5]); - translator->langopts.intonation_group = 0; - - for (ix = 0; ix < n; ix++) { - if (strcmp(names[ix], "NULL") == 0) - continue; - - if ((value = LookupTune(names[ix])) < 0) - fprintf(stderr, "Unknown tune '%s'\n", names[ix]); - else - translator->langopts.tunes[ix] = value; - } - break; case V_DICTRULES: // conditional dictionary rules and list entries if (CheckTranslator(translator, keyword_tab, key) != 0) From e1d936dc52b3f9e16c4afc6075211b5c79334be3 Mon Sep 17 00:00:00 2001 From: Juho Hiltunen Date: Tue, 4 Oct 2022 18:36:58 +0300 Subject: [PATCH 12/20] cleanup: moved dictrules to LoadLanguageOptions() --- src/libespeak-ng/langopts.c | 7 +++++++ src/libespeak-ng/voices.c | 8 +------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/libespeak-ng/langopts.c b/src/libespeak-ng/langopts.c index 40bdf328..3705005d 100644 --- a/src/libespeak-ng/langopts.c +++ b/src/libespeak-ng/langopts.c @@ -92,6 +92,13 @@ void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) { int n; switch (key) { + case V_DICTRULES: { // conditional dictionary rules and list entries + if (CheckTranslator(translator, langopts_tab, key) != 0) + break; + + ReadNumbers(keyValue, &translator->dict_condition, 32, langopts_tab, key); + break; + } case V_INTONATION: { sscanf(keyValue, "%d", &option_tone_flags); if ((option_tone_flags & 0xff) != 0) { diff --git a/src/libespeak-ng/voices.c b/src/libespeak-ng/voices.c index 6024ec58..d4bf4d53 100644 --- a/src/libespeak-ng/voices.c +++ b/src/libespeak-ng/voices.c @@ -121,6 +121,7 @@ enum { }; const MNEM_TAB langopts_tab[] = { + { "dictrules", V_DICTRULES }, { "intonation", V_INTONATION }, { "lowercaseSentence", V_LOWERCASE_SENTENCE }, { "stressAdd", V_STRESSADD }, @@ -146,7 +147,6 @@ static const MNEM_TAB keyword_tab[] = { { "pitch", V_PITCH }, { "phonemes", V_PHONEMES }, { "dictionary", V_DICTIONARY }, - { "dictrules", V_DICTRULES }, { "replace", V_REPLACE }, { "words", V_WORDGAP }, { "echo", V_ECHO }, @@ -705,12 +705,6 @@ voice_t *LoadVoice(const char *vname, int control) - case V_DICTRULES: // conditional dictionary rules and list entries - if (CheckTranslator(translator, keyword_tab, key) != 0) - break; - - ReadNumbers(p, &translator->dict_condition, 32, keyword_tab, key); - break; case V_NUMBERS: if (CheckTranslator(translator, keyword_tab, key) != 0) From bdf18eafb144e26a2e76d4821a86237ade7ee8fb Mon Sep 17 00:00:00 2001 From: Juho Hiltunen Date: Tue, 4 Oct 2022 18:45:22 +0300 Subject: [PATCH 13/20] cleanup: moved dictmin to LoadLanguageOptions() Note: This feature has no tests. It doesn't look very useful and I think could be removed. --- src/libespeak-ng/langopts.c | 10 ++++++++++ src/libespeak-ng/voices.c | 9 --------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/libespeak-ng/langopts.c b/src/libespeak-ng/langopts.c index 3705005d..f005c98e 100644 --- a/src/libespeak-ng/langopts.c +++ b/src/libespeak-ng/langopts.c @@ -92,6 +92,16 @@ void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) { int n; switch (key) { + case V_DICTMIN: { + if (CheckTranslator(translator, langopts_tab, key) != 0) + break; + + if (sscanf(keyValue, "%d", &n) == 1) + translator->dict_min_size = n; + + break; + } + case V_DICTRULES: { // conditional dictionary rules and list entries if (CheckTranslator(translator, langopts_tab, key) != 0) break; diff --git a/src/libespeak-ng/voices.c b/src/libespeak-ng/voices.c index d4bf4d53..7669bdbf 100644 --- a/src/libespeak-ng/voices.c +++ b/src/libespeak-ng/voices.c @@ -818,16 +818,7 @@ voice_t *LoadVoice(const char *vname, int control) sscanf(p, "%d", &speed.fast_settings); SetSpeed(3); break; - case V_DICTMIN: { - if (CheckTranslator(translator, keyword_tab, key) != 0) - break; - if (sscanf(p, "%d", &value) == 1) - translator->dict_min_size = value; - break; - } - - break; case V_MAINTAINER: case V_STATUS: break; From ac82698f9978a40963d81d04d5e822ac749fbe48 Mon Sep 17 00:00:00 2001 From: Juho Hiltunen Date: Wed, 5 Oct 2022 05:53:35 +0300 Subject: [PATCH 14/20] cleanup: move numbers to LoadLanguageOptions() Note: This feature has no tests. --- src/libespeak-ng/langopts.c | 24 ++++++++++++++++++++++++ src/libespeak-ng/tr_languages.c | 2 +- src/libespeak-ng/voices.c | 23 +---------------------- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/libespeak-ng/langopts.c b/src/libespeak-ng/langopts.c index f005c98e..4113e335 100644 --- a/src/libespeak-ng/langopts.c +++ b/src/libespeak-ng/langopts.c @@ -20,6 +20,7 @@ #include "config.h" +#include #include #include #include @@ -119,6 +120,29 @@ void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) { } break; } + case V_NUMBERS: { + // if (CheckTranslator(translator, langopts_tab, key) != 0) + break; + + // expect a list of numbers + while (*keyValue != 0) { + while (isspace(*keyValue)) keyValue++; + if ((n = atoi(keyValue)) > 0) { + keyValue++; + if (n < 32) { + translator->langopts.numbers |= (1 << n); + } else { + if (n < 64) + translator->langopts.numbers2 |= (1 << (n-32)); + else + fprintf(stderr, "numbers: Bad option number %d\n", n); } + } + while (isalnum(*keyValue)) keyValue++; + } + ProcessLanguageOptions(&(translator->langopts)); + + break; + } case V_LOWERCASE_SENTENCE: { if (CheckTranslator(translator, langopts_tab, key) != 0) break; diff --git a/src/libespeak-ng/tr_languages.c b/src/libespeak-ng/tr_languages.c index c278bb66..c05f79b0 100644 --- a/src/libespeak-ng/tr_languages.c +++ b/src/libespeak-ng/tr_languages.c @@ -808,7 +808,7 @@ Translator *SelectTranslator(const char *name) tr->langopts.param[LOPT_IT_DOUBLING] = 1; tr->langopts.long_stop = 130; - tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_ALLOW_SPACE | NUM_DFRACTION_2 | NUM_ORDINAL_DOT; + // tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_ALLOW_SPACE | NUM_DFRACTION_2 | NUM_ORDINAL_DOT; SetLetterVowel(tr, 'y'); tr->langopts.spelling_stress = 1; tr->langopts.intonation_group = 3; // less intonation, don't raise pitch at comma diff --git a/src/libespeak-ng/voices.c b/src/libespeak-ng/voices.c index 7669bdbf..c47c5126 100644 --- a/src/libespeak-ng/voices.c +++ b/src/libespeak-ng/voices.c @@ -124,6 +124,7 @@ const MNEM_TAB langopts_tab[] = { { "dictrules", V_DICTRULES }, { "intonation", V_INTONATION }, { "lowercaseSentence", V_LOWERCASE_SENTENCE }, + { "numbers", V_NUMBERS }, { "stressAdd", V_STRESSADD }, { "stressAmp", V_STRESSAMP }, { "stressLength", V_STRESSLENGTH }, @@ -157,7 +158,6 @@ static const MNEM_TAB keyword_tab[] = { { "voicing", V_VOICING }, { "breath", V_BREATH }, { "breathw", V_BREATHW }, - { "numbers", V_NUMBERS }, { "mbrola", V_MBROLA }, { "consonants", V_CONSONANTS }, { "klatt", V_KLATT }, @@ -706,28 +706,7 @@ voice_t *LoadVoice(const char *vname, int control) - case V_NUMBERS: - if (CheckTranslator(translator, keyword_tab, key) != 0) - break; - // expect a list of numbers - while (*p != 0) { - while (isspace(*p)) p++; - if ((n = atoi(p)) > 0) { - p++; - if (n < 32) { - translator->langopts.numbers |= (1 << n); - } else { - if (n < 64) - translator->langopts.numbers2 |= (1 << (n-32)); - else - fprintf(stderr, "numbers: Bad option number %d\n", n); } - } - while (isalnum(*p)) p++; - } - ProcessLanguageOptions(&(translator->langopts)); - - break; case V_REPLACE: if (phonemes_set == false) { // must set up a phoneme table before we can lookup phoneme mnemonics From b820b681822197f949f17ed54fcb3ee380330f21 Mon Sep 17 00:00:00 2001 From: Juho Hiltunen Date: Sun, 9 Oct 2022 13:38:45 +0300 Subject: [PATCH 15/20] cleanup: move words to LoadLanguageOptions() --- src/libespeak-ng/langopts.c | 9 +++++++++ src/libespeak-ng/voices.c | 8 +------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/libespeak-ng/langopts.c b/src/libespeak-ng/langopts.c index 4113e335..cf96f63b 100644 --- a/src/libespeak-ng/langopts.c +++ b/src/libespeak-ng/langopts.c @@ -230,6 +230,14 @@ void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) { } break; } + case V_WORDGAP: { + if (CheckTranslator(translator, langopts_tab, key) != 0) + break; + + + sscanf(keyValue, "%d %d", &translator->langopts.word_gap, &translator->langopts.vowel_pause); + break; + } case V_MAINTAINER: @@ -247,3 +255,4 @@ static int LookupTune(const char *name) { } return -1; } + diff --git a/src/libespeak-ng/voices.c b/src/libespeak-ng/voices.c index c47c5126..ddf31f9d 100644 --- a/src/libespeak-ng/voices.c +++ b/src/libespeak-ng/voices.c @@ -131,6 +131,7 @@ const MNEM_TAB langopts_tab[] = { { "stressOpt", V_STRESSOPT }, { "stressRule", V_STRESSRULE }, { "tunes", V_TUNES }, + { "words", V_WORDGAP }, { "maintainer", V_MAINTAINER }, { "status", V_STATUS }, @@ -149,7 +150,6 @@ static const MNEM_TAB keyword_tab[] = { { "phonemes", V_PHONEMES }, { "dictionary", V_DICTIONARY }, { "replace", V_REPLACE }, - { "words", V_WORDGAP }, { "echo", V_ECHO }, { "flutter", V_FLUTTER }, { "roughness", V_ROUGHNESS }, @@ -524,7 +524,6 @@ voice_t *LoadVoice(const char *vname, int control) char *p; int key; int ix; - int n; int value; int langix = 0; int tone_only = control & 2; @@ -715,12 +714,7 @@ voice_t *LoadVoice(const char *vname, int control) } PhonemeReplacement(p); break; - case V_WORDGAP: // words - if (CheckTranslator(translator, keyword_tab, key) != 0) - break; - sscanf(p, "%d %d", &translator->langopts.word_gap, &translator->langopts.vowel_pause); - break; case V_ECHO: // echo. suggest: 135mS 11% value = 0; From 159ab0ee760e64dead6be9a2d72476e740a3ac0f Mon Sep 17 00:00:00 2001 From: Juho Hiltunen Date: Sun, 9 Oct 2022 14:04:36 +0300 Subject: [PATCH 16/20] cleanup: move langopts.params handling to LoadLanguageOptions() These have no tests and should be refactore to be similar to other langopts. --- src/libespeak-ng/langopts.c | 9 +++++++++ src/libespeak-ng/voices.c | 19 +++++++------------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/libespeak-ng/langopts.c b/src/libespeak-ng/langopts.c index cf96f63b..4dcdf3e1 100644 --- a/src/libespeak-ng/langopts.c +++ b/src/libespeak-ng/langopts.c @@ -243,6 +243,15 @@ void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) { case V_MAINTAINER: case V_STATUS: break; + default: { + if ((key & 0xff00) == 0x100) { + if (CheckTranslator(translator, langopts_tab, key) != 0) + break; + + sscanf(keyValue, "%d", &translator->langopts.param[key &0xff]); + } + break; + } } } diff --git a/src/libespeak-ng/voices.c b/src/libespeak-ng/voices.c index ddf31f9d..cb3bc703 100644 --- a/src/libespeak-ng/voices.c +++ b/src/libespeak-ng/voices.c @@ -123,6 +123,11 @@ enum { const MNEM_TAB langopts_tab[] = { { "dictrules", V_DICTRULES }, { "intonation", V_INTONATION }, + { "l_dieresis", 0x100+LOPT_DIERESES }, + { "l_prefix", 0x100+LOPT_PREFIXES }, + { "l_regressive_v", 0x100+LOPT_REGRESSIVE_VOICING }, + { "l_unpronouncable", 0x100+LOPT_UNPRONOUNCABLE }, + { "l_sonorant_min", 0x100+LOPT_SONORANT_MIN }, { "lowercaseSentence", V_LOWERCASE_SENTENCE }, { "numbers", V_NUMBERS }, { "stressAdd", V_STRESSADD }, @@ -165,12 +170,7 @@ static const MNEM_TAB keyword_tab[] = { { "speed", V_SPEED }, { "dict_min", V_DICTMIN }, - // these just set a value in langopts.param[] - { "l_dieresis", 0x100+LOPT_DIERESES }, - { "l_prefix", 0x100+LOPT_PREFIXES }, - { "l_regressive_v", 0x100+LOPT_REGRESSIVE_VOICING }, - { "l_unpronouncable", 0x100+LOPT_UNPRONOUNCABLE }, - { "l_sonorant_min", 0x100+LOPT_SONORANT_MIN }, + { "apostrophe", 0x100+LOPT_APOSTROPHE }, { "brackets", 0x100+LOPT_BRACKET_PAUSE }, { "bracketsAnnounced", 0x100+LOPT_BRACKET_PAUSE_ANNOUNCED }, @@ -796,12 +796,7 @@ voice_t *LoadVoice(const char *vname, int control) case V_STATUS: break; default: - if ((key & 0xff00) == 0x100) { - if (CheckTranslator(translator, keyword_tab, key) != 0) - break; - sscanf(p, "%d", &translator->langopts.param[key &0xff]); - } else - fprintf(stderr, "Bad voice attribute: %s\n", buf); + fprintf(stderr, "Bad voice attribute: %s\n", buf); break; } } From 3182dee147279ead089bce435620743c4b1e7035 Mon Sep 17 00:00:00 2001 From: Juho Hiltunen Date: Sun, 9 Oct 2022 14:07:26 +0300 Subject: [PATCH 17/20] code cleanup: move CheckTranslator() to langopts.c --- src/libespeak-ng/langopts.c | 16 ++++++++++++++-- src/libespeak-ng/voice.h | 1 - src/libespeak-ng/voices.c | 12 ------------ 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/libespeak-ng/langopts.c b/src/libespeak-ng/langopts.c index 4dcdf3e1..c73e9041 100644 --- a/src/libespeak-ng/langopts.c +++ b/src/libespeak-ng/langopts.c @@ -27,8 +27,6 @@ #include #include -static int LookupTune(const char *name); - #include #include #include @@ -39,6 +37,9 @@ static int LookupTune(const char *name); #include "voice.h" // for CheckTranslator() #include "synthdata.h" // for n_tunes, tunes +static int CheckTranslator(Translator *tr, const MNEM_TAB *keyword_tab, int key); +static int LookupTune(const char *name); + enum { V_NAME = 1, V_LANGUAGE, @@ -265,3 +266,14 @@ static int LookupTune(const char *name) { return -1; } +int CheckTranslator(Translator *tr, const MNEM_TAB *keyword_tab, int key) +{ + // Return 0 if translator is set. + // Return 1 and print an error message for specified key if not + // used for parsing language options + if (tr) + return 0; + + fprintf(stderr, "Cannot set %s: language not set, or is invalid.\n", LookupMnemName(keyword_tab, key)); + return 1; +} \ No newline at end of file diff --git a/src/libespeak-ng/voice.h b/src/libespeak-ng/voice.h index 60fdf3af..21b1b119 100644 --- a/src/libespeak-ng/voice.h +++ b/src/libespeak-ng/voice.h @@ -84,7 +84,6 @@ extern espeak_VOICE current_voice_selected; extern voice_t *voice; extern int tone_points[12]; -int CheckTranslator(Translator *tr, const MNEM_TAB *keyword_tab, int key); const char *SelectVoice(espeak_VOICE *voice_select, int *found); espeak_VOICE *SelectVoiceByName(espeak_VOICE **voices, const char *name); voice_t *LoadVoice(const char *voice_name, int control); diff --git a/src/libespeak-ng/voices.c b/src/libespeak-ng/voices.c index cb3bc703..edffb961 100644 --- a/src/libespeak-ng/voices.c +++ b/src/libespeak-ng/voices.c @@ -498,18 +498,6 @@ void ReadNumbers(char *p, int *flags, int maxValue, const MNEM_TAB *keyword_tab } } -int CheckTranslator(Translator *tr, const MNEM_TAB *keyword_tab, int key) -{ - // Return 0 if translator is set. - // Return 1 and print an error message for specified key if not - // used for parsing language options - if (tr) - return 0; - - fprintf(stderr, "Cannot set %s: language not set, or is invalid.\n", LookupMnemName(keyword_tab, key)); - return 1; -} - voice_t *LoadVoice(const char *vname, int control) { // control, bit 0 1= no_default From 78c6873427b0499441678adf4546abba2528a8da Mon Sep 17 00:00:00 2001 From: Juho Hiltunen Date: Sun, 9 Oct 2022 14:12:26 +0300 Subject: [PATCH 18/20] cleanup: call CheckTranslator at start of LoadLangugeOptions --- src/libespeak-ng/langopts.c | 45 +++++-------------------------------- 1 file changed, 6 insertions(+), 39 deletions(-) diff --git a/src/libespeak-ng/langopts.c b/src/libespeak-ng/langopts.c index c73e9041..6dcafe7e 100644 --- a/src/libespeak-ng/langopts.c +++ b/src/libespeak-ng/langopts.c @@ -34,8 +34,8 @@ #include "langopts.h" #include "mnemonics.h" // for MNEM_TAB #include "translate.h" // for Translator -#include "voice.h" // for CheckTranslator() #include "synthdata.h" // for n_tunes, tunes +#include "voice.h" // for ReadNumbers, Read8Numbers static int CheckTranslator(Translator *tr, const MNEM_TAB *keyword_tab, int key); static int LookupTune(const char *name); @@ -90,13 +90,16 @@ enum { extern const MNEM_TAB langopts_tab[]; void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) { +if (CheckTranslator(translator, langopts_tab, key) != 0) { + return; + } + int ix; int n; switch (key) { case V_DICTMIN: { - if (CheckTranslator(translator, langopts_tab, key) != 0) - break; + if (sscanf(keyValue, "%d", &n) == 1) translator->dict_min_size = n; @@ -105,26 +108,17 @@ void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) { } case V_DICTRULES: { // conditional dictionary rules and list entries - if (CheckTranslator(translator, langopts_tab, key) != 0) - break; - ReadNumbers(keyValue, &translator->dict_condition, 32, langopts_tab, key); break; } case V_INTONATION: { sscanf(keyValue, "%d", &option_tone_flags); if ((option_tone_flags & 0xff) != 0) { - if (CheckTranslator(translator, langopts_tab, key) != 0) - break; - translator->langopts.intonation_group = option_tone_flags & 0xff; } break; } case V_NUMBERS: { - // if (CheckTranslator(translator, langopts_tab, key) != 0) - break; - // expect a list of numbers while (*keyValue != 0) { while (isspace(*keyValue)) keyValue++; @@ -145,16 +139,10 @@ void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) { break; } case V_LOWERCASE_SENTENCE: { - if (CheckTranslator(translator, langopts_tab, key) != 0) - break; - translator->langopts.lowercase_sentence = true; break; } case V_STRESSADD: { // stressAdd - if (CheckTranslator(translator, langopts_tab, key) != 0) - break; - int stress_add_set = 0; int stress_add[8]; @@ -167,8 +155,6 @@ void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) { break; } case V_STRESSAMP: { - if (CheckTranslator(translator, langopts_tab, key) != 0) - break; int stress_amps_set = 0; int stress_amps[8]; @@ -182,9 +168,6 @@ void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) { break; } case V_STRESSLENGTH: { - if (CheckTranslator(translator, langopts_tab, key) != 0) - break; - //printf("parsing: %s", keyValue); int stress_lengths_set = 0; int stress_lengths[8]; @@ -196,16 +179,10 @@ void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) { break; } case V_STRESSOPT: { - if (CheckTranslator(translator, langopts_tab, key) != 0) - break; - ReadNumbers(keyValue, &translator->langopts.stress_flags, 32, langopts_tab, key); break; } case V_STRESSRULE: { - if (CheckTranslator(translator, langopts_tab, key) != 0) - break; - sscanf(keyValue, "%d %d %d", &translator->langopts.stress_rule, &translator->langopts.unstressed_wd1, &translator->langopts.unstressed_wd2); @@ -213,9 +190,6 @@ void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) { break; } case V_TUNES: { - if (CheckTranslator(translator, langopts_tab, key) != 0) - break; - char names[8][40]; n = sscanf(keyValue, "%s %s %s %s %s %s", names[0], names[1], names[2], names[3], names[4], names[5]); translator->langopts.intonation_group = 0; @@ -232,10 +206,6 @@ void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) { break; } case V_WORDGAP: { - if (CheckTranslator(translator, langopts_tab, key) != 0) - break; - - sscanf(keyValue, "%d %d", &translator->langopts.word_gap, &translator->langopts.vowel_pause); break; } @@ -246,9 +216,6 @@ void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) { break; default: { if ((key & 0xff00) == 0x100) { - if (CheckTranslator(translator, langopts_tab, key) != 0) - break; - sscanf(keyValue, "%d", &translator->langopts.param[key &0xff]); } break; From eae4595dc9cb4bda6dfdeb79ab0da1273714f559 Mon Sep 17 00:00:00 2001 From: Juho Hiltunen Date: Sun, 9 Oct 2022 14:30:19 +0300 Subject: [PATCH 19/20] cleanup: move shared enums and MNEM_TABs to header file --- src/libespeak-ng/langopts.c | 49 +---------------- src/libespeak-ng/voice.h | 104 +++++++++++++++++++++++++++++++++++ src/libespeak-ng/voices.c | 105 ------------------------------------ 3 files changed, 105 insertions(+), 153 deletions(-) diff --git a/src/libespeak-ng/langopts.c b/src/libespeak-ng/langopts.c index 6dcafe7e..7d72c47d 100644 --- a/src/libespeak-ng/langopts.c +++ b/src/libespeak-ng/langopts.c @@ -35,58 +35,11 @@ #include "mnemonics.h" // for MNEM_TAB #include "translate.h" // for Translator #include "synthdata.h" // for n_tunes, tunes -#include "voice.h" // for ReadNumbers, Read8Numbers +#include "voice.h" // for ReadNumbers, Read8Numbers, ... static int CheckTranslator(Translator *tr, const MNEM_TAB *keyword_tab, int key); static int LookupTune(const char *name); -enum { - V_NAME = 1, - V_LANGUAGE, - V_GENDER, - V_PHONEMES, - V_DICTIONARY, - V_VARIANTS, - - V_MAINTAINER, - V_STATUS, - - // these affect voice quality, are independent of language - V_FORMANT, - V_PITCH, - V_ECHO, - V_FLUTTER, - V_ROUGHNESS, - V_CLARITY, - V_TONE, - V_VOICING, - V_BREATH, - V_BREATHW, - - // these override defaults set by the translator - V_LOWERCASE_SENTENCE, - V_WORDGAP, - V_INTONATION, - V_TUNES, - V_STRESSLENGTH, - V_STRESSAMP, - V_STRESSADD, - V_DICTRULES, - V_STRESSRULE, - V_STRESSOPT, - V_NUMBERS, - - V_MBROLA, - V_KLATT, - V_FAST, - V_SPEED, - V_DICTMIN, - - // these need a phoneme table to have been specified - V_REPLACE, - V_CONSONANTS -}; - extern const MNEM_TAB langopts_tab[]; void LoadLanguageOptions(Translator *translator, int key, char *keyValue ) { diff --git a/src/libespeak-ng/voice.h b/src/libespeak-ng/voice.h index 21b1b119..a0d93ec5 100644 --- a/src/libespeak-ng/voice.h +++ b/src/libespeak-ng/voice.h @@ -84,6 +84,110 @@ extern espeak_VOICE current_voice_selected; extern voice_t *voice; extern int tone_points[12]; +typedef enum { + V_NAME = 1, + V_LANGUAGE, + V_GENDER, + V_PHONEMES, + V_DICTIONARY, + V_VARIANTS, + + V_MAINTAINER, + V_STATUS, + + // these affect voice quality, are independent of language + V_FORMANT, + V_PITCH, + V_ECHO, + V_FLUTTER, + V_ROUGHNESS, + V_CLARITY, + V_TONE, + V_VOICING, + V_BREATH, + V_BREATHW, + + // these override defaults set by the translator + V_LOWERCASE_SENTENCE, + V_WORDGAP, + V_INTONATION, + V_TUNES, + V_STRESSLENGTH, + V_STRESSAMP, + V_STRESSADD, + V_DICTRULES, + V_STRESSRULE, + V_STRESSOPT, + V_NUMBERS, + + V_MBROLA, + V_KLATT, + V_FAST, + V_SPEED, + V_DICTMIN, + + // these need a phoneme table to have been specified + V_REPLACE, + V_CONSONANTS +} VOICELANGATTRIBUTES; + +static const MNEM_TAB langopts_tab[] = { + { "dictrules", V_DICTRULES }, + { "intonation", V_INTONATION }, + { "l_dieresis", 0x100+LOPT_DIERESES }, + { "l_prefix", 0x100+LOPT_PREFIXES }, + { "l_regressive_v", 0x100+LOPT_REGRESSIVE_VOICING }, + { "l_unpronouncable", 0x100+LOPT_UNPRONOUNCABLE }, + { "l_sonorant_min", 0x100+LOPT_SONORANT_MIN }, + { "lowercaseSentence", V_LOWERCASE_SENTENCE }, + { "numbers", V_NUMBERS }, + { "stressAdd", V_STRESSADD }, + { "stressAmp", V_STRESSAMP }, + { "stressLength", V_STRESSLENGTH }, + { "stressOpt", V_STRESSOPT }, + { "stressRule", V_STRESSRULE }, + { "tunes", V_TUNES }, + { "words", V_WORDGAP }, + + { "maintainer", V_MAINTAINER }, + { "status", V_STATUS }, + + { NULL, 0 } +}; + +static const MNEM_TAB keyword_tab[] = { + { "name", V_NAME }, + { "language", V_LANGUAGE }, + { "gender", V_GENDER }, + { "variants", V_VARIANTS }, + { "formant", V_FORMANT }, + { "pitch", V_PITCH }, + { "phonemes", V_PHONEMES }, + { "dictionary", V_DICTIONARY }, + { "replace", V_REPLACE }, + { "echo", V_ECHO }, + { "flutter", V_FLUTTER }, + { "roughness", V_ROUGHNESS }, + { "clarity", V_CLARITY }, + { "tone", V_TONE }, + { "voicing", V_VOICING }, + { "breath", V_BREATH }, + { "breathw", V_BREATHW }, + { "mbrola", V_MBROLA }, + { "consonants", V_CONSONANTS }, + { "klatt", V_KLATT }, + { "fast_test2", V_FAST }, + { "speed", V_SPEED }, + { "dict_min", V_DICTMIN }, + + + { "apostrophe", 0x100+LOPT_APOSTROPHE }, + { "brackets", 0x100+LOPT_BRACKET_PAUSE }, + { "bracketsAnnounced", 0x100+LOPT_BRACKET_PAUSE_ANNOUNCED }, + + { NULL, 0 } +}; + const char *SelectVoice(espeak_VOICE *voice_select, int *found); espeak_VOICE *SelectVoiceByName(espeak_VOICE **voices, const char *name); voice_t *LoadVoice(const char *voice_name, int control); diff --git a/src/libespeak-ng/voices.c b/src/libespeak-ng/voices.c index edffb961..60d8f23a 100644 --- a/src/libespeak-ng/voices.c +++ b/src/libespeak-ng/voices.c @@ -73,111 +73,6 @@ static espeak_VOICE *voices_list[N_VOICES_LIST]; espeak_VOICE current_voice_selected; -enum { - V_NAME = 1, - V_LANGUAGE, - V_GENDER, - V_PHONEMES, - V_DICTIONARY, - V_VARIANTS, - - V_MAINTAINER, - V_STATUS, - - // these affect voice quality, are independent of language - V_FORMANT, - V_PITCH, - V_ECHO, - V_FLUTTER, - V_ROUGHNESS, - V_CLARITY, - V_TONE, - V_VOICING, - V_BREATH, - V_BREATHW, - - // these override defaults set by the translator - V_LOWERCASE_SENTENCE, - V_WORDGAP, - V_INTONATION, - V_TUNES, - V_STRESSLENGTH, - V_STRESSAMP, - V_STRESSADD, - V_DICTRULES, - V_STRESSRULE, - V_STRESSOPT, - V_NUMBERS, - - V_MBROLA, - V_KLATT, - V_FAST, - V_SPEED, - V_DICTMIN, - - // these need a phoneme table to have been specified - V_REPLACE, - V_CONSONANTS -}; - -const MNEM_TAB langopts_tab[] = { - { "dictrules", V_DICTRULES }, - { "intonation", V_INTONATION }, - { "l_dieresis", 0x100+LOPT_DIERESES }, - { "l_prefix", 0x100+LOPT_PREFIXES }, - { "l_regressive_v", 0x100+LOPT_REGRESSIVE_VOICING }, - { "l_unpronouncable", 0x100+LOPT_UNPRONOUNCABLE }, - { "l_sonorant_min", 0x100+LOPT_SONORANT_MIN }, - { "lowercaseSentence", V_LOWERCASE_SENTENCE }, - { "numbers", V_NUMBERS }, - { "stressAdd", V_STRESSADD }, - { "stressAmp", V_STRESSAMP }, - { "stressLength", V_STRESSLENGTH }, - { "stressOpt", V_STRESSOPT }, - { "stressRule", V_STRESSRULE }, - { "tunes", V_TUNES }, - { "words", V_WORDGAP }, - - { "maintainer", V_MAINTAINER }, - { "status", V_STATUS }, - - { NULL, 0 } -}; - - -static const MNEM_TAB keyword_tab[] = { - { "name", V_NAME }, - { "language", V_LANGUAGE }, - { "gender", V_GENDER }, - { "variants", V_VARIANTS }, - { "formant", V_FORMANT }, - { "pitch", V_PITCH }, - { "phonemes", V_PHONEMES }, - { "dictionary", V_DICTIONARY }, - { "replace", V_REPLACE }, - { "echo", V_ECHO }, - { "flutter", V_FLUTTER }, - { "roughness", V_ROUGHNESS }, - { "clarity", V_CLARITY }, - { "tone", V_TONE }, - { "voicing", V_VOICING }, - { "breath", V_BREATH }, - { "breathw", V_BREATHW }, - { "mbrola", V_MBROLA }, - { "consonants", V_CONSONANTS }, - { "klatt", V_KLATT }, - { "fast_test2", V_FAST }, - { "speed", V_SPEED }, - { "dict_min", V_DICTMIN }, - - - { "apostrophe", 0x100+LOPT_APOSTROPHE }, - { "brackets", 0x100+LOPT_BRACKET_PAUSE }, - { "bracketsAnnounced", 0x100+LOPT_BRACKET_PAUSE_ANNOUNCED }, - - { NULL, 0 } -}; - #define N_VOICE_VARIANTS 12 const char variants_either[N_VOICE_VARIANTS] = { 1, 2, 12, 3, 13, 4, 14, 5, 11, 0 }; const char variants_male[N_VOICE_VARIANTS] = { 1, 2, 3, 4, 5, 6, 0 }; From a19e4b8df2417bac56138f2f225d309f8392c7db Mon Sep 17 00:00:00 2001 From: Juho Hiltunen Date: Sun, 9 Oct 2022 15:38:30 +0300 Subject: [PATCH 20/20] resize and initialize a two-dimensional array to pass sanitizer --- src/libespeak-ng/langopts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libespeak-ng/langopts.c b/src/libespeak-ng/langopts.c index 7d72c47d..320e7288 100644 --- a/src/libespeak-ng/langopts.c +++ b/src/libespeak-ng/langopts.c @@ -143,7 +143,7 @@ if (CheckTranslator(translator, langopts_tab, key) != 0) { break; } case V_TUNES: { - char names[8][40]; + char names[6][40] = { 0, 0, 0, 0, 0, 0 }; n = sscanf(keyValue, "%s %s %s %s %s %s", names[0], names[1], names[2], names[3], names[4], names[5]); translator->langopts.intonation_group = 0;