7 package com.google.appinventor.components.runtime;
9 import java.util.ArrayList;
10 import java.util.Collections;
11 import java.util.List;
12 import java.util.Locale;
14 import java.util.MissingResourceException;
16 import android.media.AudioManager;
17 import android.util.Log;
56 @DesignerComponent(version = YaVersion.TEXTTOSPEECH_COMPONENT_VERSION,
57 description =
"The TestToSpeech component speaks a given text aloud. You can set " +
58 "the pitch and the rate of speech. " +
59 "<p>You can also set a language by supplying a language code. This changes the pronunciation " +
60 "of words, not the actual language spoken. For example, setting the language to French " +
61 "and speaking English text will sound like someone speaking English (en) with a French accent.</p> " +
62 "<p>You can also specify a country by supplying a country code. This can affect the " +
63 "pronunciation. For example, British English (GBR) will sound different from US English " +
64 "(USA). Not every country code will affect every language.</p> " +
65 "<p>The languages and countries available depend on the particular device, and can be listed " +
66 "with the AvailableLanguages and AvailableCountries properties.</p>",
67 category = ComponentCategory.MEDIA,
69 iconName =
"images/textToSpeech.png")
76 private float pitch = 1.0f;
77 private float speechRate = 1.0f;
78 private static final String LOG_TAG =
"TextToSpeech";
85 private ArrayList<String> languageList;
90 private ArrayList<String> countryList;
95 private boolean result;
96 private String language;
97 private String country;
100 private String iso2Language;
101 private String iso2Country;
103 private boolean isTtsPrepared;
105 private static void initLocaleMaps() {
106 Locale[] locales = Locale.getAvailableLocales();
107 for (Locale locale : locales) {
109 String iso3Country = locale.getISO3Country();
110 if (iso3Country.length() > 0) {
111 iso3CountryToLocaleMap.put(iso3Country, locale);
113 }
catch (MissingResourceException e) {
117 String iso3Language = locale.getISO3Language();
118 if (iso3Language.length() > 0) {
119 iso3LanguageToLocaleMap.put(iso3Language, locale);
121 }
catch (MissingResourceException e) {
133 super(container.
$form());
139 Log.v(LOG_TAG,
"Using " + (useExternalLibrary ?
"external" :
"internal") +
" TTS library.");
142 public void onSuccess() {
148 public void onFailure() {
160 form.setVolumeControlStream(AudioManager.STREAM_MUSIC);
162 isTtsPrepared =
false;
163 languageList =
new ArrayList<String>();
164 countryList =
new ArrayList<String>();
191 description =
"Sets the language for TextToSpeech. This changes the way that words are " +
192 "pronounced, not the actual language that is spoken. For example setting the language to " +
193 "and speaking English text with sound like someone speaking English with a Frernch accent.")
196 switch (language.length()) {
198 locale = iso3LanguageToLocale(language);
199 this.language = locale.getISO3Language();
202 locale =
new Locale(language);
203 this.language = locale.getLanguage();
206 locale = Locale.getDefault();
207 this.language = locale.getLanguage();
210 iso2Language = locale.getLanguage();
213 private static Locale iso3LanguageToLocale(String iso3Language) {
214 Locale mappedLocale = iso3LanguageToLocaleMap.get(iso3Language);
215 if (mappedLocale ==
null) {
217 mappedLocale = iso3LanguageToLocaleMap.get(iso3Language.toLowerCase(Locale.ENGLISH));
219 return mappedLocale ==
null ? Locale.getDefault() : mappedLocale;
232 @DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_FLOAT, defaultValue =
"1.0")
233 @SimpleProperty(category = PropertyCategory.BEHAVIOR, description =
"Sets the Pitch for " +
234 "TextToSpeech The values should " +
235 "be between 0 and 2 where lower values lower the tone of synthesized voice and greater values " +
238 if (pitch < 0 || pitch > 2) {
239 Log.i(LOG_TAG,
"Pitch value should be between 0 and 2, but user specified: " + pitch);
274 "The values should be between 0 and 2 where lower values slow down the pitch and greater values " +
277 if (speechRate < 0 || speechRate > 2) {
278 Log.i(LOG_TAG,
"speechRate value should be between 0 and 2, but user specified: " + speechRate);
282 this.speechRate = speechRate;
296 return this.speechRate;
321 @
SimpleProperty(description =
"Country code to use for speech generation. This can affect the " +
322 "pronounciation. For example, British English (GBR) will sound different from US English " +
323 "(USA). Not every country code will affect every language.",
327 switch (country.length()) {
329 locale = iso3CountryToLocale(country);
330 this.country = locale.getISO3Country();
333 locale =
new Locale(country);
334 this.country = locale.getCountry();
337 locale = Locale.getDefault();
338 this.country = locale.getCountry();
341 iso2Country = locale.getCountry();
344 private static Locale iso3CountryToLocale(String iso3Country) {
345 Locale mappedLocale = iso3CountryToLocaleMap.get(iso3Country);
346 if (mappedLocale ==
null) {
348 mappedLocale = iso3CountryToLocaleMap.get(iso3Country.toUpperCase(Locale.ENGLISH));
350 return mappedLocale ==
null ? Locale.getDefault() : mappedLocale;
365 @
SimpleProperty(description =
"List of the languages available on this device " +
366 "for use with TextToSpeech. Check the Android developer documentation under supported " +
367 "languages to find the meanings of these abbreviations.")
373 @
SimpleProperty(description =
"List of the country codes available on this device " +
374 "for use with TextToSpeech. Check the Android developer documentation under supported " +
375 "languages to find the meanings of these abbreviations.")
382 if (!isTtsPrepared) {
391 getLanguageAndCountryLists();
392 isTtsPrepared =
true;
402 private void getLanguageAndCountryLists() {
410 for (Locale locale : Locale.getAvailableLocales()) {
413 if (!(res == android.speech.tts.TextToSpeech.LANG_NOT_SUPPORTED)){
414 tempLang = locale.getLanguage();
418 tempCountry = locale.getISO3Country();
419 if (!tempLang.equals(
"") && (!languageList.contains(tempLang))){
420 languageList.add(tempLang);
422 if (!tempCountry.equals(
"") && (!countryList.contains(tempCountry))){
423 countryList.add(tempCountry);
427 Collections.sort(languageList);
428 Collections.sort(countryList);
429 allLanguages = YailList.
makeList(languageList);
430 allCountries = YailList.
makeList(countryList);
438 public void Speak(
final String message) {
440 final Locale loc =
new Locale(iso2Language, iso2Country);
441 tts.
speak(message, loc);
460 @
SimpleEvent(description =
"Event to raise after the message is spoken. The result will be true "
461 +
"if the message is spoken successfully, otherwise it will be false.")