polyphony checkpoint
This commit is contained in:
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user