/*
 * Copyright (C) 2018 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 "DPFrequency"
//#define LOG_NDEBUG 0

#include <log/log.h>
#include "DPFrequency.h"
#include <algorithm>

namespace dp_fx {

using Eigen::MatrixXd;
#define MAX_BLOCKSIZE 16384 //For this implementation
#define MIN_BLOCKSIZE 8

#define CIRCULAR_BUFFER_UPSAMPLE 4  //4 times buffer size

static constexpr float MIN_ENVELOPE = 1e-6f; //-120 dB
//helper functionS
static inline bool isPowerOf2(unsigned long n) {
    return (n & (n - 1)) == 0;
}
static constexpr float EPSILON = 0.0000001f;

static inline bool isZero(float f) {
    return fabs(f) <= EPSILON;
}

template <class T>
bool compareEquality(T a, T b) {
    return (a == b);
}

template <> bool compareEquality<float>(float a, float b) {
    return isZero(a - b);
}

//TODO: avoid using macro for estimating change and assignment.
#define IS_CHANGED(c, a, b) { c |= !compareEquality(a,b); \
    (a) = (b); }

//ChannelBuffers helper
void ChannelBuffer::initBuffers(unsigned int blockSize, unsigned int overlapSize,
        unsigned int halfFftSize, unsigned int samplingRate, DPBase &dpBase) {
    ALOGV("ChannelBuffer::initBuffers blockSize %d, overlap %d, halfFft %d",
            blockSize, overlapSize, halfFftSize);

    mSamplingRate = samplingRate;
    mBlockSize = blockSize;

    cBInput.resize(mBlockSize * CIRCULAR_BUFFER_UPSAMPLE);
    cBOutput.resize(mBlockSize * CIRCULAR_BUFFER_UPSAMPLE);

    //fill input with half block size...
    for (unsigned int k = 0; k < mBlockSize/2; k++) {
        cBInput.write(0);
    }

    //temp vectors
    input.resize(mBlockSize);
    output.resize(mBlockSize);
    outTail.resize(overlapSize);

    //module vectors
    mPreEqFactorVector.resize(halfFftSize, 1.0);
    mPostEqFactorVector.resize(halfFftSize, 1.0);

    mPreEqBands.resize(dpBase.getPreEqBandCount());
    mMbcBands.resize(dpBase.getMbcBandCount());
    mPostEqBands.resize(dpBase.getPostEqBandCount());
    ALOGV("mPreEqBands %zu, mMbcBands %zu, mPostEqBands %zu",mPreEqBands.size(),
            mMbcBands.size(), mPostEqBands.size());

    DPChannel *pChannel = dpBase.getChannel(0);
    if (pChannel != nullptr) {
        mPreEqInUse = pChannel->getPreEq()->isInUse();
        mMbcInUse = pChannel->getMbc()->isInUse();
        mPostEqInUse = pChannel->getPostEq()->isInUse();
        mLimiterInUse = pChannel->getLimiter()->isInUse();
    }

    mLimiterParams.linkGroup = -1; //no group.
}

void ChannelBuffer::computeBinStartStop(BandParams &bp, size_t binStart) {

    bp.binStart = binStart;
    bp.binStop = (int)(0.5 + bp.freqCutoffHz * mBlockSize / mSamplingRate);
}

//== LinkedLimiters Helper
void LinkedLimiters::reset() {
    mGroupsMap.clear();
}

void LinkedLimiters::update(int32_t group, int index) {
    mGroupsMap[group].push_back(index);
}

void LinkedLimiters::remove(int index) {
    //check all groups and if index is found, remove it.
    //if group is empty afterwards, remove it.
    for (auto it = mGroupsMap.begin(); it != mGroupsMap.end(); ) {
        for (auto itIndex = it->second.begin(); itIndex != it->second.end(); ) {
            if (*itIndex == index) {
                itIndex = it->second.erase(itIndex);
            } else {
                ++itIndex;
            }
        }
        if (it->second.size() == 0) {
            it = mGroupsMap.erase(it);
        } else {
            ++it;
        }
    }
}

//== DPFrequency
void DPFrequency::reset() {
}

size_t DPFrequency::getMinBockSize() {
    return MIN_BLOCKSIZE;
}

size_t DPFrequency::getMaxBockSize() {
    return MAX_BLOCKSIZE;
}

void DPFrequency::configure(size_t blockSize, size_t overlapSize,
        size_t samplingRate) {
    ALOGV("configure");
    mBlockSize = blockSize;
    if (mBlockSize > MAX_BLOCKSIZE) {
        mBlockSize = MAX_BLOCKSIZE;
    } else if (mBlockSize < MIN_BLOCKSIZE) {
        mBlockSize = MIN_BLOCKSIZE;
    } else {
        if (!isPowerOf2(blockSize)) {
            //find next highest power of 2.
            mBlockSize = 1 << (32 - __builtin_clz(blockSize));
        }
    }

    mHalfFFTSize = 1 + mBlockSize / 2; //including Nyquist bin
    mOverlapSize = std::min(overlapSize, mBlockSize/2);

    int channelcount = getChannelCount();
    mSamplingRate = samplingRate;
    mChannelBuffers.resize(channelcount);
    for (int ch = 0; ch < channelcount; ch++) {
        mChannelBuffers[ch].initBuffers(mBlockSize, mOverlapSize, mHalfFFTSize,
                mSamplingRate, *this);
    }

    //effective number of frames processed per second
    mBlocksPerSecond = (float)mSamplingRate / (mBlockSize - mOverlapSize);

    fill_window(mVWindow, RDSP_WINDOW_HANNING_FLAT_TOP, mBlockSize, mOverlapSize);

    //compute window rms for energy compensation
    mWindowRms = 0;
    for (size_t i = 0; i < mVWindow.size(); i++) {
        mWindowRms += mVWindow[i] * mVWindow[i];
    }

    //Making sure window rms is not zero.
    mWindowRms = std::max(sqrt(mWindowRms / mVWindow.size()), MIN_ENVELOPE);
}

void DPFrequency::updateParameters(ChannelBuffer &cb, int channelIndex) {
    DPChannel *pChannel = getChannel(channelIndex);

    if (pChannel == nullptr) {
        ALOGE("Error: updateParameters null DPChannel %d", channelIndex);
        return;
    }

    //===Input Gain and preEq
    {
        bool changed = false;
        IS_CHANGED(changed, cb.inputGainDb, pChannel->getInputGain());
        //===EqPre
        if (cb.mPreEqInUse) {
            DPEq *pPreEq = pChannel->getPreEq();
            if (pPreEq == nullptr) {
                ALOGE("Error: updateParameters null PreEq for channel: %d", channelIndex);
                return;
            }
            IS_CHANGED(changed, cb.mPreEqEnabled, pPreEq->isEnabled());
            if (cb.mPreEqEnabled) {
                for (unsigned int b = 0; b < getPreEqBandCount(); b++) {
                    DPEqBand *pEqBand = pPreEq->getBand(b);
                    if (pEqBand == nullptr) {
                        ALOGE("Error: updateParameters null PreEqBand for band %d", b);
                        return; //failed.
                    }
                    ChannelBuffer::EqBandParams *pEqBandParams = &cb.mPreEqBands[b];
                    IS_CHANGED(changed, pEqBandParams->enabled, pEqBand->isEnabled());
                    IS_CHANGED(changed, pEqBandParams->freqCutoffHz,
                            pEqBand->getCutoffFrequency());
                    IS_CHANGED(changed, pEqBandParams->gainDb, pEqBand->getGain());
                }
            }
        }

        if (changed) {
            float inputGainFactor = dBtoLinear(cb.inputGainDb);
            if (cb.mPreEqInUse && cb.mPreEqEnabled) {
                ALOGV("preEq changed, recomputing! channel %d", channelIndex);
                size_t binNext = 0;
                for (unsigned int b = 0; b < getPreEqBandCount(); b++) {
                    ChannelBuffer::EqBandParams *pEqBandParams = &cb.mPreEqBands[b];

                    //frequency translation
                    cb.computeBinStartStop(*pEqBandParams, binNext);
                    binNext = pEqBandParams->binStop + 1;
                    float factor = dBtoLinear(pEqBandParams->gainDb);
                    if (!pEqBandParams->enabled) {
                        factor = inputGainFactor;
                    }
                    for (size_t k = pEqBandParams->binStart;
                            k <= pEqBandParams->binStop && k < mHalfFFTSize; k++) {
                        cb.mPreEqFactorVector[k] = factor * inputGainFactor;
                    }
                }
            } else {
                ALOGV("only input gain changed, recomputing!");
                //populate PreEq factor with input gain factor.
                for (size_t k = 0; k < mHalfFFTSize; k++) {
                    cb.mPreEqFactorVector[k] = inputGainFactor;
                }
            }
        }
    } //inputGain and preEq

    //===EqPost
    if (cb.mPostEqInUse) {
        bool changed = false;

        DPEq *pPostEq = pChannel->getPostEq();
        if (pPostEq == nullptr) {
            ALOGE("Error: updateParameters null postEq for channel: %d", channelIndex);
            return; //failed.
        }
        IS_CHANGED(changed, cb.mPostEqEnabled, pPostEq->isEnabled());
        if (cb.mPostEqEnabled) {
            for (unsigned int b = 0; b < getPostEqBandCount(); b++) {
                DPEqBand *pEqBand = pPostEq->getBand(b);
                if (pEqBand == nullptr) {
                    ALOGE("Error: updateParameters PostEqBand NULL for band %d", b);
                    return; //failed.
                }
                ChannelBuffer::EqBandParams *pEqBandParams = &cb.mPostEqBands[b];
                IS_CHANGED(changed, pEqBandParams->enabled, pEqBand->isEnabled());
                IS_CHANGED(changed, pEqBandParams->freqCutoffHz,
                        pEqBand->getCutoffFrequency());
                IS_CHANGED(changed, pEqBandParams->gainDb, pEqBand->getGain());
            }
            if (changed) {
                ALOGV("postEq changed, recomputing! channel %d", channelIndex);
                size_t binNext = 0;
                for (unsigned int b = 0; b < getPostEqBandCount(); b++) {
                    ChannelBuffer::EqBandParams *pEqBandParams = &cb.mPostEqBands[b];

                    //frequency translation
                    cb.computeBinStartStop(*pEqBandParams, binNext);
                    binNext = pEqBandParams->binStop + 1;
                    float factor = dBtoLinear(pEqBandParams->gainDb);
                    if (!pEqBandParams->enabled) {
                        factor = 1.0;
                    }
                    for (size_t k = pEqBandParams->binStart;
                            k <= pEqBandParams->binStop && k < mHalfFFTSize; k++) {
                        cb.mPostEqFactorVector[k] = factor;
                    }
                }
            }
        } //enabled
    }

    //===MBC
    if (cb.mMbcInUse) {
        DPMbc *pMbc = pChannel->getMbc();
        if (pMbc == nullptr) {
            ALOGE("Error: updateParameters Mbc NULL for channel: %d", channelIndex);
            return;
        }
        cb.mMbcEnabled = pMbc->isEnabled();
        if (cb.mMbcEnabled) {
            bool changed = false;
            for (unsigned int b = 0; b < getMbcBandCount(); b++) {
                DPMbcBand *pMbcBand = pMbc->getBand(b);
                if (pMbcBand == nullptr) {
                    ALOGE("Error: updateParameters MbcBand NULL for band %d", b);
                    return; //failed.
                }
                ChannelBuffer::MbcBandParams *pMbcBandParams = &cb.mMbcBands[b];
                pMbcBandParams->enabled = pMbcBand->isEnabled();
                IS_CHANGED(changed, pMbcBandParams->freqCutoffHz,
                        pMbcBand->getCutoffFrequency());

                pMbcBandParams->gainPreDb = pMbcBand->getPreGain();
                pMbcBandParams->gainPostDb = pMbcBand->getPostGain();
                pMbcBandParams->attackTimeMs = pMbcBand->getAttackTime();
                pMbcBandParams->releaseTimeMs = pMbcBand->getReleaseTime();
                pMbcBandParams->ratio = pMbcBand->getRatio();
                pMbcBandParams->thresholdDb = pMbcBand->getThreshold();
                pMbcBandParams->kneeWidthDb = pMbcBand->getKneeWidth();
                pMbcBandParams->noiseGateThresholdDb = pMbcBand->getNoiseGateThreshold();
                pMbcBandParams->expanderRatio = pMbcBand->getExpanderRatio();

            }

            if (changed) {
                ALOGV("mbc changed, recomputing! channel %d", channelIndex);
                size_t binNext= 0;
                for (unsigned int b = 0; b < getMbcBandCount(); b++) {
                    ChannelBuffer::MbcBandParams *pMbcBandParams = &cb.mMbcBands[b];

                    pMbcBandParams->previousEnvelope = 0;

                    //frequency translation
                    cb.computeBinStartStop(*pMbcBandParams, binNext);
                    binNext = pMbcBandParams->binStop + 1;
                }
            }
        }
    }

    //===Limiter
    if (cb.mLimiterInUse) {
        bool changed = false;
        DPLimiter *pLimiter = pChannel->getLimiter();
        if (pLimiter == nullptr) {
            ALOGE("Error: updateParameters Limiter NULL for channel: %d", channelIndex);
            return;
        }
        cb.mLimiterEnabled = pLimiter->isEnabled();
        if (cb.mLimiterEnabled) {
            IS_CHANGED(changed, cb.mLimiterParams.linkGroup ,
                    (int32_t)pLimiter->getLinkGroup());
            cb.mLimiterParams.attackTimeMs = pLimiter->getAttackTime();
            cb.mLimiterParams.releaseTimeMs = pLimiter->getReleaseTime();
            cb.mLimiterParams.ratio = pLimiter->getRatio();
            cb.mLimiterParams.thresholdDb = pLimiter->getThreshold();
            cb.mLimiterParams.postGainDb = pLimiter->getPostGain();
        }

        if (changed) {
            ALOGV("limiter changed, recomputing linkGroups for %d", channelIndex);
            mLinkedLimiters.remove(channelIndex); //in case it was already there.
            mLinkedLimiters.update(cb.mLimiterParams.linkGroup, channelIndex);
        }
    }

    //=== Output Gain
    cb.outputGainDb = pChannel->getOutputGain();
}

size_t DPFrequency::processSamples(const float *in, float *out, size_t samples) {
       const float *pIn = in;
       float *pOut = out;

       int channelCount = mChannelBuffers.size();
       if (channelCount < 1) {
           ALOGW("warning: no Channels ready for processing");
           return 0;
       }

       //**Check if parameters have changed and update
       for (int ch = 0; ch < channelCount; ch++) {
           updateParameters(mChannelBuffers[ch], ch);
       }

       //**separate into channels
       for (size_t k = 0; k < samples; k += channelCount) {
           for (int ch = 0; ch < channelCount; ch++) {
               mChannelBuffers[ch].cBInput.write(*pIn++);
           }
       }

       //**process all channelBuffers
       processChannelBuffers(mChannelBuffers);

       //** estimate how much data is available in ALL channels
       size_t available = mChannelBuffers[0].cBOutput.availableToRead();
       for (int ch = 1; ch < channelCount; ch++) {
           available = std::min(available, mChannelBuffers[ch].cBOutput.availableToRead());
       }

       //** make sure to output just what the buffer can handle
       if (available > samples/channelCount) {
           available = samples/channelCount;
       }

       //**Prepend zeroes if necessary
       size_t fill = samples - (channelCount * available);
       for (size_t k = 0; k < fill; k++) {
           *pOut++ = 0;
       }

       //**interleave channels
       for (size_t k = 0; k < available; k++) {
           for (int ch = 0; ch < channelCount; ch++) {
               *pOut++ = mChannelBuffers[ch].cBOutput.read();
           }
       }

       return samples;
}

size_t DPFrequency::processChannelBuffers(CBufferVector &channelBuffers) {
    const int channelCount = channelBuffers.size();
    size_t processedSamples = 0;
    size_t processFrames = mBlockSize - mOverlapSize;

    size_t available = channelBuffers[0].cBInput.availableToRead();
    for (int ch = 1; ch < channelCount; ch++) {
        available = std::min(available, channelBuffers[ch].cBInput.availableToRead());
    }

    while (available >= processFrames) {
        //First pass
        for (int ch = 0; ch < channelCount; ch++) {
            ChannelBuffer * pCb = &channelBuffers[ch];
            //move tail of previous
            std::copy(pCb->input.begin() + processFrames,
                    pCb->input.end(),
                    pCb->input.begin());

            //read new available data
            for (unsigned int k = 0; k < processFrames; k++) {
                pCb->input[mOverlapSize + k] = pCb->cBInput.read();
            }
            //first stages: fft, preEq, mbc, postEq and start of Limiter
            processedSamples += processFirstStages(*pCb);
        }

        //**compute linked limiters and update levels if needed
        processLinkedLimiters(channelBuffers);

        //final pass.
        for (int ch = 0; ch < channelCount; ch++) {
            ChannelBuffer * pCb = &channelBuffers[ch];

            //linked limiter and ifft
            processLastStages(*pCb);

            //mix tail (and capture new tail
            for (unsigned int k = 0; k < mOverlapSize; k++) {
                pCb->output[k] += pCb->outTail[k];
                pCb->outTail[k] = pCb->output[processFrames + k]; //new tail
            }

            //output data
            for (unsigned int k = 0; k < processFrames; k++) {
                pCb->cBOutput.write(pCb->output[k]);
            }
        }
        available -= processFrames;
    }
    return processedSamples;
}
size_t DPFrequency::processFirstStages(ChannelBuffer &cb) {

    //##apply window
    Eigen::Map<Eigen::VectorXf> eWindow(&mVWindow[0], mVWindow.size());
    Eigen::Map<Eigen::VectorXf> eInput(&cb.input[0], cb.input.size());

    Eigen::VectorXf eWin = eInput.cwiseProduct(eWindow); //apply window

    //##fft
    //Note: we are using eigen with the default scaling, which ensures that
    //  IFFT( FFT(x) ) = x.
    // TODO: optimize by using the noscale option, and compensate with dB scale offsets
    mFftServer.fwd(cb.complexTemp, eWin);

    size_t cSize = cb.complexTemp.size();
    size_t maxBin = std::min(cSize/2, mHalfFFTSize);

    //== EqPre (always runs)
    for (size_t k = 0; k < maxBin; k++) {
        cb.complexTemp[k] *= cb.mPreEqFactorVector[k];
    }

    //== MBC
    if (cb.mMbcInUse && cb.mMbcEnabled) {
        for (size_t band = 0; band < cb.mMbcBands.size(); band++) {
            ChannelBuffer::MbcBandParams *pMbcBandParams = &cb.mMbcBands[band];
            float fEnergySum = 0;

            //apply pre gain.
            float preGainFactor = dBtoLinear(pMbcBandParams->gainPreDb);
            float preGainSquared = preGainFactor * preGainFactor;

            for (size_t k = pMbcBandParams->binStart; k <= pMbcBandParams->binStop; k++) {
                fEnergySum += std::norm(cb.complexTemp[k]) * preGainSquared; //mag squared
            }

            //Eigen FFT is full spectrum, even if the source was real data.
            // Each half spectrum has half the energy. This is taken into account with the * 2
            // factor in the energy computations.
            // energy = sqrt(sum_components_squared) number_points
            // in here, the fEnergySum is duplicated to account for the second half spectrum,
            // and the windowRms is used to normalize by the expected energy reduction
            // caused by the window used (expected for steady state signals)
            fEnergySum = sqrt(fEnergySum * 2) / (mBlockSize * mWindowRms);

            // updates computed per frame advance.
            float fTheta = 0.0;
            float fFAttSec = pMbcBandParams->attackTimeMs / 1000; //in seconds
            float fFRelSec = pMbcBandParams->releaseTimeMs / 1000; //in seconds

            if (fEnergySum > pMbcBandParams->previousEnvelope) {
                fTheta = exp(-1.0 / (fFAttSec * mBlocksPerSecond));
            } else {
                fTheta = exp(-1.0 / (fFRelSec * mBlocksPerSecond));
            }

            float fEnv = (1.0 - fTheta) * fEnergySum + fTheta * pMbcBandParams->previousEnvelope;
            //preserve for next iteration
            pMbcBandParams->previousEnvelope = fEnv;

            if (fEnv < MIN_ENVELOPE) {
                fEnv = MIN_ENVELOPE;
            }
            const float envDb = linearToDb(fEnv);
            float newLevelDb = envDb;
            //using shorter variables for code clarity
            const float thresholdDb = pMbcBandParams->thresholdDb;
            const float ratio = pMbcBandParams->ratio;
            const float kneeWidthDbHalf = pMbcBandParams->kneeWidthDb / 2;
            const float noiseGateThresholdDb = pMbcBandParams->noiseGateThresholdDb;
            const float expanderRatio = pMbcBandParams->expanderRatio;

            //find segment
            if (envDb > thresholdDb + kneeWidthDbHalf) {
                //compression segment
                newLevelDb = envDb + ((1 / ratio) - 1) * (envDb - thresholdDb);
            } else if (envDb > thresholdDb - kneeWidthDbHalf) {
                //knee-compression segment
                float temp = (envDb - thresholdDb + kneeWidthDbHalf);
                newLevelDb = envDb + ((1 / ratio) - 1) *
                        temp * temp / (kneeWidthDbHalf * 4);
            } else if (envDb < noiseGateThresholdDb) {
                //expander segment
                newLevelDb = noiseGateThresholdDb -
                        expanderRatio * (noiseGateThresholdDb - envDb);
            }

            float newFactor = dBtoLinear(newLevelDb - envDb);

            //apply post gain.
            newFactor *= dBtoLinear(pMbcBandParams->gainPostDb);

            //apply to this band
            for (size_t k = pMbcBandParams->binStart; k <= pMbcBandParams->binStop; k++) {
                cb.complexTemp[k] *= newFactor;
            }

        } //end per band process

    } //end MBC

    //== EqPost
    if (cb.mPostEqInUse && cb.mPostEqEnabled) {
        for (size_t k = 0; k < maxBin; k++) {
            cb.complexTemp[k] *= cb.mPostEqFactorVector[k];
        }
    }

    //== Limiter. First Pass
    if (cb.mLimiterInUse && cb.mLimiterEnabled) {
        float fEnergySum = 0;
        for (size_t k = 0; k < maxBin; k++) {
            fEnergySum += std::norm(cb.complexTemp[k]);
        }

        //see explanation above for energy computation logic
        fEnergySum = sqrt(fEnergySum * 2) / (mBlockSize * mWindowRms);
        float fTheta = 0.0;
        float fFAttSec = cb.mLimiterParams.attackTimeMs / 1000; //in seconds
        float fFRelSec = cb.mLimiterParams.releaseTimeMs / 1000; //in seconds

        if (fEnergySum > cb.mLimiterParams.previousEnvelope) {
            fTheta = exp(-1.0 / (fFAttSec * mBlocksPerSecond));
        } else {
            fTheta = exp(-1.0 / (fFRelSec * mBlocksPerSecond));
        }

        float fEnv = (1.0 - fTheta) * fEnergySum + fTheta * cb.mLimiterParams.previousEnvelope;
        //preserve for next iteration
        cb.mLimiterParams.previousEnvelope = fEnv;

        const float envDb = linearToDb(fEnv);
        float newFactorDb = 0;
        //using shorter variables for code clarity
        const float thresholdDb = cb.mLimiterParams.thresholdDb;
        const float ratio = cb.mLimiterParams.ratio;

        if (envDb > thresholdDb) {
            //limiter segment
            newFactorDb = ((1 / ratio) - 1) * (envDb - thresholdDb);
        }

        float newFactor = dBtoLinear(newFactorDb);

        cb.mLimiterParams.newFactor = newFactor;

    } //end Limiter
    return mBlockSize;
}

void DPFrequency::processLinkedLimiters(CBufferVector &channelBuffers) {

    const int channelCount = channelBuffers.size();
    for (auto &groupPair : mLinkedLimiters.mGroupsMap) {
        float minFactor = 1.0;
        //estimate minfactor for all linked
        for(int index : groupPair.second) {
            if (index >= 0 && index < channelCount) {
                minFactor = std::min(channelBuffers[index].mLimiterParams.newFactor, minFactor);
            }
        }
        //apply minFactor
        for(int index : groupPair.second) {
            if (index >= 0 && index < channelCount) {
                channelBuffers[index].mLimiterParams.linkFactor = minFactor;
            }
        }
    }
}

size_t DPFrequency::processLastStages(ChannelBuffer &cb) {

    float outputGainFactor = dBtoLinear(cb.outputGainDb);
    //== Limiter. last Pass
    if (cb.mLimiterInUse && cb.mLimiterEnabled) {
        //compute factor, with post-gain
        float factor = cb.mLimiterParams.linkFactor * dBtoLinear(cb.mLimiterParams.postGainDb);
        outputGainFactor *= factor;
    }

    //apply to all if != 1.0
    if (!compareEquality(outputGainFactor, 1.0f)) {
        size_t cSize = cb.complexTemp.size();
        size_t maxBin = std::min(cSize/2, mHalfFFTSize);
        for (size_t k = 0; k < maxBin; k++) {
            cb.complexTemp[k] *= outputGainFactor;
        }
    }

    //##ifft directly to output.
    Eigen::Map<Eigen::VectorXf> eOutput(&cb.output[0], cb.output.size());
    mFftServer.inv(eOutput, cb.complexTemp);
    return mBlockSize;
}

} //namespace dp_fx
