summaryrefslogtreecommitdiffstats
path: root/services/audioflinger/AudioResamplerSinc.cpp
diff options
context:
space:
mode:
authorSathishKumar Mani <smani@codeaurora.org>2012-01-17 10:49:47 -0800
committerIliyan Malchev <malchev@google.com>2012-09-26 18:48:44 -0700
commit76b111685010e1fea7c0a865c038aee35507fde4 (patch)
tree25a9d24b4cc23476d25cc026ff0888a3ffcf73e8 /services/audioflinger/AudioResamplerSinc.cpp
parent12bff5dd87e6b863482e6bfd9f4561078ebcf3f0 (diff)
downloadframeworks_av-76b111685010e1fea7c0a865c038aee35507fde4.zip
frameworks_av-76b111685010e1fea7c0a865c038aee35507fde4.tar.gz
frameworks_av-76b111685010e1fea7c0a865c038aee35507fde4.tar.bz2
audioflinger: use resample coefficients from audio-resampler library.
-Add a separate quality VERY_HIGH_QUALITY in resampler -Use resample coefficients audio-resampler library for quality VERY_HIGH_QUALITY. -This improves the quality of resampled output. Bug: 7024293 Change-Id: Ia44142413bed5f5963d7eab7846eec877a2415e4 Signed-off-by: Iliyan Malchev <malchev@google.com>
Diffstat (limited to 'services/audioflinger/AudioResamplerSinc.cpp')
-rw-r--r--services/audioflinger/AudioResamplerSinc.cpp96
1 files changed, 87 insertions, 9 deletions
diff --git a/services/audioflinger/AudioResamplerSinc.cpp b/services/audioflinger/AudioResamplerSinc.cpp
index 76662d8..0ae4b64 100644
--- a/services/audioflinger/AudioResamplerSinc.cpp
+++ b/services/audioflinger/AudioResamplerSinc.cpp
@@ -14,8 +14,15 @@
* limitations under the License.
*/
+#define LOG_TAG "AudioResamplerSinc"
+//#define LOG_NDEBUG 0
+
#include <string.h>
#include "AudioResamplerSinc.h"
+#include <dlfcn.h>
+#include <cutils/properties.h>
+#include <stdlib.h>
+#include <utils/Log.h>
namespace android {
// ----------------------------------------------------------------------------
@@ -57,6 +64,14 @@ const int32_t AudioResamplerSinc::mFirCoefsDown[] = {
0x00000000 // this one is needed for lerping the last coefficient
};
+//Define the static variables
+int AudioResamplerSinc::coefsBits;
+int AudioResamplerSinc::cShift;
+uint32_t AudioResamplerSinc::cMask;
+int AudioResamplerSinc::pShift;
+uint32_t AudioResamplerSinc::pMask;
+unsigned int AudioResamplerSinc::halfNumCoefs;
+
// ----------------------------------------------------------------------------
static inline
@@ -133,7 +148,7 @@ int32_t mulAddRL(int left, uint32_t inRL, int32_t v, int32_t a)
// ----------------------------------------------------------------------------
AudioResamplerSinc::AudioResamplerSinc(int bitDepth,
- int inChannelCount, int32_t sampleRate)
+ int inChannelCount, int32_t sampleRate, int32_t quality)
: AudioResampler(bitDepth, inChannelCount, sampleRate),
mState(0)
{
@@ -153,26 +168,89 @@ AudioResamplerSinc::AudioResamplerSinc(int bitDepth,
*
*/
- const size_t numCoefs = 2*halfNumCoefs;
- const size_t stateSize = numCoefs * inChannelCount * 2;
- mState = new int16_t[stateSize];
- memset(mState, 0, sizeof(int16_t)*stateSize);
- mImpulse = mState + (halfNumCoefs-1)*inChannelCount;
- mRingFull = mImpulse + (numCoefs+1)*inChannelCount;
+ mResampleCoeffLib = NULL;
+ //Intialize the parameters for resampler coefficients
+ //for high quality
+ coefsBits = RESAMPLE_FIR_LERP_INT_BITS;
+ cShift = kNumPhaseBits - coefsBits;
+ cMask = ((1<< coefsBits)-1) << cShift;
+
+ pShift = kNumPhaseBits - coefsBits - pLerpBits;
+ pMask = ((1<< pLerpBits)-1) << pShift;
+
+ halfNumCoefs = RESAMPLE_FIR_NUM_COEF;
+
+ //Check if qcom highest quality can be used
+ char value[PROPERTY_VALUE_MAX];
+ //Open the dll to get the coefficients for VERY_HIGH_QUALITY
+ if (quality == VERY_HIGH_QUALITY ) {
+ mResampleCoeffLib = dlopen("libaudio-resampler.so", RTLD_NOW);
+ ALOGV("Open libaudio-resampler library = %p",mResampleCoeffLib);
+ if (mResampleCoeffLib == NULL) {
+ ALOGE("Could not open audio-resampler library: %s", dlerror());
+ return;
+ }
+ mReadResampleCoefficients = (readCoefficientsFn)dlsym(mResampleCoeffLib, "readResamplerCoefficients");
+ mReadResampleFirNumCoeff = (readResampleFirNumCoeffFn)dlsym(mResampleCoeffLib, "readResampleFirNumCoeff");
+ mReadResampleFirLerpIntBits = (readResampleFirLerpIntBitsFn)dlsym(mResampleCoeffLib,"readResampleFirLerpIntBits");
+ if (!mReadResampleCoefficients || !mReadResampleFirNumCoeff || !mReadResampleFirLerpIntBits) {
+ mReadResampleCoefficients = NULL;
+ mReadResampleFirNumCoeff = NULL;
+ mReadResampleFirLerpIntBits = NULL;
+ dlclose(mResampleCoeffLib);
+ mResampleCoeffLib = NULL;
+ ALOGE("Could not find convert symbol: %s", dlerror());
+ return;
+ }
+ // we have 16 coefs samples per zero-crossing
+ coefsBits = mReadResampleFirLerpIntBits();
+ ALOGV("coefsBits = %d",coefsBits);
+ cShift = kNumPhaseBits - coefsBits;
+ cMask = ((1<<coefsBits)-1) << cShift;
+ pShift = kNumPhaseBits - coefsBits - pLerpBits;
+ pMask = ((1<<pLerpBits)-1) << pShift;
+ // number of zero-crossing on each side
+ halfNumCoefs = mReadResampleFirNumCoeff();
+ ALOGV("halfNumCoefs = %d",halfNumCoefs);
+ }
}
+
AudioResamplerSinc::~AudioResamplerSinc()
{
+ if(mResampleCoeffLib) {
+ ALOGV("close the libaudio-resampler library");
+ dlclose(mResampleCoeffLib);
+ mResampleCoeffLib = NULL;
+ mReadResampleCoefficients = NULL;
+ mReadResampleFirNumCoeff = NULL;
+ mReadResampleFirLerpIntBits = NULL;
+ }
delete [] mState;
}
void AudioResamplerSinc::init() {
+
+ const size_t numCoefs = 2*halfNumCoefs;
+ const size_t stateSize = numCoefs * mChannelCount * 2;
+ mState = new int16_t[stateSize];
+ memset(mState, 0, sizeof(int16_t)*stateSize);
+ mImpulse = mState + (halfNumCoefs-1)*mChannelCount;
+ mRingFull = mImpulse + (numCoefs+1)*mChannelCount;
}
void AudioResamplerSinc::resample(int32_t* out, size_t outFrameCount,
AudioBufferProvider* provider)
{
- mFirCoefs = (mInSampleRate <= mSampleRate) ? mFirCoefsUp : mFirCoefsDown;
+
+ if(mResampleCoeffLib){
+ ALOGV("get coefficient from libmm-audio resampler library");
+ mFirCoefs = (mInSampleRate <= mSampleRate) ? mReadResampleCoefficients(true) : mReadResampleCoefficients(false);
+ }
+ else {
+ ALOGV("Use default coefficients");
+ mFirCoefs = (mInSampleRate <= mSampleRate) ? mFirCoefsUp : mFirCoefsDown;
+ }
// select the appropriate resampler
switch (mChannelCount) {
@@ -183,6 +261,7 @@ void AudioResamplerSinc::resample(int32_t* out, size_t outFrameCount,
resample<2>(out, outFrameCount, provider);
break;
}
+
}
@@ -352,6 +431,5 @@ void AudioResamplerSinc::interpolate(
r = l = mulAdd(samples[0], sinc, l);
}
}
-
// ----------------------------------------------------------------------------
}; // namespace android