summaryrefslogtreecommitdiffstats
path: root/services/audioflinger
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
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')
-rw-r--r--services/audioflinger/Android.mk4
-rw-r--r--services/audioflinger/AudioResampler.cpp9
-rw-r--r--services/audioflinger/AudioResampler.h3
-rw-r--r--services/audioflinger/AudioResamplerSinc.cpp96
-rw-r--r--services/audioflinger/AudioResamplerSinc.h24
5 files changed, 114 insertions, 22 deletions
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 66759d1..b9e3238 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -18,8 +18,8 @@ LOCAL_SRC_FILES:= \
AudioMixer.cpp.arm \
AudioResampler.cpp.arm \
AudioPolicyService.cpp \
- ServiceUtilities.cpp
-# AudioResamplerSinc.cpp.arm
+ ServiceUtilities.cpp \
+ AudioResamplerSinc.cpp.arm
# AudioResamplerCubic.cpp.arm
LOCAL_SRC_FILES += StateQueue.cpp
diff --git a/services/audioflinger/AudioResampler.cpp b/services/audioflinger/AudioResampler.cpp
index fbb54cf..5c1c905 100644
--- a/services/audioflinger/AudioResampler.cpp
+++ b/services/audioflinger/AudioResampler.cpp
@@ -23,8 +23,8 @@
#include <cutils/log.h>
#include <cutils/properties.h>
#include "AudioResampler.h"
-#if 0
#include "AudioResamplerSinc.h"
+#if 0
#include "AudioResamplerCubic.h"
#endif
@@ -106,11 +106,14 @@ AudioResampler* AudioResampler::create(int bitDepth, int inChannelCount,
ALOGV("Create cubic Resampler");
resampler = new AudioResamplerCubic(bitDepth, inChannelCount, sampleRate);
break;
+#endif
case HIGH_QUALITY:
- ALOGV("Create sinc Resampler");
+ ALOGV("Create HIGH_QUALITY sinc Resampler");
resampler = new AudioResamplerSinc(bitDepth, inChannelCount, sampleRate);
+ case VERY_HIGH_QUALITY:
+ ALOGV("Create VERY_HIGH_QUALITY sinc Resampler = %d",quality);
+ resampler = new AudioResamplerSinc(bitDepth, inChannelCount, sampleRate, quality);
break;
-#endif
}
// initialize resampler
diff --git a/services/audioflinger/AudioResampler.h b/services/audioflinger/AudioResampler.h
index dc696d8..71cdfda 100644
--- a/services/audioflinger/AudioResampler.h
+++ b/services/audioflinger/AudioResampler.h
@@ -38,7 +38,8 @@ public:
DEFAULT=0,
LOW_QUALITY=1,
MED_QUALITY=2,
- HIGH_QUALITY=3
+ HIGH_QUALITY=3,
+ VERY_HIGH_QUALITY=255
};
static AudioResampler* create(int bitDepth, int inChannelCount,
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
diff --git a/services/audioflinger/AudioResamplerSinc.h b/services/audioflinger/AudioResamplerSinc.h
index f0a07b8..c53c66d 100644
--- a/services/audioflinger/AudioResamplerSinc.h
+++ b/services/audioflinger/AudioResamplerSinc.h
@@ -25,11 +25,16 @@
namespace android {
+
+typedef const int32_t * (*readCoefficientsFn)(bool upDownSample);
+typedef int32_t (*readResampleFirNumCoeffFn)();
+typedef int32_t (*readResampleFirLerpIntBitsFn)();
+
// ----------------------------------------------------------------------------
class AudioResamplerSinc : public AudioResampler {
public:
- AudioResamplerSinc(int bitDepth, int inChannelCount, int32_t sampleRate);
+ AudioResamplerSinc(int bitDepth, int inChannelCount, int32_t sampleRate, int32_t quality = HIGH_QUALITY);
virtual ~AudioResamplerSinc();
@@ -55,6 +60,10 @@ private:
inline void read(int16_t*& impulse, uint32_t& phaseFraction,
const int16_t* in, size_t inputIndex);
+ readCoefficientsFn mReadResampleCoefficients ;
+ readResampleFirNumCoeffFn mReadResampleFirNumCoeff;
+ readResampleFirLerpIntBitsFn mReadResampleFirLerpIntBits;
+
int16_t *mState;
int16_t *mImpulse;
int16_t *mRingFull;
@@ -63,23 +72,24 @@ private:
static const int32_t mFirCoefsDown[];
static const int32_t mFirCoefsUp[];
+ void * mResampleCoeffLib;
// ----------------------------------------------------------------------------
static const int32_t RESAMPLE_FIR_NUM_COEF = 8;
static const int32_t RESAMPLE_FIR_LERP_INT_BITS = 4;
// we have 16 coefs samples per zero-crossing
- static const int coefsBits = RESAMPLE_FIR_LERP_INT_BITS; // 4
- static const int cShift = kNumPhaseBits - coefsBits; // 26
- static const uint32_t cMask = ((1<<coefsBits)-1) << cShift; // 0xf<<26 = 3c00 0000
+ static int coefsBits;
+ static int cShift;
+ static uint32_t cMask;
// and we use 15 bits to interpolate between these samples
// this cannot change because the mul below rely on it.
static const int pLerpBits = 15;
- static const int pShift = kNumPhaseBits - coefsBits - pLerpBits; // 11
- static const uint32_t pMask = ((1<<pLerpBits)-1) << pShift; // 0x7fff << 11
+ static int pShift;
+ static uint32_t pMask;
// number of zero-crossing on each side
- static const unsigned int halfNumCoefs = RESAMPLE_FIR_NUM_COEF;
+ static unsigned int halfNumCoefs;
};
// ----------------------------------------------------------------------------