diff options
author | Mathias Agopian <mathias@google.com> | 2012-11-03 23:37:53 -0700 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2012-11-05 01:03:02 -0800 |
commit | 50ebdf2086b645b9b703a6d489238767a9afb34f (patch) | |
tree | e8c80fb18a5e34ee4e47975b763e63c41cb83071 /services/audioflinger/AudioResamplerSinc.cpp | |
parent | fb242fa66643d1bd5362077a44c02c86c8064564 (diff) | |
download | frameworks_av-50ebdf2086b645b9b703a6d489238767a9afb34f.zip frameworks_av-50ebdf2086b645b9b703a6d489238767a9afb34f.tar.gz frameworks_av-50ebdf2086b645b9b703a6d489238767a9afb34f.tar.bz2 |
improve SINC resampler performance
The improvement is about 60% by just tweaking a few
things to help the compiler generate better code.
It turns out that inlining too much stuff manually was hurting us.
Change-Id: I8068f0f75051f95ac600e50ce552572dd1e8c304
Diffstat (limited to 'services/audioflinger/AudioResamplerSinc.cpp')
-rw-r--r-- | services/audioflinger/AudioResamplerSinc.cpp | 64 |
1 files changed, 25 insertions, 39 deletions
diff --git a/services/audioflinger/AudioResamplerSinc.cpp b/services/audioflinger/AudioResamplerSinc.cpp index 5f25760..b478e8d 100644 --- a/services/audioflinger/AudioResamplerSinc.cpp +++ b/services/audioflinger/AudioResamplerSinc.cpp @@ -23,6 +23,7 @@ #include <cutils/properties.h> #include <stdlib.h> #include <utils/Log.h> +#include <cutils/compiler.h> namespace android { // ---------------------------------------------------------------------------- @@ -305,38 +306,28 @@ void AudioResamplerSinc::resample(int32_t* out, size_t outFrameCount, // Always read-in the first samples from the input buffer int16_t* head = impulse + c->halfNumCoefs*CHANNELS; - head[0] = in[inputIndex*CHANNELS + 0]; - if (CHANNELS == 2) - head[1] = in[inputIndex*CHANNELS + 1]; + for (size_t i=0 ; i<CHANNELS ; i++) { + head[i] = in[inputIndex*CHANNELS + i]; + } // handle boundary case int32_t l, r; - while (outputIndex < outputSampleCount) { - filterCoefficient<CHANNELS>(l, r, phaseFraction, impulse); - out[outputIndex++] += 2 * mulRL(1, l, vRL); - out[outputIndex++] += 2 * mulRL(0, r, vRL); + while (CC_LIKELY(outputIndex < outputSampleCount)) { + filterCoefficient<CHANNELS>(l, r, phaseFraction, impulse, vRL); + out[outputIndex++] += l; + out[outputIndex++] += r; phaseFraction += phaseIncrement; - const uint32_t phaseIndex = phaseFraction >> kNumPhaseBits; - if (phaseIndex == 1) { - inputIndex++; - if (inputIndex >= frameCount) - break; // need a new buffer - read<CHANNELS>(impulse, phaseFraction, in, inputIndex); - } else if (phaseIndex == 2) { // maximum value - inputIndex++; - if (inputIndex >= frameCount) - break; // 0 frame available, 2 frames needed - // read first frame - read<CHANNELS>(impulse, phaseFraction, in, inputIndex); + const size_t phaseIndex = phaseFraction >> kNumPhaseBits; + for (size_t i=0 ; i<phaseIndex ; i++) { inputIndex++; - if (inputIndex >= frameCount) - break; // 0 frame available, 1 frame needed - // read second frame + if (inputIndex >= frameCount) { + goto done; // need a new buffer + } read<CHANNELS>(impulse, phaseFraction, in, inputIndex); } } - +done: // if done with buffer, save samples if (inputIndex >= frameCount) { inputIndex -= frameCount; @@ -366,20 +357,20 @@ void AudioResamplerSinc::read( const uint32_t phaseIndex = phaseFraction >> kNumPhaseBits; impulse += CHANNELS; phaseFraction -= 1LU<<kNumPhaseBits; - if (impulse >= mRingFull) { + if (CC_UNLIKELY(impulse >= mRingFull)) { const size_t stateSize = (c->halfNumCoefs*2)*CHANNELS; memcpy(mState, mState+stateSize, sizeof(int16_t)*stateSize); impulse -= stateSize; } int16_t* head = impulse + c->halfNumCoefs*CHANNELS; - head[0] = in[inputIndex*CHANNELS + 0]; - if (CHANNELS == 2) - head[1] = in[inputIndex*CHANNELS + 1]; + for (size_t i=0 ; i<CHANNELS ; i++) { + head[i] = in[inputIndex*CHANNELS + i]; + } } template<int CHANNELS> void AudioResamplerSinc::filterCoefficient( - int32_t& l, int32_t& r, uint32_t phase, const int16_t *samples) + int32_t& l, int32_t& r, uint32_t phase, const int16_t *samples, uint32_t vRL) { const Constants *c = mConstants; @@ -399,20 +390,15 @@ void AudioResamplerSinc::filterCoefficient( const int32_t* coefs = mFirCoefs; const int16_t *sP = samples; const int16_t *sN = samples+CHANNELS; - for (unsigned int i=0 ; i < c->halfNumCoefs/4 ; i++) { - interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP); - interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN); - sP -= CHANNELS; sN += CHANNELS; coefs += 1 << c->coefsBits; - interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP); - interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN); - sP -= CHANNELS; sN += CHANNELS; coefs += 1 << c->coefsBits; - interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP); - interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN); - sP -= CHANNELS; sN += CHANNELS; coefs += 1 << c->coefsBits; + const size_t offset = 1 << c->coefsBits; + const size_t count = c->halfNumCoefs; + for (size_t i=0 ; i < count ; i++) { interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP); interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN); - sP -= CHANNELS; sN += CHANNELS; coefs += 1 << c->coefsBits; + sP -= CHANNELS; sN += CHANNELS; coefs += offset; } + l = 2 * mulRL(1, l, vRL); + r = 2 * mulRL(0, r, vRL); } template<int CHANNELS> |