BogaudioModules

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

commit 3da1e2b695e256e8dd0a1b6a42bdaa4d69dc38b1
parent 31435932e6503922b148fa92a6e0c6a17fcfc045
Author: Matt Demanett <matt@demanett.net>
Date:   Sat, 17 Mar 2018 19:34:47 -0400

Table classes; factored out of oscillators.

Diffstat:
Msrc/dsp/oscillator.cpp | 25+++----------------------
Msrc/dsp/oscillator.hpp | 26++++++--------------------
Asrc/dsp/table.cpp | 26++++++++++++++++++++++++++
Asrc/dsp/table.hpp | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 110 insertions(+), 42 deletions(-)

diff --git a/src/dsp/oscillator.cpp b/src/dsp/oscillator.cpp @@ -39,28 +39,17 @@ 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); + float fi = phase * (_table.length() / 2); int i = (int)fi; - float v1 = _table[i]; - float v2 = _table[i + 1 == _length ? 0 : i + 1]; + float v1 = _table.value(i); + float v2 = _table.value(i + 1 == _table.length() ? 0 : i + 1); return _amplitude * (v1 + (fi - i)*(v2 - v1)); } @@ -85,14 +74,6 @@ 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 @@ -1,11 +1,10 @@ #pragma once #include <stdlib.h> -#include <assert.h> #include <vector> #include "base.hpp" -#include "noise.hpp" +#include "table.hpp" namespace bogaudio { namespace dsp { @@ -78,32 +77,21 @@ struct Phasor : OscillatorGenerator { }; struct TablePhasor : Phasor { - int _length = 0; - float* _table = NULL; + const Table& _table; float _amplitude; TablePhasor( + const Table& table, double sampleRate, double frequency, - float amplitude = 1.0f, - int n = 10 + float amplitude = 1.0f ) : Phasor(sampleRate, frequency) + , _table(table) , _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; }; @@ -145,11 +133,9 @@ struct SineTableOscillator : TablePhasor { float frequency, float amplitude = 1.0 ) - : TablePhasor(sampleRate, frequency, amplitude) + : TablePhasor(StaticSineTable::table(), sampleRate, frequency, amplitude) { } - - virtual void _generate() override; }; struct SawOscillator : Phasor { diff --git a/src/dsp/table.cpp b/src/dsp/table.cpp @@ -0,0 +1,26 @@ +#include <math.h> + +#include "table.hpp" + +using namespace bogaudio::dsp; + +void Table::generate() { + if (!_table) { + _table = new float[_length] {}; + _generate(); + } +} + + +void SineTable::_generate() { + const float twoPI = 2.0f * M_PI; + for (int i = 0, j = _length / 4; i <= j; ++i) { + _table[i] = sinf(twoPI * (i / (float)_length)); + } + for (int i = 1, j = _length / 4; i < j; ++i) { + _table[i + j] = _table[j - i]; + } + for (int i = 0, j = _length / 2; i < j; ++i) { + _table[i + j] = -_table[i]; + } +} diff --git a/src/dsp/table.hpp b/src/dsp/table.hpp @@ -0,0 +1,75 @@ +#pragma once + +#include <assert.h> + +#include "base.hpp" + +namespace bogaudio { +namespace dsp { + +class Table { +protected: + int _length = 0; + float* _table = NULL; + +public: + Table(int n = 10) { + assert(n > 0); + assert(n <= 16); + _length = 1 << n; + } + virtual ~Table() { + if (_table) { + delete[] _table; + } + } + + inline int length() const { return _length; } + + inline float value(int i) const { + assert(i >= 0 && i < _length); + assert(_table); + return _table[i]; + } + + void generate(); + +protected: + virtual void _generate() = 0; +}; + +template<class T, int N> class StaticTable { +private: + Table* _table = NULL; + + StaticTable() { + } + ~StaticTable() { + if (_table) { + delete _table; + } + } + +public: + StaticTable(const StaticTable&) = delete; + void operator=(const StaticTable&) = delete; + + static const Table& table() { + static StaticTable<T, N> instance; + if (!instance._table) { + instance._table = new T(N); + instance._table->generate(); + } + return *instance._table; + } +}; + + +struct SineTable : Table { + SineTable(int n = 10) : Table(n) {} + virtual void _generate() override; +}; +struct StaticSineTable : StaticTable<SineTable, 12> {}; + +} // namespace dsp +} // namespace bogaudio