/*
 * Copyright (C) 2012, 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:
 * 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 "OscillatorNode.h"

#include "AudioNodeOutput.h"
#include "AudioParam.h"
#include "AudioUtilities.h"
#include "PeriodicWave.h"
#include "VectorMath.h"
#include <wtf/IsoMallocInlines.h>

namespace WebCore {

WTF_MAKE_ISO_ALLOCATED_IMPL(OscillatorNode);

// Breakpoints where we deicde to do linear interoplation, 3-point interpolation or 5-point interpolation. See doInterpolation().
constexpr float interpolate2Point = 0.3;
constexpr float interpolate3Point = 0.16;

// Convert the detune value (in cents) to a frequency scale multiplier: 2^(d/1200).
static inline float detuneToFrequencyMultiplier(float detuneValue)
{
    return std::exp2(detuneValue / 1200);
}

// Clamp the frequency value to lie within Nyquist frequency. For NaN, arbitrarily clamp to +Nyquist.
static void clampFrequency(float* frequency, size_t framesToProcess, float nyquist)
{
    for (size_t k = 0; k < framesToProcess; ++k) {
        float f = frequency[k];
        frequency[k] = std::isnan(f) ? nyquist : clampTo(f, -nyquist, nyquist);
    }
}

ExceptionOr<Ref<OscillatorNode>> OscillatorNode::create(BaseAudioContext& context, const OscillatorOptions& options)
{
    if (options.type == OscillatorType::Custom && !options.periodicWave)
        return Exception { InvalidStateError, "Must provide periodicWave when using custom type."_s };
    
    auto oscillator = adoptRef(*new OscillatorNode(context, options));
    oscillator->suspendIfNeeded();

    auto result = oscillator->handleAudioNodeOptions(options, { 2, ChannelCountMode::Max, ChannelInterpretation::Speakers });
    if (result.hasException())
        return result.releaseException();
    
    if (options.periodicWave)
        oscillator->setPeriodicWave(*options.periodicWave);
    else {
        result = oscillator->setTypeForBindings(options.type);
        if (result.hasException())
            return result.releaseException();
    }

    return oscillator;
}

OscillatorNode::OscillatorNode(BaseAudioContext& context, const OscillatorOptions& options)
    : AudioScheduledSourceNode(context, NodeTypeOscillator)
    , m_frequency(AudioParam::create(context, "frequency"_s, options.frequency, -context.sampleRate() / 2, context.sampleRate() / 2, AutomationRate::ARate))
    , m_detune(AudioParam::create(context, "detune"_s, options.detune, -1200 * log2f(std::numeric_limits<float>::max()), 1200 * log2f(std::numeric_limits<float>::max()), AutomationRate::ARate))
    , m_phaseIncrements(AudioUtilities::renderQuantumSize)
    , m_detuneValues(AudioUtilities::renderQuantumSize)
{
    // An oscillator is always mono.
    addOutput(1);
    initialize();
}

OscillatorNode::~OscillatorNode()
{
    uninitialize();
}

ExceptionOr<void> OscillatorNode::setTypeForBindings(OscillatorType type)
{
    ALWAYS_LOG(LOGIDENTIFIER, type);
    ASSERT(isMainThread());

    if (type == OscillatorType::Custom) {
        if (m_type != OscillatorType::Custom)
            return Exception { InvalidStateError, "OscillatorNode.type cannot be changed to 'custom'"_s };
        return { };
    }

    setPeriodicWave(context().periodicWave(type));
    m_type = type;

    return { };
}

bool OscillatorNode::calculateSampleAccuratePhaseIncrements(size_t framesToProcess)
{
    bool isGood = framesToProcess <= m_phaseIncrements.size() && framesToProcess <= m_detuneValues.size();
    ASSERT(isGood);
    if (!isGood)
        return false;

    if (m_firstRender) {
        m_firstRender = false;
        m_frequency->resetSmoothedValue();
        m_detune->resetSmoothedValue();
    }

    bool hasSampleAccurateValues = false;
    bool hasFrequencyChanges = false;
    float* phaseIncrements = m_phaseIncrements.data();

    float finalScale = m_periodicWave->rateScale();

    if (m_frequency->hasSampleAccurateValues() && m_frequency->automationRate() == AutomationRate::ARate) {
        hasSampleAccurateValues = true;
        hasFrequencyChanges = true;

        // Get the sample-accurate frequency values and convert to phase increments.
        // They will be converted to phase increments below.
        m_frequency->calculateSampleAccurateValues(phaseIncrements, framesToProcess);
    } else {
        float frequency = m_frequency->finalValue();
        finalScale *= frequency;
    }

    if (m_detune->hasSampleAccurateValues() && m_detune->automationRate() == AutomationRate::ARate) {
        hasSampleAccurateValues = true;

        // Get the sample-accurate detune values.
        float* detuneValues = hasFrequencyChanges ? m_detuneValues.data() : phaseIncrements;
        m_detune->calculateSampleAccurateValues(detuneValues, framesToProcess);

        // Convert from cents to rate scalar.
        VectorMath::multiplyByScalar(detuneValues, 1.0 / 1200, detuneValues, framesToProcess);
        for (unsigned i = 0; i < framesToProcess; ++i)
            detuneValues[i] = std::exp2(detuneValues[i]);

        if (hasFrequencyChanges) {
            // Multiply frequencies by detune scalings.
            VectorMath::multiply(detuneValues, phaseIncrements, phaseIncrements, framesToProcess);
        }
    } else {
        float detune = m_detune->finalValue();
        float detuneScale = detuneToFrequencyMultiplier(detune);
        finalScale *= detuneScale;
    }

    if (hasSampleAccurateValues) {
        clampFrequency(phaseIncrements, framesToProcess, context().sampleRate() / 2);
        // Convert from frequency to wave increment.
        VectorMath::multiplyByScalar(phaseIncrements, finalScale, phaseIncrements, framesToProcess);
    }

    return hasSampleAccurateValues;
}

static float doInterpolation(double virtualReadIndex, float incr, unsigned readIndexMask, float tableInterpolationFactor, const float* lowerWaveData, const float* higherWaveData)
{
    ASSERT(incr >= 0);
    ASSERT(std::isfinite(virtualReadIndex));

    double sampleLower = 0;
    double sampleHigher = 0;

    unsigned readIndex0 = static_cast<unsigned>(virtualReadIndex);

    // Consider a typical sample rate of 44100 Hz and max periodic wave
    // size of 4096. The relationship between |incr| and the frequency
    // of the oscillator is |incr| = freq * 4096/44100. Or freq =
    // |incr|*44100/4096 = 10.8*|incr|.
    //
    // For the |incr| thresholds below, this means that we use linear
    // interpolation for all freq >= 3.2 Hz, 3-point Lagrange
    // for freq >= 1.7 Hz and 5-point Lagrange for every thing else.
    //
    // We use Lagrange interpolation because it's relatively simple to
    // implement and fairly inexpensive, and the interpolator always
    // passes through known points.
    if (incr >= interpolate2Point) {
        // Increment is fairly large, so we're doing no more than about 3
        // points between each wave table entry. Assume linear
        // interpolation between points is good enough.
        unsigned readIndex2 = readIndex0 + 1;

        // Contain within valid range.
        readIndex0 = readIndex0 & readIndexMask;
        readIndex2 = readIndex2 & readIndexMask;

        float sample1Lower = lowerWaveData[readIndex0];
        float sample2Lower = lowerWaveData[readIndex2];
        float sample1Higher = higherWaveData[readIndex0];
        float sample2Higher = higherWaveData[readIndex2];

        // Linearly interpolate within each table (lower and higher).
        double interpolationFactor = static_cast<float>(virtualReadIndex) - readIndex0;
        sampleHigher = (1 - interpolationFactor) * sample1Higher + interpolationFactor * sample2Higher;
        sampleLower = (1 - interpolationFactor) * sample1Lower + interpolationFactor * sample2Lower;

    } else if (incr >= interpolate3Point) {
        // We're doing about 6 interpolation values between each wave
        // table sample. Just use a 3-point Lagrange interpolator to get a
        // better estimate than just linear.
        //
        // See 3-point formula in http://dlmf.nist.gov/3.3#ii
        unsigned readIndex[3];

        for (int k = -1; k <= 1; ++k)
            readIndex[k + 1] = (readIndex0 + k) & readIndexMask;

        double a[3];
        double t = virtualReadIndex - readIndex0;

        a[0] = 0.5 * t * (t - 1);
        a[1] = 1 - t * t;
        a[2] = 0.5 * t * (t + 1);

        for (int k = 0; k < 3; ++k) {
            sampleLower += a[k] * lowerWaveData[readIndex[k]];
            sampleHigher += a[k] * higherWaveData[readIndex[k]];
        }
    } else {
        // For everything else (more than 6 points per entry), we'll do a
        // 5-point Lagrange interpolator. This is a trade-off between
        // quality and speed.
        //
        // See 5-point formula in http://dlmf.nist.gov/3.3#ii
        unsigned readIndex[5];
        for (int k = -2; k <= 2; ++k)
            readIndex[k + 2] = (readIndex0 + k) & readIndexMask;

        double a[5];
        double t = virtualReadIndex - readIndex0;
        double t2 = t * t;

        a[0] = t * (t2 - 1) * (t - 2) / 24;
        a[1] = -t * (t - 1) * (t2 - 4) / 6;
        a[2] = (t2 - 1) * (t2 - 4) / 4;
        a[3] = -t * (t + 1) * (t2 - 4) / 6;
        a[4] = t * (t2 - 1) * (t + 2) / 24;

        for (int k = 0; k < 5; ++k) {
            sampleLower += a[k] * lowerWaveData[readIndex[k]];
            sampleHigher += a[k] * higherWaveData[readIndex[k]];
        }
    }

    // Then interpolate between the two tables.
    float sample = (1 - tableInterpolationFactor) * sampleHigher + tableInterpolationFactor * sampleLower;
    return sample;
}

double OscillatorNode::processARate(int n, float* destP, double virtualReadIndex, float* phaseIncrements)
{
    float rateScale = m_periodicWave->rateScale();
    float invRateScale = 1 / rateScale;
    unsigned periodicWaveSize = m_periodicWave->periodicWaveSize();
    double invPeriodicWaveSize = 1.0 / periodicWaveSize;
    unsigned readIndexMask = periodicWaveSize - 1;

    float* higherWaveData = nullptr;
    float* lowerWaveData = nullptr;
    float tableInterpolationFactor = 0;

    for (int k = 0; k < n; ++k) {
        float incr = *phaseIncrements++;

        float frequency = invRateScale * incr;
        m_periodicWave->waveDataForFundamentalFrequency(frequency, lowerWaveData, higherWaveData, tableInterpolationFactor);

        float sample = doInterpolation(virtualReadIndex, fabs(incr), readIndexMask, tableInterpolationFactor, lowerWaveData, higherWaveData);

        *destP++ = sample;

        // Increment virtual read index and wrap virtualReadIndex into the range
        // 0 -> periodicWaveSize.
        virtualReadIndex += incr;
        virtualReadIndex -= floor(virtualReadIndex * invPeriodicWaveSize) * periodicWaveSize;
    }

    return virtualReadIndex;
}

double OscillatorNode::processKRate(int n, float* destP, double virtualReadIndex)
{
    unsigned periodicWaveSize = m_periodicWave->periodicWaveSize();
    double invPeriodicWaveSize = 1.0 / periodicWaveSize;
    unsigned readIndexMask = periodicWaveSize - 1;

    float frequency = 0;
    float* higherWaveData = nullptr;
    float* lowerWaveData = nullptr;
    float tableInterpolationFactor = 0;

    frequency = m_frequency->finalValue();
    float detune = m_detune->finalValue();
    float detuneScale = detuneToFrequencyMultiplier(detune);
    frequency *= detuneScale;
    clampFrequency(&frequency, 1, context().sampleRate() / 2);
    m_periodicWave->waveDataForFundamentalFrequency(frequency, lowerWaveData, higherWaveData, tableInterpolationFactor);

    float rateScale = m_periodicWave->rateScale();
    float incr = frequency * rateScale;

    for (int k = 0; k < n; ++k) {
        float sample = doInterpolation(virtualReadIndex, fabs(incr), readIndexMask, tableInterpolationFactor, lowerWaveData, higherWaveData);

        *destP++ = sample;

        // Increment virtual read index and wrap virtualReadIndex into the range
        // 0 -> periodicWaveSize.
        virtualReadIndex += incr;
        virtualReadIndex -= floor(virtualReadIndex * invPeriodicWaveSize) * periodicWaveSize;
    }

    return virtualReadIndex;
}

void OscillatorNode::process(size_t framesToProcess)
{
    auto& outputBus = *output(0)->bus();

    if (!isInitialized() || !outputBus.numberOfChannels()) {
        outputBus.zero();
        return;
    }

    ASSERT(framesToProcess <= m_phaseIncrements.size());
    if (framesToProcess > m_phaseIncrements.size())
        return;

    // The audio thread can't block on this lock, so we use tryLock() instead.
    if (!m_processLock.tryLock()) {
        // Too bad - tryLock() failed. We must be in the middle of changing wave-tables.
        outputBus.zero();
        return;
    }
    Locker locker { AdoptLock, m_processLock };

    // We must access m_periodicWave only inside the lock.
    if (!m_periodicWave.get()) {
        outputBus.zero();
        return;
    }

    size_t quantumFrameOffset = 0;
    size_t nonSilentFramesToProcess = 0;
    double startFrameOffset = 0;
    updateSchedulingInfo(framesToProcess, outputBus, quantumFrameOffset, nonSilentFramesToProcess, startFrameOffset);

    if (!nonSilentFramesToProcess) {
        outputBus.zero();
        return;
    }

    float* destP = outputBus.channel(0)->mutableData();

    ASSERT(quantumFrameOffset <= framesToProcess);

    // We keep virtualReadIndex double-precision since we're accumulating values.
    double virtualReadIndex = m_virtualReadIndex;

    float rateScale = m_periodicWave->rateScale();
    bool hasSampleAccurateValues = calculateSampleAccuratePhaseIncrements(framesToProcess);

    float frequency = 0;
    float* higherWaveData = nullptr;
    float* lowerWaveData = nullptr;
    float tableInterpolationFactor = 0;

    if (!hasSampleAccurateValues) {
        frequency = m_frequency->finalValue();
        float detune = m_detune->finalValue();
        float detuneScale = detuneToFrequencyMultiplier(detune);
        frequency *= detuneScale;
        clampFrequency(&frequency, 1, context().sampleRate() / 2);
        m_periodicWave->waveDataForFundamentalFrequency(frequency, lowerWaveData, higherWaveData, tableInterpolationFactor);
    }

    float* phaseIncrements = m_phaseIncrements.data();

    // Start rendering at the correct offset.
    destP += quantumFrameOffset;
    int n = nonSilentFramesToProcess;

    // If startFrameOffset is not 0, that means the oscillator doesn't actually
    // start at quantumFrameOffset, but just past that time. Adjust destP and n
    // to reflect that, and adjust virtualReadIndex to start the value at
    // startFrameOffset.
    if (startFrameOffset > 0) {
        ++destP;
        --n;
        virtualReadIndex += (1 - startFrameOffset) * frequency * rateScale;
        ASSERT(virtualReadIndex < m_periodicWave->periodicWaveSize());
    } else if (startFrameOffset < 0)
        virtualReadIndex = -startFrameOffset * frequency * rateScale;

    if (hasSampleAccurateValues)
        virtualReadIndex = processARate(n, destP, virtualReadIndex, phaseIncrements);
    else
        virtualReadIndex = processKRate(n, destP, virtualReadIndex);

    m_virtualReadIndex = virtualReadIndex;

    outputBus.clearSilentFlag();
}

void OscillatorNode::setPeriodicWave(PeriodicWave& periodicWave)
{
    ALWAYS_LOG(LOGIDENTIFIER, "sample rate = ", periodicWave.sampleRate(), ", wave size = ", periodicWave.periodicWaveSize(), ", rate scale = ", periodicWave.rateScale());
    ASSERT(isMainThread());
    
    // This synchronizes with process().
    Locker locker { m_processLock };
    m_periodicWave = &periodicWave;
    m_type = OscillatorType::Custom;
}

bool OscillatorNode::propagatesSilence() const
{
    ASSERT(context().isAudioThread());
    if (!isPlayingOrScheduled() || hasFinished())
        return true;
    if (!m_processLock.tryLock())
        return false; // Assume we have a periodic wave if we are unable to grab the lock.
    Locker locker { AdoptLock, m_processLock };
    return !m_periodicWave.get();
}

} // namespace WebCore

#endif // ENABLE(WEB_AUDIO)
