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.
146 lines
4.6 KiB
146 lines
4.6 KiB
#include <iostream>
|
|
|
|
#include "synth/globals.h"
|
|
#include "synth/cc.h"
|
|
|
|
#include "synth/channel.h"
|
|
|
|
float timeToStep(float t) {
|
|
return (1.0 / SAMPLE_RATE) / t;
|
|
}
|
|
|
|
float ccToA(int x) {
|
|
return 5.0 * exp(9.2 * (x / 127.0) - 9.2);
|
|
}
|
|
|
|
float ccToDR(int x) {
|
|
return 5.0 * exp(7.0 * (x / 127.0) - 7.0);
|
|
}
|
|
|
|
float ccToLFOStep(int x) {
|
|
return PIx2 * 0.1 * exp((1 + x) * 6.907755278982137 / 128.0) / SAMPLE_RATE;
|
|
}
|
|
|
|
float ccToLFOPitchMod(int x) {
|
|
return pow(x / 127.0, 2) * 6;
|
|
}
|
|
|
|
void Channel::loadPreset(const Preset * preset) {
|
|
settings.osc1Mode = Oscillator::Mode(preset->osc1Mode);
|
|
settings.osc2Mode = Oscillator::Mode(preset->osc2Mode);
|
|
settings.oscMix = preset->oscMix / 127.0;
|
|
settings.oscDetune = preset->oscDetune / 254.0;
|
|
settings.osc2Pitch = floorf(preset->osc2Pitch * (13.0 / 128.0));
|
|
|
|
settings.filter.type = Filter::Type(preset->filter.type);
|
|
settings.filter.slope = Filter::Slope(preset->filter.slope);
|
|
settings.filter.freq = preset->filter.freq / 127.0;
|
|
settings.filter.res = preset->filter.Q / 31.75;
|
|
|
|
settings.ampEnv.attackStep = timeToStep(ccToA(preset->ampEnv.attack));
|
|
settings.ampEnv.decayStep = timeToStep(ccToDR(preset->ampEnv.decay));
|
|
settings.ampEnv.sustain = preset->ampEnv.sustain / 127.0;
|
|
settings.ampEnv.releaseStep = timeToStep(ccToDR(preset->ampEnv.release));
|
|
|
|
settings.modEnv.attackStep = timeToStep(ccToA(preset->modEnv.attack));
|
|
settings.modEnv.decayStep = timeToStep(ccToDR(preset->modEnv.decay));
|
|
settings.modEnv.sustain = preset->modEnv.sustain / 127.0;
|
|
settings.modEnv.releaseStep = timeToStep(ccToDR(preset->modEnv.release));
|
|
|
|
settings.modEnvFltGain = preset->modEnvFltGain / 127.0;
|
|
settings.keyTrack = preset->keyTrack / 127.0;
|
|
settings.lfoStep = ccToLFOStep(preset->lfoFreq);
|
|
settings.lfoPitchMod = ccToLFOPitchMod(preset->lfoPitchMod);
|
|
settings.lfoFltMod = (preset->lfoFltMod - 64) / 126.0;
|
|
}
|
|
|
|
void Channel::noteOn(int note, int velocity) {
|
|
Voice* const voice = voiceManager->get(number);
|
|
voice->assign(&settings);
|
|
voice->noteOn(note);
|
|
}
|
|
|
|
void Channel::noteOff(int note) {
|
|
Voice** voices = voiceManager->getChannelVoices(number);
|
|
for(Voice** voice = voices; *voice != NULL; ++voice) {
|
|
if((*voice)->note == note) {
|
|
(*voice)->noteOff();
|
|
}
|
|
}
|
|
}
|
|
|
|
void Channel::control(int code, int value) {
|
|
switch(code) {
|
|
case CC_VOLUME: // Volume (Standard MIDI)
|
|
volume = value / 127.0;
|
|
break;
|
|
|
|
case CC_FLT_ATK: // Filter Attack Time
|
|
settings.modEnv.attackStep = timeToStep(ccToA(value));
|
|
break;
|
|
|
|
case CC_FLT_DEC: // Filter Decay Time
|
|
settings.modEnv.decayStep = timeToStep(ccToDR(value));
|
|
break;
|
|
|
|
case CC_FLT_SUS: // Filter Sustain
|
|
settings.modEnv.sustain = value / 127.0;
|
|
break;
|
|
|
|
case CC_FLT_REL: // Filter Release Time
|
|
settings.modEnv.releaseStep = timeToStep(ccToDR(value));
|
|
break;
|
|
|
|
case CC_FLT_Q: // Timbre / Harmonic Content (Standard MIDI)
|
|
settings.filter.res = value / 31.75;
|
|
break;
|
|
|
|
case CC_AMP_REL: // Release Time (Standard MIDI)
|
|
settings.ampEnv.releaseStep = timeToStep(ccToDR(value));
|
|
break;
|
|
|
|
case CC_AMP_ATK: // Attack Time (Standard MIDI)
|
|
settings.ampEnv.attackStep = timeToStep(ccToA(value));
|
|
break;
|
|
|
|
case CC_FLT_FRQ: // Brightness (Standard MIDI)
|
|
settings.filter.freq = value / 127.0;
|
|
break;
|
|
|
|
case CC_AMP_DEC: // Decay Time
|
|
settings.ampEnv.decayStep = timeToStep(ccToDR(value));
|
|
break;
|
|
|
|
case CC_AMP_SUS: // Sustain
|
|
settings.ampEnv.sustain = value / 127.0;
|
|
break;
|
|
|
|
case CC_OSC_DET: // Detune (Standard MIDI)
|
|
settings.oscDetune = value / 254.0;
|
|
break;
|
|
|
|
case CC_OSC2PIT: // Oscillator 2 Pitch
|
|
settings.osc2Pitch = floorf(value * (13.0 / 128.0));
|
|
break;
|
|
|
|
case CC_MOD_FLT: // Mod Envelope Filter Gain
|
|
settings.modEnvFltGain = value / 127.0;
|
|
break;
|
|
|
|
case CC_KEY_TRK: // Filter Key Tracking
|
|
settings.keyTrack = value / 127.0;
|
|
break;
|
|
|
|
case CC_LFO_FRQ: // LFO Frequency
|
|
settings.lfoStep = ccToLFOStep(value);
|
|
break;
|
|
|
|
case CC_LFO_PIT: // LFO Pitch Modulation
|
|
settings.lfoPitchMod = ccToLFOPitchMod(value);
|
|
break;
|
|
|
|
case CC_LFO_FLT: // LFO Filter Modulation
|
|
settings.lfoFltMod = (value - 64) / 126.0;
|
|
break;
|
|
}
|
|
} |