/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"

#if ENABLE(WEB_AUDIO)

#include "platform/audio/DownSampler.h"

#include "wtf/MathExtras.h"

namespace blink {

DownSampler::DownSampler(size_t inputBlockSize)
    : m_inputBlockSize(inputBlockSize)
    , m_reducedKernel(DefaultKernelSize / 2)
    , m_convolver(inputBlockSize / 2) // runs at 1/2 source sample-rate
    , m_tempBuffer(inputBlockSize / 2)
    , m_inputBuffer(inputBlockSize * 2)
{
    initializeKernel();
}

void DownSampler::initializeKernel()
{
    // Blackman window parameters.
    double alpha = 0.16;
    double a0 = 0.5 * (1.0 - alpha);
    double a1 = 0.5;
    double a2 = 0.5 * alpha;

    int n = DefaultKernelSize;
    int halfSize = n / 2;

    // Half-band filter.
    double sincScaleFactor = 0.5;

    // Compute only the odd terms because the even ones are zero, except
    // right in the middle at halfSize, which is 0.5 and we'll handle specially during processing
    // after doing the main convolution using m_reducedKernel.
    for (int i = 1; i < n; i += 2) {
        // Compute the sinc() with offset.
        double s = sincScaleFactor * piDouble * (i - halfSize);
        double sinc = !s ? 1.0 : sin(s) / s;
        sinc *= sincScaleFactor;

        // Compute Blackman window, matching the offset of the sinc().
        double x = static_cast<double>(i) / n;
        double window = a0 - a1 * cos(twoPiDouble * x) + a2 * cos(twoPiDouble * 2.0 * x);

        // Window the sinc() function.
        // Then store only the odd terms in the kernel.
        // In a sense, this is shifting forward in time by one sample-frame at the destination sample-rate.
        m_reducedKernel[(i - 1) / 2] = sinc * window;
    }
}

void DownSampler::process(const float* sourceP, float* destP, size_t sourceFramesToProcess)
{
    bool isInputBlockSizeGood = sourceFramesToProcess == m_inputBlockSize;
    ASSERT(isInputBlockSizeGood);
    if (!isInputBlockSizeGood)
        return;

    size_t destFramesToProcess = sourceFramesToProcess / 2;

    bool isTempBufferGood = destFramesToProcess == m_tempBuffer.size();
    ASSERT(isTempBufferGood);
    if (!isTempBufferGood)
        return;

    bool isReducedKernelGood = m_reducedKernel.size() == DefaultKernelSize / 2;
    ASSERT(isReducedKernelGood);
    if (!isReducedKernelGood)
        return;

    size_t halfSize = DefaultKernelSize / 2;

    // Copy source samples to 2nd half of input buffer.
    bool isInputBufferGood = m_inputBuffer.size() == sourceFramesToProcess * 2 && halfSize <= sourceFramesToProcess;
    ASSERT(isInputBufferGood);
    if (!isInputBufferGood)
        return;

    float* inputP = m_inputBuffer.data() + sourceFramesToProcess;
    memcpy(inputP, sourceP, sizeof(float) * sourceFramesToProcess);

    // Copy the odd sample-frames from sourceP, delayed by one sample-frame (destination sample-rate)
    // to match shifting forward in time in m_reducedKernel.
    float* oddSamplesP = m_tempBuffer.data();
    for (unsigned i = 0; i < destFramesToProcess; ++i)
        oddSamplesP[i] = *((inputP - 1) + i * 2);

    // Actually process oddSamplesP with m_reducedKernel for efficiency.
    // The theoretical kernel is double this size with 0 values for even terms (except center).
    m_convolver.process(&m_reducedKernel, oddSamplesP, destP, destFramesToProcess);

    // Now, account for the 0.5 term right in the middle of the kernel.
    // This amounts to a delay-line of length halfSize (at the source sample-rate),
    // scaled by 0.5.

    // Sum into the destination.
    for (unsigned i = 0; i < destFramesToProcess; ++i)
        destP[i] += 0.5 * *((inputP - halfSize) + i * 2);

    // Copy 2nd half of input buffer to 1st half.
    memcpy(m_inputBuffer.data(), inputP, sizeof(float) * sourceFramesToProcess);
}

void DownSampler::reset()
{
    m_convolver.reset();
    m_inputBuffer.zero();
}

size_t DownSampler::latencyFrames() const
{
    // Divide by two since this is a linear phase kernel and the delay is at the center of the kernel.
    return m_reducedKernel.size() / 2;
}

} // namespace blink

#endif // ENABLE(WEB_AUDIO)
