summaryrefslogtreecommitdiffstats
path: root/media/libeffects/testlibs/AudioPeakingFilter.cpp
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2010-07-09 12:28:50 -0700
committerEric Laurent <elaurent@google.com>2010-07-17 06:33:00 -0700
commit2c8e5cab3faa6d360e222b7a6c40a80083d021ac (patch)
treefd19b8baa829edb78116b089d1122ea4ef0921e1 /media/libeffects/testlibs/AudioPeakingFilter.cpp
parentada2ac8e09b6d3f2b3c3155a852ba0fffae1b592 (diff)
downloadframeworks_av-2c8e5cab3faa6d360e222b7a6c40a80083d021ac.zip
frameworks_av-2c8e5cab3faa6d360e222b7a6c40a80083d021ac.tar.gz
frameworks_av-2c8e5cab3faa6d360e222b7a6c40a80083d021ac.tar.bz2
First submission of audio effect library from NXP software.
This CL contains the first open sourceable version of the audio effect library from NXP software. The effects implemented are: - Bass boost - Virtualizer (stereo widening) - Equalizer - Spectrum analyzer Source file for the effect engines are located under libeffects/lvm/lib The wrapper implementing the interface with the audio effect framework in under libeffects/lvm/wrapper The code of other effect libraries has also been reorganized fo clarity: - the effect factory is now under libeffects/factory - the test equalizer and reverb effects are under libeffect/testlibs - the visualizer is under libeffects/virtualizer Change-Id: I8d91e2181f81b89f8fc0c1e1e6bf552c5809b2eb
Diffstat (limited to 'media/libeffects/testlibs/AudioPeakingFilter.cpp')
-rw-r--r--media/libeffects/testlibs/AudioPeakingFilter.cpp121
1 files changed, 121 insertions, 0 deletions
diff --git a/media/libeffects/testlibs/AudioPeakingFilter.cpp b/media/libeffects/testlibs/AudioPeakingFilter.cpp
new file mode 100644
index 0000000..60fefe6
--- /dev/null
+++ b/media/libeffects/testlibs/AudioPeakingFilter.cpp
@@ -0,0 +1,121 @@
+/* //device/include/server/AudioFlinger/AudioPeakingFilter.cpp
+ **
+ ** Copyright 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 "AudioPeakingFilter.h"
+#include "AudioCommon.h"
+#include "EffectsMath.h"
+
+#include <new>
+#include <assert.h>
+
+#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
+#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
+
+namespace android {
+// Format of the coefficient table:
+// kCoefTable[freq][gain][bw][coef]
+// freq - peak frequency, in octaves below Nyquist,from -9 to -1.
+// gain - gain, in millibel, starting at -9600, jumps of 1024, to 4736 millibel.
+// bw - bandwidth, starting at 1 cent, jumps of 1024, to 3073 cents.
+// coef - 0: b0
+// 1: b1
+// 2: b2
+// 3: -a1
+// 4: -a2
+static const size_t kInDims[3] = {9, 15, 4};
+static const audio_coef_t kCoefTable[9*15*4*5] = {
+#include "AudioPeakingFilterCoef.inl"
+};
+
+AudioCoefInterpolator AudioPeakingFilter::mCoefInterp(3, kInDims, 5, (const audio_coef_t*) kCoefTable);
+
+AudioPeakingFilter::AudioPeakingFilter(int nChannels, int sampleRate)
+ : mBiquad(nChannels, sampleRate) {
+ configure(nChannels, sampleRate);
+ reset();
+}
+
+void AudioPeakingFilter::configure(int nChannels, int sampleRate) {
+ mNiquistFreq = sampleRate * 500;
+ mFrequencyFactor = ((1ull) << 42) / mNiquistFreq;
+ mBiquad.configure(nChannels, sampleRate);
+ setFrequency(mNominalFrequency);
+ commit(true);
+}
+
+void AudioPeakingFilter::reset() {
+ setGain(0);
+ setFrequency(0);
+ setBandwidth(2400);
+ commit(true);
+}
+
+void AudioPeakingFilter::setFrequency(uint32_t millihertz) {
+ mNominalFrequency = millihertz;
+ if (UNLIKELY(millihertz > mNiquistFreq / 2)) {
+ millihertz = mNiquistFreq / 2;
+ }
+ uint32_t normFreq = static_cast<uint32_t>(
+ (static_cast<uint64_t>(millihertz) * mFrequencyFactor) >> 10);
+ if (LIKELY(normFreq > (1 << 23))) {
+ mFrequency = (Effects_log2(normFreq) - ((32-9) << 15)) << (FREQ_PRECISION_BITS - 15);
+ } else {
+ mFrequency = 0;
+ }
+}
+
+void AudioPeakingFilter::setGain(int32_t millibel) {
+ mGain = millibel + 9600;
+}
+
+void AudioPeakingFilter::setBandwidth(uint32_t cents) {
+ mBandwidth = cents - 1;
+}
+
+void AudioPeakingFilter::commit(bool immediate) {
+ audio_coef_t coefs[5];
+ int intCoord[3] = {
+ mFrequency >> FREQ_PRECISION_BITS,
+ mGain >> GAIN_PRECISION_BITS,
+ mBandwidth >> BANDWIDTH_PRECISION_BITS
+ };
+ uint32_t fracCoord[3] = {
+ mFrequency << (32 - FREQ_PRECISION_BITS),
+ static_cast<uint32_t>(mGain) << (32 - GAIN_PRECISION_BITS),
+ mBandwidth << (32 - BANDWIDTH_PRECISION_BITS)
+ };
+ mCoefInterp.getCoef(intCoord, fracCoord, coefs);
+ mBiquad.setCoefs(coefs, immediate);
+}
+
+void AudioPeakingFilter::getBandRange(uint32_t & low, uint32_t & high) const {
+ // Half bandwidth, in octaves, 15-bit precision
+ int32_t halfBW = (((mBandwidth + 1) / 2) << 15) / 1200;
+
+ low = static_cast<uint32_t>((static_cast<uint64_t>(mNominalFrequency) * Effects_exp2(-halfBW + (16 << 15))) >> 16);
+ if (UNLIKELY(halfBW >= (16 << 15))) {
+ high = mNiquistFreq;
+ } else {
+ high = static_cast<uint32_t>((static_cast<uint64_t>(mNominalFrequency) * Effects_exp2(halfBW + (16 << 15))) >> 16);
+ if (UNLIKELY(high > mNiquistFreq)) {
+ high = mNiquistFreq;
+ }
+ }
+}
+
+}
+