summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--media/libmedia/Android.mk9
-rw-r--r--services/audioflinger/Android.mk22
-rw-r--r--services/audioflinger/AudioMixer.cpp13
-rw-r--r--services/audioflinger/AudioResampler.cpp25
-rw-r--r--services/audioflinger/AudioResampler.h3
-rw-r--r--services/audioflinger/AudioResamplerQTI.cpp168
-rw-r--r--services/audioflinger/AudioResamplerQTI.h52
7 files changed, 291 insertions, 1 deletions
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index 4d84bd0..74e4eb1 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -69,6 +69,15 @@ LOCAL_SRC_FILES:= \
StringArray.cpp \
AudioPolicy.cpp
+
+#QTI Resampler
+ifeq ($(call is-vendor-board-platform,QCOM), true)
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_RESAMPLER)), true)
+LOCAL_CFLAGS += -DQTI_RESAMPLER
+endif
+endif
+#QTI Resampler
+
LOCAL_SHARED_LIBRARIES := \
libui liblog libcutils libutils libbinder libsonivox libicuuc libicui18n libexpat \
libcamera_client libstagefright_foundation \
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index debcdf9..4791ce4 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -71,6 +71,14 @@ LOCAL_STATIC_LIBRARIES := \
libcpustats \
libmedia_helper
+#QTI Resampler
+ifeq ($(call is-vendor-board-platform,QCOM), true)
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_RESAMPLER)), true)
+LOCAL_CFLAGS += -DQTI_RESAMPLER
+endif
+endif
+#QTI Resampler
+
LOCAL_MODULE:= libaudioflinger
LOCAL_32_BIT_ONLY := true
@@ -134,7 +142,19 @@ LOCAL_C_INCLUDES := \
LOCAL_SHARED_LIBRARIES := \
libcutils \
libdl \
- liblog
+ liblog \
+ libaudioutils
+
+#QTI Resampler
+ifeq ($(call is-vendor-board-platform,QCOM), true)
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_RESAMPLER)), true)
+LOCAL_SRC_FILES_$(TARGET_2ND_ARCH) += AudioResamplerQTI.cpp.arm
+LOCAL_C_INCLUDES_$(TARGET_2ND_ARCH) += $(TARGET_OUT_HEADERS)/mm-audio/audio-src
+LOCAL_SHARED_LIBRARIES_$(TARGET_2ND_ARCH) += libqct_resampler
+LOCAL_CFLAGS_$(TARGET_2ND_ARCH) += -DQTI_RESAMPLER
+endif
+endif
+#QTI Resampler
LOCAL_MODULE := libaudioresampler
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index 8a9a837..27a2f65 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -85,6 +85,9 @@ static const bool kUseFloat = true;
// Set to default copy buffer size in frames for input processing.
static const size_t kCopyBufferFrameCount = 256;
+#ifdef QTI_RESAMPLER
+#define QTI_RESAMPLER_MAX_SAMPLERATE 192000
+#endif
namespace android {
// ----------------------------------------------------------------------------
@@ -779,6 +782,13 @@ bool AudioMixer::track_t::setResampler(uint32_t trackSampleRate, uint32_t devSam
// but if none exists, it is the channel count (1 for mono).
const int resamplerChannelCount = downmixerBufferProvider != NULL
? mMixerChannelCount : channelCount;
+#ifdef QTI_RESAMPLER
+ if ((trackSampleRate <= QTI_RESAMPLER_MAX_SAMPLERATE) &&
+ (trackSampleRate > devSampleRate * 2) &&
+ ((devSampleRate == 48000)||(devSampleRate == 44100))) {
+ quality = AudioResampler::QTI_QUALITY;
+ }
+#endif
ALOGVV("Creating resampler:"
" format(%#x) channels(%d) devSampleRate(%u) quality(%d)\n",
mMixerInFormat, resamplerChannelCount, devSampleRate, quality);
@@ -1644,6 +1654,9 @@ void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state,
// Note: In case of later int16_t sink output,
// conversion and clamping is done by memcpy_to_i16_from_float().
} while (--outFrames);
+ //assign fout to out, when no more frames are available, so that 0s
+ //can be filled at the right place
+ out = (int32_t *)fout;
break;
case AUDIO_FORMAT_PCM_16_BIT:
if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN_INT || uint32_t(vr) > UNITY_GAIN_INT)) {
diff --git a/services/audioflinger/AudioResampler.cpp b/services/audioflinger/AudioResampler.cpp
index e49b7b1..ab3294a 100644
--- a/services/audioflinger/AudioResampler.cpp
+++ b/services/audioflinger/AudioResampler.cpp
@@ -28,6 +28,10 @@
#include "AudioResamplerCubic.h"
#include "AudioResamplerDyn.h"
+#ifdef QTI_RESAMPLER
+#include "AudioResamplerQTI.h"
+#endif
+
#ifdef __arm__
#define ASM_ARM_RESAMP1 // enable asm optimisation for ResamplerOrder1
#endif
@@ -90,6 +94,9 @@ bool AudioResampler::qualityIsSupported(src_quality quality)
case DYN_LOW_QUALITY:
case DYN_MED_QUALITY:
case DYN_HIGH_QUALITY:
+#ifdef QTI_RESAMPLER
+ case QTI_QUALITY:
+#endif
return true;
default:
return false;
@@ -110,7 +117,11 @@ void AudioResampler::init_routine()
if (*endptr == '\0') {
defaultQuality = (src_quality) l;
ALOGD("forcing AudioResampler quality to %d", defaultQuality);
+#ifdef QTI_RESAMPLER
+ if (defaultQuality < DEFAULT_QUALITY || defaultQuality > QTI_QUALITY) {
+#else
if (defaultQuality < DEFAULT_QUALITY || defaultQuality > DYN_HIGH_QUALITY) {
+#endif
defaultQuality = DEFAULT_QUALITY;
}
}
@@ -129,6 +140,9 @@ uint32_t AudioResampler::qualityMHz(src_quality quality)
case HIGH_QUALITY:
return 20;
case VERY_HIGH_QUALITY:
+#ifdef QTI_RESAMPLER
+ case QTI_QUALITY: //for QTI_QUALITY, currently assuming same as VHQ
+#endif
return 34;
case DYN_LOW_QUALITY:
return 4;
@@ -204,6 +218,11 @@ AudioResampler* AudioResampler::create(audio_format_t format, int inChannelCount
case DYN_HIGH_QUALITY:
quality = DYN_MED_QUALITY;
break;
+#ifdef QTI_RESAMPLER
+ case QTI_QUALITY:
+ quality = DYN_HIGH_QUALITY;
+ break;
+#endif
}
}
pthread_mutex_unlock(&mutex);
@@ -250,6 +269,12 @@ AudioResampler* AudioResampler::create(audio_format_t format, int inChannelCount
}
}
break;
+#ifdef QTI_RESAMPLER
+ case QTI_QUALITY:
+ ALOGV("Create QTI_QUALITY Resampler = %d",quality);
+ resampler = new AudioResamplerQTI(format, inChannelCount, sampleRate);
+ break;
+#endif
}
// initialize resampler
diff --git a/services/audioflinger/AudioResampler.h b/services/audioflinger/AudioResampler.h
index a8e3e6f..6669a85 100644
--- a/services/audioflinger/AudioResampler.h
+++ b/services/audioflinger/AudioResampler.h
@@ -47,6 +47,9 @@ public:
DYN_LOW_QUALITY=5,
DYN_MED_QUALITY=6,
DYN_HIGH_QUALITY=7,
+#ifdef QTI_RESAMPLER
+ QTI_QUALITY=8,
+#endif
};
static const CONSTEXPR float UNITY_GAIN_FLOAT = 1.0f;
diff --git a/services/audioflinger/AudioResamplerQTI.cpp b/services/audioflinger/AudioResamplerQTI.cpp
new file mode 100644
index 0000000..44b741e
--- /dev/null
+++ b/services/audioflinger/AudioResamplerQTI.cpp
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2014, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "AudioResamplerQTI.h"
+#include "QCT_Resampler.h"
+#include <sys/time.h>
+#include <audio_utils/primitives.h>
+
+namespace android {
+AudioResamplerQTI::AudioResamplerQTI(int format,
+ int inChannelCount, int32_t sampleRate)
+ :AudioResampler(inChannelCount, sampleRate, QTI_QUALITY),
+ mOutFrameCount(0), mTmpBuf(0), mResamplerOutBuf(0), mFrameIndex(0)
+{
+ stateSize = QCT_Resampler::MemAlloc(format, inChannelCount, sampleRate, sampleRate);
+ mState = new int16_t[stateSize];
+ mVolume[0] = mVolume[1] = 0;
+ mBuffer.frameCount = 0;
+}
+
+AudioResamplerQTI::~AudioResamplerQTI()
+{
+ if (mState) {
+ delete [] mState;
+ }
+ if (mTmpBuf) {
+ delete [] mTmpBuf;
+ }
+ if(mResamplerOutBuf) {
+ delete [] mResamplerOutBuf;
+ }
+}
+
+size_t AudioResamplerQTI::resample(int32_t* out, size_t outFrameCount,
+ AudioBufferProvider* provider)
+{
+ int16_t vl = mVolume[0];
+ int16_t vr = mVolume[1];
+ int16_t *pBuf;
+
+ size_t inFrameRequest;
+ size_t inFrameCount = getNumInSample(outFrameCount);
+ size_t index = 0;
+ size_t frameIndex = mFrameIndex;
+ size_t out_count = outFrameCount * 2;
+ float *fout = reinterpret_cast<float *>(out);
+
+ if (mChannelCount == 1) {
+ inFrameRequest = inFrameCount;
+ } else {
+ inFrameRequest = inFrameCount * 2;
+ }
+
+ if (mOutFrameCount < outFrameCount) {
+ mOutFrameCount = outFrameCount;
+ if (mTmpBuf) {
+ delete [] mTmpBuf;
+ }
+ if(mResamplerOutBuf) {
+ delete [] mResamplerOutBuf;
+ }
+ mTmpBuf = new int16_t[inFrameRequest + 16];
+ mResamplerOutBuf = new int32_t[out_count];
+ }
+
+ if (mChannelCount == 1) {
+ // buffer is empty, fetch a new one
+ while (index < inFrameCount) {
+ if (!mBuffer.frameCount) {
+ mBuffer.frameCount = inFrameCount;
+ provider->getNextBuffer(&mBuffer);
+ frameIndex = 0;
+ }
+
+ if (mBuffer.raw == NULL) {
+ while (index < inFrameCount) {
+ mTmpBuf[index++] = 0;
+ }
+ QCT_Resampler::Resample90dB(mState, mTmpBuf, mResamplerOutBuf, inFrameCount, outFrameCount);
+ goto resample_exit;
+ }
+
+ mTmpBuf[index++] = clamp16_from_float(*((float *)mBuffer.raw + frameIndex++));
+
+ if (frameIndex >= mBuffer.frameCount) {
+ provider->releaseBuffer(&mBuffer);
+ }
+ }
+
+ QCT_Resampler::Resample90dB(mState, mTmpBuf, mResamplerOutBuf, inFrameCount, outFrameCount);
+ } else {
+ pBuf = &mTmpBuf[inFrameCount];
+ // buffer is empty, fetch a new one
+ while (index < inFrameCount) {
+ if (!mBuffer.frameCount) {
+ mBuffer.frameCount = inFrameCount;
+ provider->getNextBuffer(&mBuffer);
+ frameIndex = 0;
+ }
+ if (mBuffer.raw == NULL) {
+ while (index < inFrameCount) {
+ mTmpBuf[index] = 0;
+ pBuf[index++] = 0;
+ }
+ QCT_Resampler::Resample90dB(mState, mTmpBuf, mResamplerOutBuf, inFrameCount, outFrameCount);
+ goto resample_exit;
+ }
+
+ mTmpBuf[index] = clamp16_from_float(*((float *)mBuffer.raw + frameIndex++));
+ pBuf[index++] = clamp16_from_float(*((float *)mBuffer.raw + frameIndex++));
+ if (frameIndex >= mBuffer.frameCount * 2) {
+ provider->releaseBuffer(&mBuffer);
+ }
+ }
+
+ QCT_Resampler::Resample90dB(mState, mTmpBuf, mResamplerOutBuf, inFrameCount, outFrameCount);
+ }
+
+resample_exit:
+ for (int i = 0; i < out_count; i += 2) {
+ fout[i] += float_from_q4_27(mResamplerOutBuf[i] * vl);
+ fout[i+1] += float_from_q4_27(mResamplerOutBuf[i+1] * vr);
+ }
+
+ mFrameIndex = frameIndex;
+ return index;
+}
+
+void AudioResamplerQTI::setSampleRate(int32_t inSampleRate)
+{
+ if (mInSampleRate != inSampleRate) {
+ mInSampleRate = inSampleRate;
+ init();
+ }
+}
+
+void AudioResamplerQTI::init()
+{
+ QCT_Resampler::Init(mState, mChannelCount, mInSampleRate, mSampleRate);
+}
+
+size_t AudioResamplerQTI::getNumInSample(size_t outFrameCount)
+{
+ size_t size = (size_t)QCT_Resampler::GetNumInSamp(mState, outFrameCount);
+ return size;
+}
+
+void AudioResamplerQTI::reset()
+{
+ AudioResampler::reset();
+}
+
+}; // namespace android
diff --git a/services/audioflinger/AudioResamplerQTI.h b/services/audioflinger/AudioResamplerQTI.h
new file mode 100644
index 0000000..0b30a9f
--- /dev/null
+++ b/services/audioflinger/AudioResamplerQTI.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2014, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <cutils/log.h>
+
+#include "AudioResampler.h"
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class AudioResamplerQTI : public AudioResampler {
+public:
+ AudioResamplerQTI(int format, int inChannelCount, int32_t sampleRate);
+ ~AudioResamplerQTI();
+ size_t resample(int32_t* out, size_t outFrameCount,
+ AudioBufferProvider* provider);
+ void setSampleRate(int32_t inSampleRate);
+ size_t getNumInSample(size_t outFrameCount);
+
+ int16_t *mState;
+ int16_t *mTmpBuf;
+ int32_t *mResamplerOutBuf;
+ size_t mFrameIndex;
+ size_t stateSize;
+ size_t mOutFrameCount;
+
+ static const int kNumTmpBufSize = 1024;
+
+ void init();
+ void reset();
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+