From dc4f85865daacb3c84100fad53b5deaeb477f3e4 Mon Sep 17 00:00:00 2001 From: "Reece H. Dunn" Date: Tue, 18 Dec 2012 15:39:00 +0000 Subject: [PATCH] SpeechSynthesis: fix the getSampleText behaviour when passed Java-style locale codes. --- .../espeak/test/SpeechSynthesisTest.java | 6 ++ .../com/reecedunn/espeak/test/VoiceData.java | 6 +- .../com/reecedunn/espeak/SpeechSynthesis.java | 97 ++++++++++++++++++- 3 files changed, 104 insertions(+), 5 deletions(-) diff --git a/android/eSpeakTests/src/com/reecedunn/espeak/test/SpeechSynthesisTest.java b/android/eSpeakTests/src/com/reecedunn/espeak/test/SpeechSynthesisTest.java index d6acc066..fb6ceab2 100644 --- a/android/eSpeakTests/src/com/reecedunn/espeak/test/SpeechSynthesisTest.java +++ b/android/eSpeakTests/src/com/reecedunn/espeak/test/SpeechSynthesisTest.java @@ -321,6 +321,12 @@ public class SpeechSynthesisTest extends AndroidTestCase { final Locale ianaLocale = new Locale(data.ianaLanguage, data.ianaCountry, data.variant); assertThat(SpeechSynthesis.getSampleText(getContext(), ianaLocale), is(data.sampleText)); + + if (!data.javaLanguage.equals("")) + { + final Locale javaLocale = new Locale(data.javaLanguage, data.javaCountry, data.variant); + assertThat(SpeechSynthesis.getSampleText(getContext(), javaLocale), is(data.sampleText)); + } } catch (AssertionError e) { diff --git a/android/eSpeakTests/src/com/reecedunn/espeak/test/VoiceData.java b/android/eSpeakTests/src/com/reecedunn/espeak/test/VoiceData.java index 1539711c..ec963111 100644 --- a/android/eSpeakTests/src/com/reecedunn/espeak/test/VoiceData.java +++ b/android/eSpeakTests/src/com/reecedunn/espeak/test/VoiceData.java @@ -138,10 +138,10 @@ public class VoiceData new Voice("en-uk-rp", "en/en-rp", "en", "eng", "GB", "GBR", "rp", SpeechSynthesis.GENDER_MALE, "English (Received Pronunciation)", "en-GB-rp", "This is a sample of text spoken in English (United Kingdom,RP)"), new Voice("en-uk-wmids", "en/en-wm", "en", "eng", "GB", "GBR", "wmids", SpeechSynthesis.GENDER_MALE, "English (West Midlands)", "en-GB-wmids", "This is a sample of text spoken in English (United Kingdom,WMIDS)"), new Voice("en-us", "en/en-us", "en", "eng", "US", "USA", "", SpeechSynthesis.GENDER_MALE, "English (US)", "en-US", "This is a sample of text spoken in English (United States)"), - new Voice("en-wi", "en/en-wi", "en", "eng", "029", "", "", SpeechSynthesis.GENDER_MALE, "English (Caribbean)", "en-029", "This is a sample of text spoken in English (Caribbean)"), + new Voice("en-wi", "en/en-wi", "en", "eng", "029", "", "", SpeechSynthesis.GENDER_MALE, "English (Caribbean)", "en-029", "This is a sample of text spoken in English"), new Voice("eo", "eo", "eo", "epo", "", "", "", SpeechSynthesis.GENDER_MALE, "Esperanto", "eo", "This is a sample of text spoken in Esperanto"), new Voice("es", "es", "es", "spa", "", "", "", SpeechSynthesis.GENDER_MALE, "Spanish", "es", "Esto es un ejemplo de texto hablado en español."), - new Voice("es-la", "es-la", "es", "spa", "419", "", "", SpeechSynthesis.GENDER_MALE, "Spanish (Latin America)", "es-419", "Esto es un ejemplo de texto hablado en español (Latinoamérica)."), + new Voice("es-la", "es-la", "es", "spa", "419", "", "", SpeechSynthesis.GENDER_MALE, "Spanish (Latin America)", "es-419", "Esto es un ejemplo de texto hablado en español."), new Voice("et", "et", "et", "est", "", "", "", SpeechSynthesis.GENDER_UNSPECIFIED, "Estonian", "et", "This is a sample of text spoken in eesti"), new Voice("fi", "fi", "fi", "fin", "", "", "", SpeechSynthesis.GENDER_MALE, "Finnish", "fi", "Tämä on näyte kielellä suomi puhutusta tekstistä"), new Voice("fr-be", "fr-be", "fr", "fra", "BE", "BEL", "", SpeechSynthesis.GENDER_MALE, "French (Belgium)", "fr-BE", "Voici un exemple de texte énoncé en français (Belgique)."), @@ -200,6 +200,6 @@ public class VoiceData new Voice("vi", "vi", "vi", "vie", "", "", "", SpeechSynthesis.GENDER_MALE, "Vietnamese", "vi", "Đây là mẫu văn bản được đọc bằng Tiếng Việt"), new Voice("wo", "test/wo", "wo", "wol", "", "", "", SpeechSynthesis.GENDER_UNSPECIFIED, "Wolof", "wo", "This is a sample of text spoken in Wolof"), new Voice("zh", "zh", "zh", "zho", "", "", "", SpeechSynthesis.GENDER_MALE, "Chinese (Mandarin)", "zh", "This is a sample of text spoken in 中文"), - new Voice("zh-yue", "zh-yue", "yue", "", "", "", "", SpeechSynthesis.GENDER_MALE, "Chinese (Cantonese)", "yue", "This is a sample of text spoken in Cantonese"), + new Voice("zh-yue", "zh-yue", "yue", "", "", "", "", SpeechSynthesis.GENDER_MALE, "Chinese (Cantonese)", "yue", "This is a sample of text spoken in 中文"), }; } diff --git a/android/src/com/reecedunn/espeak/SpeechSynthesis.java b/android/src/com/reecedunn/espeak/SpeechSynthesis.java index 9df98ad4..900f3687 100644 --- a/android/src/com/reecedunn/espeak/SpeechSynthesis.java +++ b/android/src/com/reecedunn/espeak/SpeechSynthesis.java @@ -32,9 +32,11 @@ import android.util.DisplayMetrics; import android.util.Log; import java.io.File; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Locale; +import java.util.Map; public class SpeechSynthesis { private static final String TAG = SpeechSynthesis.class.getSimpleName(); @@ -166,10 +168,13 @@ public class SpeechSynthesis { public static String getSampleText(Context context, Locale locale) { final DisplayMetrics metrics = context.getResources().getDisplayMetrics(); final Configuration config = context.getResources().getConfiguration(); - config.locale = locale; + + final String language = getIanaLocaleCode(locale.getLanguage(), mJavaToIanaLanguageCode); + final String country = getIanaLocaleCode(locale.getCountry(), mJavaToIanaCountryCode); + config.locale = new Locale(language, country, locale.getVariant()); Resources res = new Resources(context.getAssets(), metrics, config); - return res.getString(R.string.sample_text, locale.getDisplayName(locale)); + return res.getString(R.string.sample_text, config.locale.getDisplayName(config.locale)); } private int mNativeData; @@ -290,4 +295,92 @@ public class SpeechSynthesis { return locale.toString().replace('_', '-'); } } + + private static String getIanaLocaleCode(String code, final Map javaToIana) { + final String iana = javaToIana.get(code); + if (iana != null) { + return iana; + } + return code; + } + + private static final Map mJavaToIanaLanguageCode = new HashMap(); + private static final Map mJavaToIanaCountryCode = new HashMap(); + static { + mJavaToIanaLanguageCode.put("afr", "af"); + mJavaToIanaLanguageCode.put("aka", "ak"); + mJavaToIanaLanguageCode.put("amh", "am"); + mJavaToIanaLanguageCode.put("aze", "az"); + mJavaToIanaLanguageCode.put("bul", "bg"); + mJavaToIanaLanguageCode.put("bos", "bs"); + mJavaToIanaLanguageCode.put("cat", "ca"); + mJavaToIanaLanguageCode.put("ces", "cs"); + mJavaToIanaLanguageCode.put("cym", "cy"); + mJavaToIanaLanguageCode.put("dan", "da"); + mJavaToIanaLanguageCode.put("deu", "de"); + mJavaToIanaLanguageCode.put("div", "dv"); + mJavaToIanaLanguageCode.put("ell", "el"); + mJavaToIanaLanguageCode.put("eng", "en"); + mJavaToIanaLanguageCode.put("epo", "eo"); + mJavaToIanaLanguageCode.put("spa", "es"); + mJavaToIanaLanguageCode.put("est", "et"); + mJavaToIanaLanguageCode.put("fin", "fi"); + mJavaToIanaLanguageCode.put("fra", "fr"); + mJavaToIanaLanguageCode.put("gle", "ga"); + mJavaToIanaLanguageCode.put("hin", "hi"); + mJavaToIanaLanguageCode.put("hrv", "hr"); + mJavaToIanaLanguageCode.put("hat", "ht"); + mJavaToIanaLanguageCode.put("hun", "hu"); + mJavaToIanaLanguageCode.put("hye", "hy"); + mJavaToIanaLanguageCode.put("ind", "in"); // NOTE: The deprecated 'in' code is used by Java/Android. + mJavaToIanaLanguageCode.put("isl", "is"); + mJavaToIanaLanguageCode.put("ita", "it"); + mJavaToIanaLanguageCode.put("kat", "ka"); + mJavaToIanaLanguageCode.put("kaz", "kk"); + mJavaToIanaLanguageCode.put("kal", "kl"); + mJavaToIanaLanguageCode.put("kan", "kn"); + mJavaToIanaLanguageCode.put("kor", "ko"); + mJavaToIanaLanguageCode.put("kur", "ku"); + mJavaToIanaLanguageCode.put("lat", "la"); + mJavaToIanaLanguageCode.put("lit", "lt"); + mJavaToIanaLanguageCode.put("lav", "lv"); + mJavaToIanaLanguageCode.put("mkd", "mk"); + mJavaToIanaLanguageCode.put("mal", "ml"); + mJavaToIanaLanguageCode.put("mlt", "mt"); + mJavaToIanaLanguageCode.put("nep", "ne"); + mJavaToIanaLanguageCode.put("nld", "nl"); + mJavaToIanaLanguageCode.put("nor", "no"); + mJavaToIanaLanguageCode.put("pan", "pa"); + mJavaToIanaLanguageCode.put("pol", "pl"); + mJavaToIanaLanguageCode.put("por", "pt"); + mJavaToIanaLanguageCode.put("ron", "ro"); + mJavaToIanaLanguageCode.put("rus", "ru"); + mJavaToIanaLanguageCode.put("kin", "rw"); + mJavaToIanaLanguageCode.put("sin", "si"); + mJavaToIanaLanguageCode.put("slk", "sk"); + mJavaToIanaLanguageCode.put("slv", "sl"); + mJavaToIanaLanguageCode.put("sqi", "sq"); + mJavaToIanaLanguageCode.put("srp", "sr"); + mJavaToIanaLanguageCode.put("swe", "sv"); + mJavaToIanaLanguageCode.put("swa", "sw"); + mJavaToIanaLanguageCode.put("tam", "ta"); + mJavaToIanaLanguageCode.put("tel", "te"); + mJavaToIanaLanguageCode.put("tsn", "tn"); + mJavaToIanaLanguageCode.put("tur", "tr"); + mJavaToIanaLanguageCode.put("tat", "tt"); + mJavaToIanaLanguageCode.put("urd", "ur"); + mJavaToIanaLanguageCode.put("vie", "vi"); + mJavaToIanaLanguageCode.put("wol", "wo"); + mJavaToIanaLanguageCode.put("zho", "zh"); + mJavaToIanaLanguageCode.put("yue", "zh"); + + mJavaToIanaCountryCode.put("029", ""); // Locale.getCountry() does not map numeric country codes. + mJavaToIanaCountryCode.put("419", ""); // Locale.getCountry() does not map numeric country codes. + mJavaToIanaCountryCode.put("BEL", "BE"); + mJavaToIanaCountryCode.put("BRA", "BR"); + mJavaToIanaCountryCode.put("FRA", "FR"); + mJavaToIanaCountryCode.put("GBR", "GB"); + mJavaToIanaCountryCode.put("PRT", "PT"); + mJavaToIanaCountryCode.put("USA", "US"); + } }