Analog synthesis engine for Klang Modular
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

83 lines
2.0 KiB

#ifndef __PART_H__
#define __PART_H__
#include <unordered_map>
#include <set>
#include "globals.h"
#include "voicemanager.h"
#include "voice.h"
#include "preset.h"
#include "dsp/frame.h"
#include "luts.h"
#include "perf.h"
class Channel {
public:
VoiceManager::channel_t number;
VoiceManager* voiceManager;
Voice::Settings settings;
Channel() : volume(1), pitchBend(0), modulation(0), lfoPhase(randFrac()) {}
void loadPreset(const Preset* preset);
void noteOn(int note, int vel);
void noteOff(int note);
void control(int cc, int val);
bool tick(float *out, const size_t bufferSize) {
nano_t started = nanos();
Voice** voices = voiceManager->getChannelVoices(number);
if(*voices == NULL) {
nano_t finished = nanos();
perfNanos.channel += finished - started;
return false;
}
const size_t numFrames = bufferSize / 2;
float lfo[numFrames];
for(size_t i = 0; i < numFrames; ++i) {
lfo[i] = fastSin(lfoPhase);
lfoPhase += settings.lfoStep;
lfoPhase -= floorf(lfoPhase);
}
float pitchMod[numFrames];
for(size_t i = 0; i < numFrames; ++i) {
pitchMod[i] = settings.lfoPitchMod * lfo[i];
}
float fltMod[numFrames];
for(size_t i = 0; i < numFrames; ++i) {
fltMod[i] = settings.lfoFltMod * lfo[i];
}
std::fill(out, out + bufferSize, 0.f);
for(Voice** voice = voices; *voice != NULL; ++voice) {
float voiceOut[bufferSize];
(*voice)->tick(voiceOut, bufferSize, pitchMod, fltMod);
for(size_t i = 0; i < bufferSize; ++i) {
out[i] += voiceOut[i];
}
}
nano_t finished = nanos();
perfNanos.channel += finished - started;
return true;
}
private:
float volume;
float pitchBend;
float modulation;
float lfoPhase;
};
#endif