summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorAndy Hung <hunga@google.com>2015-03-26 19:13:55 -0700
committerAndy Hung <hunga@google.com>2015-04-09 18:49:15 -0700
commit8edb8dc44b8a2f81bdb5db645b6b708548771a31 (patch)
tree663bda0f8a3d43894fa6d3d3f4283ed0df427f03 /services
parentc5656cc900aeb4a705e27508dd82c70030a97709 (diff)
downloadframeworks_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')
-rw-r--r--services/audioflinger/Threads.cpp45
-rw-r--r--services/audioflinger/Tracks.cpp9
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.