From 50ebdf2086b645b9b703a6d489238767a9afb34f Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Sat, 3 Nov 2012 23:37:53 -0700 Subject: 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 --- services/audioflinger/AudioResamplerSinc.cpp | 64 +++++++++++----------------- 1 file changed, 25 insertions(+), 39 deletions(-) (limited to 'services/audioflinger/AudioResamplerSinc.cpp') 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 #include #include +#include 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(l, r, phaseFraction, impulse); - out[outputIndex++] += 2 * mulRL(1, l, vRL); - out[outputIndex++] += 2 * mulRL(0, r, vRL); + while (CC_LIKELY(outputIndex < outputSampleCount)) { + filterCoefficient(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(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(impulse, phaseFraction, in, inputIndex); + const size_t phaseIndex = phaseFraction >> kNumPhaseBits; + for (size_t i=0 ; i= frameCount) - break; // 0 frame available, 1 frame needed - // read second frame + if (inputIndex >= frameCount) { + goto done; // need a new buffer + } read(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<= 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 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(l, r, coefs+indexP, lerpP, sP); - interpolate(l, r, coefs+indexN, lerpN, sN); - sP -= CHANNELS; sN += CHANNELS; coefs += 1 << c->coefsBits; - interpolate(l, r, coefs+indexP, lerpP, sP); - interpolate(l, r, coefs+indexN, lerpN, sN); - sP -= CHANNELS; sN += CHANNELS; coefs += 1 << c->coefsBits; - interpolate(l, r, coefs+indexP, lerpP, sP); - interpolate(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(l, r, coefs+indexP, lerpP, sP); interpolate(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 -- cgit v1.1