BogaudioModules

BogaudioModules for VCV Rack
Log | Files | Refs | README | LICENSE

commit b57623d3c35cc9cc1bf900e77b5e720912742f06
parent 8d6cd6d023afd97720d4d470bc1d50a2f97ee4c4
Author: Matt Demanett <matt@demanett.net>
Date:   Thu,  4 Jan 2018 21:44:28 -0500

Sine oscillator; use it in Reftone.

Diffstat:
Abenchmarks/oscillator.cpp | 14++++++++++++++
Msrc/Reftone.cpp | 22+++++++++++++++-------
Msrc/dsp/dsp.hpp | 2++
Asrc/dsp/oscillator.cpp | 20++++++++++++++++++++
Asrc/dsp/oscillator.hpp | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 116 insertions(+), 7 deletions(-)

diff --git a/benchmarks/oscillator.cpp b/benchmarks/oscillator.cpp @@ -0,0 +1,14 @@ + +#include <benchmark/benchmark.h> + +#include <dsp.hpp> + +using namespace bogaudio::dsp; + +static void BM_SineOscillator(benchmark::State& state) { + SineOscillator o(44100.0, 440.0); + for (auto _ : state) { + o.next(); + } +} +BENCHMARK(BM_SineOscillator); diff --git a/src/Reftone.cpp b/src/Reftone.cpp @@ -1,7 +1,11 @@ #include <string.h> #include <algorithm> + #include "BogaudioModules.hpp" +#include "dsp/dsp.hpp" + +using namespace bogaudio::dsp; struct Reftone : Module { enum ParamsIds { @@ -29,18 +33,21 @@ struct Reftone : Module { int _octave = 4; float _fine = 0.0; float _frequency = 440.0; + SineOscillator _sine; - Reftone() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { - reset(); + Reftone() + : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) + , _sine(engineGetSampleRate(), _frequency) + { + } + + virtual void onSampleRateChange() override { + _sine.setSampleRate(engineGetSampleRate()); } - virtual void reset() override; virtual void step() override; }; -void Reftone::reset() { -} - void Reftone::step() { const float f0 = 261.626; const int f0Pitch = 0; @@ -51,9 +58,10 @@ void Reftone::step() { _octave = clampf(params[OCTAVE_PARAM].value, 1.0, 8.0); _fine = clampf(params[FINE_PARAM].value, -0.99, 0.99); _frequency = f0*powf(twelfthRootTwo, 12*(_octave - f0Octave) + (_pitch - f0Pitch) + _fine); + _sine.setFrequency(_frequency); outputs[CV_OUTPUT].value = log2f(_frequency / f0); - outputs[OUT_OUTPUT].value = 0.0; // FIXME: sine out. + outputs[OUT_OUTPUT].value = _sine.next() * 5.0; } diff --git a/src/dsp/dsp.hpp b/src/dsp/dsp.hpp @@ -3,5 +3,7 @@ #include "base.hpp" #include "buffer.hpp" + #include "analyzer.hpp" +#include "oscillator.hpp" #include "noise.hpp" diff --git a/src/dsp/oscillator.cpp b/src/dsp/oscillator.cpp @@ -0,0 +1,20 @@ +#include <math.h> + +#include "dsp.hpp" + +using namespace bogaudio::dsp; + +void SineOscillator::updateDeltaTheta() { + float sampleTime = 1.0 / _sampleRate; + float cycleTime = 1.0 / _frequency; + float _deltaTheta = (sampleTime / cycleTime) * 2.0f * M_PI; + _sinDeltaTheta = sinf(_deltaTheta); + _cosDeltaTheta = cosf(_deltaTheta); +} + +float SineOscillator::_next() { + float x2 = _x*_cosDeltaTheta - _y*_sinDeltaTheta; + _y = _x*_sinDeltaTheta + _y*_cosDeltaTheta; + _x = x2; + return _y; +} diff --git a/src/dsp/oscillator.hpp b/src/dsp/oscillator.hpp @@ -0,0 +1,65 @@ + +namespace bogaudio { +namespace dsp { + +struct OscillatorGenerator : Generator { + float _sampleRate; + float _frequency; + + OscillatorGenerator( + float sampleRate, + float frequency + ) + : _sampleRate(sampleRate) + , _frequency(frequency) + { + } + + void setSampleRate(float sampleRate) { + if (_sampleRate != sampleRate) { + _sampleRate = sampleRate; + _sampleRateChanged(); + } + } + + virtual void _sampleRateChanged() {} + + void setFrequency(float frequency) { + if (_frequency != frequency) { + _frequency = frequency; + _frequencyChanged(); + } + } + + virtual void _frequencyChanged() {} +}; + +struct SineOscillator : OscillatorGenerator { + float _x = 1.0; + float _y = 0.0; + float _sinDeltaTheta; + float _cosDeltaTheta; + + SineOscillator( + float sampleRate, + float frequency + ) + : OscillatorGenerator(sampleRate, frequency) + { + updateDeltaTheta(); + } + + virtual void _sampleRateChanged() override { + updateDeltaTheta(); + } + + virtual void _frequencyChanged() override { + updateDeltaTheta(); + } + + void updateDeltaTheta(); + virtual float _next() override; +}; + +} // namespace dsp +} // namespace bogaudio