summaryrefslogtreecommitdiffstats
path: root/core/java/android/speech/tts
diff options
context:
space:
mode:
authorNarayan Kamath <narayan@google.com>2011-09-14 11:56:32 +0100
committerNarayan Kamath <narayan@google.com>2011-09-14 16:51:05 +0100
commit69bc1b2696dde849102f0ac8071999843d01b8d1 (patch)
tree6e3b7b0807f5294b8997c1022a2af5face6141e2 /core/java/android/speech/tts
parent62bb0cdc746e850c2d2d5da4f6c7a38f8782f4bc (diff)
downloadframeworks_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.java55
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;