6

i am developing one module to read text file and play as a voice using TTS. i have successfully integrated TTS in my module. and also reading and speaking first 4000 characters.

i have string with more then 4000 characters, it may have more then 10000 too. at this time i am unable to read file and play using TTS.

i have tried by splitting large string into a small part of string. each string part have 4000 characters.

while i am playing first string part, its working fine as required. but after completed of first string part, i want to start second part immediately. but TTS not starting it.

i am using

int pos = 0;

while(true) {

            String var = "";

            try {
                var = str.substring(pos, 3999);
                pos += 3999;
            } catch(Exception e) {
                var = str.substring(pos, str.length());
                break;
            }

            HashMap<String, String> map = new HashMap<String, String>();
            map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "utteranceId");
            tts.speak(var, TextToSpeech.QUEUE_ADD, map);
        }

i have tried a lot. also searched on web but not getting any good solution.

there is one setOnUtteranceCompletedListener() i think this may be usefull. but how Can anyone please help me. how can i play large text using TTS. or any other technique available?

Ajay
  • 1,189
  • 1
  • 12
  • 28
  • 1
    possible duplicate of [Android TTS text longer than 4k chars not playing](http://stackoverflow.com/questions/13440251/android-tts-text-longer-than-4k-chars-not-playing) – cygery Mar 13 '15 at 16:41

2 Answers2

2

I also tried to find everywhere but could not find exact answer but definitely got some help. You need to break your long paragraph into small chunks of sentences. You can use the below method to do so.

private void speech(String charSequence) {
    ///
    Pattern re = Pattern.compile("[^.!?\\s][^.!?]*(?:[.!?](?!['\"]?\\s|$)[^.!?]*)*[.!?]?['\"]?(?=\\s|$)", Pattern.MULTILINE | Pattern.COMMENTS);
    Matcher reMatcher = re.matcher(charSequence);
    /////
    int position=0 ;
    int sizeOfChar= charSequence.length();
    String testStri= charSequence.substring(position,sizeOfChar);
    while(reMatcher.find()) {
        String temp="";

        try {

            temp = testStri.substring(charSequence.lastIndexOf(reMatcher.group()), charSequence.indexOf(reMatcher.group())+reMatcher.group().length());
            textToSpeech.speak(temp, TextToSpeech.QUEUE_ADD, null,"speak");


        } catch (Exception e) {
            temp = testStri.substring(0, testStri.length());
            textToSpeech.speak(temp, TextToSpeech.QUEUE_ADD, null);
            break;

        }

    }

}

Just pass your text in this method and it will read your text.

Narendra Jadon
  • 148
  • 1
  • 11
0

You may try to use:

tts.speak(var, TextToSpeech.QUEUE_FLUSH, map);

I suppose that, like you have done in the posted code, after the first iteration the pipe is full and you are not able to add other text. I think that flushing the pipe content with QUEUE_FLUSH and invoking the synthesis with the new utterance would work.

You can test if this is true for example setting the utterance length to 1000. If it is how I said you are able to reproduce 3 blocks of text end when you starts the fourth one it should not work anymore because the pipe is full-filled.

I would suggest you not to split on tts engine limit. You could split on the limit nearest break so you won't catch delays. I would also suggest to use a global variable to define the limit because maybe it will change in the future releases. You can get queue limit with

tts.getMaxSpeechInputLength();
Giuseppe
  • 307
  • 3
  • 18