summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/speech/tts/AudioPlaybackHandler.java31
-rw-r--r--core/java/android/speech/tts/SynthesisMessageParams.java5
2 files changed, 29 insertions, 7 deletions
diff --git a/core/java/android/speech/tts/AudioPlaybackHandler.java b/core/java/android/speech/tts/AudioPlaybackHandler.java
index 8ef4295de33a..12109417b2d5 100644
--- a/core/java/android/speech/tts/AudioPlaybackHandler.java
+++ b/core/java/android/speech/tts/AudioPlaybackHandler.java
@@ -384,7 +384,7 @@ class AudioPlaybackHandler {
}
count += written;
}
-
+ param.mBytesWritten += count;
param.mLogger.onPlaybackStart();
}
@@ -396,14 +396,16 @@ class AudioPlaybackHandler {
params.mLogger.onWriteData();
}
- // Flush all remaining data to the audio track, stop it and release
- // all it's resources.
+ // Wait for the audio track to stop playing, and then release it's resources.
private void handleSynthesisDone(SynthesisMessageParams params) {
if (DBG) Log.d(TAG, "handleSynthesisDone()");
final AudioTrack audioTrack = params.getAudioTrack();
try {
if (audioTrack != null) {
+ if (DBG) Log.d(TAG, "Waiting for audio track to complete : " +
+ audioTrack.hashCode());
+ blockUntilDone(params);
if (DBG) Log.d(TAG, "Releasing audio track [" + audioTrack.hashCode() + "]");
// The last call to AudioTrack.write( ) will return only after
// all data from the audioTrack has been sent to the mixer, so
@@ -417,6 +419,18 @@ class AudioPlaybackHandler {
}
}
+ private static void blockUntilDone(SynthesisMessageParams params) {
+ if (params.mAudioTrack == null || params.mBytesWritten <= 0) {
+ return;
+ }
+
+ final AudioTrack track = params.mAudioTrack;
+ final int bytesPerFrame = getBytesPerFrame(params.mAudioFormat);
+ final int lengthInBytes = params.mBytesWritten;
+
+ blockUntilDone(track, bytesPerFrame, lengthInBytes);
+ }
+
private void handleSynthesisCompleteDataAvailable(MessageParams msg) {
final SynthesisMessageParams params = (SynthesisMessageParams) msg;
if (DBG) Log.d(TAG, "completeAudioAvailable(" + params + ")");
@@ -455,13 +469,18 @@ class AudioPlaybackHandler {
}
- private static void blockUntilDone(AudioTrack audioTrack, int bytesPerFrame, int length) {
- int lengthInFrames = length / bytesPerFrame;
+ private static void blockUntilDone(AudioTrack audioTrack, int bytesPerFrame,
+ int lengthInBytes) {
+ int lengthInFrames = lengthInBytes / bytesPerFrame;
int currentPosition = 0;
while ((currentPosition = audioTrack.getPlaybackHeadPosition()) < lengthInFrames) {
+ if (audioTrack.getPlayState() != AudioTrack.PLAYSTATE_PLAYING) {
+ break;
+ }
+
long estimatedTimeMs = ((lengthInFrames - currentPosition) * 1000) /
audioTrack.getSampleRate();
- audioTrack.getPlayState();
+
if (DBG) Log.d(TAG, "About to sleep for : " + estimatedTimeMs + " ms," +
" Playback position : " + currentPosition);
try {
diff --git a/core/java/android/speech/tts/SynthesisMessageParams.java b/core/java/android/speech/tts/SynthesisMessageParams.java
index caf02ef3eb56..ffe70e27378e 100644
--- a/core/java/android/speech/tts/SynthesisMessageParams.java
+++ b/core/java/android/speech/tts/SynthesisMessageParams.java
@@ -32,7 +32,9 @@ final class SynthesisMessageParams extends MessageParams {
final float mPan;
final EventLogger mLogger;
- public volatile AudioTrack mAudioTrack;
+ volatile AudioTrack mAudioTrack;
+ // Not volatile, accessed only from the synthesis thread.
+ int mBytesWritten;
private final LinkedList<ListEntry> mDataBufferList = new LinkedList<ListEntry>();
@@ -52,6 +54,7 @@ final class SynthesisMessageParams extends MessageParams {
// initially null.
mAudioTrack = null;
+ mBytesWritten = 0;
}
@Override