summaryrefslogtreecommitdiffstats
path: root/services/audioflinger/AudioResamplerSinc.cpp
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2012-11-10 04:44:30 -0800
committerMathias Agopian <mathias@google.com>2012-11-10 04:49:15 -0800
commit7492a7ff46a75b5d8e10ae11d4ad50429cf945ce (patch)
treedf55f34b9daec1a5c8b1ffb95bd08e59e8c751f5 /services/audioflinger/AudioResamplerSinc.cpp
parent0d585c85524eb5d398fadff5ca8dd43939ed9cb4 (diff)
downloadframeworks_av-7492a7ff46a75b5d8e10ae11d4ad50429cf945ce.zip
frameworks_av-7492a7ff46a75b5d8e10ae11d4ad50429cf945ce.tar.gz
frameworks_av-7492a7ff46a75b5d8e10ae11d4ad50429cf945ce.tar.bz2
more optimizations...
calculate the offsets from the phase differently, this happens to reduce the register pressure in the main loop, which in turns allows the compiler to generate much better code (doesn't need to spill a lot of stuff on the stack). this gives another 15% performance increase Change-Id: I2ce3479dd48b9e6941adb80e6d443d6e14d64d96
Diffstat (limited to 'services/audioflinger/AudioResamplerSinc.cpp')
-rw-r--r--services/audioflinger/AudioResamplerSinc.cpp31
1 files changed, 18 insertions, 13 deletions
diff --git a/services/audioflinger/AudioResamplerSinc.cpp b/services/audioflinger/AudioResamplerSinc.cpp
index 952abb4..d68b839 100644
--- a/services/audioflinger/AudioResamplerSinc.cpp
+++ b/services/audioflinger/AudioResamplerSinc.cpp
@@ -637,17 +637,20 @@ template<int CHANNELS>
void AudioResamplerSinc::filterCoefficient(
int32_t* out, uint32_t phase, const int16_t *samples, uint32_t vRL)
{
+ // NOTE: be very careful when modifying the code here. register
+ // pressure is very high and a small change might cause the compiler
+ // to generate far less efficient code.
+ // Always sanity check the result with objdump or test-resample.
+
// compute the index of the coefficient on the positive side and
// negative side
const Constants& c(*mConstants);
+ const int32_t ONE = c.cMask | c.pMask;
uint32_t indexP = ( phase & c.cMask) >> c.cShift;
- uint32_t indexN = (-phase & c.cMask) >> c.cShift;
uint32_t lerpP = ( phase & c.pMask) >> c.pShift;
- uint32_t lerpN = (-phase & c.pMask) >> c.pShift;
- if ((indexP == 0) && (lerpP == 0)) {
- indexN = c.cMask >> c.cShift;
- lerpN = c.pMask >> c.pShift;
- }
+ uint32_t indexN = ((ONE-phase) & c.cMask) >> c.cShift;
+ uint32_t lerpN = ((ONE-phase) & c.pMask) >> c.pShift;
+
const size_t offset = c.halfNumCoefs;
indexP *= offset;
indexN *= offset;
@@ -677,7 +680,8 @@ void AudioResamplerSinc::filterCoefficient(
asm (
"vmov.32 d2[0], %[lerpP] \n" // load the positive phase
"vmov.32 d2[1], %[lerpN] \n" // load the negative phase
- "veor q0, q0 \n" // result, initialize to 0
+ "veor q0, q0, q0 \n" // result, initialize to 0
+ "vshl.s32 d2, d2, #16 \n" // convert to 32 bits
"1: \n"
"vld1.16 { d4}, [%[sP]] \n" // load 4 16-bits stereo samples
@@ -727,8 +731,8 @@ void AudioResamplerSinc::filterCoefficient(
[coefsN1] "+r" (coefsN1),
[sP] "+r" (sP),
[sN] "+r" (sN)
- : [lerpP] "r" (lerpP<<16),
- [lerpN] "r" (lerpN<<16),
+ : [lerpP] "r" (lerpP),
+ [lerpN] "r" (lerpN),
[vLR] "r" (mVolumeSIMD)
: "cc", "memory",
"q0", "q1", "q2", "q3",
@@ -742,8 +746,9 @@ void AudioResamplerSinc::filterCoefficient(
asm (
"vmov.32 d2[0], %[lerpP] \n" // load the positive phase
"vmov.32 d2[1], %[lerpN] \n" // load the negative phase
- "veor q0, q0 \n" // result, initialize to 0
- "veor q4, q4 \n" // result, initialize to 0
+ "veor q0, q0, q0 \n" // result, initialize to 0
+ "veor q4, q4, q4 \n" // result, initialize to 0
+ "vshl.s32 d2, d2, #16 \n" // convert to 32 bits
"1: \n"
"vld2.16 {d4,d5}, [%[sP]] \n" // load 4 16-bits stereo samples
@@ -802,8 +807,8 @@ void AudioResamplerSinc::filterCoefficient(
[coefsN1] "+r" (coefsN1),
[sP] "+r" (sP),
[sN] "+r" (sN)
- : [lerpP] "r" (lerpP<<16),
- [lerpN] "r" (lerpN<<16),
+ : [lerpP] "r" (lerpP),
+ [lerpN] "r" (lerpN),
[vLR] "r" (mVolumeSIMD)
: "cc", "memory",
"q0", "q1", "q2", "q3", "q4",