Basic stringy sound, highpass filters

This commit is contained in:
Gordon JC Pearce 2025-08-17 23:03:12 +01:00
parent 55bdeae1e7
commit 11ca33ffd8
6 changed files with 53 additions and 18 deletions

View File

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

View File

@ -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);
}

View File

@ -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();
};

View File

@ -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<NUM_VOICES; k++) {
uint8_t n1 = noteTable[k] % 12, n2 = (noteTable[k]/12 - 2);
output[i] += ((phase[n1] & (0x80000000 >> 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);
}

View File

@ -21,16 +21,33 @@
#include <stdint.h>
#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

View File

@ -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() {