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