diff options
author | Andy Hung <hunga@google.com> | 2015-03-26 19:13:55 -0700 |
---|---|---|
committer | Andy Hung <hunga@google.com> | 2015-04-09 18:49:15 -0700 |
commit | 8edb8dc44b8a2f81bdb5db645b6b708548771a31 (patch) | |
tree | 663bda0f8a3d43894fa6d3d3f4283ed0df427f03 /services/audioflinger | |
parent | c5656cc900aeb4a705e27508dd82c70030a97709 (diff) | |
download | frameworks_av-8edb8dc44b8a2f81bdb5db645b6b708548771a31.zip frameworks_av-8edb8dc44b8a2f81bdb5db645b6b708548771a31.tar.gz frameworks_av-8edb8dc44b8a2f81bdb5db645b6b708548771a31.tar.bz2 |
Add playback rate to AudioTrack
Bug: 19196501
Change-Id: I6411e1d3ce652b711a71a6d9df020cb5f60d4714
Diffstat (limited to 'services/audioflinger')
-rw-r--r-- | services/audioflinger/Threads.cpp | 45 | ||||
-rw-r--r-- | services/audioflinger/Tracks.cpp | 9 |
2 files changed, 36 insertions, 18 deletions
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index 1a20fae..b30fd20 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -1608,13 +1608,19 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac // If you change this calculation, also review the start threshold which is related. if (!(*flags & IAudioFlinger::TRACK_FAST) && audio_is_linear_pcm(format) && sharedBuffer == 0) { + // this must match AudioTrack.cpp calculateMinFrameCount(). + // TODO: Move to a common library uint32_t latencyMs = mOutput->stream->get_latency(mOutput->stream); uint32_t minBufCount = latencyMs / ((1000 * mNormalFrameCount) / mSampleRate); if (minBufCount < 2) { minBufCount = 2; } + // For normal mixing tracks, if speed is > 1.0f (normal), AudioTrack + // or the client should compute and pass in a larger buffer request. size_t minFrameCount = - minBufCount * sourceFramesNeeded(sampleRate, mNormalFrameCount, mSampleRate); + minBufCount * sourceFramesNeededWithTimestretch( + sampleRate, mNormalFrameCount, + mSampleRate, AUDIO_TIMESTRETCH_SPEED_NORMAL /*speed*/); if (frameCount < minFrameCount) { // including frameCount == 0 frameCount = minFrameCount; } @@ -3592,21 +3598,17 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac // hence the test on (mMixerStatus == MIXER_TRACKS_READY) meaning the track was mixed // during last round size_t desiredFrames; - uint32_t sr = track->sampleRate(); - if (sr == mSampleRate) { - desiredFrames = mNormalFrameCount; - } else { - desiredFrames = sourceFramesNeeded(sr, mNormalFrameCount, mSampleRate); - // add frames already consumed but not yet released by the resampler - // because mAudioTrackServerProxy->framesReady() will include these frames - desiredFrames += mAudioMixer->getUnreleasedFrames(track->name()); -#if 0 - // the minimum track buffer size is normally twice the number of frames necessary - // to fill one buffer and the resampler should not leave more than one buffer worth - // of unreleased frames after each pass, but just in case... - ALOG_ASSERT(desiredFrames <= cblk->frameCount_); -#endif - } + const uint32_t sampleRate = track->mAudioTrackServerProxy->getSampleRate(); + float speed, pitch; + track->mAudioTrackServerProxy->getPlaybackRate(&speed, &pitch); + + desiredFrames = sourceFramesNeededWithTimestretch( + sampleRate, mNormalFrameCount, mSampleRate, speed); + // TODO: ONLY USED FOR LEGACY RESAMPLERS, remove when they are removed. + // add frames already consumed but not yet released by the resampler + // because mAudioTrackServerProxy->framesReady() will include these frames + desiredFrames += mAudioMixer->getUnreleasedFrames(track->name()); + uint32_t minFrames = 1; if ((track->sharedBuffer() == 0) && !track->isStopped() && !track->isPausing() && (mMixerStatusIgnoringFastTracks == MIXER_TRACKS_READY)) { @@ -3769,6 +3771,17 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac AudioMixer::RESAMPLE, AudioMixer::SAMPLE_RATE, (void *)(uintptr_t)reqSampleRate); + + // set the playback rate as an float array {speed, pitch} + float playbackRate[2]; + track->mAudioTrackServerProxy->getPlaybackRate( + &playbackRate[0] /*speed*/, &playbackRate[1] /*pitch*/); + mAudioMixer->setParameter( + name, + AudioMixer::TIMESTRETCH, + AudioMixer::PLAYBACK_RATE, + playbackRate); + /* * Select the appropriate output buffer for the track. * diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp index 1566b1f..da2d634 100644 --- a/services/audioflinger/Tracks.cpp +++ b/services/audioflinger/Tracks.cpp @@ -903,9 +903,14 @@ status_t AudioFlinger::PlaybackThread::Track::getTimestamp(AudioTimestamp& times mPreviousTimestampValid = false; return INVALID_OPERATION; } + // FIXME Not accurate under dynamic changes of sample rate and speed. + // Do not use track's mSampleRate as it is not current for mixer tracks. + uint32_t sampleRate = mAudioTrackServerProxy->getSampleRate(); + float speed, pitch; + mAudioTrackServerProxy->getPlaybackRate(&speed, &pitch); uint32_t unpresentedFrames = - ((int64_t) playbackThread->mLatchQ.mUnpresentedFrames * mSampleRate) / - playbackThread->mSampleRate; + ((double) playbackThread->mLatchQ.mUnpresentedFrames * sampleRate * speed) + / playbackThread->mSampleRate; // FIXME Since we're using a raw pointer as the key, it is theoretically possible // for a brand new track to share the same address as a recently destroyed // track, and thus for us to get the frames released of the wrong track. |