1135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/*
2135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * Copyright 2009, The Android Open Source Project
3135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent *
4135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License");
5135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * you may not use this file except in compliance with the License.
6135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * You may obtain a copy of the License at
7135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent *
8135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent *     http://www.apache.org/licenses/LICENSE-2.0
9135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent *
10135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * Unless required by applicable law or agreed to in writing, software
11135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS,
12135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * See the License for the specific language governing permissions and
14135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * limitations under the License.
15135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent */
16135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
17135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#define LOG_TAG "AudioEqualizer"
18135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
19135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include <assert.h>
20135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include <stdlib.h>
21135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include <new>
22135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include <utils/Log.h>
23135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
24135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include "AudioEqualizer.h"
25135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include "AudioPeakingFilter.h"
26135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include "AudioShelvingFilter.h"
27135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include "EffectsMath.h"
28135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
29135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentnamespace android {
30135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
31135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentsize_t AudioEqualizer::GetInstanceSize(int nBands) {
32135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    assert(nBands >= 2);
33135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return sizeof(AudioEqualizer) +
34135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent           sizeof(AudioShelvingFilter) * 2 +
35135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent           sizeof(AudioPeakingFilter) * (nBands - 2);
36135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
37135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
38135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric LaurentAudioEqualizer * AudioEqualizer::CreateInstance(void * pMem, int nBands,
39135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                                                int nChannels, int sampleRate,
40135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                                                const PresetConfig * presets,
41135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                                                int nPresets) {
423856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioEqualizer::CreateInstance(pMem=%p, nBands=%d, nChannels=%d, "
43135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent         "sampleRate=%d, nPresets=%d)",
44135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent         pMem, nBands, nChannels, sampleRate, nPresets);
45135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    assert(nBands >= 2);
46135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    bool ownMem = false;
47135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (pMem == NULL) {
48135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pMem = malloc(GetInstanceSize(nBands));
49135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        if (pMem == NULL) {
50135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            return NULL;
51135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
52135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        ownMem = true;
53135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
54135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return new (pMem) AudioEqualizer(pMem, nBands, nChannels, sampleRate,
55135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                                     ownMem, presets, nPresets);
56135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
57135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
58135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentvoid AudioEqualizer::configure(int nChannels, int sampleRate) {
593856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioEqualizer::configure(nChannels=%d, sampleRate=%d)", nChannels,
60135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent         sampleRate);
61135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    mpLowShelf->configure(nChannels, sampleRate);
62135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    for (int i = 0; i < mNumPeaking; ++i) {
63135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        mpPeakingFilters[i].configure(nChannels, sampleRate);
64135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
65135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    mpHighShelf->configure(nChannels, sampleRate);
66135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
67135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
68135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentvoid AudioEqualizer::clear() {
693856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioEqualizer::clear()");
70135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    mpLowShelf->clear();
71135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    for (int i = 0; i < mNumPeaking; ++i) {
72135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        mpPeakingFilters[i].clear();
73135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
74135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    mpHighShelf->clear();
75135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
76135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
77135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentvoid AudioEqualizer::free() {
783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioEqualizer::free()");
79135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (mpMem != NULL) {
80135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        ::free(mpMem);
81135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
82135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
83135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
84135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentvoid AudioEqualizer::reset() {
853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioEqualizer::reset()");
86135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    const int32_t bottom = Effects_log2(kMinFreq);
87135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    const int32_t top = Effects_log2(mSampleRate * 500);
88135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    const int32_t jump = (top - bottom) / (mNumPeaking + 2);
89135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int32_t centerFreq = bottom + jump/2;
90135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
91135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    mpLowShelf->reset();
92135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    mpLowShelf->setFrequency(Effects_exp2(centerFreq));
93135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    centerFreq += jump;
94135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    for (int i = 0; i < mNumPeaking; ++i) {
95135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        mpPeakingFilters[i].reset();
96135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        mpPeakingFilters[i].setFrequency(Effects_exp2(centerFreq));
97135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        centerFreq += jump;
98135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
99135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    mpHighShelf->reset();
100135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    mpHighShelf->setFrequency(Effects_exp2(centerFreq));
101135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    commit(true);
102135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    mCurPreset = PRESET_CUSTOM;
103135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
104135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
105135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentvoid AudioEqualizer::setGain(int band, int32_t millibel) {
1063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioEqualizer::setGain(band=%d, millibel=%d)", band, millibel);
107135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    assert(band >= 0 && band < mNumPeaking + 2);
108135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (band == 0) {
109135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        mpLowShelf->setGain(millibel);
110135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    } else if (band == mNumPeaking + 1) {
111135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        mpHighShelf->setGain(millibel);
112135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    } else {
113135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        mpPeakingFilters[band - 1].setGain(millibel);
114135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
115135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    mCurPreset = PRESET_CUSTOM;
116135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
117135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
118135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentvoid AudioEqualizer::setFrequency(int band, uint32_t millihertz) {
1193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioEqualizer::setFrequency(band=%d, millihertz=%d)", band,
120135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent         millihertz);
121135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    assert(band >= 0 && band < mNumPeaking + 2);
122135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (band == 0) {
123135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        mpLowShelf->setFrequency(millihertz);
124135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    } else if (band == mNumPeaking + 1) {
125135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        mpHighShelf->setFrequency(millihertz);
126135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    } else {
127135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        mpPeakingFilters[band - 1].setFrequency(millihertz);
128135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
129135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    mCurPreset = PRESET_CUSTOM;
130135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
131135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
132135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentvoid AudioEqualizer::setBandwidth(int band, uint32_t cents) {
1333856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioEqualizer::setBandwidth(band=%d, cents=%d)", band, cents);
134135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    assert(band >= 0 && band < mNumPeaking + 2);
135135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (band > 0 && band < mNumPeaking + 1) {
136135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        mpPeakingFilters[band - 1].setBandwidth(cents);
137135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        mCurPreset = PRESET_CUSTOM;
138135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
139135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
140135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
141135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentint32_t AudioEqualizer::getGain(int band) const {
142135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    assert(band >= 0 && band < mNumPeaking + 2);
143135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (band == 0) {
144135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return mpLowShelf->getGain();
145135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    } else if (band == mNumPeaking + 1) {
146135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return mpHighShelf->getGain();
147135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    } else {
148135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return mpPeakingFilters[band - 1].getGain();
149135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
150135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
151135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
152135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentuint32_t AudioEqualizer::getFrequency(int band) const {
153135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    assert(band >= 0 && band < mNumPeaking + 2);
154135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (band == 0) {
155135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return mpLowShelf->getFrequency();
156135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    } else if (band == mNumPeaking + 1) {
157135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return mpHighShelf->getFrequency();
158135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    } else {
159135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return mpPeakingFilters[band - 1].getFrequency();
160135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
161135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
162135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
163135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentuint32_t AudioEqualizer::getBandwidth(int band) const {
164135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    assert(band >= 0 && band < mNumPeaking + 2);
165135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (band == 0 || band == mNumPeaking + 1) {
166135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return 0;
167135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    } else {
168135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return mpPeakingFilters[band - 1].getBandwidth();
169135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
170135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
171135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
172135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentvoid AudioEqualizer::getBandRange(int band, uint32_t & low,
173135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                                  uint32_t & high) const {
174135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    assert(band >= 0 && band < mNumPeaking + 2);
175135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (band == 0) {
176135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        low = 0;
177135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        high = mpLowShelf->getFrequency();
178135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    } else if (band == mNumPeaking + 1) {
179135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        low = mpHighShelf->getFrequency();
180135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        high = mSampleRate * 500;
181135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    } else {
182135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        mpPeakingFilters[band - 1].getBandRange(low, high);
183135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
184135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
185135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
186135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentconst char * AudioEqualizer::getPresetName(int preset) const {
187135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    assert(preset < mNumPresets && preset >= PRESET_CUSTOM);
188135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (preset == PRESET_CUSTOM) {
189135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return "Custom";
190135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    } else {
191135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return mpPresets[preset].name;
192135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
193135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
194135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
195135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentint AudioEqualizer::getNumPresets() const {
196135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return mNumPresets;
197135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
198135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
199135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentint AudioEqualizer::getPreset() const {
200135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return mCurPreset;
201135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
202135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
203135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentvoid AudioEqualizer::setPreset(int preset) {
2043856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioEqualizer::setPreset(preset=%d)", preset);
205135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    assert(preset < mNumPresets && preset >= 0);
206135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    const PresetConfig &presetCfg = mpPresets[preset];
207135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    for (int band = 0; band < (mNumPeaking + 2); ++band) {
208135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        const BandConfig & bandCfg = presetCfg.bandConfigs[band];
209135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        setGain(band, bandCfg.gain);
210135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        setFrequency(band, bandCfg.freq);
211135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        setBandwidth(band, bandCfg.bandwidth);
212135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
213135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    mCurPreset = preset;
214135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
215135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
216135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentvoid AudioEqualizer::commit(bool immediate) {
2173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioEqualizer::commit(immediate=%d)", immediate);
218135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    mpLowShelf->commit(immediate);
219135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    for (int i = 0; i < mNumPeaking; ++i) {
220135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        mpPeakingFilters[i].commit(immediate);
221135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
222135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    mpHighShelf->commit(immediate);
223135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
224135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
225135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentvoid AudioEqualizer::process(const audio_sample_t * pIn,
226135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                             audio_sample_t * pOut,
227135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                             int frameCount) {
2283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block//    ALOGV("AudioEqualizer::process(frameCount=%d)", frameCount);
229135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    mpLowShelf->process(pIn, pOut, frameCount);
230135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    for (int i = 0; i < mNumPeaking; ++i) {
231135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        mpPeakingFilters[i].process(pIn, pOut, frameCount);
232135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
233135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    mpHighShelf->process(pIn, pOut, frameCount);
234135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
235135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
236135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentvoid AudioEqualizer::enable(bool immediate) {
2373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioEqualizer::enable(immediate=%d)", immediate);
238135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    mpLowShelf->enable(immediate);
239135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    for (int i = 0; i < mNumPeaking; ++i) {
240135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        mpPeakingFilters[i].enable(immediate);
241135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
242135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    mpHighShelf->enable(immediate);
243135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
244135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
245135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentvoid AudioEqualizer::disable(bool immediate) {
2463856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioEqualizer::disable(immediate=%d)", immediate);
247135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    mpLowShelf->disable(immediate);
248135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    for (int i = 0; i < mNumPeaking; ++i) {
249135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        mpPeakingFilters[i].disable(immediate);
250135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
251135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    mpHighShelf->disable(immediate);
252135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
253135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
254135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentint AudioEqualizer::getMostRelevantBand(uint32_t targetFreq) const {
255135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // First, find the two bands that the target frequency is between.
256135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    uint32_t low = mpLowShelf->getFrequency();
257135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (targetFreq <= low) {
258135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return 0;
259135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
260135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    uint32_t high = mpHighShelf->getFrequency();
261135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (targetFreq >= high) {
262135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return mNumPeaking + 1;
263135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
264135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int band = mNumPeaking;
265135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    for (int i = 0; i < mNumPeaking; ++i) {
266135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        uint32_t freq = mpPeakingFilters[i].getFrequency();
267135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        if (freq >= targetFreq) {
268135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            high = freq;
269135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            band = i;
270135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            break;
271135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
272135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        low = freq;
273135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
274135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // Now, low is right below the target and high is right above. See which one
275135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // is closer on a log scale.
276135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    low = Effects_log2(low);
277135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    high = Effects_log2(high);
278135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    targetFreq = Effects_log2(targetFreq);
279135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (high - targetFreq < targetFreq - low) {
280135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return band + 1;
281135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    } else {
282135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return band;
283135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
284135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
285135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
286135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
287135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric LaurentAudioEqualizer::AudioEqualizer(void * pMem, int nBands, int nChannels,
288135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                               int sampleRate, bool ownMem,
289135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                               const PresetConfig * presets, int nPresets)
290135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                               : mSampleRate(sampleRate)
291135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                               , mpPresets(presets)
292135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                               , mNumPresets(nPresets) {
293135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    assert(pMem != NULL);
294135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    assert(nPresets == 0 || nPresets > 0 && presets != NULL);
295135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    mpMem = ownMem ? pMem : NULL;
296135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
297135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pMem = (char *) pMem + sizeof(AudioEqualizer);
298135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    mpLowShelf = new (pMem) AudioShelvingFilter(AudioShelvingFilter::kLowShelf,
299135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                                                nChannels, sampleRate);
300135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pMem = (char *) pMem + sizeof(AudioShelvingFilter);
301135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    mpHighShelf = new (pMem) AudioShelvingFilter(AudioShelvingFilter::kHighShelf,
302135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                                                 nChannels, sampleRate);
303135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pMem = (char *) pMem + sizeof(AudioShelvingFilter);
304135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    mNumPeaking = nBands - 2;
305135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (mNumPeaking > 0) {
306135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        mpPeakingFilters = reinterpret_cast<AudioPeakingFilter *>(pMem);
307135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        for (int i = 0; i < mNumPeaking; ++i) {
308135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            new (&mpPeakingFilters[i]) AudioPeakingFilter(nChannels,
309135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                                                          sampleRate);
310135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
311135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
312135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    reset();
313135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
314135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
315135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
316