diff options
author | Narayan Kamath <narayan@google.com> | 2011-07-20 10:41:52 +0100 |
---|---|---|
committer | Narayan Kamath <narayan@google.com> | 2011-07-21 13:06:28 +0100 |
commit | 673f360b0e22a8591f515cba7a90d5cfcfad81a7 (patch) | |
tree | 6325b7ea3f967fa99568aeba03b8d5ec9a0a7371 | |
parent | 5a8ca580b078c7335d8ee384dd93dc86663d8d53 (diff) | |
download | frameworks_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.java | 46 | ||||
-rw-r--r-- | core/java/android/speech/tts/SynthesisMessageParams.java | 2 |
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 |