Saturday, September 3, 2011

Audio Manager issues

I have been struggling to get the text message (SMS) reader working well. It works fine when I send the Text-To-Speech (TTS) to the music stream and you are using the default music player. It will pause the music, play the TTS, and then resume the music. If you use most other players (like Winamp or Amazon) it does not work properly.

If you use the in-call stream, it seems to work great on the Droid phones. However, some devices using Android 2.2.0 will reboot when the TTS is done playing. They also won't play the TTS (it appears muted). Even on the Droid's something strange happens. It all seems fine until you disconnect from the device. Then your streams all go to the phone earpiece instead of the phones speaker. A quick reboot fixes it but that is very annoying.

I added another stream selection, the alarm stream, to 2.3.7. That one works quite strange. It will play through the phones speaker even when connected to a Bluetooth handsfree and A2DP device. OK, so maybe that is not so bad. However, it never pauses the music, it just permanently mutes the A2DP stream after playing the TTS.

I tried capturing AudioMode before, and then restoring after but it made no difference. I have tried reordering the calls, disabling each call one at a time, etc. I have scoured Stack Overflow and of course Google. Not sure I can totally fix this now. I have read the documentation and examples several times. It appears the audio focus has many strange bugs. Maybe it is all a timing issue? I just implemented the on focus change listener but I have not really put any code in it as I did not really see the need. Maybe I need to have this listener look for the state change before progressing to the next audio manager command.

One other strange thing I noticed is when using the in-call stream if I try to pause the music right after the TTS gets done it will keep restarting by itself. If I wait a few seconds its fine. This is part of what makes me think it could be a timing issue. Also, I used the alarm stream and it muted A2DP as explained above. Then I switch it to the music stream. After the next text was read, the A2DP stream worked fine again. So, when I make a audio focus call again, it seems to move the streams around fixing or breaking things

I am testing on both a Droid 2 and Droid 3. Both have Gingerbread.

Thoughts anyone?

6 comments:

  1. I have absolutely nothing constructive to say I just wanted to thank Jim for inviting me to follow his b l o g

    ReplyDelete
  2. OK, I think it is fixed now in 2.3.7. I tested with Droid 2 and Droid 3 using both the default music player and Amazon MP3. I tested all 3 TTS stream options. In all cases the following would happen upon receiving a text:

    1) Music would pause
    2) SMS details would be read over the selected stream
    3) Music would resume

    And now the phone returns to normal mode after the device disconnects (fixed issue 70). Please test!

    ReplyDelete
  3. OK, I'll explain the fix more now. Its not pretty.

    There is some sort of bug in the AudioManager I believe. Even after abandoning focus it would leave the device streams in a mess. Unless the last TTS was read over the music stream just before abandoning focus, it would route streams wrong, mute streams, etc. So, I just have it read a single period if a SMS had been read over any stream except the music stream before abandoning focus. I also cleaned up the order I called things in, and fixed some of the phone mode, etc after reading a TTS. Strangely it seems to work well.

    Need to clean up a few strings for translations but other than that, I am hoping to post to Android Market real soon.

    ReplyDelete
  4. Maybe the TTS stream staying on after the speeach output could be caused by the TTS engine not shutdown. I would only initialize the TTS engine, when a SMS comes in, play the sound and then shut it down again. This will ensure that it does not sit on the stream all the time.

    In the documentation of TTS it suggests, that you only initialize the TTS engine, if you actually want to send text to it, as it needs resources all the time.

    I checked with a process viewer, that when enabling SMS output in a2dpvolume, the TTS engine's service is running all the time, which was not the case before. Before it only started e.g. when Google Map Nav was activated or you started Google Translate. You will get in general only few SMS, so it would be a good idea to shut it down when unused.

    ReplyDelete
  5. Actually I tried that. I do dispose of tts on service destroy and that did not fixit. You are correct,I should start tts only when needed. I will implement that in the next few days just to free resources.

    Have you tried 2.3.7? How do each of the 3 stream options work?

    ReplyDelete
  6. I changed the service to only initialize the TTS right before speaking. That worked on the emulator but failed on the phone. What would need to happen it a sequence of call-back responses chained together to make the timing work out. I chose a simpler approach. I now initialize the TTS when the device connects. Then it is ready when an SMS comes in but it is not initialized all the time when devices are not connected.

    ReplyDelete