/*
 * Copyright (C) 2016 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.
 */

#ifndef SINE_GENERATOR_H
#define SINE_GENERATOR_H

#include <math.h>

class SineGenerator
{
public:
    SineGenerator() {}
    virtual ~SineGenerator() = default;

    void setup(double frequency, double frameRate) {
        mFrameRate = frameRate;
        mPhaseIncrement = frequency * M_PI * 2 / frameRate;
    }

    void setSweep(double frequencyLow, double frequencyHigh, double seconds) {
        mPhaseIncrementLow = frequencyLow * M_PI * 2 / mFrameRate;
        mPhaseIncrementHigh = frequencyHigh * M_PI * 2 / mFrameRate;

        double numFrames = seconds * mFrameRate;
        mUpScaler = pow((frequencyHigh / frequencyLow), (1.0 / numFrames));
        mDownScaler = 1.0 / mUpScaler;
        mGoingUp = true;
        mSweeping = true;
    }

    void render(int16_t *buffer, int32_t channelStride, int32_t numFrames) {
        int sampleIndex = 0;
        for (int i = 0; i < numFrames; i++) {
            buffer[sampleIndex] = (int16_t) (32767 * sin(mPhase) * mAmplitude);
            sampleIndex += channelStride;
            advancePhase();
        }
    }
    void render(float *buffer, int32_t channelStride, int32_t numFrames) {
        int sampleIndex = 0;
        for (int i = 0; i < numFrames; i++) {
            buffer[sampleIndex] = sin(mPhase) * mAmplitude;
            sampleIndex += channelStride;
            advancePhase();
        }
    }

    void setAmplitude(double amplitude) {
        mAmplitude = amplitude;
    }
    double getAmplitude() const {
        return mAmplitude;
    }

private:
    void advancePhase() {
        mPhase += mPhaseIncrement;
        if (mPhase > M_PI * 2) {
            mPhase -= M_PI * 2;
        }
        if (mSweeping) {
            if (mGoingUp) {
                mPhaseIncrement *= mUpScaler;
                if (mPhaseIncrement > mPhaseIncrementHigh) {
                    mGoingUp = false;
                }
            } else {
                mPhaseIncrement *= mDownScaler;
                if (mPhaseIncrement < mPhaseIncrementLow) {
                    mGoingUp = true;
                }
            }
        }
    }

    double mAmplitude = 0.05;  // unitless scaler
    double mPhase = 0.0;
    double mPhaseIncrement = 440 * M_PI * 2 / 48000;
    double mFrameRate = 48000;
    double mPhaseIncrementLow;
    double mPhaseIncrementHigh;
    double mUpScaler = 1.0;
    double mDownScaler = 1.0;
    bool   mGoingUp = false;
    bool   mSweeping = false;
};

#endif /* SINE_GENERATOR_H */

