diff --git a/media/libeffects/AudioEqualizer.cpp b/media/libeffects/AudioEqualizer.cpp
new file mode 100644
index 0000000..44c9476
--- /dev/null
+++ b/media/libeffects/AudioEqualizer.cpp
@@ -0,0 +1,315 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AudioEqualizer"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <new>
+#include <utils/Log.h>
+
+#include "AudioEqualizer.h"
+#include "AudioPeakingFilter.h"
+#include "AudioShelvingFilter.h"
+#include "EffectsMath.h"
+
+namespace android {
+
+size_t AudioEqualizer::GetInstanceSize(int nBands) {
+    assert(nBands >= 2);
+    return sizeof(AudioEqualizer) +
+           sizeof(AudioShelvingFilter) * 2 +
+           sizeof(AudioPeakingFilter) * (nBands - 2);
+}
+
+AudioEqualizer * AudioEqualizer::CreateInstance(void * pMem, int nBands,
+                                                int nChannels, int sampleRate,
+                                                const PresetConfig * presets,
+                                                int nPresets) {
+    LOGV("AudioEqualizer::CreateInstance(pMem=%p, nBands=%d, nChannels=%d, "
+         "sampleRate=%d, nPresets=%d)",
+         pMem, nBands, nChannels, sampleRate, nPresets);
+    assert(nBands >= 2);
+    bool ownMem = false;
+    if (pMem == NULL) {
+        pMem = malloc(GetInstanceSize(nBands));
+        if (pMem == NULL) {
+            return NULL;
+        }
+        ownMem = true;
+    }
+    return new (pMem) AudioEqualizer(pMem, nBands, nChannels, sampleRate,
+                                     ownMem, presets, nPresets);
+}
+
+void AudioEqualizer::configure(int nChannels, int sampleRate) {
+    LOGV("AudioEqualizer::configure(nChannels=%d, sampleRate=%d)", nChannels,
+         sampleRate);
+    mpLowShelf->configure(nChannels, sampleRate);
+    for (int i = 0; i < mNumPeaking; ++i) {
+        mpPeakingFilters[i].configure(nChannels, sampleRate);
+    }
+    mpHighShelf->configure(nChannels, sampleRate);
+}
+
+void AudioEqualizer::clear() {
+    LOGV("AudioEqualizer::clear()");
+    mpLowShelf->clear();
+    for (int i = 0; i < mNumPeaking; ++i) {
+        mpPeakingFilters[i].clear();
+    }
+    mpHighShelf->clear();
+}
+
+void AudioEqualizer::free() {
+    LOGV("AudioEqualizer::free()");
+    if (mpMem != NULL) {
+        ::free(mpMem);
+    }
+}
+
+void AudioEqualizer::reset() {
+    LOGV("AudioEqualizer::reset()");
+    const int32_t bottom = Effects_log2(kMinFreq);
+    const int32_t top = Effects_log2(mSampleRate * 500);
+    const int32_t jump = (top - bottom) / (mNumPeaking + 2);
+    int32_t centerFreq = bottom + jump/2;
+
+    mpLowShelf->reset();
+    mpLowShelf->setFrequency(Effects_exp2(centerFreq));
+    centerFreq += jump;
+    for (int i = 0; i < mNumPeaking; ++i) {
+        mpPeakingFilters[i].reset();
+        mpPeakingFilters[i].setFrequency(Effects_exp2(centerFreq));
+        centerFreq += jump;
+    }
+    mpHighShelf->reset();
+    mpHighShelf->setFrequency(Effects_exp2(centerFreq));
+    commit(true);
+    mCurPreset = PRESET_CUSTOM;
+}
+
+void AudioEqualizer::setGain(int band, int32_t millibel) {
+    LOGV("AudioEqualizer::setGain(band=%d, millibel=%d)", band, millibel);
+    assert(band >= 0 && band < mNumPeaking + 2);
+    if (band == 0) {
+        mpLowShelf->setGain(millibel);
+    } else if (band == mNumPeaking + 1) {
+        mpHighShelf->setGain(millibel);
+    } else {
+        mpPeakingFilters[band - 1].setGain(millibel);
+    }
+    mCurPreset = PRESET_CUSTOM;
+}
+
+void AudioEqualizer::setFrequency(int band, uint32_t millihertz) {
+    LOGV("AudioEqualizer::setFrequency(band=%d, millihertz=%d)", band,
+         millihertz);
+    assert(band >= 0 && band < mNumPeaking + 2);
+    if (band == 0) {
+        mpLowShelf->setFrequency(millihertz);
+    } else if (band == mNumPeaking + 1) {
+        mpHighShelf->setFrequency(millihertz);
+    } else {
+        mpPeakingFilters[band - 1].setFrequency(millihertz);
+    }
+    mCurPreset = PRESET_CUSTOM;
+}
+
+void AudioEqualizer::setBandwidth(int band, uint32_t cents) {
+    LOGV("AudioEqualizer::setBandwidth(band=%d, cents=%d)", band, cents);
+    assert(band >= 0 && band < mNumPeaking + 2);
+    if (band > 0 && band < mNumPeaking + 1) {
+        mpPeakingFilters[band - 1].setBandwidth(cents);
+        mCurPreset = PRESET_CUSTOM;
+    }
+}
+
+int32_t AudioEqualizer::getGain(int band) const {
+    assert(band >= 0 && band < mNumPeaking + 2);
+    if (band == 0) {
+        return mpLowShelf->getGain();
+    } else if (band == mNumPeaking + 1) {
+        return mpHighShelf->getGain();
+    } else {
+        return mpPeakingFilters[band - 1].getGain();
+    }
+}
+
+uint32_t AudioEqualizer::getFrequency(int band) const {
+    assert(band >= 0 && band < mNumPeaking + 2);
+    if (band == 0) {
+        return mpLowShelf->getFrequency();
+    } else if (band == mNumPeaking + 1) {
+        return mpHighShelf->getFrequency();
+    } else {
+        return mpPeakingFilters[band - 1].getFrequency();
+    }
+}
+
+uint32_t AudioEqualizer::getBandwidth(int band) const {
+    assert(band >= 0 && band < mNumPeaking + 2);
+    if (band == 0 || band == mNumPeaking + 1) {
+        return 0;
+    } else {
+        return mpPeakingFilters[band - 1].getBandwidth();
+    }
+}
+
+void AudioEqualizer::getBandRange(int band, uint32_t & low,
+                                  uint32_t & high) const {
+    assert(band >= 0 && band < mNumPeaking + 2);
+    if (band == 0) {
+        low = 0;
+        high = mpLowShelf->getFrequency();
+    } else if (band == mNumPeaking + 1) {
+        low = mpHighShelf->getFrequency();
+        high = mSampleRate * 500;
+    } else {
+        mpPeakingFilters[band - 1].getBandRange(low, high);
+    }
+}
+
+const char * AudioEqualizer::getPresetName(int preset) const {
+    assert(preset < mNumPresets && preset >= PRESET_CUSTOM);
+    if (preset == PRESET_CUSTOM) {
+        return "Custom";
+    } else {
+        return mpPresets[preset].name;
+    }
+}
+
+int AudioEqualizer::getNumPresets() const {
+    return mNumPresets;
+}
+
+int AudioEqualizer::getPreset() const {
+    return mCurPreset;
+}
+
+void AudioEqualizer::setPreset(int preset) {
+    LOGV("AudioEqualizer::setPreset(preset=%d)", preset);
+    assert(preset < mNumPresets && preset >= 0);
+    const PresetConfig &presetCfg = mpPresets[preset];
+    for (int band = 0; band < (mNumPeaking + 2); ++band) {
+        const BandConfig & bandCfg = presetCfg.bandConfigs[band];
+        setGain(band, bandCfg.gain);
+        setFrequency(band, bandCfg.freq);
+        setBandwidth(band, bandCfg.bandwidth);
+    }
+    mCurPreset = preset;
+}
+
+void AudioEqualizer::commit(bool immediate) {
+    LOGV("AudioEqualizer::commit(immediate=%d)", immediate);
+    mpLowShelf->commit(immediate);
+    for (int i = 0; i < mNumPeaking; ++i) {
+        mpPeakingFilters[i].commit(immediate);
+    }
+    mpHighShelf->commit(immediate);
+}
+
+void AudioEqualizer::process(const audio_sample_t * pIn,
+                             audio_sample_t * pOut,
+                             int frameCount) {
+//    LOGV("AudioEqualizer::process(frameCount=%d)", frameCount);
+    mpLowShelf->process(pIn, pOut, frameCount);
+    for (int i = 0; i < mNumPeaking; ++i) {
+        mpPeakingFilters[i].process(pIn, pOut, frameCount);
+    }
+    mpHighShelf->process(pIn, pOut, frameCount);
+}
+
+void AudioEqualizer::enable(bool immediate) {
+    LOGV("AudioEqualizer::enable(immediate=%d)", immediate);
+    mpLowShelf->enable(immediate);
+    for (int i = 0; i < mNumPeaking; ++i) {
+        mpPeakingFilters[i].enable(immediate);
+    }
+    mpHighShelf->enable(immediate);
+}
+
+void AudioEqualizer::disable(bool immediate) {
+    LOGV("AudioEqualizer::disable(immediate=%d)", immediate);
+    mpLowShelf->disable(immediate);
+    for (int i = 0; i < mNumPeaking; ++i) {
+        mpPeakingFilters[i].disable(immediate);
+    }
+    mpHighShelf->disable(immediate);
+}
+
+int AudioEqualizer::getMostRelevantBand(uint32_t targetFreq) const {
+    // First, find the two bands that the target frequency is between.
+    uint32_t low = mpLowShelf->getFrequency();
+    if (targetFreq <= low) {
+        return 0;
+    }
+    uint32_t high = mpHighShelf->getFrequency();
+    if (targetFreq >= high) {
+        return mNumPeaking + 1;
+    }
+    int band = mNumPeaking;
+    for (int i = 0; i < mNumPeaking; ++i) {
+        uint32_t freq = mpPeakingFilters[i].getFrequency();
+        if (freq >= targetFreq) {
+            high = freq;
+            band = i;
+            break;
+        }
+        low = freq;
+    }
+    // Now, low is right below the target and high is right above. See which one
+    // is closer on a log scale.
+    low = Effects_log2(low);
+    high = Effects_log2(high);
+    targetFreq = Effects_log2(targetFreq);
+    if (high - targetFreq < targetFreq - low) {
+        return band + 1;
+    } else {
+        return band;
+    }
+}
+
+
+AudioEqualizer::AudioEqualizer(void * pMem, int nBands, int nChannels,
+                               int sampleRate, bool ownMem,
+                               const PresetConfig * presets, int nPresets)
+                               : mSampleRate(sampleRate)
+                               , mpPresets(presets)
+                               , mNumPresets(nPresets) {
+    assert(pMem != NULL);
+    assert(nPresets == 0 || nPresets > 0 && presets != NULL);
+    mpMem = ownMem ? pMem : NULL;
+
+    pMem = (char *) pMem + sizeof(AudioEqualizer);
+    mpLowShelf = new (pMem) AudioShelvingFilter(AudioShelvingFilter::kLowShelf,
+                                                nChannels, sampleRate);
+    pMem = (char *) pMem + sizeof(AudioShelvingFilter);
+    mpHighShelf = new (pMem) AudioShelvingFilter(AudioShelvingFilter::kHighShelf,
+                                                 nChannels, sampleRate);
+    pMem = (char *) pMem + sizeof(AudioShelvingFilter);
+    mNumPeaking = nBands - 2;
+    if (mNumPeaking > 0) {
+        mpPeakingFilters = reinterpret_cast<AudioPeakingFilter *>(pMem);
+        for (int i = 0; i < mNumPeaking; ++i) {
+            new (&mpPeakingFilters[i]) AudioPeakingFilter(nChannels,
+                                                          sampleRate);
+        }
+    }
+    reset();
+}
+
+}
