From af2968c23feeba7a891039eb006d75774f239807 Mon Sep 17 00:00:00 2001 From: Gordon JC Pearce Date: Sun, 20 Oct 2024 01:08:50 +0100 Subject: [PATCH] better --- Makefile | 1 + plugin/assigner.cpp | 12 ++-- plugin/assigner.hpp | 13 ++++- plugin/oscillator.cpp | 2 +- plugin/peacock.cpp | 7 ++- plugin/peacock.hpp | 6 ++ plugin/voiceboard.cpp | 124 ++++++++++++++++++++++-------------------- plugin/voiceboard.hpp | 6 +- 8 files changed, 93 insertions(+), 78 deletions(-) diff --git a/Makefile b/Makefile index 051d16e..92a7e52 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,7 @@ include dpf/Makefile.base.mk +CFLAGS += -ggdb all: plugins gen plugins: diff --git a/plugin/assigner.cpp b/plugin/assigner.cpp index 87ba7c8..264bc72 100644 --- a/plugin/assigner.cpp +++ b/plugin/assigner.cpp @@ -21,8 +21,6 @@ #include "voiceboard.hpp" #include "peacock.hpp" -Assigner ic1; - void Assigner::printMap() { printf("note memory:\n"); for (uint8_t i = 0; i < NUM_VOICES; i++) printf("%02x ", voicemap[i]); @@ -52,14 +50,14 @@ void Assigner::handleMidi(const MidiEvent *ev) { case 0xb0: switch (ev->data[1]) { case 0x01: - ic29.modWheel = ev->data[2]; + _ic29->modWheel = ev->data[2]; break; default: break; } break; // nothing to do here except in special cases where we don't expect the host to pass on controls case 0xe0: // pitch bend; - ic29.pitchBend = ev->data[2] << 7 | ev->data[1]; + _ic29->pitchBend = ev->data[2] << 7 | ev->data[1]; break; default: d_debug("unhandled MIDI event, status %02x value %02x\n", ev->data[0], ev->data[1]); @@ -75,7 +73,7 @@ void Assigner::noteOff(uint8_t note) { memmove(keymap + i, keymap + i + 1, NUM_VOICES - i - 1); voicemap[NUM_VOICES - 1] = voice; keymap[NUM_VOICES - 1] = note | 0x80; - ic29.voiceOff(voice); + _ic29->voiceOff(voice); } } } @@ -91,7 +89,7 @@ void Assigner::noteOn(uint8_t note) { memmove(keymap + 1, keymap, i); keymap[0] = note; // show note as on voicemap[0] = voice; - ic29.voiceOn(voice, note); + _ic29->voiceOn(voice, note); return; } } @@ -105,7 +103,7 @@ void Assigner::noteOn(uint8_t note) { memmove(keymap + 1, keymap, i); keymap[0] = note; // show note as on voicemap[0] = voice; - ic29.voiceOn(voice, note); + _ic29->voiceOn(voice, note); return; } } diff --git a/plugin/assigner.hpp b/plugin/assigner.hpp index f5dffa3..dc4c3e8 100644 --- a/plugin/assigner.hpp +++ b/plugin/assigner.hpp @@ -18,20 +18,27 @@ #pragma once -#include "peacock.hpp" +#include "DistrhoPlugin.hpp" +#define NUM_VOICES 8 + +#include "voiceboard.hpp" class Assigner { public: Assigner(); + void setVoiceBoard(Synth& s) { + _ic29 = &s; + } void handleMidi(const MidiEvent *ev); + private: void noteOn(uint8_t note); void noteOff(uint8_t note); void printMap(); + Synth* _ic29; + uint8_t keymap[NUM_VOICES]; uint8_t voicemap[NUM_VOICES]; }; - -extern Assigner ic1; \ No newline at end of file diff --git a/plugin/oscillator.cpp b/plugin/oscillator.cpp index 31c2587..0fd65f9 100644 --- a/plugin/oscillator.cpp +++ b/plugin/oscillator.cpp @@ -68,7 +68,7 @@ void Voice::run(float *buffer, uint32_t pos, uint32_t samples) { // the DC correction is important because the hardware synth is AC-coupled effectively high-passing // the signal at about 10Hz or so, preventing any PWM rumble from leaking through! delay += subosc; - delay += ic29.noise[i+pos]; + //delay += ic29.noise[i+pos]; lastpw = pwrc; buffer[i + pos] = y * 0.707; diff --git a/plugin/peacock.cpp b/plugin/peacock.cpp index adc8aec..9c9900e 100644 --- a/plugin/peacock.cpp +++ b/plugin/peacock.cpp @@ -25,6 +25,7 @@ START_NAMESPACE_DISTRHO Peacock::Peacock() : Plugin(paramCount, 0, 0), sampleRate(getSampleRate()) { printf("peacock constructor\n"); + ic1.setVoiceBoard(ic29); ic29.buildTables(getSampleRate()); ic29.bufferSize = getBufferSize(); } @@ -84,10 +85,10 @@ void Peacock::run(const float **, float **outputs, uint32_t frames, const MidiEv // run every synth voice into the buffer here FIXME for (uint8_t i = 0; i < NUM_VOICES; i++) { - ic29.voices[i].run(outputs[0], framePos, sizeThisTime); - ic29.voices[i].filter(outputs[0], framePos, sizeThisTime); + //ic29->voices[i].run(outputs[0], framePos, sizeThisTime); + //ic29->voices[i].filter(outputs[0], framePos, sizeThisTime); for (uint8_t j=0; jvoices[i].env.level/16384.0; } } diff --git a/plugin/peacock.hpp b/plugin/peacock.hpp index 9e1fc5e..452afc8 100644 --- a/plugin/peacock.hpp +++ b/plugin/peacock.hpp @@ -23,6 +23,9 @@ #include "DistrhoPlugin.hpp" +#include "assigner.hpp" +#include "voiceboard.hpp" + START_NAMESPACE_DISTRHO class Peacock : public Plugin { @@ -87,6 +90,9 @@ class Peacock : public Plugin { uint32_t blockLeft = 0; uint32_t lastEvent = 0; + Assigner ic1; + Synth ic29; + void runMidi(const MidiEvent *ev, uint32_t count, uint32_t timeLimit); DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Peacock); diff --git a/plugin/voiceboard.cpp b/plugin/voiceboard.cpp index c8ee426..205a55b 100644 --- a/plugin/voiceboard.cpp +++ b/plugin/voiceboard.cpp @@ -18,14 +18,15 @@ #include "voiceboard.hpp" +#include + +#include "DistrhoPlugin.hpp" #include "ic29tables.hpp" -Synth ic29; +#define DEBUG Synth::Synth() { - d_debug("initialising synth\n"); - portaCoeff = 0x0; - noise = new float [4096]; + printf("Synth constructor\n"); } void Synth::buildTables(double sampleRate) { @@ -40,9 +41,7 @@ void Synth::buildTables(double sampleRate) { // the ROM preset for adjusting the VCF scale and centre presets cutoff to $31 // and key scale to $7f, which corresponds to C4 = 248Hz and C6 = 992Hz, B3 and B5 - for (uint16_t i = 0; i< 256; i++) { - - + for (uint16_t i = 0; i < 256; i++) { } } @@ -50,10 +49,10 @@ void Synth::run() { // handle a "loop" worth of envelopes, pitch calculations, etc // callled once every 4.3ms block of samples - ic29.lfo.run(); + lfo.run(); masterPitch = 0x1818; - uint16_t vcoLfoDepth = ic29.lfoDepthTable[ic29.patchRam.vcoLfoMod] + ic29.modWheel; + uint16_t vcoLfoDepth = lfoDepthTable[patchRam.vcoLfoMod] + modWheel; vcoLfoDepth = (vcoLfoDepth < 0xff) ? vcoLfoDepth : 0xff; masterPitch += (lfo.lfoOut * vcoLfoDepth) >> 11; @@ -65,31 +64,34 @@ void Synth::run() { // PWM is bit 0 sw2, 0 = fixed 1 = lfo // 0 sets EA to 0x3fff, 1 adds - uint16_t pwmVal = 0x2000 - ic29.lfo.lfoOut; - if (ic29.patchRam.switch2 & 0x01) pwmVal = 0x3fff; - ic29.pwm = 0.5 - pwmVal / 32768.0f * (ic29.patchRam.pwmLfoMod / 106.0f); + uint16_t pwmVal = 0x2000 - lfo.lfoOut; + if (patchRam.switch2 & 0x01) pwmVal = 0x3fff; + pwm = 0.5 - pwmVal / 32768.0f * (patchRam.pwmLfoMod / 106.0f); // generate the voices, then - for (uint32_t i=0; i target) pitch = target; + } + // portamento down + if (pitch > target) { + pitch -= ic29.portaCoeff; + if (pitch < target) pitch = target; + } + } else { + pitch = target; + } - if (ic29.portaCoeff != 0) { - // portamento up - if (pitch < target) { - pitch += ic29.portaCoeff; - if (pitch > target) pitch = target; - } - // portamento down - if (pitch > target) { - pitch -= ic29.portaCoeff; - if (pitch < target) pitch = target; - } - } else { - pitch = target; + pitch += ic29.masterPitch; + + if (pitch < 0x3000) pitch = 0x3000; // lowest note + if (pitch > 0x9700) pitch = 0x6700; // highest note + + pitch -= 0x3000; + + // interpolate between the two table values + double o1 = ic29.pitchTable[pitch >> 8]; + double o2 = ic29.pitchTable[(pitch >> 8) + 1]; + double frac = (pitch & 0xff) / 256.0f; + + omega = ((o2 - o1) * frac) + o1; } - pitch += ic29.masterPitch; + void Voice::update() { + // calculate the once-per-block values + env.run(); + calcPitch(); - if (pitch < 0x3000) pitch = 0x3000; // lowest note - if (pitch > 0x9700) pitch = 0x6700; // highest note + pw = (ic29.patchRam.switch1 & 0x08) ? ic29.pwm : 0.0f; + saw = (ic29.patchRam.switch1 & 0x10) ? 1.0f : 0.0f; + sub = ic29.patchRam.subLevel / 128.0f; - pitch -= 0x3000; + ic29.lfo.rate = ic29.patchRam.lfoRate; - // interpolate between the two table values - double o1 = ic29.pitchTable[pitch >> 8]; - double o2 = ic29.pitchTable[(pitch >> 8) + 1]; - double frac = (pitch & 0xff) / 256.0f; - - omega = ((o2 - o1) * frac) + o1; -} - -void Voice::update() { - // calculate the once-per-block values - env.run(); - calcPitch(); - - pw = (ic29.patchRam.switch1 & 0x08) ? ic29.pwm : 0.0f; - saw = (ic29.patchRam.switch1 & 0x10) ? 1.0f : 0.0f; - sub = ic29.patchRam.subLevel / 128.0f; - - ic29.lfo.rate = ic29.patchRam.lfoRate; - - // do filter values + // do filter values + */ } void Voice::on(uint8_t key) { + d_debug("Voice on key %02x\n", key); voiceState = V_ON; if (note != key) { phase = 0; @@ -221,9 +226,8 @@ void Voice::on(uint8_t key) { } void Voice::off() { + d_debug("Voice off\n"); // sustain - I need to rethink this bit FIXME voiceState = V_OFF; - if (!ic29.sustained) { - env.off(); - } + env.off(); } diff --git a/plugin/voiceboard.hpp b/plugin/voiceboard.hpp index f21951a..e0fa4f5 100644 --- a/plugin/voiceboard.hpp +++ b/plugin/voiceboard.hpp @@ -18,8 +18,9 @@ #pragma once -#include "peacock.hpp" +#include +#define NUM_VOICES 8 class LFO { public: LFO(); @@ -157,6 +158,3 @@ class Synth { const static uint8_t lfoDepthTable[128]; const static uint8_t portaTable[128]; }; - -// global -extern Synth ic29;