diff options
author | SathishKumar Mani <smani@codeaurora.org> | 2012-01-17 10:49:47 -0800 |
---|---|---|
committer | Iliyan Malchev <malchev@google.com> | 2012-09-26 18:48:44 -0700 |
commit | 76b111685010e1fea7c0a865c038aee35507fde4 (patch) | |
tree | 25a9d24b4cc23476d25cc026ff0888a3ffcf73e8 /services/audioflinger/AudioResamplerSinc.cpp | |
parent | 12bff5dd87e6b863482e6bfd9f4561078ebcf3f0 (diff) | |
download | frameworks_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.cpp | 96 |
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 |