diff --git a/src/espeak-ng.c b/src/espeak-ng.c index 812397fe..0d5a09fe 100644 --- a/src/espeak-ng.c +++ b/src/espeak-ng.c @@ -113,6 +113,10 @@ static const char *help_text = "--voices=\n" "\t List the available voices for the specified language.\n" "\t If is omitted, then list all voices.\n" + "--load Load voice from a file in current directory by name.\n" + "--dump=\n" + "\t Dump the currently loaded voice definition into a file\n" + "\t in the current directory\n" "-h, --help Show this help.\n"; int samplerate; @@ -321,6 +325,8 @@ int main(int argc, char **argv) { "compile-mbrola", optional_argument, 0, 0x10e }, { "compile-intonations", no_argument, 0, 0x10f }, { "compile-phonemes", optional_argument, 0, 0x110 }, + { "load", no_argument, 0, 0x111 }, + { "dump", required_argument, 0, 0x112 }, { 0, 0, 0, 0 } }; @@ -336,6 +342,7 @@ int main(int argc, char **argv) int value; int flag_stdin = 0; int flag_compile = 0; + int flag_load = 0; int filesize = 0; int synth_flags = espeakCHARS_AUTO | espeakPHONEMES | espeakENDPAUSE; @@ -349,8 +356,9 @@ int main(int argc, char **argv) int phoneme_options = 0; int option_linelength = 0; int option_waveout = 0; - + espeak_VOICE voice_select; + char dumpfile[200]; char filename[200]; char voicename[40]; char devicename[200]; @@ -562,6 +570,12 @@ int main(int argc, char **argv) } return EXIT_SUCCESS; } + case 0x111: // --load + flag_load = 1; + break; + case 0x112: // --dump + strncpy(dumpfile, optarg2, sizeof(dumpfile) - 1); + break; default: exit(0); } @@ -605,7 +619,10 @@ int main(int argc, char **argv) if (voicename[0] == 0) strcpy(voicename, ESPEAKNG_DEFAULT_VOICE); - result = espeak_ng_SetVoiceByName(voicename); + if(flag_load) + result = espeak_ng_SetVoiceByFile(voicename); + else + result = espeak_ng_SetVoiceByName(voicename); if (result != ENS_OK) { memset(&voice_select, 0, sizeof(voice_select)); voice_select.languages = voicename; diff --git a/src/include/espeak-ng/speak_lib.h b/src/include/espeak-ng/speak_lib.h index 5cce6164..cc1e35e7 100644 --- a/src/include/espeak-ng/speak_lib.h +++ b/src/include/espeak-ng/speak_lib.h @@ -606,6 +606,19 @@ ESPEAK_API const espeak_VOICE **espeak_ListVoices(espeak_VOICE *voice_spec); are listed, and they are listed in preference order. */ +#ifdef __cplusplus +extern "C" +#endif +ESPEAK_API espeak_ERROR espeak_SetVoiceByFile(const char *filename); +/* Loads a voice given the file path. Language is not considered. + "filename" is a UTF8 string. + + Return: EE_OK: operation achieved + EE_BUFFER_FULL: the command can not be buffered; + you may try after a while to call the function again. + EE_INTERNAL_ERROR. +*/ + #ifdef __cplusplus extern "C" #endif diff --git a/src/libespeak-ng/espeak_api.c b/src/libespeak-ng/espeak_api.c index 0a5f6fd7..73d9417b 100644 --- a/src/libespeak-ng/espeak_api.c +++ b/src/libespeak-ng/espeak_api.c @@ -128,6 +128,11 @@ ESPEAK_API espeak_ERROR espeak_SetVoiceByName(const char *name) return status_to_espeak_error(espeak_ng_SetVoiceByName(name)); } +ESPEAK_API espeak_ERROR espeak_SetVoiceByFile(const char *filename) +{ + return status_to_espeak_error(espeak_ng_SetVoiceByFile(filename)); +} + ESPEAK_API espeak_ERROR espeak_SetVoiceByProperties(espeak_VOICE *voice_selector) { return status_to_espeak_error(espeak_ng_SetVoiceByProperties(voice_selector)); diff --git a/src/libespeak-ng/voices.c b/src/libespeak-ng/voices.c index 73a48fc4..66b30f8f 100644 --- a/src/libespeak-ng/voices.c +++ b/src/libespeak-ng/voices.c @@ -1466,6 +1466,44 @@ static void GetVoices(const char *path, int len_path_voices, int is_language_fil #pragma GCC visibility push(default) +ESPEAK_NG_API espeak_ng_STATUS espeak_ng_SetVoiceByFile(const char *filename) +{ + espeak_VOICE *v; + int ix; + espeak_VOICE voice_selector; + char *variant_name; + static char buf[60]; + + strncpy0(buf, filename, sizeof(buf)); + + variant_name = ExtractVoiceVariantName(buf, 0, 1); + + for (ix = 0;; ix++) { + // convert voice name to lower case (ascii) + if ((buf[ix] = tolower(buf[ix])) == 0) + break; + } + + memset(&voice_selector, 0, sizeof(voice_selector)); + voice_selector.name = (char *)filename; // include variant name in voice stack ?? + + // first check for a voice with this filename + // This may avoid the need to call espeak_ListVoices(). + + if (LoadVoice(buf, 0x10) != NULL) { + if (variant_name[0] != 0) + LoadVoice(variant_name, 2); + + DoVoiceChange(voice); + voice_selector.languages = voice->language_name; + SetVoiceStack(&voice_selector, variant_name); + return ENS_OK; + } + + return ENS_VOICE_NOT_FOUND; +} + + ESPEAK_NG_API espeak_ng_STATUS espeak_ng_SetVoiceByName(const char *name) { espeak_VOICE *v;