#pragma once #include #include #include #include #include #include #include #include #include #include using std::shared_ptr; using std::vector; using std::for_each; using namespace boost::multiprecision; typedef cpp_bin_float_double MP_TYPE; const MP_TYPE two_pi = boost::math::constants::two_pi(); template class Generator { public: virtual dataType getSample() = 0; virtual void getSamples(size_t nSamples, dataType* buf); virtual float getFrequency() const; virtual void setFrequency(float frequency); virtual float getAmplitude() const; virtual void setAmplitude(float amplitude); virtual float getAmplitudeDb() const; virtual void setAmplitudeDb(float amplitude); virtual bool isEnabled() const; virtual void enable(); virtual void disable(); virtual ~Generator(); // disallow copy of virtual interface Generator(Generator const&) = delete; Generator& operator=(Generator const&) = delete; protected: Generator(uint32_t _sampleRate, float _frequency, float _amplitude = 1); uint32_t sampleRate; float frequency; float amplitude; bool enabled; private: }; template class SineGenerator : public Generator { public: SineGenerator(uint32_t _sampleRate, float _frequency, float _amplitude = 1, bool caching = true); dataType getSample() final; void setFrequency(float _frequency) final; void setFrequency(MP_TYPE frequency); void setAmplitude(float amplitude); virtual ~SineGenerator(); private: MP_TYPE instPhase; MP_TYPE phaseIncr; void dirtyCache(); dataType unCachedGetSample(); dataType cachedGetSample(); vector sampleCache; typename vector::const_iterator cachePos; const bool caching; bool cacheInvalid; }; template class NoiseGenerator : public Generator { public: enum NOISE_TYPE { WHITE, }; NoiseGenerator(uint32_t _sampleRate, NOISE_TYPE type, float _amplitude = 1); dataType getSample() final; virtual ~NoiseGenerator(); private: std::mt19937_64 rand_gen; }; template class JTestGenerator : public Generator { public: JTestGenerator(uint32_t sampleRate, uint8_t nbits); dataType getSample() final; virtual ~JTestGenerator(); private: std::vector loop; typename std::vector::const_iterator pos; }; template class SweepGenerator : public Generator { public: SweepGenerator(uint32_t sampleRate, float startFreq, float endFreq, float length, float amplitude = 1); virtual ~SweepGenerator(); dataType getSample() final; float getFrequency() const; void setAmplitude(float amplitude); void setFrequency(float frequency); private: SineGenerator sg; float length; MP_TYPE startFreq; MP_TYPE curFreq; MP_TYPE freqStep; }; template class SineSynth { public: SineSynth(uint32_t _sampleRate); void addSynth(shared_ptr>); vector>> getSynths() const; void clearSynths(); void getSamples(size_t nSamples, dataType* buf); private: uint32_t sampleRate; vector>> generators; };