xref: /aosp_15_r20/frameworks/av/media/libeffects/testlibs/AudioEqualizer.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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