3

An Android book I have states that using TextToSpeech.playEarcon() is preferable to playing audio files (using MediaPlayer) because:

Instead of having to determine the opportune moment to play an audible cue and relying on callbacks to get the timing right, we can instead queue up our earcons among the text we send to the TTS engine. We then know that our earcons will be played at the appropriate time, and we can use the same pathway to get our sounds to the user, including the onUtteranceCompleted() callbacks to let us know where we are.

But my short and simple experiment with this shows this isn't the case:

String utteranceId = String.valueOf(utteranceNum++);
params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, utteranceId);
params.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_MUSIC));
tts.speak("FIRST part of sentence", TextToSpeech.QUEUE_ADD, params);

utteranceId = String.valueOf(utteranceNum++);
params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, utteranceId);
params.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_MUSIC));
tts.playEarcon("[fancyring]", TextToSpeech.QUEUE_ADD, params);

utteranceId = String.valueOf(utteranceNum++);
params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, utteranceId);
params.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_MUSIC));
tts.speak("SECOND part of sentence", TextToSpeech.QUEUE_ADD, params);

When I examine the logs from onUtteranceCompleted() I only see the utteranceIds of the ones played by tts.speak(), not the one played by tts.playEarcon().

Why is this discrepancy? Is there a workaround for this?

P.S. At the risk of stating the obvious: All three utterances are played out fine and at the right order. It is only the onUtteranceCompleted() that isn't called for some reason for the tts.playEarcon().

an00b
  • 11,338
  • 13
  • 64
  • 101
  • 1
    The documentation of `playEarcon(...)` says: "*Plays the earcon using the specified queueing mode and parameters. The earcon must already have been added with `addEarcon(String, String)` or `addEarcon(String, String, int)`.*" Not sure why it plays at all, considering above documentation, but might be worth a try? – MH. Apr 13 '12 at 03:42
  • @MH I only included the relevant code, to avoid distraction from the main issue. I of course do all the proper initialization, including `addEarcon()` (otherwise it wouldn't have been played, as you correctly noted). Still looking for a solution to this mystery... – an00b Apr 13 '12 at 12:30
  • 3
    What platform version are you testing your code on? Starting API level 15 `TextToSpeech.OnUtteranceCompletedListener` is deprecated and replaced by `UtteranceProgressListener`. Furthermore, you might want to check the return values for `addEarcon(...)` and `playEarcon(...)`, even though the text gets spoken. Finally, you could try a couple of different TTS engines to see if the behaviour is consistent. – MH. Apr 13 '12 at 12:50
  • 1
    @MH I am using API 8. I can't use API 15 because my app must be able to run on older Android 2.2 phones... I did try with different TTS engines: They all exhibit the same exact behavior. Looks like this "bug" is by design. – an00b Apr 13 '12 at 16:06

1 Answers1

2

Answering myself. The incredibly long and very detailed documentation about TextToSpeech.OnUtteranceCompletedListener reads (the emphasis is mine):

Called when an utterance has been synthesized.

An earcon is never a result of synthesization, so of course onUtteranceCompleted() will never be called for it. This is by design.

Which gets us back to a new question: If there is no advantage to earcons over playing .mp3 files (using MediaPlayer), why use earcons at all?

an00b
  • 11,338
  • 13
  • 64
  • 101
  • Are you sure that's the reason? [This old thread](http://groups.google.com/group/tts-for-android/browse_frm/thread/6d5feb49a599e9f9) states that you have to add a dummy `KEY_PARAM_UTTERANCE_ID` parameter to get the darn thing to call your [onUtteranceCompleted](http://developer.android.com/reference/android/speech/tts/TextToSpeech.OnUtteranceCompletedListener.html#onUtteranceCompleted%28java.lang.String%29). – ef2011 Jun 20 '12 at 15:11
  • @ef2011 Yes, I am sure. I use the KEY_PARAM_UTTERANCE_ID for the `playEarcon()` too but that doesn't help. It doesn't produce an onUtteranceCompleted. Period. – an00b Jul 13 '12 at 00:53