summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Hung <hunga@google.com>2015-04-16 20:12:07 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-04-16 20:12:07 +0000
commit71933d769c54dadb5d8618ccb1ae69a3926f890b (patch)
tree35a881d80da4100792bad920b3d78f25cf9ba9e0
parentff9863b206cd5d1e856dbfdf66bc85581aee7608 (diff)
parent26145643ce22d797b3b1675c82c47a2d8c79ecaa (diff)
downloadframeworks_av-71933d769c54dadb5d8618ccb1ae69a3926f890b.zip
frameworks_av-71933d769c54dadb5d8618ccb1ae69a3926f890b.tar.gz
frameworks_av-71933d769c54dadb5d8618ccb1ae69a3926f890b.tar.bz2
Merge "Work around lack of pitch adjustment in Timestretcher"
-rw-r--r--media/libmedia/AudioTrack.cpp52
1 files changed, 40 insertions, 12 deletions
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index d32db7c..30d4355 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -56,6 +56,24 @@ static int64_t getNowUs()
return convertTimespecToUs(tv);
}
+// FIXME: we don't use the pitch setting in the time stretcher (not working);
+// instead we emulate it using our sample rate converter.
+static const bool kFixPitch = true; // enable pitch fix
+static inline uint32_t adjustSampleRate(uint32_t sampleRate, float pitch)
+{
+ return kFixPitch ? (sampleRate * pitch + 0.5) : sampleRate;
+}
+
+static inline float adjustSpeed(float speed, float pitch)
+{
+ return kFixPitch ? (speed / pitch) : speed;
+}
+
+static inline float adjustPitch(float pitch)
+{
+ return kFixPitch ? AUDIO_TIMESTRETCH_PITCH_NORMAL : pitch;
+}
+
// Must match similar computation in createTrack_l in Threads.cpp.
// TODO: Move to a common library
static size_t calculateMinFrameCount(
@@ -703,13 +721,15 @@ status_t AudioTrack::setSampleRate(uint32_t rate)
if (AudioSystem::getSamplingRate(mOutput, &afSamplingRate) != NO_ERROR) {
return NO_INIT;
}
- if (rate == 0 || rate > afSamplingRate * AUDIO_RESAMPLER_DOWN_RATIO_MAX) {
+ // pitch is emulated by adjusting speed and sampleRate
+ const uint32_t effectiveSampleRate = adjustSampleRate(rate, mPitch);
+ if (rate == 0 || effectiveSampleRate > afSamplingRate * AUDIO_RESAMPLER_DOWN_RATIO_MAX) {
return BAD_VALUE;
}
// TODO: Should we also check if the buffer size is compatible?
mSampleRate = rate;
- mProxy->setSampleRate(rate);
+ mProxy->setSampleRate(effectiveSampleRate);
return NO_ERROR;
}
@@ -739,12 +759,6 @@ uint32_t AudioTrack::getSampleRate() const
status_t AudioTrack::setPlaybackRate(float speed, float pitch)
{
- if (speed < AUDIO_TIMESTRETCH_SPEED_MIN
- || speed > AUDIO_TIMESTRETCH_SPEED_MAX
- || pitch < AUDIO_TIMESTRETCH_PITCH_MIN
- || pitch > AUDIO_TIMESTRETCH_PITCH_MAX) {
- return BAD_VALUE;
- }
AutoMutex lock(mLock);
if (speed == mSpeed && pitch == mPitch) {
return NO_ERROR;
@@ -755,14 +769,25 @@ status_t AudioTrack::setPlaybackRate(float speed, float pitch)
if (mFlags & AUDIO_OUTPUT_FLAG_FAST) {
return INVALID_OPERATION;
}
+ // pitch is emulated by adjusting speed and sampleRate
+ const uint32_t effectiveRate = adjustSampleRate(mSampleRate, pitch);
+ const float effectiveSpeed = adjustSpeed(speed, pitch);
+ const float effectivePitch = adjustPitch(pitch);
+ if (effectiveSpeed < AUDIO_TIMESTRETCH_SPEED_MIN
+ || effectiveSpeed > AUDIO_TIMESTRETCH_SPEED_MAX
+ || effectivePitch < AUDIO_TIMESTRETCH_PITCH_MIN
+ || effectivePitch > AUDIO_TIMESTRETCH_PITCH_MAX) {
+ return BAD_VALUE;
+ }
// Check if the buffer size is compatible.
- if (!isSampleRateSpeedAllowed_l(mSampleRate, speed)) {
+ if (!isSampleRateSpeedAllowed_l(effectiveRate, effectiveSpeed)) {
ALOGV("setPlaybackRate(%f, %f) failed", speed, pitch);
return BAD_VALUE;
}
mSpeed = speed;
mPitch = pitch;
- mProxy->setPlaybackRate(speed, pitch);
+ mProxy->setPlaybackRate(effectiveSpeed, effectivePitch);
+ mProxy->setSampleRate(effectiveRate); // FIXME: not quite "atomic" with setPlaybackRate
return NO_ERROR;
}
@@ -1317,8 +1342,11 @@ status_t AudioTrack::createTrack_l()
gain_from_float(mVolume[AUDIO_INTERLEAVE_RIGHT])));
mProxy->setSendLevel(mSendLevel);
- mProxy->setSampleRate(mSampleRate);
- mProxy->setPlaybackRate(mSpeed, mPitch);
+ const uint32_t effectiveSampleRate = adjustSampleRate(mSampleRate, mPitch);
+ const float effectiveSpeed = adjustSpeed(mSpeed, mPitch);
+ const float effectivePitch = adjustPitch(mPitch);
+ mProxy->setSampleRate(effectiveSampleRate);
+ mProxy->setPlaybackRate(effectiveSpeed, effectivePitch);
mProxy->setMinimum(mNotificationFramesAct);
mDeathNotifier = new DeathNotifier(this);