Android: two instances of Text-to-Speech work very slowly

2.6k views Asked by At

I need to implement feature in my Andorind app which allows to play two different synthesized languages in current Acitivity - for instance having two buttons Say English and Say French

I've tried to do it in two following ways but both of them works ineffectively because there is long delay before sound plays:

  1. first approach: create single instance of TTS and change language by setLocale method depending on what language has to be played. Unfortunately switching between languages by setLocale is time consuming which has impact on reaction after button is clicked
  2. second approach: create two instances of TTS each for respective language. Unfortunately delay occurs here as well and there is no difference between the first solution.

Can you please help to solve this annoying problem?

3

There are 3 answers

1
Ben Elliott On

How about waiting for the two TTS engines to finish initialising at the start of your app, before any user interaction (do this by creating an OnInitListener and waiting -- e.g. with a semaphore -- until the onInit() method is called), so that by the time the user gets to the point in the app where the buttons are introduced, you have the two engines already initialised?

3
sam On

I solved out this issue by creating those instances together on thread other than main application thread:

private class tempTask extends AsyncTask {
    ...
    @Override
    protected Object doInBackground(Object... params) {
        firstTTSObj = new TextToSpeech(getApplicationContext(), 
        new TextToSpeech.OnInitListener() {
            @Override
            public void onInit(int status) {
                if(status != TextToSpeech.ERROR){
                    firstTTSObj.setLanguage(Locale.UK);
                }               
            }
        });
        secondTTSObj = new TextToSpeech(getApplicationContext(), 
        new TextToSpeech.OnInitListener() {
            @Override
            public void onInit(int status) {
                if(status != TextToSpeech.ERROR){
                    secondTTSObj .setLanguage(Locale.KOREA);
                }               
            }
        });
        return null;
    }
}

Hope this helps.

0
engilyin On

Looks like it is how TextToSpeech is designed. Guess it could load just one language data same time and when you request another one it have to unload current language data and load new one. I have added the issue here: https://code.google.com/p/android/issues/detail?id=200974

Probably Google will fix it in future. They did it!

As workaround for now you can pre-synthesize the audio-file and then simply play back it. F.g. you can start some AsyncTask when starting the Activity and generate the sound on the background. And when it is ready reveal the button on UI to allow user to play it. Also I found that TextToSpeech stuff better to put into own service process using android:process attribute for the Service to avoid freeze of UI on some devices when setLanguage is loading the language data.

UPDATE 2016-02-17: I just have updated TextToSpeech to the version 3.8.14 from Feb 15. And no more delays! I'm using 2 languages reading the different language texts one by one and no delay between anymore! Thanks Google and TextToSpeech team! You are the best!

UPDATE 2016-02-18: I have tested more devices and found the problem still exists for older devices where Android 4.x is still used. Tested on XOOM with Android 4.1.2 and some noname device 7100 with Android 4.1.1. Both still have the same delays. Not sure is it related but I noticed that both Android device with Android 4.x have the problem with the UtteranceProgressListener. To make it work on such devices I had to pass the utteranceId parameter into the speak() function. However the device where this bug is gone worked well without this parameter. The device where it is working fine for now is LG d405 with Android 5.0.2 And it had the same delay issue before I install recent TextToSpeech update.