/*
 * Copyright 2016 The Chromium Authors. All rights reserved.
 * Copyright (C) 2020-2022 Apple 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:
 * 1.  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2.  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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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 "IIRFilterNode.h"

#include "BaseAudioContext.h"
#include "IIRFilter.h"
#include "ScriptExecutionContext.h"
#include <wtf/IsoMallocInlines.h>

namespace WebCore {

WTF_MAKE_ISO_ALLOCATED_IMPL(IIRFilterNode);

// Determine if filter is stable based on the feedback coefficients.
// We compute the reflection coefficients for the filter. If, at any
// point, the magnitude of the reflection coefficient is greater than
// or equal to 1, the filter is declared unstable.
//
// Let A(z) be the feedback polynomial given by
//   A[n](z) = 1 + a[1]/z + a[2]/z^2 + ... + a[n]/z^n
//
// The first reflection coefficient k[n] = a[n]. Then, recursively compute
//
//   A[n-1](z) = (A[n](z) - k[n]*A[n](1/z)/z^n)/(1-k[n]^2);
//
// stopping at A[1](z). If at any point |k[n]| >= 1, the filter is unstable.
static bool isFilterStable(const Vector<double>& feedback)
{
    // Make a copy of the feedback coefficients
    Vector<double> coefficients(feedback);
    int order = coefficients.size() - 1;

    // If necessary, normalize filter coefficients so that constant term is 1.
    if (coefficients[0] != 1) {
        for (int m = 1; m <= order; ++m)
            coefficients[m] /= coefficients[0];
        coefficients[0] = 1;
    }

    // Begin recursion, using a work array to hold intermediate results.
    Vector<double> work(order + 1);
    for (int n = order; n >= 1; --n) {
        double k = coefficients[n];

        if (std::fabs(k) >= 1)
            return false;

        // Note that A[n](1/z)/z^n is basically the coefficients of A[n]
        // in reverse order.
        double factor = 1 - k * k;
        for (int m = 0; m <= n; ++m)
            work[m] = (coefficients[m] - k * coefficients[n - m]) / factor;
        coefficients.swap(work);
    }

    return true;
}

ExceptionOr<Ref<IIRFilterNode>> IIRFilterNode::create(ScriptExecutionContext& scriptExecutionContext, BaseAudioContext& context, IIRFilterOptions&& options)
{
    if (!options.feedforward.size() || options.feedforward.size() > IIRFilter::maxOrder)
        return Exception { NotSupportedError, "feedforward array must have a length between 1 and 20"_s };

    auto nonZeroValueIndex = options.feedforward.findIf([](auto& value) { return !!value; });
    if (nonZeroValueIndex == notFound)
        return Exception { InvalidStateError, "feedforward array must contain a non-zero value"_s };

    if (!options.feedback.size() || options.feedback.size() > IIRFilter::maxOrder)
        return Exception { NotSupportedError, "feedback array must have a length between 1 and 20"_s };

    if (!options.feedback[0])
        return Exception { InvalidStateError, "first value of feedback array cannot be zero"_s };

    bool isFilterStable = WebCore::isFilterStable(options.feedback);
    if (!isFilterStable)
        scriptExecutionContext.addConsoleMessage(MessageSource::JS, MessageLevel::Warning, "IIRFilter is unstable with provided feedback coefficients"_s);

    auto node = adoptRef(*new IIRFilterNode(context, options.feedforward, options.feedback, isFilterStable));

    auto result = node->handleAudioNodeOptions(options, { 2, ChannelCountMode::Max, ChannelInterpretation::Speakers });
    if (result.hasException())
        return result.releaseException();

    return node;
}

IIRFilterNode::IIRFilterNode(BaseAudioContext& context, const Vector<double>& feedforward, const Vector<double>& feedback, bool isFilterStable)
    : AudioBasicProcessorNode(context, NodeTypeIIRFilter)
{
    m_processor = makeUnique<IIRProcessor>(context.sampleRate(), 1, feedforward, feedback, isFilterStable);

    initialize();
}

ExceptionOr<void> IIRFilterNode::getFrequencyResponse(Float32Array& frequencyHz, Float32Array& magResponse, Float32Array& phaseResponse)
{
    auto expectedLength = frequencyHz.length();
    if (magResponse.length() != expectedLength || phaseResponse.length() != expectedLength)
        return Exception { InvalidAccessError, "Arrays must have the same length"_s };

    // Nothing to do if the length is 0.
    if (expectedLength > 0)
        iirProcessor()->getFrequencyResponse(expectedLength, frequencyHz.data(), magResponse.data(), phaseResponse.data());

    return { };
}

} // namespace WebCore

#endif // ENABLE(WEB_AUDIO)
