/*
 * 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 <log/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) {
    ALOGV("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) {
    ALOGV("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() {
    ALOGV("AudioEqualizer::clear()");
    mpLowShelf->clear();
    for (int i = 0; i < mNumPeaking; ++i) {
        mpPeakingFilters[i].clear();
    }
    mpHighShelf->clear();
}

void AudioEqualizer::free() {
    ALOGV("AudioEqualizer::free()");
    if (mpMem != NULL) {
        ::free(mpMem);
    }
}

void AudioEqualizer::reset() {
    ALOGV("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) {
    ALOGV("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) {
    ALOGV("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) {
    ALOGV("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) {
    ALOGV("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) {
    ALOGV("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) {
//    ALOGV("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) {
    ALOGV("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) {
    ALOGV("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();
}

}
