diff options
| author | Narayan Kamath <narayan@google.com> | 2011-09-14 11:56:32 +0100 |
|---|---|---|
| committer | Narayan Kamath <narayan@google.com> | 2011-09-14 16:51:05 +0100 |
| commit | 69bc1b2696dde849102f0ac8071999843d01b8d1 (patch) | |
| tree | 6e3b7b0807f5294b8997c1022a2af5face6141e2 /core/java/android/speech/tts | |
| parent | 62bb0cdc746e850c2d2d5da4f6c7a38f8782f4bc (diff) | |
| download | frameworks_base-69bc1b2696dde849102f0ac8071999843d01b8d1.zip frameworks_base-69bc1b2696dde849102f0ac8071999843d01b8d1.tar.gz frameworks_base-69bc1b2696dde849102f0ac8071999843d01b8d1.tar.bz2 | |
Don't wait indefinitely for audio tracks to finish playing.
If the track doesn't make progress for a fixed amount of time,
bail.
bug:5309562
Change-Id: I76966b8b3b2f05ba577892899791a09f50a70107
Diffstat (limited to 'core/java/android/speech/tts')
| -rw-r--r-- | core/java/android/speech/tts/AudioPlaybackHandler.java | 55 |
1 files changed, 49 insertions, 6 deletions
diff --git a/core/java/android/speech/tts/AudioPlaybackHandler.java b/core/java/android/speech/tts/AudioPlaybackHandler.java index 75dcd6e..d970ae6 100644 --- a/core/java/android/speech/tts/AudioPlaybackHandler.java +++ b/core/java/android/speech/tts/AudioPlaybackHandler.java @@ -450,6 +450,19 @@ class AudioPlaybackHandler { */ private static final long MIN_SLEEP_TIME_MS = 20; + /** + * The maximum increment of time to sleep while waiting for an audiotrack + * to finish playing. + */ + private static final long MAX_SLEEP_TIME_MS = 2500; + + /** + * The maximum amount of time to wait for an audio track to make progress while + * it remains in PLAYSTATE_PLAYING. This should never happen in normal usage, but + * could happen in exceptional circumstances like a media_server crash. + */ + private static final long MAX_PROGRESS_WAIT_MS = MAX_SLEEP_TIME_MS; + private static void blockUntilDone(SynthesisMessageParams params) { if (params.mAudioTrack == null || params.mBytesWritten <= 0) { return; @@ -490,16 +503,34 @@ class AudioPlaybackHandler { final AudioTrack audioTrack = params.mAudioTrack; final int lengthInFrames = params.mBytesWritten / params.mBytesPerFrame; + int previousPosition = -1; int currentPosition = 0; - while ((currentPosition = audioTrack.getPlaybackHeadPosition()) < lengthInFrames) { - if (audioTrack.getPlayState() != AudioTrack.PLAYSTATE_PLAYING) { - break; - } + long blockedTimeMs = 0; + + while ((currentPosition = audioTrack.getPlaybackHeadPosition()) < lengthInFrames && + audioTrack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING) { final long estimatedTimeMs = ((lengthInFrames - currentPosition) * 1000) / audioTrack.getSampleRate(); - - final long sleepTimeMs = Math.max(estimatedTimeMs, MIN_SLEEP_TIME_MS); + final long sleepTimeMs = clip(estimatedTimeMs, MIN_SLEEP_TIME_MS, MAX_SLEEP_TIME_MS); + + // Check if the audio track has made progress since the last loop + // iteration. We should then add in the amount of time that was + // spent sleeping in the last iteration. + if (currentPosition == previousPosition) { + // This works only because the sleep time that would have been calculated + // would be the same in the previous iteration too. + blockedTimeMs += sleepTimeMs; + // If we've taken too long to make progress, bail. + if (blockedTimeMs > MAX_PROGRESS_WAIT_MS) { + Log.w(TAG, "Waited unsuccessfully for " + MAX_PROGRESS_WAIT_MS + "ms " + + "for AudioTrack to make progress, Aborting"); + break; + } + } else { + blockedTimeMs = 0; + } + previousPosition = currentPosition; if (DBG) Log.d(TAG, "About to sleep for : " + sleepTimeMs + " ms," + " Playback position : " + currentPosition + ", Length in frames : " @@ -512,6 +543,18 @@ class AudioPlaybackHandler { } } + private static final long clip(long value, long min, long max) { + if (value < min) { + return min; + } + + if (value > max) { + return max; + } + + return value; + } + private static AudioTrack createStreamingAudioTrack(SynthesisMessageParams params) { final int channelConfig = getChannelConfig(params.mChannelCount); final int sampleRateInHz = params.mSampleRateInHz; |
