summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNarayan Kamath <narayan@google.com>2011-07-20 10:41:52 +0100
committerNarayan Kamath <narayan@google.com>2011-07-21 13:06:28 +0100
commit673f360b0e22a8591f515cba7a90d5cfcfad81a7 (patch)
tree6325b7ea3f967fa99568aeba03b8d5ec9a0a7371
parent5a8ca580b078c7335d8ee384dd93dc86663d8d53 (diff)
downloadframeworks_base-673f360b0e22a8591f515cba7a90d5cfcfad81a7.zip
frameworks_base-673f360b0e22a8591f515cba7a90d5cfcfad81a7.tar.gz
frameworks_base-673f360b0e22a8591f515cba7a90d5cfcfad81a7.tar.bz2
Fix some AudioTrack related issues.
(a) Call stop() when we've written less than the AudioTrack buffer. This forces pending buffers to get mixed. (b) Introduce a minimum sleep time to avoid spinlocks if they system is busy Change-Id: If70937e8b4e8c5d02d7dadc0d3086f97a10eb7ef
-rw-r--r--core/java/android/speech/tts/AudioPlaybackHandler.java46
-rw-r--r--core/java/android/speech/tts/SynthesisMessageParams.java2
2 files changed, 29 insertions, 19 deletions
diff --git a/core/java/android/speech/tts/AudioPlaybackHandler.java b/core/java/android/speech/tts/AudioPlaybackHandler.java
index 255b333..89b6f32 100644
--- a/core/java/android/speech/tts/AudioPlaybackHandler.java
+++ b/core/java/android/speech/tts/AudioPlaybackHandler.java
@@ -356,9 +356,7 @@ class AudioPlaybackHandler {
mLastSynthesisRequest = param;
// Create the audio track.
- final AudioTrack audioTrack = createStreamingAudioTrack(
- param.mStreamType, param.mSampleRateInHz, param.mAudioFormat,
- param.mChannelCount, param.mVolume, param.mPan);
+ final AudioTrack audioTrack = createStreamingAudioTrack(param);
if (DBG) Log.d(TAG, "Created audio track [" + audioTrack.hashCode() + "]");
@@ -405,16 +403,10 @@ class AudioPlaybackHandler {
param.mLogger.onPlaybackStart();
}
+ // Wait for the audio track to stop playing, and then release its resources.
private void handleSynthesisDone(MessageParams msg) {
final SynthesisMessageParams params = (SynthesisMessageParams) msg;
- handleSynthesisDone(params);
- // This call is delayed more than it should be, but we are
- // certain at this point that we have all the data we want.
- params.mLogger.onWriteData();
- }
- // 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();
@@ -422,6 +414,10 @@ class AudioPlaybackHandler {
return;
}
+ if (params.mBytesWritten < params.mAudioBufferSize) {
+ audioTrack.stop();
+ }
+
if (DBG) Log.d(TAG, "Waiting for audio track to complete : " +
audioTrack.hashCode());
blockUntilDone(params);
@@ -442,8 +438,15 @@ class AudioPlaybackHandler {
}
params.getDispatcher().dispatchUtteranceCompleted();
mLastSynthesisRequest = null;
+ params.mLogger.onWriteData();
}
+ /**
+ * The minimum increment of time to wait for an audiotrack to finish
+ * playing.
+ */
+ private static final long MIN_SLEEP_TIME_MS = 20;
+
private static void blockUntilDone(SynthesisMessageParams params) {
if (params.mAudioTrack == null || params.mBytesWritten <= 0) {
return;
@@ -460,36 +463,41 @@ class AudioPlaybackHandler {
break;
}
- long estimatedTimeMs = ((lengthInFrames - currentPosition) * 1000) /
+ final long estimatedTimeMs = ((lengthInFrames - currentPosition) * 1000) /
audioTrack.getSampleRate();
- if (DBG) Log.d(TAG, "About to sleep for : " + estimatedTimeMs + " ms," +
- " Playback position : " + currentPosition);
+ final long sleepTimeMs = Math.max(estimatedTimeMs, MIN_SLEEP_TIME_MS);
+
+ if (DBG) Log.d(TAG, "About to sleep for : " + sleepTimeMs + " ms," +
+ " Playback position : " + currentPosition + ", Length in frames : "
+ + lengthInFrames);
try {
- Thread.sleep(estimatedTimeMs);
+ Thread.sleep(sleepTimeMs);
} catch (InterruptedException ie) {
break;
}
}
}
- private static AudioTrack createStreamingAudioTrack(int streamType, int sampleRateInHz,
- int audioFormat, int channelCount, float volume, float pan) {
- int channelConfig = getChannelConfig(channelCount);
+ private static AudioTrack createStreamingAudioTrack(SynthesisMessageParams params) {
+ final int channelConfig = getChannelConfig(params.mChannelCount);
+ final int sampleRateInHz = params.mSampleRateInHz;
+ final int audioFormat = params.mAudioFormat;
int minBufferSizeInBytes
= AudioTrack.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);
int bufferSizeInBytes = Math.max(MIN_AUDIO_BUFFER_SIZE, minBufferSizeInBytes);
- AudioTrack audioTrack = new AudioTrack(streamType, sampleRateInHz, channelConfig,
+ AudioTrack audioTrack = new AudioTrack(params.mStreamType, sampleRateInHz, channelConfig,
audioFormat, bufferSizeInBytes, AudioTrack.MODE_STREAM);
if (audioTrack.getState() != AudioTrack.STATE_INITIALIZED) {
Log.w(TAG, "Unable to create audio track.");
audioTrack.release();
return null;
}
+ params.mAudioBufferSize = bufferSizeInBytes;
- setupVolume(audioTrack, volume, pan);
+ setupVolume(audioTrack, params.mVolume, params.mPan);
return audioTrack;
}
diff --git a/core/java/android/speech/tts/SynthesisMessageParams.java b/core/java/android/speech/tts/SynthesisMessageParams.java
index ffe70e2..7da5daa 100644
--- a/core/java/android/speech/tts/SynthesisMessageParams.java
+++ b/core/java/android/speech/tts/SynthesisMessageParams.java
@@ -35,6 +35,7 @@ final class SynthesisMessageParams extends MessageParams {
volatile AudioTrack mAudioTrack;
// Not volatile, accessed only from the synthesis thread.
int mBytesWritten;
+ int mAudioBufferSize;
private final LinkedList<ListEntry> mDataBufferList = new LinkedList<ListEntry>();
@@ -55,6 +56,7 @@ final class SynthesisMessageParams extends MessageParams {
// initially null.
mAudioTrack = null;
mBytesWritten = 0;
+ mAudioBufferSize = 0;
}
@Override