BogaudioModules

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

commit 407a5484cdfccaec0fbfbb3b67214904abdb062c
parent aeddb9f698094d2be9a39bd561408dd3a62825e6
Author: Matt Demanett <matt@demanett.net>
Date:   Wed,  7 Mar 2018 22:38:03 -0500

Add wavetable sine oscillator; use it in 8FO.

Diffstat:
Msrc/EightFO.cpp | 2+-
Msrc/EightFO.hpp | 2++
Msrc/Test.cpp | 2+-
Msrc/Test.hpp | 9++++++---
Msrc/dsp/oscillator.cpp | 34++++++++++++++++++++++++++++++++++
Msrc/dsp/oscillator.hpp | 44++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 88 insertions(+), 5 deletions(-)

diff --git a/src/EightFO.cpp b/src/EightFO.cpp @@ -116,7 +116,7 @@ void EightFO::updateOutput(bool useSample, Output& output, float& offset, float& assert(false); } case SINE_WAVE: { - v = sinf((_phasor._phase + offset) * M_PI); // FIXME + v = _sine.nextFromPhasor(_phasor, offset); break; } case TRIANGLE_WAVE: { diff --git a/src/EightFO.hpp b/src/EightFO.hpp @@ -95,6 +95,7 @@ struct EightFO : Module { SchmittTrigger _resetTrigger; Phasor _phasor; + SineTableOscillator _sine; TriangleOscillator _triangle; SawOscillator _ramp; SquareOscillator _square; @@ -129,6 +130,7 @@ struct EightFO : Module { EightFO() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) , _phasor(engineGetSampleRate(), 1.0f) + , _sine(0.0f, 0.0f) , _triangle(0.0f, 0.0f) , _ramp(0.0f, 0.0f) , _square(0.0f, 0.0f) diff --git a/src/Test.cpp b/src/Test.cpp @@ -37,7 +37,7 @@ void Test::step() { _sine2.setSampleRate(engineGetSampleRate()); _sine2.setFrequency(oscillatorPitch()); - outputs[OUT2_OUTPUT].value = 5.0f * powf(_sine2.next(), 5.0f); + outputs[OUT2_OUTPUT].value = _sine2.next(); #elif SQUARE _square.setSampleRate(engineGetSampleRate()); diff --git a/src/Test.hpp b/src/Test.hpp @@ -74,7 +74,7 @@ struct Test : Module { LowPassFilter _lpf; #elif SINE SineOscillator _sine; - SineOscillator _sine2; + SineTableOscillator _sine2; #elif SQUARE SquareOscillator _square; #elif SAW @@ -99,7 +99,7 @@ struct Test : Module { , _lpf(44100.0, 1000.0, 1.0) #elif SINE , _sine(44100.0, 1000.0, 5.0) - , _sine2(44100.0, 1000.0, 1.0, M_PI/1.0f) + , _sine2(44100.0, 1000.0, 5.0) #elif SQUARE , _square(44100.0, 1000.0, 5.0) #elif SAW @@ -117,7 +117,10 @@ struct Test : Module { { onReset(); -#ifdef SINEBANK +#ifdef SINE + _sine2.setPhase(M_PI); + +#elif SINEBANK const float baseAmplitude = 5.0; switch (5) { case 1: { diff --git a/src/dsp/oscillator.cpp b/src/dsp/oscillator.cpp @@ -39,6 +39,32 @@ float Phasor::_nextForPhase(float phase) { } +void TablePhasor::generate() { + if (!_table) { + _table = new float[_length] {}; + _generate(); + } +} + +float TablePhasor::_nextForPhase(float phase) { + if (!_table) { + generate(); + } + + while (phase >= maxPhase) { + phase -= maxPhase; + } + while (phase < 0.0f) { + phase += maxPhase; + } + float fi = phase * (_length / 2); + int i = (int)fi; + float v1 = _table[i]; + float v2 = _table[i + 1 == _length ? 0 : i + 1]; + return _amplitude * (v1 + (fi - i)*(v2 - v1)); +} + + // A New Recursive Quadrature Oscillator, Martin Vicanek, 2015 - http://vicanek.de/articles/QuadOsc.pdf void SineOscillator::setPhase(double phase) { _x = cos(phase); @@ -59,6 +85,14 @@ float SineOscillator::_next() { } +void SineTableOscillator::_generate() { + const float twoPI = 2.0f * M_PI; + for (int i = 0; i < _length; ++i) { + _table[i] = sinf(twoPI * (i / (float)_length)); + } +} + + float SawOscillator::_nextForPhase(float phase) { return _amplitude * (phase - halfMaxPhase); } diff --git a/src/dsp/oscillator.hpp b/src/dsp/oscillator.hpp @@ -2,6 +2,7 @@ #include <stdlib.h> #include <stdint.h> +#include <assert.h> #include <vector> #include "base.hpp" @@ -77,6 +78,36 @@ struct Phasor : OscillatorGenerator { static float phaseToRadians(float phase) { return phase * M_PI; } }; +struct TablePhasor : Phasor { + int _length = 0; + float* _table = NULL; + float _amplitude; + + TablePhasor( + double sampleRate, + double frequency, + float amplitude = 1.0f, + int n = 10 + ) + : Phasor(sampleRate, frequency) + , _amplitude(amplitude) + { + assert(n > 0); + assert(n <= 16); + _length = 1 << n; + } + virtual ~TablePhasor() { + if (_table) { + delete[] _table; + } + } + + void generate(); + virtual void _generate() = 0; + + virtual float _nextForPhase(float phase) override; +}; + struct SineOscillator : OscillatorGenerator { double _k1, _k2; double _x; @@ -109,6 +140,19 @@ struct SineOscillator : OscillatorGenerator { virtual float _next() override; }; +struct SineTableOscillator : TablePhasor { + SineTableOscillator( + float sampleRate, + float frequency, + float amplitude = 1.0 + ) + : TablePhasor(sampleRate, frequency, amplitude) + { + } + + virtual void _generate() override; +}; + struct SawOscillator : Phasor { const float halfMaxPhase = 0.5f * maxPhase; float _amplitude;