#pragma once #include "AudioMath.h" #include "LookupTable.h" #include "ObjectCache.h" #include "SawOscillator.h" template class SinOscillatorParams; template class SinOscillatorState; /** * A simple sin oscillator based on lookup table. * Advantage: * fast. * frequency may be changed without phase discontinuity. * Optional quadrature output. * Disadvantage: * Not the best spectral purity (significant amount of phase jitter) */ template class SinOscillator { public: SinOscillator() = delete; // we are only static static void setFrequency(SinOscillatorParams&, T frequency); static T run(SinOscillatorState&, const SinOscillatorParams&); static void runQuadrature(T& output, T& outputQuadrature, SinOscillatorState&, const SinOscillatorParams&); }; template inline void SinOscillator::setFrequency(SinOscillatorParams& params, T frequency) { std::function f = AudioMath::makeFunc_Sin(); // TODO: figure out a better initialization strategy // and a better strategy for table size // with 4096 thd was -130 db. let's use less memory! // if (!params.lookupParams.isValid()) { // LookupTable::init(params.lookupParams, 256, 0, 1, f); // } assert(params.lookupParams->isValid()); SawOscillator::setFrequency(params.sawParams, frequency); } template inline T SinOscillator::run( SinOscillatorState& state, const SinOscillatorParams& params) { const T temp = SawOscillator::runSaw(state.sawState, params.sawParams); const T ret = LookupTable::lookup(*params.lookupParams, temp); return ret; } template inline void SinOscillator::runQuadrature( T& output, T& outputQuadrature, SinOscillatorState& state, const SinOscillatorParams& params) { T saw, quadratureSaw; SawOscillator::runQuadrature(saw, quadratureSaw, state.sawState, params.sawParams); output = LookupTable::lookup(*params.lookupParams, saw); outputQuadrature = LookupTable::lookup(*params.lookupParams, quadratureSaw); }; template class SinOscillatorParams { public: SawOscillatorParams sawParams; // LookupTableParams lookupParams; std::shared_ptr> lookupParams; SinOscillatorParams() { lookupParams = ObjectCache::getSinLookup(); } SinOscillatorParams(const SinOscillatorParams&) = delete; }; template class SinOscillatorState { public: SawOscillatorState sawState; };