Text-To-Speech Initialization Delay - android

I am trying to add text-to-speech feature to my app, and it is working fine until I updated TTS from Google Play store.
There wasn't any delay to initialize the TTS in onCreate Method.
After the update, it would take 3-5 seconds for this TTS to finish initializing.
Basically, the text-to-speech is not ready until 3-5 seconds later.
Can someone please tell me what I've done wrong?
private HashMap<String, String> TTS_ID = new HashMap<String, String>();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
.....
.....
TextToSpeech_Initialize();
}
public void TextToSpeech_Initialize() {
TTS_ID.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "UniqueID");
speech = new TextToSpeech(MainActivity.this, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if(status == TextToSpeech.SUCCESS) {
speech.setSpeechRate(SpeechRateValue);
speech.speak(IntroSpeech, TextToSpeech.QUEUE_FLUSH, TTS_ID);
}
}
});
}
Thank you very much

Confirmed! This is an issue with Google text to speech engine, if you try any other tts the delay disappears, eg Pico tts.

I have stumbled across this problem before but now I have found a proper solution..
You can initialize TextToSpeach in onCreate() like this:
TextToSpeach textToSpeech = new TextToSpeech(this, this);
but first you need to implement TextToSpeech.OnInitListener, and then you need to override the onInit() method:
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
int result = tts.setLanguage(Locale.US);
if (result == TextToSpeech.LANG_MISSING_DATA
|| result == TextToSpeech.LANG_NOT_SUPPORTED) {
Toast.makeText(getApplicationContext(), "Language not supported", Toast.LENGTH_SHORT).show();
} else {
button.setEnabled(true);
}
} else {
Toast.makeText(getApplicationContext(), "Init failed", Toast.LENGTH_SHORT).show();
}
}
I also noticed that if you didn't set the language in onInit() there is gonna be a delay!!
And now you can write the method that says the text:
private void speakOut(final String detectedText){
if(textToSpeech !=null){
textToSpeech.stop(); //stop and say the new word
textToSpeech.speak(detectedText ,TextToSpeech.QUEUE_FLUSH, null, null);
}
}

Related

Android TextToSpeech behaves irregular

Update: After some digging I managed to find some information in the Logcat. See bottom.
Edit 2:
I have now created a new activity from scratch to reduce the problem. It does still not work correctly. Here is the code:
public class MainActivity extends AppCompatActivity {
private TextToSpeech textToSpeech;
private boolean isInitialized = false;
private MainActivity mainActivity;
int ctr = 0;
private String words[] = {"ord", "kula", "fotboll"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mainActivity = this;
textToSpeech = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS){
textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
#Override
public void onStart(String utteranceId) {
System.out.println("---onStart");
}
#Override
public void onDone(String utteranceId) {
System.out.println("-----onDone");
}
#Override
public void onError(String utteranceId) {
System.out.println("-----onError");
}
#Override
public void onError(String utteranceId, int errorCode){
onError(utteranceId);
System.out.println("Error with code: " + errorCode);
}
});
isInitialized = true;
Locale locale = new Locale("swe");
textToSpeech.setLanguage(locale);
}
}
});
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (isInitialized){
System.out.println(textToSpeech.getLanguage().getDisplayLanguage());
textToSpeech.speak(words[ctr], TextToSpeech.QUEUE_FLUSH, null, "SpeakTest");
ctr++;
ctr %= words.length;
} else {
Snackbar.make(view, "Speaker not ready", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
}
});
}
}
What is extremely surprising is that only the words "ord" and "fotboll" are spoken, but not "kula". If I change words to {"kula", "kula", "kula"} and try long enough, it suddenly starts to work. As I have understood the documentation one should use the tags here. I have tried se, swe, sv, all with same result. Further, the command System.out.println(textToSpeech.getLanguage().getDisplayLanguage()); gives svenska which is correct.
If I change to en it works all the time. Also I get System.out.println(textToSpeech.getLanguage().getDisplayLanguage());
= engelska again correct.
What on earth is going on?
EDIT:
I have added a UtteranceProgressListener, according to this, the method
onError(String id) is deprecated and should be replaced by onError(String id, int errorCode). However, I have extended my class with UtteranceProgressListener and it forces me to implement the old onError method. This is always called, so something is wrong but I do not know what.
This is because the other onError(String id, int code) is never called.
I have updated the code.
I have a function that is supposed to speak a word in a specific language when the function is called.
Until for a couple of days ago it worked fine in my Sony Compact XZ2, but now it is irregular. Sometimes the word is spoken and sometimes not. The command textToSpeech.getEngines() returns com.google.android.tts
For example for Swedish, in setLanguage, I have tried "sv" and "sv-SV" when I create the Locale object. That has not helped.
I just noticed that when I press the button that calls playWord(text) a bunch of times ( > 40) it works and sometimes it works directly. Seems to be some strange delay.
The function speakText is called from this function in my Fragment:
private void playWord(){
if (text2Speech.isReady()) {
text2Speech.checkSpeaking();
text2Speech.setLanguage(getAcronym(mTraining.getCurrentSrc()));
text2Speech.speakText(front);
} else {
Toast.makeText(getContext(),"Speaker not ready yet", Toast.LENGTH_SHORT).show();
}
}
This is the class that handles the speaking. I have not obtained any error messages. It just seems random when the speaker works.
public class Text2Speech extends UtteranceProgressListener {
private Context mContext;
private TextToSpeech textToSpeech;
private boolean isReady = false;
public Text2Speech(Context context, final String src){
mContext = context;
System.out.println("text2Speech created");
textToSpeech = new TextToSpeech(mContext, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
isReady = true;
Locale locale = new Locale(src);
int ttsLang = textToSpeech.setLanguage(locale);
if (ttsLang == TextToSpeech.LANG_MISSING_DATA
|| ttsLang == TextToSpeech.LANG_NOT_SUPPORTED) {
Log.e("TTS", "The Language is not supported!");
} else {
Log.i("TTS", "Language Supported.");
}
Log.i("TTS", "Initialization success.");
} else {
Toast.makeText(mContext, "TTS Initialization failed!", Toast.LENGTH_SHORT).show();
}
}
});
}
public boolean isReady(){
return isReady;
}
public void checkSpeaking(){
if (textToSpeech.isSpeaking()){
textToSpeech.stop();
}
}
public void showMessage(String msg){
Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
}
public void speakText(String text){
int speechStatus = textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, null);
switch (speechStatus){
case TextToSpeech.ERROR_INVALID_REQUEST:
showMessage("Invalid Request");
break;
case TextToSpeech.ERROR_NETWORK:
showMessage("Network Error");
break;
case TextToSpeech.ERROR_NETWORK_TIMEOUT:
showMessage("Network Timeout");
break;
case TextToSpeech.ERROR_NOT_INSTALLED_YET:
showMessage("Error Not Yet Downloaded");
break;
case TextToSpeech.ERROR_OUTPUT:
showMessage("Output Error");
break;
case TextToSpeech.ERROR_SERVICE:
showMessage("Error of TTS service");
break;
case TextToSpeech.ERROR_SYNTHESIS:
showMessage("Error synthesizing");
break;
case TextToSpeech.LANG_NOT_SUPPORTED:
showMessage("Language nor supported");
break;
}
if (speechStatus == TextToSpeech.ERROR) {
Log.e("TTS", "Error in converting Text to Speech!");
}
System.out.println("speech status - text " + speechStatus + " - " + text);
}
public void setLanguage(String src){
Locale locale = new Locale(src);
int tts = textToSpeech.setLanguage(locale);
System.out.println(tts + " " + src);
if (tts == TextToSpeech.LANG_MISSING_DATA
|| tts == TextToSpeech.LANG_NOT_SUPPORTED) {
Toast.makeText(mContext, "Language not yet supported.", Toast.LENGTH_LONG).show();
}
}
public void stop(){
textToSpeech.stop();
textToSpeech.shutdown();
}
#Override
public void onStart(String utteranceId) {
Log.e("START", "start speaking");
}
#Override
public void onDone(String utteranceId) {
Log.e("DONE", "done speaking");
}
#Override
public void onError(String utteranceID){
Log.e("Error", "Not infromative");
}
// This is not called!
#Override
public void onError(String utteranceId, int errorCode) {
Log.e("Error", "Error speaking");
}
}
Here is the error message in the Logcat:
NetworkSynthesizer: ExecutionException during NetworkFetchTask
java.util.concurrent.ExecutionException: clx: RESOURCE_EXHAUSTED: Quota exceeded for quota metric 's3-sessions' and limit 's3-session-limit' of service 'speechs3proto2-pa.googleapis.com' for consumer 'project_number:529030122437'.
at java.util.concurrent.FutureTask.report(FutureTask.java:123)
at java.util.concurrent.FutureTask.get(FutureTask.java:207)
at avf.a(PG:37)
at avf.a(PG:154)
at com.google.android.tts.service.GoogleTTSService.onSynthesizeText(PG:250)
at android.speech.tts.TextToSpeechService$SynthesisSpeechItem.playImpl(TextToSpeechService.java:1033)
at android.speech.tts.TextToSpeechService$SpeechItem.play(TextToSpeechService.java:819)
at android.speech.tts.TextToSpeechService$SynthHandler$1.run(TextToSpeechService.java:583)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:280)
at android.os.HandlerThread.run(HandlerThread.java:65)
Caused by: clx: RESOURCE_EXHAUSTED: Quota exceeded for quota metric 's3-sessions' and limit 's3-session-limit' of service 'speechs3proto2-pa.googleapis.com' for consumer 'project_number:529030122437'.
at cze.a(PG:58)
at cze.a(PG:29)
at dao.a(PG:21)
at ave.a(PG:36)
at ave.call(PG:80)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
2019-03-16 21:35:46.917 1356-5238/? E/ActivityManager: Sending non-protected broadcast com.sonymobile.intent.action.POWER_BACK_OFF_FACTOR_CHANGED from system 2179:com.android.phone/1001 pkg com.android.phone
java.lang.Throwable
at com.android.server.am.ActivityManagerService.checkBroadcastFromSystem(ActivityManagerService.java:21814)
at com.android.server.am.ActivityManagerService.broadcastIntentLocked(ActivityManagerService.java:22423)
at com.android.server.am.ActivityManagerService.broadcastIntent(ActivityManagerService.java:22565)
at android.app.IActivityManager$Stub.onTransact$broadcastIntent$(IActivityManager.java:10171)
at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:167)
at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:3416)
at android.os.Binder.execTransact(Binder.java:731)
2019-03-16 21:35:46.917 12061-13318/? E/TTS.GoogleTTSServiceImp: Synthesis failure with error status code: -4
2019-03-16 21:35:46.918 12061-13318/? W/PlaybackSynthesisRequest: done() was called before start() call
2019-03-16 21:35:46.919 6468-6489/com.erikbylow.tailoreddictfire D/SPEECH: Error
When I turn WiFi on, it works.
Speculation: Can it be that the languages were missing and not downloaded when I did not use WiFi? When I turned WiFi on, the languages were downloaded?
To me this error: clx: RESOURCE_EXHAUSTED: Quota exceeded for quota metric... looks like there was always a network request, but after turning WiFi on, I could use TextToSpeach in flight mode.
On the other hand, I tried it woth russian in flight mode, that did not work. I turned internet on without WiFi, then it worked. Turned WiFi on again and then Russian worked as well. At least this suggests something needed to be downloaded?
I would like to find out what causes the problem and how to solve it since it is an app on Google Play. (Although I currently have exactly 0 active users beside me...) :).
Just to give some closure: This was an Android Framework Bug that has been closed with Android 12 (API 31). See also my referenced Bug Ticket: https://issuetracker.google.com/issues/138321382?pli=1

When I use TTS, occur setLanguage failed on android

I use TTS (Text to speech) but my device not speak voice.
TtsEngine::setLanguage called with unsupported language
setLanguage(kor, KOR,) failed
I think my device not supported korean language.
how to install korean language pack?
my source.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//create TTS
tts = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int i) {
if (i != ERROR) {
tts.setLanguage(Locale.KOREAN);
}
else {
}
}
});
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
tts.speak(editText.getText().toString(), TextToSpeech.QUEUE_FLUSH, null);
}
});
}
How to speak on my android device ?
thanks:..
Try this
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
tts = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS ) {
{
int result = tts.setLanguage(Locale.getDefault());
System.out.println ( "Result : " + result + " " + Locale.getDefault().getLanguage() );
if (result == TextToSpeech.LANG_MISSING_DATA
|| result == TextToSpeech.LANG_NOT_SUPPORTED)
{
Toast.makeText( this , "Please Set your Language to English US.", Toast.LENGTH_LONG ).show();
}
else
{
tts.setLanguage(Locale.KOREAN);//remove this line
tts.setLanguage(new Locale("ko_KR"));//add this line
tts.speak( "hey",TextToSpeech.QUEUE_FLUSH, null );
}
}
});
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
tts.speak(editText.getText().toString(), TextToSpeech.QUEUE_FLUSH, null);
}
});
Short answer: Try to turn the WIFI on
I had the same problem.
If you filter the word "TTS" in the logcat, you can see that the device is trying to download the locale. So, if you turn on Wifi, your problem should be solved. I'm looking for a solution to load the Locale locally on the device to avoid downloading it over the Internet.

How to set and speak multiple language in a sentence for TextToSpeech in Android?

I am developing TextToSpeech in Android. I use the following code and it work fine.
public void EnableTextToSpeech(){
//TextToSpeech
text_to_speech = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if(status == TextToSpeech.SUCCESS){
Log.d(TAG,"TextToSpeech init SUCCESS");
int result = text_to_speech.setLanguage(Locale.US);
text_to_speech.setPitch(1);
text_to_speech.setSpeechRate(1);
if(result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED){
Log.d(TAG,"TextToSpeech NOT SUPPORT");
}else {
Log.d(TAG,"TextToSpeech Enable");
String welcome = "Welcome";
text_to_speech.speak(welcome , TextToSpeech.QUEUE_FLUSH,null,"TEST");
}
}else {
Log.d(TAG,"TextToSpeech init FAIL");
}
}
});
}
But I want it to speak the multiple language like Chines and English in one sentence.
Can I set different language like the following code?
text_to_speech.setLanguage(Locale.CHINESE);
text_to_speech.setLanguage(Locale.US);
How to set and speak multiple language in a sentence for TextToSpeech in Android ?

I have to wait some seconds before TextToSpeech speak

I have a problem with my TextToSpeech. In fact when I call my function "Son"(see below) (when I click for example) then I have to wait 4 seconds for the first click to hear the voice speaks but after the first click, it's instantaneous to hear the voice.
But sometimes it works perfectly from the first click. In the Android Monitor, if it works or not, I can see :
I/TextToSpeech: Sucessfully bound to com.google.android.tts
I/TextToSpeech: Connected to ComponentInfo{com.google.android.tts/com.google.android.tts.service.GoogleTTSService}
I/TextToSpeech: Set up connection to ComponentInfo{com.google.android.tts/com.google.android.tts.service.GoogleTTSService}
So I assume that it depends on Android but I hope I can do something to correct that... Do you have any idea ?
If you need any more information, don't hesitate to ask !
Thank you guys !
My code:
public void Son(final String texte_son){
t1=new TextToSpeech(this, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if(status != TextToSpeech.ERROR) {
t1.setLanguage(Locale.FRENCH);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
ttsGreater21(texte_son);
} else {
ttsUnder20(texte_son);
}
}
}
});
}
#SuppressWarnings("deprecation")
private void ttsUnder20(String text) {
HashMap<String, String> map = new HashMap<>();
map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "MessageId");
t1.speak(text, TextToSpeech.QUEUE_FLUSH, map);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void ttsGreater21(String text) {
String utteranceId=this.hashCode() + "";
t1.speak(text, TextToSpeech.QUEUE_FLUSH, null, utteranceId);
}
Init TTS when application starts and store the pointer to it, do not create TTS every time when you need to synthesize a script
public YourActivity implements Activity {
private Tts tts;
void onCreate() {
tts = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
tts.setLanguage(Locale.FRENCH);
}
});
}
void Son(String text) {
if (tts != null) {
HashMap<String, String> map = new HashMap<>();
map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "MessageId");
tts.speak(text, TextToSpeech.QUEUE_FLUSH, map);
}
}
}

Text to speech works on emulator but not on phone

I have gone through almost all the links related to this topic but haven't found any suitable answer. I am trying to build a basic text to speech application. It works perfectly fine on the emulator. But when i run it on my phone, it shows language not supported.
I guess this has something to do with the locale. The default locale set in my phone is en_US
My code is as follows:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tts = new TextToSpeech(this, this);
btnSpeak = (Button) findViewById(R.id.btnSpeak);
txtText = (EditText) findViewById(R.id.txtText);
btnSpeak.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
// Method yet to be defined
speakOut();
}
});
}
public void onInit(int status) {
// TODO Auto-generated method stub
// TTS is successfully initialized
if (status == TextToSpeech.SUCCESS) {
// Setting speech language
// System.out.println(Locale.getAvailableLocales());
int result = tts.setLanguage(Locale.ENGLISH);
// int result = tts.setLanguage(Locale.getDefault());
// If your device doesn't support language you set above
if (result == TextToSpeech.LANG_MISSING_DATA
|| result == TextToSpeech.LANG_NOT_SUPPORTED) {
// Cook simple toast message with message
Toast.makeText(this, "Language not supported",
Toast.LENGTH_LONG).show();
Log.e("TTS", "Language is not supported");
} else {
btnSpeak.setEnabled(true);
}
// TTS is not initialized properly
} else {
Toast.makeText(this, "TTS Initilization Failed", Toast.LENGTH_LONG)
.show();
Log.e("TTS", "Initilization Failed");
}
}
private void speakOut() {
// Get the text typed
String text = txtText.getText().toString();
// If no text is typed, tts will read out 'You haven't typed text'
// else it reads out the text you typed
if (text.length() == 0) {
tts.speak("You haven't typed text", TextToSpeech.QUEUE_FLUSH, null);
} else {
tts.speak(text, TextToSpeech.QUEUE_FLUSH, null);
}
}
public void onDestroy() {
// Don't forget to shutdown!
if (tts != null) {
tts.stop();
tts.shutdown();
}
super.onDestroy();
}
even if i use int result = tts.setLanguage(Locale.getDefault()); instead of Locale.ENGLISH, it shows the same language not supported message
LOGCAT ERROR:
02-26 16:24:57.492: I/TextToSpeech.java(23356): initTts() successfully bound to service
02-26 16:24:58.015: E/TTS(23356): Language is not supported
I am running this on my phone- Samsung Galaxy-Y (GT-S5360) with Android version 2.3.6
found a solution myself. the problem was that the locales available on the android default tts engine did not match those on my phone.
i installed another tts engine and it works perfectly fine with it.

Categories

Resources