[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] espeak - Add config option to show variants in voice list
From: |
Luke Yelavich |
Subject: |
[PATCH] espeak - Add config option to show variants in voice list |
Date: |
Wed, 3 Jun 2015 12:23:10 +1000 |
From: Luke Yelavich <address@hidden>
To: address@hidden
Longre term we need to extend the client API to allow synths to present
such information to the user, but this will work for now, disabled by default.
---
config/modules/espeak.conf | 7 +++
src/modules/espeak.c | 110 ++++++++++++++++++++++++++++++++++++---------
2 files changed, 97 insertions(+), 20 deletions(-)
diff --git a/config/modules/espeak.conf b/config/modules/espeak.conf
index ce9963a..e8afa4c 100644
--- a/config/modules/espeak.conf
+++ b/config/modules/espeak.conf
@@ -35,7 +35,14 @@ EspeakNormalRate 170
# Maximum rate (100 in speech-dispatcher)
EspeakMaxRate 390
+# -- Espeak variants --
+# Controls whether espeak voice variants are presented in the list of
+# available voices. A value of 1 will present an espeak voice, plus the
+# espeak voice with all the available variants. A value of 0 will present
+# the list of espeak voices only.
+
+EspeakListVoiceVariants 0
# -- Internal parameters --
diff --git a/src/modules/espeak.c b/src/modules/espeak.c
index b4040bd..48fc743 100644
--- a/src/modules/espeak.c
+++ b/src/modules/espeak.c
@@ -193,6 +193,7 @@ MOD_OPTION_1_STR(EspeakPunctuationList)
MOD_OPTION_1_INT(EspeakMinRate)
MOD_OPTION_1_INT(EspeakNormalRate)
MOD_OPTION_1_INT(EspeakMaxRate)
+ MOD_OPTION_1_INT(EspeakListVoiceVariants)
MOD_OPTION_1_INT(EspeakAudioChunkSize)
MOD_OPTION_1_INT(EspeakAudioQueueMaxSize)
@@ -219,6 +220,7 @@ int module_load(void)
MOD_OPTION_1_INT_REG(EspeakMaxRate, 390);
MOD_OPTION_1_STR_REG(EspeakPunctuationList, "@/+-_");
MOD_OPTION_1_INT_REG(EspeakCapitalPitchRise, 800);
+ MOD_OPTION_1_INT_REG(EspeakListVoiceVariants, 0);
if (EspeakCapitalPitchRise == 1 || EspeakCapitalPitchRise == 2) {
EspeakCapitalPitchRise = 0;
}
@@ -1159,31 +1161,43 @@ static void *_espeak_play(void *nothing)
static SPDVoice **espeak_list_synthesis_voices()
{
SPDVoice **result = NULL;
- const espeak_VOICE **espeak_voices = espeak_ListVoices(NULL);
+ SPDVoice *voice = NULL;
+ SPDVoice *vo = NULL;
+ const espeak_VOICE **espeak_voices = NULL;
+ const espeak_VOICE **espeak_variants = NULL;
+ espeak_VOICE *variant_spec = NULL;
+ const espeak_VOICE *v = NULL;
+ GQueue *voice_list = NULL;
+ GQueue *variant_list = NULL;
+ GList *voice_list_iter = NULL;
+ GList *variant_list_iter = NULL;
+ const gchar *first_lang = NULL;
+ gchar *lang = NULL;
+ gchar *variant = NULL;
+ gchar *dash = NULL;
+ gchar *vname = NULL;
+ int numvoices = 0;
+ int numvariants = 0;
+ int totalvoices = 0;
int i = 0;
- int j = 0;
- /* Count number of voices */
- int numvoices = 0;
- while (espeak_voices[numvoices] != NULL) {
- numvoices++;
- }
- DBG("Espeak: %d voices total.", numvoices);
- result = g_new0(SPDVoice *, numvoices + 1);
- for (i = j = 0; espeak_voices[i] != NULL; i++) {
- const espeak_VOICE *v = espeak_voices[i];
+ espeak_voices = espeak_ListVoices(NULL);
+ voice_list = g_queue_new();
+
+ for (i = 0; espeak_voices[i] != NULL; i++) {
+ v = espeak_voices[i];
if (!g_str_has_prefix(v->identifier, "mb/")) {
/* Not an mbrola voice */
- SPDVoice *voice = g_new0(SPDVoice, 1);
+ voice = g_new0(SPDVoice, 1);
voice->name = g_strdup(v->name);
- const gchar *first_lang = v->languages + 1;
- gchar *lang = NULL;
- gchar *variant = NULL;
+ first_lang = v->languages + 1;
+ lang = NULL;
+ variant = NULL;
if (g_utf8_validate(first_lang, -1, NULL)) {
- gchar *dash =
- g_utf8_strchr(first_lang, -1, '-');
+ dash =
+ g_utf8_strchr(first_lang, -1, '-');
if (dash != NULL) {
/* There is probably a variant string
(like en-uk) */
lang =
@@ -1201,11 +1215,67 @@ static SPDVoice **espeak_list_synthesis_voices()
voice->language = lang;
voice->variant = variant;
- result[j++] = voice;
+ g_queue_push_tail(voice_list, voice);
+ }
+
+ }
+
+ numvoices = g_queue_get_length(voice_list);
+ DBG("Espeak: %d voices total.", numvoices)
+
+ if (EspeakListVoiceVariants) {
+ variant_spec = g_new0(espeak_VOICE, 1);
+ variant_spec->languages = "variant";
+ espeak_variants = espeak_ListVoices(variant_spec);
+ variant_list = g_queue_new();
+
+ for (i = 0; espeak_variants[i] != NULL; i++) {
+ v = espeak_variants[i];
+
+ vname = g_strdup(v->name);
+ g_queue_push_tail(variant_list, vname);
+ }
+
+ numvariants = g_queue_get_length(variant_list);
+ DBG("Espeak: %d variants total.", numvariants)
+ }
+
+ totalvoices = (numvoices * numvariants) + numvoices;
+ result = g_new0(SPDVoice *, totalvoices + 1);
+ voice_list_iter = g_queue_peek_head_link(voice_list);
+
+ for (i = 0; i < totalvoices; i++) {
+ result[i] = voice_list_iter->data;
+
+ if (!g_queue_is_empty(variant_list)) {
+ vo = voice_list_iter->data;
+ variant_list_iter =
g_queue_peek_head_link(variant_list);
+
+ while (variant_list_iter != NULL &&
variant_list_iter->data != NULL) {
+ voice = g_new0(SPDVoice, 1);
+
+ voice->name = g_strdup_printf("%s+%s", vo->name,
+
variant_list_iter->data);
+ voice->language = g_strdup(vo->language);
+ voice->variant = g_strdup(vo->variant);
+
+ result[++i] = voice;
+ variant_list_iter = variant_list_iter->next;
+ }
}
+
+ voice_list_iter = voice_list_iter->next;
}
- result[j] = NULL;
- DBG("Espeak: %d usable voices.", j);
+
+ if (voice_list != NULL)
+ g_queue_free(voice_list);
+ if (variant_list != NULL)
+ g_queue_free_full(variant_list, (GDestroyNotify)g_free);
+ if (variant_spec != NULL)
+ g_free(variant_spec);
+
+ result[i] = NULL;
+ DBG("Espeak: %d usable voices.", totalvoices);
return result;
}
--
2.1.4
- [PATCH] espeak - Add config option to show variants in voice list,
Luke Yelavich <=