Loading include/media/AudioResamplerPublic.h +17 −0 Original line number Original line Diff line number Diff line Loading @@ -108,6 +108,23 @@ static inline bool isAudioPlaybackRateEqual(const AudioPlaybackRate &pr1, pr2.mFallbackMode == pr2.mFallbackMode; pr2.mFallbackMode == pr2.mFallbackMode; } } static inline bool isAudioPlaybackRateValid(const AudioPlaybackRate &playbackRate) { if (playbackRate.mFallbackMode == AUDIO_TIMESTRETCH_FALLBACK_FAIL && (playbackRate.mStretchMode == AUDIO_TIMESTRETCH_STRETCH_SPEECH || playbackRate.mStretchMode == AUDIO_TIMESTRETCH_STRETCH_DEFAULT)) { //test sonic specific constraints return playbackRate.mSpeed >= TIMESTRETCH_SONIC_SPEED_MIN && playbackRate.mSpeed <= TIMESTRETCH_SONIC_SPEED_MAX && playbackRate.mPitch >= AUDIO_TIMESTRETCH_PITCH_MIN && playbackRate.mPitch <= AUDIO_TIMESTRETCH_PITCH_MAX; } else { return playbackRate.mSpeed >= AUDIO_TIMESTRETCH_SPEED_MIN && playbackRate.mSpeed <= AUDIO_TIMESTRETCH_SPEED_MAX && playbackRate.mPitch >= AUDIO_TIMESTRETCH_PITCH_MIN && playbackRate.mPitch <= AUDIO_TIMESTRETCH_PITCH_MAX; } } // TODO: Consider putting these inlines into a class scope // TODO: Consider putting these inlines into a class scope // Returns the source frames needed to resample to destination frames. This is not a precise // Returns the source frames needed to resample to destination frames. This is not a precise Loading media/libmedia/AudioTrack.cpp +20 −12 Original line number Original line Diff line number Diff line Loading @@ -78,7 +78,7 @@ static inline uint32_t adjustSampleRate(uint32_t sampleRate, float pitch) static inline float adjustSpeed(float speed, float pitch) static inline float adjustSpeed(float speed, float pitch) { { return kFixPitch ? (speed / pitch) : speed; return kFixPitch ? speed / max(pitch, AUDIO_TIMESTRETCH_PITCH_MIN_DELTA) : speed; } } static inline float adjustPitch(float pitch) static inline float adjustPitch(float pitch) Loading Loading @@ -809,25 +809,33 @@ status_t AudioTrack::setPlaybackRate(const AudioPlaybackRate &playbackRate) const uint32_t effectiveRate = adjustSampleRate(mSampleRate, playbackRate.mPitch); const uint32_t effectiveRate = adjustSampleRate(mSampleRate, playbackRate.mPitch); const float effectiveSpeed = adjustSpeed(playbackRate.mSpeed, playbackRate.mPitch); const float effectiveSpeed = adjustSpeed(playbackRate.mSpeed, playbackRate.mPitch); const float effectivePitch = adjustPitch(playbackRate.mPitch); const float effectivePitch = adjustPitch(playbackRate.mPitch); if (effectiveSpeed < AUDIO_TIMESTRETCH_SPEED_MIN AudioPlaybackRate playbackRateTemp = playbackRate; || effectiveSpeed > AUDIO_TIMESTRETCH_SPEED_MAX playbackRateTemp.mSpeed = effectiveSpeed; || effectivePitch < AUDIO_TIMESTRETCH_PITCH_MIN playbackRateTemp.mPitch = effectivePitch; || effectivePitch > AUDIO_TIMESTRETCH_PITCH_MAX) { if (!isAudioPlaybackRateValid(playbackRateTemp)) { return BAD_VALUE; return BAD_VALUE; //TODO: add function in AudioResamplerPublic.h to check for validity. } } // Check if the buffer size is compatible. // Check if the buffer size is compatible. if (!isSampleRateSpeedAllowed_l(effectiveRate, effectiveSpeed)) { if (!isSampleRateSpeedAllowed_l(effectiveRate, effectiveSpeed)) { ALOGV("setPlaybackRate(%f, %f) failed", playbackRate.mSpeed, playbackRate.mPitch); ALOGV("setPlaybackRate(%f, %f) failed", playbackRate.mSpeed, playbackRate.mPitch); return BAD_VALUE; return BAD_VALUE; } } mPlaybackRate = playbackRate; mProxy->setPlaybackRate(playbackRate); //modify this // Check resampler ratios are within bounds AudioPlaybackRate playbackRateTemp = playbackRate; if (effectiveRate > mSampleRate * AUDIO_RESAMPLER_DOWN_RATIO_MAX) { playbackRateTemp.mSpeed = effectiveSpeed; ALOGV("setPlaybackRate(%f, %f) failed. Resample rate exceeds max accepted value", playbackRateTemp.mPitch = effectivePitch; playbackRate.mSpeed, playbackRate.mPitch); return BAD_VALUE; } if (effectiveRate * AUDIO_RESAMPLER_UP_RATIO_MAX < mSampleRate) { ALOGV("setPlaybackRate(%f, %f) failed. Resample rate below min accepted value", playbackRate.mSpeed, playbackRate.mPitch); return BAD_VALUE; } mPlaybackRate = playbackRate; //set effective rates mProxy->setPlaybackRate(playbackRateTemp); mProxy->setPlaybackRate(playbackRateTemp); mProxy->setSampleRate(effectiveRate); // FIXME: not quite "atomic" with setPlaybackRate mProxy->setSampleRate(effectiveRate); // FIXME: not quite "atomic" with setPlaybackRate return NO_ERROR; return NO_ERROR; Loading services/audioflinger/AudioMixer.cpp +3 −7 Original line number Original line Diff line number Diff line Loading @@ -733,13 +733,9 @@ void AudioMixer::setParameter(int name, int target, int param, void *value) case PLAYBACK_RATE: { case PLAYBACK_RATE: { const AudioPlaybackRate *playbackRate = const AudioPlaybackRate *playbackRate = reinterpret_cast<AudioPlaybackRate*>(value); reinterpret_cast<AudioPlaybackRate*>(value); ALOG_ASSERT(AUDIO_TIMESTRETCH_SPEED_MIN <= playbackRate->mSpeed ALOGW_IF(!isAudioPlaybackRateValid(*playbackRate), && playbackRate->mSpeed <= AUDIO_TIMESTRETCH_SPEED_MAX, "bad parameters speed %f, pitch %f",playbackRate->mSpeed, "bad speed %f", playbackRate->mSpeed); playbackRate->mPitch); ALOG_ASSERT(AUDIO_TIMESTRETCH_PITCH_MIN <= playbackRate->mPitch && playbackRate->mPitch <= AUDIO_TIMESTRETCH_PITCH_MAX, "bad pitch %f", playbackRate->mPitch); //TODO: use function from AudioResamplerPublic.h to test validity. if (track.setPlaybackRate(*playbackRate)) { if (track.setPlaybackRate(*playbackRate)) { ALOGV("setParameter(TIMESTRETCH, PLAYBACK_RATE, STRETCH_MODE, FALLBACK_MODE " ALOGV("setParameter(TIMESTRETCH, PLAYBACK_RATE, STRETCH_MODE, FALLBACK_MODE " "%f %f %d %d", "%f %f %d %d", Loading services/audioflinger/BufferProviders.cpp +5 −3 Original line number Original line Diff line number Diff line Loading @@ -332,7 +332,8 @@ TimestretchBufferProvider::TimestretchBufferProvider(int32_t channelCount, mLocalBufferData(NULL), mLocalBufferData(NULL), mRemaining(0), mRemaining(0), mSonicStream(sonicCreateStream(sampleRate, mChannelCount)), mSonicStream(sonicCreateStream(sampleRate, mChannelCount)), mFallbackFailErrorShown(false) mFallbackFailErrorShown(false), mAudioPlaybackRateValid(false) { { LOG_ALWAYS_FATAL_IF(mSonicStream == NULL, LOG_ALWAYS_FATAL_IF(mSonicStream == NULL, "TimestretchBufferProvider can't allocate Sonic stream"); "TimestretchBufferProvider can't allocate Sonic stream"); Loading Loading @@ -460,6 +461,8 @@ status_t TimestretchBufferProvider::setPlaybackRate(const AudioPlaybackRate &pla sonicSetSpeed(mSonicStream, mPlaybackRate.mSpeed); sonicSetSpeed(mSonicStream, mPlaybackRate.mSpeed); //TODO: pitch is ignored for now //TODO: pitch is ignored for now //TODO: optimize: if parameters are the same, don't do any extra computation. //TODO: optimize: if parameters are the same, don't do any extra computation. mAudioPlaybackRateValid = isAudioPlaybackRateValid(mPlaybackRate); return OK; return OK; } } Loading @@ -479,8 +482,7 @@ void TimestretchBufferProvider::processFrames(void *dstBuffer, size_t *dstFrames *srcFrames = targetSrc + 1; *srcFrames = targetSrc + 1; } } if (mPlaybackRate.mSpeed< TIMESTRETCH_SONIC_SPEED_MIN || if (!mAudioPlaybackRateValid) { mPlaybackRate.mSpeed > TIMESTRETCH_SONIC_SPEED_MAX ) { //fallback mode //fallback mode if (*dstFrames > 0) { if (*dstFrames > 0) { switch(mPlaybackRate.mFallbackMode) { switch(mPlaybackRate.mFallbackMode) { Loading services/audioflinger/BufferProviders.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -188,6 +188,7 @@ private: sonicStream mSonicStream; // handle to sonic timestretch object sonicStream mSonicStream; // handle to sonic timestretch object //FIXME: this dependency should be abstracted out //FIXME: this dependency should be abstracted out bool mFallbackFailErrorShown; // log fallback error only once bool mFallbackFailErrorShown; // log fallback error only once bool mAudioPlaybackRateValid; // flag for current parameters validity }; }; // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- Loading Loading
include/media/AudioResamplerPublic.h +17 −0 Original line number Original line Diff line number Diff line Loading @@ -108,6 +108,23 @@ static inline bool isAudioPlaybackRateEqual(const AudioPlaybackRate &pr1, pr2.mFallbackMode == pr2.mFallbackMode; pr2.mFallbackMode == pr2.mFallbackMode; } } static inline bool isAudioPlaybackRateValid(const AudioPlaybackRate &playbackRate) { if (playbackRate.mFallbackMode == AUDIO_TIMESTRETCH_FALLBACK_FAIL && (playbackRate.mStretchMode == AUDIO_TIMESTRETCH_STRETCH_SPEECH || playbackRate.mStretchMode == AUDIO_TIMESTRETCH_STRETCH_DEFAULT)) { //test sonic specific constraints return playbackRate.mSpeed >= TIMESTRETCH_SONIC_SPEED_MIN && playbackRate.mSpeed <= TIMESTRETCH_SONIC_SPEED_MAX && playbackRate.mPitch >= AUDIO_TIMESTRETCH_PITCH_MIN && playbackRate.mPitch <= AUDIO_TIMESTRETCH_PITCH_MAX; } else { return playbackRate.mSpeed >= AUDIO_TIMESTRETCH_SPEED_MIN && playbackRate.mSpeed <= AUDIO_TIMESTRETCH_SPEED_MAX && playbackRate.mPitch >= AUDIO_TIMESTRETCH_PITCH_MIN && playbackRate.mPitch <= AUDIO_TIMESTRETCH_PITCH_MAX; } } // TODO: Consider putting these inlines into a class scope // TODO: Consider putting these inlines into a class scope // Returns the source frames needed to resample to destination frames. This is not a precise // Returns the source frames needed to resample to destination frames. This is not a precise Loading
media/libmedia/AudioTrack.cpp +20 −12 Original line number Original line Diff line number Diff line Loading @@ -78,7 +78,7 @@ static inline uint32_t adjustSampleRate(uint32_t sampleRate, float pitch) static inline float adjustSpeed(float speed, float pitch) static inline float adjustSpeed(float speed, float pitch) { { return kFixPitch ? (speed / pitch) : speed; return kFixPitch ? speed / max(pitch, AUDIO_TIMESTRETCH_PITCH_MIN_DELTA) : speed; } } static inline float adjustPitch(float pitch) static inline float adjustPitch(float pitch) Loading Loading @@ -809,25 +809,33 @@ status_t AudioTrack::setPlaybackRate(const AudioPlaybackRate &playbackRate) const uint32_t effectiveRate = adjustSampleRate(mSampleRate, playbackRate.mPitch); const uint32_t effectiveRate = adjustSampleRate(mSampleRate, playbackRate.mPitch); const float effectiveSpeed = adjustSpeed(playbackRate.mSpeed, playbackRate.mPitch); const float effectiveSpeed = adjustSpeed(playbackRate.mSpeed, playbackRate.mPitch); const float effectivePitch = adjustPitch(playbackRate.mPitch); const float effectivePitch = adjustPitch(playbackRate.mPitch); if (effectiveSpeed < AUDIO_TIMESTRETCH_SPEED_MIN AudioPlaybackRate playbackRateTemp = playbackRate; || effectiveSpeed > AUDIO_TIMESTRETCH_SPEED_MAX playbackRateTemp.mSpeed = effectiveSpeed; || effectivePitch < AUDIO_TIMESTRETCH_PITCH_MIN playbackRateTemp.mPitch = effectivePitch; || effectivePitch > AUDIO_TIMESTRETCH_PITCH_MAX) { if (!isAudioPlaybackRateValid(playbackRateTemp)) { return BAD_VALUE; return BAD_VALUE; //TODO: add function in AudioResamplerPublic.h to check for validity. } } // Check if the buffer size is compatible. // Check if the buffer size is compatible. if (!isSampleRateSpeedAllowed_l(effectiveRate, effectiveSpeed)) { if (!isSampleRateSpeedAllowed_l(effectiveRate, effectiveSpeed)) { ALOGV("setPlaybackRate(%f, %f) failed", playbackRate.mSpeed, playbackRate.mPitch); ALOGV("setPlaybackRate(%f, %f) failed", playbackRate.mSpeed, playbackRate.mPitch); return BAD_VALUE; return BAD_VALUE; } } mPlaybackRate = playbackRate; mProxy->setPlaybackRate(playbackRate); //modify this // Check resampler ratios are within bounds AudioPlaybackRate playbackRateTemp = playbackRate; if (effectiveRate > mSampleRate * AUDIO_RESAMPLER_DOWN_RATIO_MAX) { playbackRateTemp.mSpeed = effectiveSpeed; ALOGV("setPlaybackRate(%f, %f) failed. Resample rate exceeds max accepted value", playbackRateTemp.mPitch = effectivePitch; playbackRate.mSpeed, playbackRate.mPitch); return BAD_VALUE; } if (effectiveRate * AUDIO_RESAMPLER_UP_RATIO_MAX < mSampleRate) { ALOGV("setPlaybackRate(%f, %f) failed. Resample rate below min accepted value", playbackRate.mSpeed, playbackRate.mPitch); return BAD_VALUE; } mPlaybackRate = playbackRate; //set effective rates mProxy->setPlaybackRate(playbackRateTemp); mProxy->setPlaybackRate(playbackRateTemp); mProxy->setSampleRate(effectiveRate); // FIXME: not quite "atomic" with setPlaybackRate mProxy->setSampleRate(effectiveRate); // FIXME: not quite "atomic" with setPlaybackRate return NO_ERROR; return NO_ERROR; Loading
services/audioflinger/AudioMixer.cpp +3 −7 Original line number Original line Diff line number Diff line Loading @@ -733,13 +733,9 @@ void AudioMixer::setParameter(int name, int target, int param, void *value) case PLAYBACK_RATE: { case PLAYBACK_RATE: { const AudioPlaybackRate *playbackRate = const AudioPlaybackRate *playbackRate = reinterpret_cast<AudioPlaybackRate*>(value); reinterpret_cast<AudioPlaybackRate*>(value); ALOG_ASSERT(AUDIO_TIMESTRETCH_SPEED_MIN <= playbackRate->mSpeed ALOGW_IF(!isAudioPlaybackRateValid(*playbackRate), && playbackRate->mSpeed <= AUDIO_TIMESTRETCH_SPEED_MAX, "bad parameters speed %f, pitch %f",playbackRate->mSpeed, "bad speed %f", playbackRate->mSpeed); playbackRate->mPitch); ALOG_ASSERT(AUDIO_TIMESTRETCH_PITCH_MIN <= playbackRate->mPitch && playbackRate->mPitch <= AUDIO_TIMESTRETCH_PITCH_MAX, "bad pitch %f", playbackRate->mPitch); //TODO: use function from AudioResamplerPublic.h to test validity. if (track.setPlaybackRate(*playbackRate)) { if (track.setPlaybackRate(*playbackRate)) { ALOGV("setParameter(TIMESTRETCH, PLAYBACK_RATE, STRETCH_MODE, FALLBACK_MODE " ALOGV("setParameter(TIMESTRETCH, PLAYBACK_RATE, STRETCH_MODE, FALLBACK_MODE " "%f %f %d %d", "%f %f %d %d", Loading
services/audioflinger/BufferProviders.cpp +5 −3 Original line number Original line Diff line number Diff line Loading @@ -332,7 +332,8 @@ TimestretchBufferProvider::TimestretchBufferProvider(int32_t channelCount, mLocalBufferData(NULL), mLocalBufferData(NULL), mRemaining(0), mRemaining(0), mSonicStream(sonicCreateStream(sampleRate, mChannelCount)), mSonicStream(sonicCreateStream(sampleRate, mChannelCount)), mFallbackFailErrorShown(false) mFallbackFailErrorShown(false), mAudioPlaybackRateValid(false) { { LOG_ALWAYS_FATAL_IF(mSonicStream == NULL, LOG_ALWAYS_FATAL_IF(mSonicStream == NULL, "TimestretchBufferProvider can't allocate Sonic stream"); "TimestretchBufferProvider can't allocate Sonic stream"); Loading Loading @@ -460,6 +461,8 @@ status_t TimestretchBufferProvider::setPlaybackRate(const AudioPlaybackRate &pla sonicSetSpeed(mSonicStream, mPlaybackRate.mSpeed); sonicSetSpeed(mSonicStream, mPlaybackRate.mSpeed); //TODO: pitch is ignored for now //TODO: pitch is ignored for now //TODO: optimize: if parameters are the same, don't do any extra computation. //TODO: optimize: if parameters are the same, don't do any extra computation. mAudioPlaybackRateValid = isAudioPlaybackRateValid(mPlaybackRate); return OK; return OK; } } Loading @@ -479,8 +482,7 @@ void TimestretchBufferProvider::processFrames(void *dstBuffer, size_t *dstFrames *srcFrames = targetSrc + 1; *srcFrames = targetSrc + 1; } } if (mPlaybackRate.mSpeed< TIMESTRETCH_SONIC_SPEED_MIN || if (!mAudioPlaybackRateValid) { mPlaybackRate.mSpeed > TIMESTRETCH_SONIC_SPEED_MAX ) { //fallback mode //fallback mode if (*dstFrames > 0) { if (*dstFrames > 0) { switch(mPlaybackRate.mFallbackMode) { switch(mPlaybackRate.mFallbackMode) { Loading
services/audioflinger/BufferProviders.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -188,6 +188,7 @@ private: sonicStream mSonicStream; // handle to sonic timestretch object sonicStream mSonicStream; // handle to sonic timestretch object //FIXME: this dependency should be abstracted out //FIXME: this dependency should be abstracted out bool mFallbackFailErrorShown; // log fallback error only once bool mFallbackFailErrorShown; // log fallback error only once bool mAudioPlaybackRateValid; // flag for current parameters validity }; }; // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- Loading