/*  FrequencyFunction.h

    flatzebra - SDL-based sound renderer
    Copyright (C) 2011 Pierre Sarrazin <http://sarrazip.com/>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public
    License along with this program; if not, write to the Free
    Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA  02110-1301, USA.
*/

#pragma once

#include <stddef.h>


namespace roundbeetle {


// Abstract class giving the number of samples per period as a function
// of time, expressed as a number of samples since the beginning of playback.
//
class FrequencyFunction
{
public:

    virtual ~FrequencyFunction()
    {
    }

    virtual size_t getNumSamplesPerPeriod(size_t sampleCounter) = 0;

};


class LinearMovingFreq : public FrequencyFunction
{
public:

    // Function that moves the frequency (in hertz) linearly from _startFreq
    // to _endFreq as the time in seconds goes from zero to _totalTimeInS.
    // Uses SoundRenderer::freq() to convert a number of samples to seconds.
    //
    // _startFreqInHz: must be positive.
    // _endFreqInHz: must be positive.
    // _totalTimeInS: must be positive.
    //
    LinearMovingFreq(float _startFreqInHz, float _endFreqInHz, float _totalTimeInS);

    virtual ~LinearMovingFreq();

    // Returns a number of samples per period as a function of the time
    // elapsed since the beginning of playback, where the time is received
    // as a number of played samples.
    //
    // Formula: samples per period = renderer freq. divided by current freq.
    //                             = startFreq + t * (endFreq - startFreq)
    // where t goes from 0 to 1 as sampleCounter goes from 0 to totalTime.
    // But t = (sampleCounter / rendererFreq) / totalTime,
    // so formula is:
    // startFreq + sampleCounter * ((endFreq - startFreq) / (rendererFreq * totalTime)).
    // Here, sampleCounter's factor is precompted.
    //
    virtual size_t getNumSamplesPerPeriod(size_t sampleCounter) override;

    float startFreq;  // hertz
    float rendererFreq;  // hertz
    float factor;
};


}  // namespace roundbeetle
