speechd-discuss
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] modules, config - ibmtts: list of installed languages


From: Gilles Casse
Subject: [PATCH] modules, config - ibmtts: list of installed languages
Date: Wed, 30 Dec 2009 16:02:10 +0100

* module_list_voices returns the list of installed languages.
  For example, the Orca user will read this list in the Orca Preferences menu.

* The IbmttDialect and the list of possible voices have been moved from the 
ibmtts.conf file to the ibmtts.c file for clarifying the configuration file.

* The encoding associated to each language has been updated (same values as in 
Gnome Speech Viavoice driver).

Signed-off-by: Gilles Casse <gcasse at oralux.org>
---
 ChangeLog                  |    7 ++
 config/modules/ibmtts.conf |   95 --------------------
 src/modules/ibmtts.c       |  204 ++++++++++++++++++++++++++++++++------------
 3 files changed, 158 insertions(+), 148 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 2c09a39..605c6f6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2009-12-30  Gilles Casse <gcasse at oralux.org>
+ 
+       * src/modules/ibmtts.c, config/modules/ibmtts.conf: 
+         - module_list_voices returns the list of the installed languages,
+         - the encoding associated to each language has been updated (same 
values as in Gnome Speech Viavoice driver).
+         - the IbmttDialect and the list of possible voices have been removed 
from the ibmtts.conf file.
+
 2009-07-08  Luke Yelavich <luke.yelavich at canonical.com>
 
        * src/server/config.c (load_default_global_set_options): Set the default
diff --git a/config/modules/ibmtts.conf b/config/modules/ibmtts.conf
index 11c1de9..e692159 100644
--- a/config/modules/ibmtts.conf
+++ b/config/modules/ibmtts.conf
@@ -43,54 +43,6 @@ Debug 0
 
 # DebugFile "/tmp/debug-ibmtts"
 
-# -- VOICES --
-
-# Maps a language code and standard Speech Dispatcher voice to an
-# IBM TTS voice dialect.
-# See the Speech Dispatcher manual for standard voice names.
-# The Dialect must be one of the dialects listed in the DIALECTS section below.
-
-#        Lang Voice     Dialect
-#        ---- --------- ------------------------
-AddVoice "en" "male1"   "GeneralAmericanEnglish"
-AddVoice "en" "male2"   "BritishEnglish"
-AddVoice "es" "male1"   "CastilianSpanish"
-AddVoice "es" "male2"   "MexicanSpanish"
-AddVoice "fr" "male1"   "StandardFrench"
-AddVoice "fr" "male2"   "CanadianFrench"
-AddVoice "de" "male1"   "StandardGerman"
-AddVoice "it" "male1"   "StandardItalian"
-AddVoice "zh" "male1"   "MandarinChinese"
-AddVoice "zh" "male2"   "MandarinChineseGB"
-AddVoice "zh" "male3"   "MandarinChinesePinYin"
-#AddVoice "zh" "male1"   "MandarinChineseUCS"
-#AddVoice "zh" "male1"   "TaiwaneseMandarin"
-#AddVoice "zh" "male2"   "TaiwaneseMandarinBig5"
-#AddVoice "zh" "male3"   "TaiwaneseMandarinZhuYin"
-#AddVoice "zh" "male1"   "TaiwaneseMandarinPinYin"
-#AddVoice "zh" "male2"   "TaiwaneseMandarinUCS"
-AddVoice "pt" "male1"   "BrazilianPortuguese"
-AddVoice "jp" "male1"   "StandardJapanese"
-AddVoice "jp" "male2"   "StandardJapaneseSJIS"
-AddVoice "jp" "male3"   "StandardJapaneseUCS"
-AddVoice "fi" "male1"   "StandardFinnish"
-AddVoice "ko" "male1"   "StandardKorean"
-AddVoice "ko" "male2"   "StandardKoreanUHC"
-AddVoice "ko" "male3"   "StandardKoreanUCS"
-#AddVoice "zh" "male1"   "StandardCantonese"
-#AddVoice "zh" "male2"   "StandardCantoneseGB"
-#AddVoice "zh" "male3"   "StandardCantoneseUCS"
-AddVoice "zh" "male1"   "HongKongCantonese"
-AddVoice "zh" "male2"   "HongKongCantoneseBig5"
-AddVoice "zh" "male3"   "HongKongCantoneseUCS"
-AddVoice "nl" "male1"   "StandardDutch"
-AddVoice "nn" "male1"   "StandardNorwegian"
-AddVoice "sv" "male1"   "StandardSwedish"
-AddVoice "da" "male1"   "StandardDanish"
-AddVoice "xx" "male1"   "StandardReserved"
-AddVoice "th" "male1"   "StandardThai"
-AddVoice "th" "male2"   "StandardThaiTIS"
-
 # -- VOICE PARAMETERS --
 
 # This table provides a mechanism for fine-tuning the voices used for 
synthesis.
@@ -141,53 +93,6 @@ IbmttsVoiceParameters  "child_male"     0   0  35  85  35   
0    50
 # child_male        none provided (that is why it is uncommented, by default)
 # child_female      Child
 
-# -- DIALECTS --
-# Do not change these unless you know what you are doing.
-# These codes are hard-coded in the IBM TTS engine.
-# See ech.h in IBM TTS SDK.
-
-#             Dialect                        Code (Hex)   encoding
-#             -----------------------------  ----------- ---------
-IbmttsDialect "NODEFINEDCODESET"             "00000000"    "cp1252"
-IbmttsDialect "GeneralAmericanEnglish"       "00010000"    "cp1252"
-IbmttsDialect "BritishEnglish"               "00010001"    "cp1252"
-IbmttsDialect "CastilianSpanish"             "00020000"    "cp1252"
-IbmttsDialect "MexicanSpanish"               "00020001"    "cp1252"
-IbmttsDialect "StandardFrench"               "00030000"    "cp1252"
-IbmttsDialect "CanadianFrench"               "00030001"    "cp1252"
-IbmttsDialect "StandardGerman"               "00040000"    "cp1252"
-IbmttsDialect "StandardItalian"              "00050000"    "cp1252"
-IbmttsDialect "MandarinChinese"              "00060000"    "utf-16"
-IbmttsDialect "MandarinChineseGB"            "00060000"    "utf-16"
-IbmttsDialect "MandarinChinesePinYin"        "00060100"    "utf-16"
-IbmttsDialect "MandarinChineseUCS"           "00060800"    "utf-16"
-IbmttsDialect "TaiwaneseMandarin"            "00060001"    "utf-16"
-IbmttsDialect "TaiwaneseMandarinBig5"        "00060001"    "utf-16"
-IbmttsDialect "TaiwaneseMandarinZhuYin"      "00060101"    "utf-16"
-IbmttsDialect "TaiwaneseMandarinPinYin"      "00060201"    "utf-16"
-IbmttsDialect "TaiwaneseMandarinUCS"         "00060801"    "utf-16"
-IbmttsDialect "BrazilianPortuguese"          "00070000"    "cp1252"
-IbmttsDialect "StandardJapanese"             "00080000"    "utf-16"
-IbmttsDialect "StandardJapaneseSJIS"         "00080000"    "utf-16"
-IbmttsDialect "StandardJapaneseUCS"          "00080800"    "utf-16"
-IbmttsDialect "StandardFinnish"              "00090000"    "cp1252"
-IbmttsDialect "StandardKorean"               "000A0000"    "utf-16"
-IbmttsDialect "StandardKoreanUHC"            "000A0000"    "utf-16"
-IbmttsDialect "StandardKoreanUCS"            "000A0800"    "utf-16"
-IbmttsDialect "StandardCantonese"            "000B0000"    "utf-16"
-IbmttsDialect "StandardCantoneseGB"          "000B0000"    "utf-16"
-IbmttsDialect "StandardCantoneseUCS"         "000B0800"    "utf-16"
-IbmttsDialect "HongKongCantonese"            "000B0001"    "utf-16"
-IbmttsDialect "HongKongCantoneseBig5"        "000B0001"    "utf-16"
-IbmttsDialect "HongKongCantoneseUCS"         "000B0801"    "utf-16"
-IbmttsDialect "StandardDutch"                "000C0000"    "cp1252"
-IbmttsDialect "StandardNorwegian"            "000D0000"    "cp1252"
-IbmttsDialect "StandardSwedish"              "000E0000"    "cp1252"
-IbmttsDialect "StandardDanish"               "000F0000"    "cp1252"
-IbmttsDialect "StandardReserved"             "00100000"    "cp1252"
-IbmttsDialect "StandardThai"                 "00110000"    "utf-16"
-IbmttsDialect "StandardThaiTIS"              "00110000"    "utf-16"
-
 # -- KEY NAME SUBSTITUTIONS --
 
 # Maps Speech Dispatcher key names used in SSIP KEY commands to speakable 
words.
diff --git a/src/modules/ibmtts.c b/src/modules/ibmtts.c
index 869c71f..dc34489 100644
--- a/src/modules/ibmtts.c
+++ b/src/modules/ibmtts.c
@@ -241,6 +241,10 @@ int ibmtts_voice_speed;
 /* Expected input encoding for current language dialect. */
 static char *ibmtts_input_encoding = "cp1252";
 
+/* list of voices */
+static VoiceDescription **ibmtts_voice_list = NULL;
+static int *ibmtts_voice_index = NULL;
+
 /* Internal function prototypes for main thread. */
 static void ibmtts_set_language(char *lang);
 static void ibmtts_set_voice(EVoiceType voice);
@@ -253,7 +257,6 @@ static void ibmtts_set_volume(signed int pitch);
 /* Internal function prototypes for synthesis thread. */
 static char* ibmtts_extract_mark_name(char *mark);
 static char* ibmtts_next_part(char *msg, char **mark_name);
-static enum ECILanguageDialect ibmtts_dialect_to_code(char *dialect_name);
 static int ibmtts_replace(char *from, char *to, GString *msg);
 static void ibmtts_subst_keys_cb(gpointer data, gpointer user_data);
 static char* ibmtts_subst_keys(char *key);
@@ -280,6 +283,8 @@ static TIbmttsBool ibmtts_play_file(char *filename);
 static TIbmttsBool is_thread_busy(pthread_mutex_t *suspended_mutex);
 static void ibmtts_log_eci_error();
 static void ibmtts_clear_playback_queue();
+static void alloc_voice_list();
+static void free_voice_list();
 
 /* The synthesis thread start routine. */
 static void* _ibmtts_synth(void*);
@@ -299,11 +304,62 @@ MOD_OPTION_1_INT(IbmttsUseSSML);
 MOD_OPTION_1_INT(IbmttsUseAbbreviation);
 MOD_OPTION_1_INT(IbmttsAudioChunkSize);
 MOD_OPTION_1_STR(IbmttsSoundIconFolder);
-MOD_OPTION_3_HT(IbmttsDialect, dialect, code, encoding);
 MOD_OPTION_6_INT_HT(IbmttsVoiceParameters,
     gender, breathiness, head_size, pitch_baseline, pitch_fluctuation, 
roughness, speed);
 MOD_OPTION_3_STR_HT_DLL(IbmttsKeySubstitution, lang, key, newkey);
 
+
+typedef struct _eciLocale {
+       char *name;
+       char *lang;
+       char *dialect;
+       enum ECILanguageDialect langID;
+       char* charset;
+} eciLocale, *eciLocaleList;
+
+static eciLocale eciLocales[] = {
+    {"American_English", "en", "US", eciGeneralAmericanEnglish, "ISO-8859-1"},
+    {"British_English", "en", "GB", eciBritishEnglish, "ISO-8859-1"},
+    {"Castilian_Spanish", "es", "ES", eciCastilianSpanish, "ISO-8859-1"},
+    {"Mexican_Spanish", "es", "MX", eciMexicanSpanish, "ISO-8859-1"},
+    {"French", "fr", "FR", eciStandardFrench, "ISO-8859-1"},
+    {"Canadian_French", "ca", "FR", eciCanadianFrench, "ISO-8859-1"},
+    {"German", "de", "DE", eciStandardGerman, "ISO-8859-1"},
+    {"Italian", "it", "IT", eciStandardItalian, "ISO-8859-1"},
+    {"Mandarin_Chinese", "zh", "CN", eciMandarinChinese, "GBK"},
+    {"Mandarin_Chinese GB", "zh", "CN_GB", eciMandarinChineseGB, "GBK"},
+    {"Mandarin_Chinese PinYin", "zh", "CN_PinYin", eciMandarinChinesePinYin, 
"GBK"},
+    {"Mandarin_Chinese UCS", "zh", "CN_UCS", eciMandarinChineseUCS, "UCS2"},
+    {"Taiwanese_Mandarin", "zh", "TW", eciTaiwaneseMandarin, "BIG5"},
+    {"Taiwanese_Mandarin Big 5", "zh", "TW_Big5", eciTaiwaneseMandarinBig5, 
"BIG5"},
+    {"Taiwanese_Mandarin ZhuYin", "zh", "TW_ZhuYin", 
eciTaiwaneseMandarinZhuYin, "BIG5"},
+    {"Taiwanese_Mandarin PinYin", "zh", "TW_PinYin", 
eciTaiwaneseMandarinPinYin, "BIG5"},
+    {"Taiwanese_Mandarin UCS", "zh", "TW_UCS", eciTaiwaneseMandarinUCS, 
"UCS2"},
+    {"Brazilian_Portuguese", "pt", "BR", eciBrazilianPortuguese, "ISO-8859-1"},
+    {"Japanese", "ja", "JP", eciStandardJapanese, "SJIS"},
+    {"Japanese_SJIS", "ja", "JP_SJIS", eciStandardJapaneseSJIS, "SJIS"},
+    {"Japanese_UCS", "ja", "JP_UCS", eciStandardJapaneseUCS, "UCS2"},
+    {"Finnish", "fi", "FI", eciStandardFinnish, "ISO-8859-1"},
+    {"Korean", "ko", "KR", eciStandardKorean, "UHC"},
+    {"Korean_UHC", "ko", "KR_UHC", eciStandardKoreanUHC, "UHC"},
+    {"Korean_UCS", "ko", "KR_UCS", eciStandardKoreanUCS, "UCS2"},
+    {"Cantonese", "zh", "HK", eciStandardCantonese, "GBK"},
+    {"Cantonese_GB", "zh", "HK_GB", eciStandardCantoneseGB, "GBK"},
+    {"Cantonese_UCS", "zh", "HK_UCS", eciStandardCantoneseUCS, "UCS2"},
+    {"HongKong_Cantonese", "zh", "HK", eciHongKongCantonese, "BIG5"},
+    {"HongKong_Cantonese Big 5", "zh", "HK_BIG5", eciHongKongCantoneseBig5, 
"BIG5"},
+    {"HongKong_Cantonese UCS", "zh", "HK_UCS", eciHongKongCantoneseUCS, 
"UCS-2"},
+    {"Dutch", "nl", "BE", eciStandardDutch, "ISO-8859-1"},
+    {"Norwegian", "no", "NO", eciStandardNorwegian, "ISO-8859-1"},
+    {"Swedish", "sv", "SE", eciStandardSwedish, "ISO-8859-1"},
+    {"Danish", "da", "DK", eciStandardDanish, "ISO-8859-1"},
+    {"Reserved", "en", "US", eciStandardReserved, "ISO-8859-1"},
+    {"Thai", "th", "TH", eciStandardThai, "TIS-620"},
+    {"ThaiTIS", "th", "TH_TIS", eciStandardThaiTIS, "TIS-620"},
+    {NULL, 0, NULL}
+};
+
+
 /* Public functions */
 
 int
@@ -326,9 +382,6 @@ module_load(void)
     /* Register voices. */
     module_register_settings_voices();
 
-    /* Register dialects. */
-    MOD_OPTION_HT_REG(IbmttsDialect);
-
     /* Register voice parameters */
     MOD_OPTION_HT_REG(IbmttsVoiceParameters);
 
@@ -348,7 +401,6 @@ int
 module_init(char **status_info)
 {
     int ret;
-    char *error;
     GString *info;
     char ibmVersion[20];
     int ibm_sample_rate;
@@ -405,6 +457,8 @@ module_init(char **status_info)
 
     eciSetParam (eciHandle, eciDictionary, !IbmttsUseAbbreviation);
 
+    alloc_voice_list();
+
     /* These mutexes are locked when the corresponding threads are suspended. 
*/
     pthread_mutex_init(&ibmtts_synth_suspended_mutex, NULL);
     pthread_mutex_init(&ibmtts_play_suspended_mutex, NULL);
@@ -480,14 +534,15 @@ module_audio_init(char **status_info){
 VoiceDescription**
 module_list_voices(void)
 {
-  return NULL;
+  DBG("Ibmtts: %s", __FUNCTION__);
+  return ibmtts_voice_list;
 }
 
 
 int
 module_speak(gchar *data, size_t bytes, EMessageType msgtype)
 {
-       DBG("Ibmtts: module_speak().");
+    DBG("Ibmtts: module_speak().");
 
     if (is_thread_busy(&ibmtts_synth_suspended_mutex) || 
         is_thread_busy(&ibmtts_play_suspended_mutex) ||
@@ -639,6 +694,8 @@ module_close(int status)
         ibmtts_index_mark_ht = NULL;
     }
 
+    free_voice_list();
+    
     exit(status);
 }
 
@@ -1035,31 +1092,6 @@ ibmtts_set_pitch(signed int pitch)
         DBG("Ibmtts: Pitch set to %i.", pitchBaseline);
 }
 
-/* Given an IBM TTS Dialect Name returns the code from the DIALECTS table in 
config file. */
-static enum ECILanguageDialect ibmtts_dialect_to_code(char *dialect_name)
-{
-    long int code = 0;
-    TIbmttsDialect *dialect = (TIbmttsDialect *) 
module_get_ht_option(IbmttsDialect, dialect_name);
-    if (NULL == dialect) {
-        DBG("Ibmtts: Invalid dialect name %s.  Check VOICES and DIALECTS 
sections of ibmtts.conf file.", dialect_name);
-        ibmtts_log_eci_error();
-        return NODEFINEDCODESET;
-    }
-    sscanf(dialect->code, "%08X", &code);
-    return code;
-}
-
-/* Given an IBM TTS Dialect Name returns the expected input encoding from the 
DIALECTS table in config file. */
-static char *ibmtts_dialect_to_encoding(char *dialect_name)
-{
-        TIbmttsDialect *dialect = (TIbmttsDialect *) 
module_get_ht_option(IbmttsDialect, dialect_name);
-    if (NULL == dialect) {
-        DBG("Ibmtts: Invalid dialect name %s.  Check VOICES and DIALECTS 
sections of ibmtts.conf file.", dialect_name);
-        ibmtts_log_eci_error();
-        return NULL;
-    }
-    return dialect->encoding;
-}
 
 static char*
 ibmtts_voice_enum_to_str(EVoiceType voice)
@@ -1086,33 +1118,34 @@ ibmtts_voice_enum_to_str(EVoiceType voice)
 static void
 ibmtts_set_language_and_voice(char *lang, EVoiceType voice)
 {
-       char *dialect_name;
-    enum ECILanguageDialect dialect_code = NODEFINEDCODESET;
+    char *dialect_name;
     char *voicename = ibmtts_voice_enum_to_str(voice);
     int eciVoice;
     int ret = -1;
-    /* Map language and symbolic voice name to dialect name. */
-    dialect_name = module_getvoice(lang, voice);
-    if (NULL != dialect_name) {
-         /* Map dialect name to dialect code. */
-         dialect_code = ibmtts_dialect_to_code(dialect_name);
-         if (NODEFINEDCODESET != dialect_code) {
-             /* Set the dialect. */
-             ret = eciSetParam(eciHandle, eciLanguageDialect, dialect_code);
-        }
-                /* Set expected input encoding for dialect */
-                char *encoding = ibmtts_dialect_to_encoding(dialect_name);
-                if (encoding != NULL) {
-                        ibmtts_input_encoding = encoding;
-                }
+    int i = 0;
+ 
+    DBG("Ibmtts: %s, lang=%s, voice=%d", __FUNCTION__, lang, (int)voice);
+
+    VoiceDescription **v = ibmtts_voice_list;
+    assert(v);
+
+    for (i=0; v[i]; i++) {
+       if (!strcmp(v[i]->language, lang)) {
+           int j = ibmtts_voice_index[i];
+           dialect_name = v[i]->name;
+           ret = eciSetParam(eciHandle, eciLanguageDialect, 
eciLocales[j].langID);
+           ibmtts_input_encoding = eciLocales[j].charset;
+           break;
+       }
     }
+
     if (-1 == ret) {
-        DBG("Ibmtts: Unable to set language %s and voice %s,  dialect %08X.",
-            lang, voicename, dialect_code);
+        DBG("Ibmtts: Unable to set language %s and voice %s",
+            lang, voicename);
         ibmtts_log_eci_error();
     } else
-        DBG("Ibmtts: Successfully set language %s and voice %s, dialect %s = 
%08X.",
-            lang, voicename, dialect_name, dialect_code);
+        DBG("Ibmtts: Successfully set language %s and voice %s, name=%s",
+            lang, voicename, dialect_name);
     /* Set voice parameters (if any are defined for this voice.) */
     TIbmttsVoiceParameters *params = 
g_hash_table_lookup(IbmttsVoiceParameters, voicename);
     if (NULL == params) {
@@ -1579,4 +1612,69 @@ cleanup1:
     return result;
 }
 
+
+void 
+alloc_voice_list()
+{
+#define MAX_NB_OF_LANGUAGES 13
+
+    enum ECILanguageDialect aLanguage[MAX_NB_OF_LANGUAGES];
+    int nLanguages = MAX_NB_OF_LANGUAGES;
+    int i = 0;
+
+    if (eciGetAvailableLanguages(aLanguage, &nLanguages))
+       return;
+
+    ibmtts_voice_list = malloc((nLanguages+1)*sizeof(VoiceDescription*));
+    ibmtts_voice_index = malloc((nLanguages+1)*sizeof(VoiceDescription*));
+    if (!ibmtts_voice_list)
+       return;
+
+    DBG("Ibmtts: nLanguages=%d", nLanguages);
+    for(i=0; i<nLanguages; i++) {
+       /* look for the language name */
+       int j;
+       ibmtts_voice_list[i] = malloc(sizeof(VoiceDescription));
+
+       DBG("Ibmtts: aLanguage[%d]=0x%08x", i, aLanguage[i]);
+       for (j=0; j<MAX_NB_OF_LANGUAGES; j++) {
+           DBG("Ibmtts: eciLocales[%d].langID=0x%08x", j, 
eciLocales[j].langID);
+           if (eciLocales[j].langID == aLanguage[i]) {
+               ibmtts_voice_list[i]->name = eciLocales[j].name;
+               ibmtts_voice_list[i]->language = eciLocales[j].lang;
+               ibmtts_voice_list[i]->dialect = eciLocales[j].dialect;
+               ibmtts_voice_index[i] = j;
+               DBG("Ibmtts: alloc_voice_list %s", ibmtts_voice_list[i]->name);
+               break;
+           }
+       }
+       assert(j<MAX_NB_OF_LANGUAGES);
+    }
+    ibmtts_voice_list[nLanguages] = NULL;
+    DBG("Ibmtts: LEAVE %s", __func__);
+}
+
+static void
+free_voice_list()
+{
+    int i=0;
+
+    if (ibmtts_voice_index) {
+       free(ibmtts_voice_index);
+       ibmtts_voice_index = NULL;
+    }
+
+    if (!ibmtts_voice_list)
+       return;
+
+    for(i=0; ibmtts_voice_list[i]; i++) {
+       free(ibmtts_voice_list[i]);
+    }
+
+    free(ibmtts_voice_list);
+    ibmtts_voice_list = NULL;
+}
+
+
+
 #include "module_main.c"
-- 
1.5.6.3


--------------090908040609050607000407--



reply via email to

[Prev in Thread] Current Thread [Next in Thread]