Option --load makes espeak-ng consider the voice name provided a name of a file relative to the current directory. Signed-off-by: golubovsky <[email protected]>master
| "--voices=<language>\n" | "--voices=<language>\n" | ||||
| "\t List the available voices for the specified language.\n" | "\t List the available voices for the specified language.\n" | ||||
| "\t If <language> is omitted, then list all voices.\n" | "\t If <language> is omitted, then list all voices.\n" | ||||
| "--load Load voice from a file in current directory by name.\n" | |||||
| "--dump=<file>\n" | |||||
| "\t Dump the currently loaded voice definition into a file\n" | |||||
| "\t in the current directory\n" | |||||
| "-h, --help Show this help.\n"; | "-h, --help Show this help.\n"; | ||||
| int samplerate; | int samplerate; | ||||
| { "compile-mbrola", optional_argument, 0, 0x10e }, | { "compile-mbrola", optional_argument, 0, 0x10e }, | ||||
| { "compile-intonations", no_argument, 0, 0x10f }, | { "compile-intonations", no_argument, 0, 0x10f }, | ||||
| { "compile-phonemes", optional_argument, 0, 0x110 }, | { "compile-phonemes", optional_argument, 0, 0x110 }, | ||||
| { "load", no_argument, 0, 0x111 }, | |||||
| { "dump", required_argument, 0, 0x112 }, | |||||
| { 0, 0, 0, 0 } | { 0, 0, 0, 0 } | ||||
| }; | }; | ||||
| int value; | int value; | ||||
| int flag_stdin = 0; | int flag_stdin = 0; | ||||
| int flag_compile = 0; | int flag_compile = 0; | ||||
| int flag_load = 0; | |||||
| int filesize = 0; | int filesize = 0; | ||||
| int synth_flags = espeakCHARS_AUTO | espeakPHONEMES | espeakENDPAUSE; | int synth_flags = espeakCHARS_AUTO | espeakPHONEMES | espeakENDPAUSE; | ||||
| int phoneme_options = 0; | int phoneme_options = 0; | ||||
| int option_linelength = 0; | int option_linelength = 0; | ||||
| int option_waveout = 0; | int option_waveout = 0; | ||||
| espeak_VOICE voice_select; | espeak_VOICE voice_select; | ||||
| char dumpfile[200]; | |||||
| char filename[200]; | char filename[200]; | ||||
| char voicename[40]; | char voicename[40]; | ||||
| char devicename[200]; | char devicename[200]; | ||||
| } | } | ||||
| return EXIT_SUCCESS; | return EXIT_SUCCESS; | ||||
| } | } | ||||
| case 0x111: // --load | |||||
| flag_load = 1; | |||||
| break; | |||||
| case 0x112: // --dump | |||||
| strncpy(dumpfile, optarg2, sizeof(dumpfile) - 1); | |||||
| break; | |||||
| default: | default: | ||||
| exit(0); | exit(0); | ||||
| } | } | ||||
| if (voicename[0] == 0) | if (voicename[0] == 0) | ||||
| strcpy(voicename, ESPEAKNG_DEFAULT_VOICE); | 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) { | if (result != ENS_OK) { | ||||
| memset(&voice_select, 0, sizeof(voice_select)); | memset(&voice_select, 0, sizeof(voice_select)); | ||||
| voice_select.languages = voicename; | voice_select.languages = voicename; |
| are listed, and they are listed in preference order. | 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 | #ifdef __cplusplus | ||||
| extern "C" | extern "C" | ||||
| #endif | #endif |
| return status_to_espeak_error(espeak_ng_SetVoiceByName(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) | ESPEAK_API espeak_ERROR espeak_SetVoiceByProperties(espeak_VOICE *voice_selector) | ||||
| { | { | ||||
| return status_to_espeak_error(espeak_ng_SetVoiceByProperties(voice_selector)); | return status_to_espeak_error(espeak_ng_SetVoiceByProperties(voice_selector)); |
| #pragma GCC visibility push(default) | #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_NG_API espeak_ng_STATUS espeak_ng_SetVoiceByName(const char *name) | ||||
| { | { | ||||
| espeak_VOICE *v; | espeak_VOICE *v; |