package com.cwport.sentencer.media;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
/**
* Created by isayev on 10.03.14.
* Use Google Text-to-Speech API
* at https://gist.github.com/alotaiba/1728771
* Example: http://translate.google.com/translate_tts?ie=UTF-8&q=Hello%20World&tl=en-us
* Speech API supports only 100 characters, If the text is more than 100 characters it gives an error.
* The text should be split by 100-chars chunks
* http://stackoverflow.com/questions/14257598/what-are-language-codes-for-voice-recognition-languages-in-chromes-implementati
* Supported languages: https://developers.google.com/translate/v2/using_rest#language-params
* Example:
* https://translate.google.com/translate_tts?ie=UTF-8&q=%D1%87%D1%82%D0%BE%20%D1%82%D0%B2%D0%BE%D1%8E%20%D0%BA%D0%BE%D0%BC%D0%BD%D0%B0%D1%82%D1%83%20%D0%B2%D1%81%D0%B5%D0%B3%D0%B4%D0%B0%20%D1%83%D0%B1%D0%B8%D1%80%D0%B0%D1%8E%D1%82%20%D0%BA%20%D0%BF%D1%80%D0%B8%D1%85%D0%BE%D0%B4%D1%83%20%D1%82%D0%B2%D0%BE%D0%B8%D1%85%20%D0%B4%D1%80%D1%83%D0%B7%D0%B5%D0%B9.
* &tl=ru&total=2&idx=1&textlen=55&client=t&prev=input
*/
public class TextToSpeech {
private static final String TAG = TextToSpeech.class.getSimpleName();
public static final String TTS_URL = "http://translate.google.com/translate_tts";
public static final int TTS_TEXT_MAXLEN = 96;
public static final String supportedLocales[] = {
"en_US",
"sv_SE", // + Swedish
"cs", // + Czech
"nl_NL", // + Dutch
"fi", // + Finnish
"fr_FR", // + French
"gl", // + Galician
"de_DE", // + German
"pt_PT", // + Portuguese
"ro_RO", // + Romanian
"ru_RU", // + Russian
"sr_SP", //+ Serbian
"sk", // + Slovak
"es_ES", // All Spanish
"cs", // + Czech
"nl_NL", // + Dutch
"fi", // + Finnish
"fr_FR", // + French
"gl", // + Galician
"de_DE", // + German
"he", // + Hebrew
"hu", // + Hungarian
"is", // + Icelandic
"it_IT" // + Italian
/*
+ English (Australia) en-AU
+? English (Canada) en-CA
+ English (India) en-IN
+ English (New Zealand) en-NZ
+ English (South Africa) en-ZA
+ English(UK) en-GB
+ English(US) en-US
"af", // + Afrikaans
"eu", // + Basque
"bg", // + Bulgarian
"ca", // + Catalan
"ar", /* all Arabic
"ar-EG", + Arabic (Egypt)
+? Arabic (Jordan) ar-JO
+ Arabic (Kuwait) ar-KW
+? Arabic (Lebanon) ar-LB
+ Arabic (Qatar) ar-QA
+ Arabic (UAE) ar-AE
.+ Arabic (Morocco) ar-MA
.+ Arabic (Iraq) ar-IQ
.+ Arabic (Algeria) ar-DZ
.+ Arabic (Bahrain) ar-BH
.+ Arabic (Lybia) ar-LY
.+ Arabic (Oman) ar-OM
.+ Arabic (Saudi Arabia) ar-SA
.+ Arabic (Tunisia) ar-TN
.+ Arabic (Yemen) ar-YE
"cs", // + Czech
"nl_NL", // + Dutch
"fi", // + Finnish
"fr_FR", // + French
"gl", // + Galician
"de_DE", // + German
"he", // + Hebrew
"hu", // + Hungarian
"is", // + Icelandic
"it_IT", // + Italian
"id", // + Indonesian
"ja", // + Japanese
"ko", // + Korean
"la", // + Latin
"zh_CN", // + Mandarin Chinese
"zh_TW", // + Traditional Taiwan
"zh_CN", // ? +? Simplified China
"zh_HK", // + Simplified Hong Kong
"zh_yue", // + Yue Chinese (Traditional Hong Kong)
"ms_MY", // + Malaysian
"no_NO", // + Norwegian
"pl", // + Polish
+? Pig Latin xx-piglatin
"pt_PT", // + Portuguese
"pt_BR", // .+ Portuguese (brasil)
"ro_RO", // + Romanian
"ru_RU", // + Russian
"sr_SP", // + Serbian
"sk", // + Slovak
"es_ES", // All Spanish
+ Spanish (Argentina) es-AR
+ Spanish(Bolivia) es-BO
+? Spanish( Chile) es-CL
+? Spanish (Colombia) es-CO
+? Spanish(Costa Rica) es-CR
+ Spanish(Dominican Republic) es-DO
+ Spanish(Ecuador) es-EC
+ Spanish(El Salvador) es-SV
+ Spanish(Guatemala) es-GT
+ Spanish(Honduras) es-HN
+ Spanish(Mexico) es-MX
+ Spanish(Nicaragua) es-NI
+ Spanish(Panama) es-PA
+ Spanish(Paraguay) es-PY
+ Spanish(Peru) es-PE
+ Spanish(Puerto Rico) es-PR
+ Spanish(Spain) es-ES
+ Spanish(US) es-US
+ Spanish(Uruguay) es-UY
+ Spanish(Venezuela) es-VE
"sv_SE", // + Swedish
"tr", // + Turkish
"zu" // + Zulu
*/
};
/**
* Convert text to a list of Google text-to-speech API urls
* @param text
* @param locale
* @return List of urls
* @throws UnsupportedEncodingException
*/
public static ArrayList<String> textToSpeech(String text, String locale)
throws UnsupportedEncodingException {
ArrayList<String> urls = new ArrayList<String>();
StringBuilder url = new StringBuilder();
ArrayList<String> chunks = new ArrayList<String>();
if(text.length() > TTS_TEXT_MAXLEN) {
StringBuilder chunk = new StringBuilder();
String delim = ",|\\s+|,\\s*|\\.\\s*|\\!\\s*|\\?\\s*|\\/\\s*|\\\\s*";
String[] tokens = text.split(delim);
if(tokens.length > 0) {
int i = 0;
while (true) {
if (tokens[i].length() > TTS_TEXT_MAXLEN) {
chunk.append(tokens[i].substring(0, TTS_TEXT_MAXLEN));
url = url.append(buildTtsUrl(text, locale).toString());
urls.add(url.toString());
break; // crop the token and leave a loop because of too long strange string w/o delimeters
} else {
if (chunk.length() + tokens[i].length() < TTS_TEXT_MAXLEN) {
chunk.append(tokens[i]).append(" "); // append token and one space
i++;
} else {
chunks.add(chunk.toString());
url = url.append(buildTtsUrl(text, locale).toString());
urls.add(url.toString());
chunk = new StringBuilder();
}
}
if(i > tokens.length - 1) {
if(chunk.length() > 0) {
chunks.add(chunk.toString());
url = url.append(buildTtsUrl(text, locale).toString());
urls.add(url.toString());
}
break;
}
}
}
} else {
url = url.append(buildTtsUrl(text, locale).toString());
urls.add(url.toString());
}
return urls;
}
public static StringBuilder buildTtsUrl(String text, String locale)
throws UnsupportedEncodingException {
return (new StringBuilder()).append(TTS_URL)
.append("?ie=UTF-8&tl=")
.append(locale)
.append("&q=")
.append(java.net.URLEncoder.encode(text, "UTF-8"));
}
public static boolean localeSupported(String locale) {
boolean found;
found = Arrays.asList(supportedLocales).contains(locale);
return found;
}
}