/*
 * Copyrightm (C) 2010 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.
 */

#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <string.h>
#include <math.h>

#define LOG_TAG "Echo"
#include <utils/Log.h>

#include "EchoSuppressor.h"

// It is very difficult to do echo cancellation at this level due to the lack of
// the timing information of the samples being played and recorded. Therefore,
// for the first release only echo suppression is implemented.

// The algorithm is derived from the "previous works" summarized in
//   A new class of doubletalk detectors based on cross-correlation,
//   J Benesty, DR Morgan, JH Cho, IEEE Trans. on Speech and Audio Processing.
// The method proposed in that paper is not used because of its high complexity.

// It is well known that cross-correlation can be computed using convolution,
// but unfortunately not every mobile processor has a (fast enough) FPU. Thus
// we use integer arithmetic as much as possible and do lots of bookkeeping.
// Again, parameters and thresholds are chosen by experiments.

EchoSuppressor::EchoSuppressor(int sampleCount, int tailLength)
{
    tailLength += sampleCount * 4;

    int shift = 0;
    while ((sampleCount >> shift) > 1 && (tailLength >> shift) > 256) {
        ++shift;
    }

    mShift = shift + 4;
    mScale = 1 << shift;
    mSampleCount = sampleCount;
    mWindowSize = sampleCount >> shift;
    mTailLength = tailLength >> shift;
    mRecordLength = tailLength * 2 / sampleCount;
    mRecordOffset = 0;

    mXs = new uint16_t[mTailLength + mWindowSize];
    memset(mXs, 0, sizeof(*mXs) * (mTailLength + mWindowSize));
    mXSums = new uint32_t[mTailLength];
    memset(mXSums, 0, sizeof(*mXSums) * mTailLength);
    mX2Sums = new uint32_t[mTailLength];
    memset(mX2Sums, 0, sizeof(*mX2Sums) * mTailLength);
    mXRecords = new uint16_t[mRecordLength * mWindowSize];
    memset(mXRecords, 0, sizeof(*mXRecords) * mRecordLength * mWindowSize);

    mYSum = 0;
    mY2Sum = 0;
    mYRecords = new uint32_t[mRecordLength];
    memset(mYRecords, 0, sizeof(*mYRecords) * mRecordLength);
    mY2Records = new uint32_t[mRecordLength];
    memset(mY2Records, 0, sizeof(*mY2Records) * mRecordLength);

    mXYSums = new uint32_t[mTailLength];
    memset(mXYSums, 0, sizeof(*mXYSums) * mTailLength);
    mXYRecords = new uint32_t[mRecordLength * mTailLength];
    memset(mXYRecords, 0, sizeof(*mXYRecords) * mRecordLength * mTailLength);

    mLastX = 0;
    mLastY = 0;
    mWeight = 1.0f / (mRecordLength * mWindowSize);
}

EchoSuppressor::~EchoSuppressor()
{
    delete [] mXs;
    delete [] mXSums;
    delete [] mX2Sums;
    delete [] mXRecords;
    delete [] mYRecords;
    delete [] mY2Records;
    delete [] mXYSums;
    delete [] mXYRecords;
}

void EchoSuppressor::run(int16_t *playbacked, int16_t *recorded)
{
    // Update Xs.
    for (int i = mTailLength - 1; i >= 0; --i) {
        mXs[i + mWindowSize] = mXs[i];
    }
    for (int i = mWindowSize - 1, j = 0; i >= 0; --i, j += mScale) {
        uint32_t sum = 0;
        for (int k = 0; k < mScale; ++k) {
            int32_t x = playbacked[j + k] << 15;
            mLastX += x;
            sum += ((mLastX >= 0) ? mLastX : -mLastX) >> 15;
            mLastX -= (mLastX >> 10) + x;
        }
        mXs[i] = sum >> mShift;
    }

    // Update XSums, X2Sums, and XRecords.
    for (int i = mTailLength - mWindowSize - 1; i >= 0; --i) {
        mXSums[i + mWindowSize] = mXSums[i];
        mX2Sums[i + mWindowSize] = mX2Sums[i];
    }
    uint16_t *xRecords = &mXRecords[mRecordOffset * mWindowSize];
    for (int i = mWindowSize - 1; i >= 0; --i) {
        uint16_t x = mXs[i];
        mXSums[i] = mXSums[i + 1] + x - xRecords[i];
        mX2Sums[i] = mX2Sums[i + 1] + x * x - xRecords[i] * xRecords[i];
        xRecords[i] = x;
    }

    // Compute Ys.
    uint16_t ys[mWindowSize];
    for (int i = mWindowSize - 1, j = 0; i >= 0; --i, j += mScale) {
        uint32_t sum = 0;
        for (int k = 0; k < mScale; ++k) {
            int32_t y = recorded[j + k] << 15;
            mLastY += y;
            sum += ((mLastY >= 0) ? mLastY : -mLastY) >> 15;
            mLastY -= (mLastY >> 10) + y;
        }
        ys[i] = sum >> mShift;
    }

    // Update YSum, Y2Sum, YRecords, and Y2Records.
    uint32_t ySum = 0;
    uint32_t y2Sum = 0;
    for (int i = mWindowSize - 1; i >= 0; --i) {
        ySum += ys[i];
        y2Sum += ys[i] * ys[i];
    }
    mYSum += ySum - mYRecords[mRecordOffset];
    mY2Sum += y2Sum - mY2Records[mRecordOffset];
    mYRecords[mRecordOffset] = ySum;
    mY2Records[mRecordOffset] = y2Sum;

    // Update XYSums and XYRecords.
    uint32_t *xyRecords = &mXYRecords[mRecordOffset * mTailLength];
    for (int i = mTailLength - 1; i >= 0; --i) {
        uint32_t xySum = 0;
        for (int j = mWindowSize - 1; j >= 0; --j) {
            xySum += mXs[i + j] * ys[j];
        }
        mXYSums[i] += xySum - xyRecords[i];
        xyRecords[i] = xySum;
    }

    // Compute correlations.
    int latency = 0;
    float corr2 = 0.0f;
    float varX = 0.0f;
    float varY = mY2Sum - mWeight * mYSum * mYSum;
    for (int i = mTailLength - 1; i >= 0; --i) {
        float cov = mXYSums[i] - mWeight * mXSums[i] * mYSum;
        if (cov > 0.0f) {
            float varXi = mX2Sums[i] - mWeight * mXSums[i] * mXSums[i];
            float corr2i = cov * cov / (varXi * varY + 1);
            if (corr2i > corr2) {
                varX = varXi;
                corr2 = corr2i;
                latency = i;
            }
        }
    }
    //LOGI("corr^2 %.5f, var %8.0f %8.0f, latency %d", corr2, varX, varY,
    //        latency * mScale);

    // Do echo suppression.
    if (corr2 > 0.1f && varX > 10000.0f) {
        int factor = (corr2 > 1.0f) ? 0 : (1.0f - sqrtf(corr2)) * 4096;
        for (int i = 0; i < mSampleCount; ++i) {
            recorded[i] = recorded[i] * factor >> 16;
        }
    }

    // Increase RecordOffset.
    ++mRecordOffset;
    if (mRecordOffset == mRecordLength) {
        mRecordOffset = 0;
    }
}
