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:
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