1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker * Copyright 2009, The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker *
4*ec779b8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker *
8*ec779b8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker *
10*ec779b8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker */
16*ec779b8eSAndroid Build Coastguard Worker
17*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "AudioEqualizer"
18*ec779b8eSAndroid Build Coastguard Worker
19*ec779b8eSAndroid Build Coastguard Worker #include <assert.h>
20*ec779b8eSAndroid Build Coastguard Worker #include <stdlib.h>
21*ec779b8eSAndroid Build Coastguard Worker #include <new>
22*ec779b8eSAndroid Build Coastguard Worker #include <log/log.h>
23*ec779b8eSAndroid Build Coastguard Worker
24*ec779b8eSAndroid Build Coastguard Worker #include "AudioEqualizer.h"
25*ec779b8eSAndroid Build Coastguard Worker #include "AudioPeakingFilter.h"
26*ec779b8eSAndroid Build Coastguard Worker #include "AudioShelvingFilter.h"
27*ec779b8eSAndroid Build Coastguard Worker #include "EffectsMath.h"
28*ec779b8eSAndroid Build Coastguard Worker
29*ec779b8eSAndroid Build Coastguard Worker namespace android {
30*ec779b8eSAndroid Build Coastguard Worker
GetInstanceSize(int nBands)31*ec779b8eSAndroid Build Coastguard Worker size_t AudioEqualizer::GetInstanceSize(int nBands) {
32*ec779b8eSAndroid Build Coastguard Worker assert(nBands >= 2);
33*ec779b8eSAndroid Build Coastguard Worker return sizeof(AudioEqualizer) +
34*ec779b8eSAndroid Build Coastguard Worker sizeof(AudioShelvingFilter) * 2 +
35*ec779b8eSAndroid Build Coastguard Worker sizeof(AudioPeakingFilter) * (nBands - 2);
36*ec779b8eSAndroid Build Coastguard Worker }
37*ec779b8eSAndroid Build Coastguard Worker
CreateInstance(void * pMem,int nBands,int nChannels,int sampleRate,const PresetConfig * presets,int nPresets)38*ec779b8eSAndroid Build Coastguard Worker AudioEqualizer * AudioEqualizer::CreateInstance(void * pMem, int nBands,
39*ec779b8eSAndroid Build Coastguard Worker int nChannels, int sampleRate,
40*ec779b8eSAndroid Build Coastguard Worker const PresetConfig * presets,
41*ec779b8eSAndroid Build Coastguard Worker int nPresets) {
42*ec779b8eSAndroid Build Coastguard Worker ALOGV("AudioEqualizer::CreateInstance(pMem=%p, nBands=%d, nChannels=%d, "
43*ec779b8eSAndroid Build Coastguard Worker "sampleRate=%d, nPresets=%d)",
44*ec779b8eSAndroid Build Coastguard Worker pMem, nBands, nChannels, sampleRate, nPresets);
45*ec779b8eSAndroid Build Coastguard Worker assert(nBands >= 2);
46*ec779b8eSAndroid Build Coastguard Worker bool ownMem = false;
47*ec779b8eSAndroid Build Coastguard Worker if (pMem == NULL) {
48*ec779b8eSAndroid Build Coastguard Worker pMem = malloc(GetInstanceSize(nBands));
49*ec779b8eSAndroid Build Coastguard Worker if (pMem == NULL) {
50*ec779b8eSAndroid Build Coastguard Worker return NULL;
51*ec779b8eSAndroid Build Coastguard Worker }
52*ec779b8eSAndroid Build Coastguard Worker ownMem = true;
53*ec779b8eSAndroid Build Coastguard Worker }
54*ec779b8eSAndroid Build Coastguard Worker return new (pMem) AudioEqualizer(pMem, nBands, nChannels, sampleRate,
55*ec779b8eSAndroid Build Coastguard Worker ownMem, presets, nPresets);
56*ec779b8eSAndroid Build Coastguard Worker }
57*ec779b8eSAndroid Build Coastguard Worker
configure(int nChannels,int sampleRate)58*ec779b8eSAndroid Build Coastguard Worker void AudioEqualizer::configure(int nChannels, int sampleRate) {
59*ec779b8eSAndroid Build Coastguard Worker ALOGV("AudioEqualizer::configure(nChannels=%d, sampleRate=%d)", nChannels,
60*ec779b8eSAndroid Build Coastguard Worker sampleRate);
61*ec779b8eSAndroid Build Coastguard Worker mpLowShelf->configure(nChannels, sampleRate);
62*ec779b8eSAndroid Build Coastguard Worker for (int i = 0; i < mNumPeaking; ++i) {
63*ec779b8eSAndroid Build Coastguard Worker mpPeakingFilters[i].configure(nChannels, sampleRate);
64*ec779b8eSAndroid Build Coastguard Worker }
65*ec779b8eSAndroid Build Coastguard Worker mpHighShelf->configure(nChannels, sampleRate);
66*ec779b8eSAndroid Build Coastguard Worker }
67*ec779b8eSAndroid Build Coastguard Worker
clear()68*ec779b8eSAndroid Build Coastguard Worker void AudioEqualizer::clear() {
69*ec779b8eSAndroid Build Coastguard Worker ALOGV("AudioEqualizer::clear()");
70*ec779b8eSAndroid Build Coastguard Worker mpLowShelf->clear();
71*ec779b8eSAndroid Build Coastguard Worker for (int i = 0; i < mNumPeaking; ++i) {
72*ec779b8eSAndroid Build Coastguard Worker mpPeakingFilters[i].clear();
73*ec779b8eSAndroid Build Coastguard Worker }
74*ec779b8eSAndroid Build Coastguard Worker mpHighShelf->clear();
75*ec779b8eSAndroid Build Coastguard Worker }
76*ec779b8eSAndroid Build Coastguard Worker
free()77*ec779b8eSAndroid Build Coastguard Worker void AudioEqualizer::free() {
78*ec779b8eSAndroid Build Coastguard Worker ALOGV("AudioEqualizer::free()");
79*ec779b8eSAndroid Build Coastguard Worker if (mpMem != NULL) {
80*ec779b8eSAndroid Build Coastguard Worker ::free(mpMem);
81*ec779b8eSAndroid Build Coastguard Worker }
82*ec779b8eSAndroid Build Coastguard Worker }
83*ec779b8eSAndroid Build Coastguard Worker
reset()84*ec779b8eSAndroid Build Coastguard Worker void AudioEqualizer::reset() {
85*ec779b8eSAndroid Build Coastguard Worker ALOGV("AudioEqualizer::reset()");
86*ec779b8eSAndroid Build Coastguard Worker const int32_t bottom = Effects_log2(kMinFreq);
87*ec779b8eSAndroid Build Coastguard Worker const int32_t top = Effects_log2(mSampleRate * 500);
88*ec779b8eSAndroid Build Coastguard Worker const int32_t jump = (top - bottom) / (mNumPeaking + 2);
89*ec779b8eSAndroid Build Coastguard Worker int32_t centerFreq = bottom + jump/2;
90*ec779b8eSAndroid Build Coastguard Worker
91*ec779b8eSAndroid Build Coastguard Worker mpLowShelf->reset();
92*ec779b8eSAndroid Build Coastguard Worker mpLowShelf->setFrequency(Effects_exp2(centerFreq));
93*ec779b8eSAndroid Build Coastguard Worker centerFreq += jump;
94*ec779b8eSAndroid Build Coastguard Worker for (int i = 0; i < mNumPeaking; ++i) {
95*ec779b8eSAndroid Build Coastguard Worker mpPeakingFilters[i].reset();
96*ec779b8eSAndroid Build Coastguard Worker mpPeakingFilters[i].setFrequency(Effects_exp2(centerFreq));
97*ec779b8eSAndroid Build Coastguard Worker centerFreq += jump;
98*ec779b8eSAndroid Build Coastguard Worker }
99*ec779b8eSAndroid Build Coastguard Worker mpHighShelf->reset();
100*ec779b8eSAndroid Build Coastguard Worker mpHighShelf->setFrequency(Effects_exp2(centerFreq));
101*ec779b8eSAndroid Build Coastguard Worker commit(true);
102*ec779b8eSAndroid Build Coastguard Worker mCurPreset = PRESET_CUSTOM;
103*ec779b8eSAndroid Build Coastguard Worker }
104*ec779b8eSAndroid Build Coastguard Worker
setGain(int band,int32_t millibel)105*ec779b8eSAndroid Build Coastguard Worker void AudioEqualizer::setGain(int band, int32_t millibel) {
106*ec779b8eSAndroid Build Coastguard Worker ALOGV("AudioEqualizer::setGain(band=%d, millibel=%d)", band, millibel);
107*ec779b8eSAndroid Build Coastguard Worker assert(band >= 0 && band < mNumPeaking + 2);
108*ec779b8eSAndroid Build Coastguard Worker if (band == 0) {
109*ec779b8eSAndroid Build Coastguard Worker mpLowShelf->setGain(millibel);
110*ec779b8eSAndroid Build Coastguard Worker } else if (band == mNumPeaking + 1) {
111*ec779b8eSAndroid Build Coastguard Worker mpHighShelf->setGain(millibel);
112*ec779b8eSAndroid Build Coastguard Worker } else {
113*ec779b8eSAndroid Build Coastguard Worker mpPeakingFilters[band - 1].setGain(millibel);
114*ec779b8eSAndroid Build Coastguard Worker }
115*ec779b8eSAndroid Build Coastguard Worker mCurPreset = PRESET_CUSTOM;
116*ec779b8eSAndroid Build Coastguard Worker }
117*ec779b8eSAndroid Build Coastguard Worker
setFrequency(int band,uint32_t millihertz)118*ec779b8eSAndroid Build Coastguard Worker void AudioEqualizer::setFrequency(int band, uint32_t millihertz) {
119*ec779b8eSAndroid Build Coastguard Worker ALOGV("AudioEqualizer::setFrequency(band=%d, millihertz=%d)", band,
120*ec779b8eSAndroid Build Coastguard Worker millihertz);
121*ec779b8eSAndroid Build Coastguard Worker assert(band >= 0 && band < mNumPeaking + 2);
122*ec779b8eSAndroid Build Coastguard Worker if (band == 0) {
123*ec779b8eSAndroid Build Coastguard Worker mpLowShelf->setFrequency(millihertz);
124*ec779b8eSAndroid Build Coastguard Worker } else if (band == mNumPeaking + 1) {
125*ec779b8eSAndroid Build Coastguard Worker mpHighShelf->setFrequency(millihertz);
126*ec779b8eSAndroid Build Coastguard Worker } else {
127*ec779b8eSAndroid Build Coastguard Worker mpPeakingFilters[band - 1].setFrequency(millihertz);
128*ec779b8eSAndroid Build Coastguard Worker }
129*ec779b8eSAndroid Build Coastguard Worker mCurPreset = PRESET_CUSTOM;
130*ec779b8eSAndroid Build Coastguard Worker }
131*ec779b8eSAndroid Build Coastguard Worker
setBandwidth(int band,uint32_t cents)132*ec779b8eSAndroid Build Coastguard Worker void AudioEqualizer::setBandwidth(int band, uint32_t cents) {
133*ec779b8eSAndroid Build Coastguard Worker ALOGV("AudioEqualizer::setBandwidth(band=%d, cents=%d)", band, cents);
134*ec779b8eSAndroid Build Coastguard Worker assert(band >= 0 && band < mNumPeaking + 2);
135*ec779b8eSAndroid Build Coastguard Worker if (band > 0 && band < mNumPeaking + 1) {
136*ec779b8eSAndroid Build Coastguard Worker mpPeakingFilters[band - 1].setBandwidth(cents);
137*ec779b8eSAndroid Build Coastguard Worker mCurPreset = PRESET_CUSTOM;
138*ec779b8eSAndroid Build Coastguard Worker }
139*ec779b8eSAndroid Build Coastguard Worker }
140*ec779b8eSAndroid Build Coastguard Worker
getGain(int band) const141*ec779b8eSAndroid Build Coastguard Worker int32_t AudioEqualizer::getGain(int band) const {
142*ec779b8eSAndroid Build Coastguard Worker assert(band >= 0 && band < mNumPeaking + 2);
143*ec779b8eSAndroid Build Coastguard Worker if (band == 0) {
144*ec779b8eSAndroid Build Coastguard Worker return mpLowShelf->getGain();
145*ec779b8eSAndroid Build Coastguard Worker } else if (band == mNumPeaking + 1) {
146*ec779b8eSAndroid Build Coastguard Worker return mpHighShelf->getGain();
147*ec779b8eSAndroid Build Coastguard Worker } else {
148*ec779b8eSAndroid Build Coastguard Worker return mpPeakingFilters[band - 1].getGain();
149*ec779b8eSAndroid Build Coastguard Worker }
150*ec779b8eSAndroid Build Coastguard Worker }
151*ec779b8eSAndroid Build Coastguard Worker
getFrequency(int band) const152*ec779b8eSAndroid Build Coastguard Worker uint32_t AudioEqualizer::getFrequency(int band) const {
153*ec779b8eSAndroid Build Coastguard Worker assert(band >= 0 && band < mNumPeaking + 2);
154*ec779b8eSAndroid Build Coastguard Worker if (band == 0) {
155*ec779b8eSAndroid Build Coastguard Worker return mpLowShelf->getFrequency();
156*ec779b8eSAndroid Build Coastguard Worker } else if (band == mNumPeaking + 1) {
157*ec779b8eSAndroid Build Coastguard Worker return mpHighShelf->getFrequency();
158*ec779b8eSAndroid Build Coastguard Worker } else {
159*ec779b8eSAndroid Build Coastguard Worker return mpPeakingFilters[band - 1].getFrequency();
160*ec779b8eSAndroid Build Coastguard Worker }
161*ec779b8eSAndroid Build Coastguard Worker }
162*ec779b8eSAndroid Build Coastguard Worker
getBandwidth(int band) const163*ec779b8eSAndroid Build Coastguard Worker uint32_t AudioEqualizer::getBandwidth(int band) const {
164*ec779b8eSAndroid Build Coastguard Worker assert(band >= 0 && band < mNumPeaking + 2);
165*ec779b8eSAndroid Build Coastguard Worker if (band == 0 || band == mNumPeaking + 1) {
166*ec779b8eSAndroid Build Coastguard Worker return 0;
167*ec779b8eSAndroid Build Coastguard Worker } else {
168*ec779b8eSAndroid Build Coastguard Worker return mpPeakingFilters[band - 1].getBandwidth();
169*ec779b8eSAndroid Build Coastguard Worker }
170*ec779b8eSAndroid Build Coastguard Worker }
171*ec779b8eSAndroid Build Coastguard Worker
getBandRange(int band,uint32_t & low,uint32_t & high) const172*ec779b8eSAndroid Build Coastguard Worker void AudioEqualizer::getBandRange(int band, uint32_t & low,
173*ec779b8eSAndroid Build Coastguard Worker uint32_t & high) const {
174*ec779b8eSAndroid Build Coastguard Worker assert(band >= 0 && band < mNumPeaking + 2);
175*ec779b8eSAndroid Build Coastguard Worker if (band == 0) {
176*ec779b8eSAndroid Build Coastguard Worker low = 0;
177*ec779b8eSAndroid Build Coastguard Worker high = mpLowShelf->getFrequency();
178*ec779b8eSAndroid Build Coastguard Worker } else if (band == mNumPeaking + 1) {
179*ec779b8eSAndroid Build Coastguard Worker low = mpHighShelf->getFrequency();
180*ec779b8eSAndroid Build Coastguard Worker high = mSampleRate * 500;
181*ec779b8eSAndroid Build Coastguard Worker } else {
182*ec779b8eSAndroid Build Coastguard Worker mpPeakingFilters[band - 1].getBandRange(low, high);
183*ec779b8eSAndroid Build Coastguard Worker }
184*ec779b8eSAndroid Build Coastguard Worker }
185*ec779b8eSAndroid Build Coastguard Worker
getPresetName(int preset) const186*ec779b8eSAndroid Build Coastguard Worker const char * AudioEqualizer::getPresetName(int preset) const {
187*ec779b8eSAndroid Build Coastguard Worker assert(preset < mNumPresets && preset >= PRESET_CUSTOM);
188*ec779b8eSAndroid Build Coastguard Worker if (preset == PRESET_CUSTOM) {
189*ec779b8eSAndroid Build Coastguard Worker return "Custom";
190*ec779b8eSAndroid Build Coastguard Worker } else {
191*ec779b8eSAndroid Build Coastguard Worker return mpPresets[preset].name;
192*ec779b8eSAndroid Build Coastguard Worker }
193*ec779b8eSAndroid Build Coastguard Worker }
194*ec779b8eSAndroid Build Coastguard Worker
getNumPresets() const195*ec779b8eSAndroid Build Coastguard Worker int AudioEqualizer::getNumPresets() const {
196*ec779b8eSAndroid Build Coastguard Worker return mNumPresets;
197*ec779b8eSAndroid Build Coastguard Worker }
198*ec779b8eSAndroid Build Coastguard Worker
getPreset() const199*ec779b8eSAndroid Build Coastguard Worker int AudioEqualizer::getPreset() const {
200*ec779b8eSAndroid Build Coastguard Worker return mCurPreset;
201*ec779b8eSAndroid Build Coastguard Worker }
202*ec779b8eSAndroid Build Coastguard Worker
setPreset(int preset)203*ec779b8eSAndroid Build Coastguard Worker void AudioEqualizer::setPreset(int preset) {
204*ec779b8eSAndroid Build Coastguard Worker ALOGV("AudioEqualizer::setPreset(preset=%d)", preset);
205*ec779b8eSAndroid Build Coastguard Worker assert(preset < mNumPresets && preset >= 0);
206*ec779b8eSAndroid Build Coastguard Worker const PresetConfig &presetCfg = mpPresets[preset];
207*ec779b8eSAndroid Build Coastguard Worker for (int band = 0; band < (mNumPeaking + 2); ++band) {
208*ec779b8eSAndroid Build Coastguard Worker const BandConfig & bandCfg = presetCfg.bandConfigs[band];
209*ec779b8eSAndroid Build Coastguard Worker setGain(band, bandCfg.gain);
210*ec779b8eSAndroid Build Coastguard Worker setFrequency(band, bandCfg.freq);
211*ec779b8eSAndroid Build Coastguard Worker setBandwidth(band, bandCfg.bandwidth);
212*ec779b8eSAndroid Build Coastguard Worker }
213*ec779b8eSAndroid Build Coastguard Worker mCurPreset = preset;
214*ec779b8eSAndroid Build Coastguard Worker }
215*ec779b8eSAndroid Build Coastguard Worker
commit(bool immediate)216*ec779b8eSAndroid Build Coastguard Worker void AudioEqualizer::commit(bool immediate) {
217*ec779b8eSAndroid Build Coastguard Worker ALOGV("AudioEqualizer::commit(immediate=%d)", immediate);
218*ec779b8eSAndroid Build Coastguard Worker mpLowShelf->commit(immediate);
219*ec779b8eSAndroid Build Coastguard Worker for (int i = 0; i < mNumPeaking; ++i) {
220*ec779b8eSAndroid Build Coastguard Worker mpPeakingFilters[i].commit(immediate);
221*ec779b8eSAndroid Build Coastguard Worker }
222*ec779b8eSAndroid Build Coastguard Worker mpHighShelf->commit(immediate);
223*ec779b8eSAndroid Build Coastguard Worker }
224*ec779b8eSAndroid Build Coastguard Worker
process(const audio_sample_t * pIn,audio_sample_t * pOut,int frameCount)225*ec779b8eSAndroid Build Coastguard Worker void AudioEqualizer::process(const audio_sample_t * pIn,
226*ec779b8eSAndroid Build Coastguard Worker audio_sample_t * pOut,
227*ec779b8eSAndroid Build Coastguard Worker int frameCount) {
228*ec779b8eSAndroid Build Coastguard Worker // ALOGV("AudioEqualizer::process(frameCount=%d)", frameCount);
229*ec779b8eSAndroid Build Coastguard Worker mpLowShelf->process(pIn, pOut, frameCount);
230*ec779b8eSAndroid Build Coastguard Worker for (int i = 0; i < mNumPeaking; ++i) {
231*ec779b8eSAndroid Build Coastguard Worker mpPeakingFilters[i].process(pIn, pOut, frameCount);
232*ec779b8eSAndroid Build Coastguard Worker }
233*ec779b8eSAndroid Build Coastguard Worker mpHighShelf->process(pIn, pOut, frameCount);
234*ec779b8eSAndroid Build Coastguard Worker }
235*ec779b8eSAndroid Build Coastguard Worker
enable(bool immediate)236*ec779b8eSAndroid Build Coastguard Worker void AudioEqualizer::enable(bool immediate) {
237*ec779b8eSAndroid Build Coastguard Worker ALOGV("AudioEqualizer::enable(immediate=%d)", immediate);
238*ec779b8eSAndroid Build Coastguard Worker mpLowShelf->enable(immediate);
239*ec779b8eSAndroid Build Coastguard Worker for (int i = 0; i < mNumPeaking; ++i) {
240*ec779b8eSAndroid Build Coastguard Worker mpPeakingFilters[i].enable(immediate);
241*ec779b8eSAndroid Build Coastguard Worker }
242*ec779b8eSAndroid Build Coastguard Worker mpHighShelf->enable(immediate);
243*ec779b8eSAndroid Build Coastguard Worker }
244*ec779b8eSAndroid Build Coastguard Worker
disable(bool immediate)245*ec779b8eSAndroid Build Coastguard Worker void AudioEqualizer::disable(bool immediate) {
246*ec779b8eSAndroid Build Coastguard Worker ALOGV("AudioEqualizer::disable(immediate=%d)", immediate);
247*ec779b8eSAndroid Build Coastguard Worker mpLowShelf->disable(immediate);
248*ec779b8eSAndroid Build Coastguard Worker for (int i = 0; i < mNumPeaking; ++i) {
249*ec779b8eSAndroid Build Coastguard Worker mpPeakingFilters[i].disable(immediate);
250*ec779b8eSAndroid Build Coastguard Worker }
251*ec779b8eSAndroid Build Coastguard Worker mpHighShelf->disable(immediate);
252*ec779b8eSAndroid Build Coastguard Worker }
253*ec779b8eSAndroid Build Coastguard Worker
getMostRelevantBand(uint32_t targetFreq) const254*ec779b8eSAndroid Build Coastguard Worker int AudioEqualizer::getMostRelevantBand(uint32_t targetFreq) const {
255*ec779b8eSAndroid Build Coastguard Worker // First, find the two bands that the target frequency is between.
256*ec779b8eSAndroid Build Coastguard Worker uint32_t low = mpLowShelf->getFrequency();
257*ec779b8eSAndroid Build Coastguard Worker if (targetFreq <= low) {
258*ec779b8eSAndroid Build Coastguard Worker return 0;
259*ec779b8eSAndroid Build Coastguard Worker }
260*ec779b8eSAndroid Build Coastguard Worker uint32_t high = mpHighShelf->getFrequency();
261*ec779b8eSAndroid Build Coastguard Worker if (targetFreq >= high) {
262*ec779b8eSAndroid Build Coastguard Worker return mNumPeaking + 1;
263*ec779b8eSAndroid Build Coastguard Worker }
264*ec779b8eSAndroid Build Coastguard Worker int band = mNumPeaking;
265*ec779b8eSAndroid Build Coastguard Worker for (int i = 0; i < mNumPeaking; ++i) {
266*ec779b8eSAndroid Build Coastguard Worker uint32_t freq = mpPeakingFilters[i].getFrequency();
267*ec779b8eSAndroid Build Coastguard Worker if (freq >= targetFreq) {
268*ec779b8eSAndroid Build Coastguard Worker high = freq;
269*ec779b8eSAndroid Build Coastguard Worker band = i;
270*ec779b8eSAndroid Build Coastguard Worker break;
271*ec779b8eSAndroid Build Coastguard Worker }
272*ec779b8eSAndroid Build Coastguard Worker low = freq;
273*ec779b8eSAndroid Build Coastguard Worker }
274*ec779b8eSAndroid Build Coastguard Worker // Now, low is right below the target and high is right above. See which one
275*ec779b8eSAndroid Build Coastguard Worker // is closer on a log scale.
276*ec779b8eSAndroid Build Coastguard Worker low = Effects_log2(low);
277*ec779b8eSAndroid Build Coastguard Worker high = Effects_log2(high);
278*ec779b8eSAndroid Build Coastguard Worker targetFreq = Effects_log2(targetFreq);
279*ec779b8eSAndroid Build Coastguard Worker if (high - targetFreq < targetFreq - low) {
280*ec779b8eSAndroid Build Coastguard Worker return band + 1;
281*ec779b8eSAndroid Build Coastguard Worker } else {
282*ec779b8eSAndroid Build Coastguard Worker return band;
283*ec779b8eSAndroid Build Coastguard Worker }
284*ec779b8eSAndroid Build Coastguard Worker }
285*ec779b8eSAndroid Build Coastguard Worker
286*ec779b8eSAndroid Build Coastguard Worker
AudioEqualizer(void * pMem,int nBands,int nChannels,int sampleRate,bool ownMem,const PresetConfig * presets,int nPresets)287*ec779b8eSAndroid Build Coastguard Worker AudioEqualizer::AudioEqualizer(void * pMem, int nBands, int nChannels,
288*ec779b8eSAndroid Build Coastguard Worker int sampleRate, bool ownMem,
289*ec779b8eSAndroid Build Coastguard Worker const PresetConfig * presets, int nPresets)
290*ec779b8eSAndroid Build Coastguard Worker : mSampleRate(sampleRate)
291*ec779b8eSAndroid Build Coastguard Worker , mpPresets(presets)
292*ec779b8eSAndroid Build Coastguard Worker , mNumPresets(nPresets) {
293*ec779b8eSAndroid Build Coastguard Worker assert(pMem != NULL);
294*ec779b8eSAndroid Build Coastguard Worker assert(nPresets == 0 || nPresets > 0 && presets != NULL);
295*ec779b8eSAndroid Build Coastguard Worker mpMem = ownMem ? pMem : NULL;
296*ec779b8eSAndroid Build Coastguard Worker
297*ec779b8eSAndroid Build Coastguard Worker pMem = (char *) pMem + sizeof(AudioEqualizer);
298*ec779b8eSAndroid Build Coastguard Worker mpLowShelf = new (pMem) AudioShelvingFilter(AudioShelvingFilter::kLowShelf,
299*ec779b8eSAndroid Build Coastguard Worker nChannels, sampleRate);
300*ec779b8eSAndroid Build Coastguard Worker pMem = (char *) pMem + sizeof(AudioShelvingFilter);
301*ec779b8eSAndroid Build Coastguard Worker mpHighShelf = new (pMem) AudioShelvingFilter(AudioShelvingFilter::kHighShelf,
302*ec779b8eSAndroid Build Coastguard Worker nChannels, sampleRate);
303*ec779b8eSAndroid Build Coastguard Worker pMem = (char *) pMem + sizeof(AudioShelvingFilter);
304*ec779b8eSAndroid Build Coastguard Worker mNumPeaking = nBands - 2;
305*ec779b8eSAndroid Build Coastguard Worker if (mNumPeaking > 0) {
306*ec779b8eSAndroid Build Coastguard Worker mpPeakingFilters = reinterpret_cast<AudioPeakingFilter *>(pMem);
307*ec779b8eSAndroid Build Coastguard Worker for (int i = 0; i < mNumPeaking; ++i) {
308*ec779b8eSAndroid Build Coastguard Worker new (&mpPeakingFilters[i]) AudioPeakingFilter(nChannels,
309*ec779b8eSAndroid Build Coastguard Worker sampleRate);
310*ec779b8eSAndroid Build Coastguard Worker }
311*ec779b8eSAndroid Build Coastguard Worker }
312*ec779b8eSAndroid Build Coastguard Worker reset();
313*ec779b8eSAndroid Build Coastguard Worker }
314*ec779b8eSAndroid Build Coastguard Worker
315*ec779b8eSAndroid Build Coastguard Worker }
316