polyphony checkpoint

This commit is contained in:
2026-06-12 23:13:18 -05:00
parent 347f585630
commit 9f79f11a19
10 changed files with 218 additions and 39 deletions

View File

@@ -0,0 +1,87 @@
#include "Synth.hpp"
Synth::Synth(ConfigService* config, LoggerService* logger, ScopeBuffer* scope, NoteQueue* queue) :
config_(config), logger_(logger), scope_(scope), noteQueue_(queue) {
voices_.fill(Voice(config_, logger_));
}
void Synth::handleNoteEvent(const NoteEvent& event) {
Voice* v = findVoiceByNote(event.note);
if(v != nullptr) v->noteOff();
if(event.type == NoteEventType::NoteOn) {
v = findFreeVoice();
if(v != nullptr) v->noteOn(event.note, event.velocity);
}
}
void Synth::process(float* out, size_t nFrames) {
NoteEvent noteEvent;
while(noteQueue_->pop(noteEvent)) {
handleNoteEvent(noteEvent);
}
// size_t lowestVoice = 0;
// float lowestFreq = 100000.0f;
// for(size_t i = 0; i < voices_.size(); i++) {
// if(!voices_[i].isActive()) continue;
// float currentFreq = voices_[i].frequency();
// if(currentFreq < lowestFreq) {
// lowestVoice = i;
// lowestFreq = currentFreq;
// }
// }
float sampleOut = 0.0f;
for(size_t i = 0; i < nFrames; i++) {
float mix = 0.0f;
for(size_t j = 0; j < voices_.size(); j++) {
bool temp = false;
if(!voices_[j].isActive()) continue;
mix += voices_[j].process(temp);
// if(j == lowestVoice) triggered = temp;
}
mix = tanh(mix/4.0f); // prevent clipping
sampleOut = mix;
out[2*i] = sampleOut;
out[2*i+1] = sampleOut;
// if(scope_) scope_->push(sampleOut);
// if(triggered && !once) {
// scope_->setTrigger(i);
// once = true;
// }
}
}
Voice* Synth::findFreeVoice() {
for(Voice& v : voices_) {
if(!v.isActive()) {
return &v;
}
}
return nullptr;
}
Voice* Synth::findVoiceByNote(uint8_t note) {
for(Voice& v : voices_) {
if(v.isActive() && v.note() == note) {
return &v;
}
}
return nullptr;
}