diff --git a/notes.txt b/notes.txt index 18c5ad0..3edaf28 100644 --- a/notes.txt +++ b/notes.txt @@ -6,8 +6,8 @@ c5 = bottom of divider chain = midi C3 = 130.81Hz RC networks = capacitor and effectively 10k because of the diode and 27.6k resistor network -c1=2842 -c6 = +c1= 5n6/10k 2842Hz +c6 = 180n/10k 80Hz Each key drives two sets of gates, for 4' (violin) and 8' (viola/trumpet/horn) Five sets of gates apiece diff --git a/plugin/assigner.cpp b/plugin/assigner.cpp index e542a36..8fd2114 100644 --- a/plugin/assigner.cpp +++ b/plugin/assigner.cpp @@ -17,8 +17,8 @@ */ #include "assigner.hpp" - -// #define DEBUG +#include "generator.hpp" +#define DEBUG void Assigner::dumpTables() { #ifdef DEBUG @@ -32,7 +32,7 @@ void Assigner::dumpTables() { #endif } -Assigner::Assigner() { +Assigner::Assigner(Voice *v) { d_debug("assigner constructor"); // set up the assigner tables @@ -40,6 +40,7 @@ Assigner::Assigner() { voiceTbl[i] = i; noteTbl[i] = 0x80; } + voices = v; } void Assigner::handleMidi(MidiEvent *ev) { @@ -135,5 +136,7 @@ void Assigner::noteOn(uint8_t note) { // printf("at end, l=%d e=%d\n", l,e); noteTbl[v] = note; + voices[v].startNote(note, 48000); + d_debug("send voice on %3d to voice %d", note, v); } diff --git a/plugin/assigner.hpp b/plugin/assigner.hpp index 3078c61..b5f1f54 100644 --- a/plugin/assigner.hpp +++ b/plugin/assigner.hpp @@ -21,9 +21,11 @@ #include "DistrhoPlugin.hpp" +#include "generator.hpp" + class Assigner { public: - Assigner(); + Assigner(Voice *v); void handleMidi(MidiEvent *ev); uint8_t noteTbl[NUM_VOICES]; // note played by voice @@ -32,6 +34,8 @@ class Assigner { void noteOff(uint8_t note); // incoming note off uint8_t voiceTbl[NUM_VOICES]; // voices in order of use + Voice *voices; + void dumpTables(); }; diff --git a/plugin/generator.cpp b/plugin/generator.cpp index 5129ceb..6d4f6e6 100644 --- a/plugin/generator.cpp +++ b/plugin/generator.cpp @@ -38,7 +38,6 @@ void Generator::setupGenerator(double sampleRate) { } void Generator::runBlock(float *output, uint8_t *noteTable, uint32_t frames) { - memset(output, 0, frames * sizeof(float)); for (uint32_t i = 0; i < frames; i++) { @@ -46,14 +45,26 @@ void Generator::runBlock(float *output, uint8_t *noteTable, uint32_t frames) { phase[p] += omega[p]; } - for (uint8_t k=0; k> n2)) ? 0.1 : -0.1) * (noteTable[k]&0x80?0:1); + for (uint8_t k = 0; k < NUM_VOICES; k++) { + uint8_t n1 = noteTable[k] % 12, n2 = (noteTable[k] / 12 - 3); + float n = ((phase[n1] & (0x80000000 >> n2)) ? 0.25 : -0.25); + + voices[k].vc34 = ((n - voices[k].vc34) * voices[k].c34) + voices[k].vc34; + + n -= voices[k].vc34; + n *= (phase[n1] & (0x80000000 >> n2)) ? 1 : 0; + + output[i] += n * (noteTable[k] & 0x80 ? 0 : 1); } - - - } - - +} + +void Voice::startNote(uint8_t key, double sampleRate) { + // start a new note + // float fc = 88.4 * powf(2, 0.083334 * (key - 36)); + // c34 = powf((1 - 2 * fc / sampleRate), 2); + float fc = 88.4 * powf(2, 0.083334 * (key - 36)); + float coef = 1 - exp(-6.283 * fc / 48000.0); + c34 = coef; + printf("key = %d, shaper cutoff = %f, coefficient = %f %f\n", key, fc, coef, c34); } diff --git a/plugin/generator.hpp b/plugin/generator.hpp index 9fa362a..1634bbb 100644 --- a/plugin/generator.hpp +++ b/plugin/generator.hpp @@ -21,16 +21,33 @@ #include +#include "DistrhoPluginInfo.h" + +class Generator; + +class Voice { + friend Generator; + + public: + void startNote(uint8_t key, double sampleRate); + + private: + uint8_t semi, oct; + float c34=0, vc34=0; +}; + + class Generator { public: Generator(); - void setupGenerator(double sampleRate); - void runBlock(float *output, uint8_t *noteTable, uint32_t frames); + Voice voices[NUM_VOICES]; + private: uint32_t phase[12]; uint32_t omega[12]; }; + #endif \ No newline at end of file diff --git a/plugin/sonnenlicht.cpp b/plugin/sonnenlicht.cpp index f16b627..245ac02 100644 --- a/plugin/sonnenlicht.cpp +++ b/plugin/sonnenlicht.cpp @@ -24,8 +24,8 @@ START_NAMESPACE_DISTRHO Sonnenlicht::Sonnenlicht() : Plugin(kParameterCount, 0, 0), fSampleRate(getSampleRate()) { printf("initialiser called\n"); - assigner = new Assigner; genny.setupGenerator(fSampleRate); + assigner = new Assigner(genny.voices); } Sonnenlicht::~Sonnenlicht() {