|
|
|
@ -5,6 +5,10 @@ |
|
|
|
|
|
|
|
|
|
#include "synth/channel.h" |
|
|
|
|
|
|
|
|
|
float midiToNote(int note) { |
|
|
|
|
return note + 24; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
float timeToStep(float t) { |
|
|
|
|
return (1.0f / SAMPLE_RATE) / t; |
|
|
|
|
} |
|
|
|
@ -22,50 +26,57 @@ float ccToLFOStep(int x) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
float ccToLFOPitchMod(int x) { |
|
|
|
|
return pow(x / 127.0, 2) * 6; |
|
|
|
|
return 6.f * x * x / 16129.f; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
float ccToLFOFltMod(int x) { |
|
|
|
|
return (float) FILTER_CV_MAX * (x - 64) / 126.f; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Channel::loadPreset(const Preset * preset) { |
|
|
|
|
settings.unison = 1 + floorf(preset->unison * 4.f / 128.f); |
|
|
|
|
|
|
|
|
|
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.oscDetune = preset->oscDetune / 254.f; |
|
|
|
|
settings.osc2Pitch = floorf(preset->osc2Pitch * 13.f / 128.f); |
|
|
|
|
settings.oscMix = preset->oscMix / 127.f; |
|
|
|
|
|
|
|
|
|
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.filter.freq = (float) FILTER_CV_MAX * preset->filter.freq / 127.f; |
|
|
|
|
settings.filter.res = preset->filter.Q / 31.75f; |
|
|
|
|
|
|
|
|
|
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.sustain = preset->ampEnv.sustain / 127.f; |
|
|
|
|
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.sustain = preset->modEnv.sustain / 127.f; |
|
|
|
|
settings.modEnv.releaseStep = timeToStep(ccToDR(preset->modEnv.release)); |
|
|
|
|
|
|
|
|
|
settings.modEnvFltGain = preset->modEnvFltGain / 127.0; |
|
|
|
|
settings.keyTrack = preset->keyTrack / 127.0; |
|
|
|
|
settings.modEnvFltGain = (float) FILTER_CV_MAX * preset->modEnvFltGain / 127.f; |
|
|
|
|
settings.keyTrack = preset->keyTrack / 127.f; |
|
|
|
|
settings.lfoStep = ccToLFOStep(preset->lfoFreq); |
|
|
|
|
settings.lfoPitchMod = ccToLFOPitchMod(preset->lfoPitchMod); |
|
|
|
|
settings.lfoFltMod = (preset->lfoFltMod - 64) / 126.0; |
|
|
|
|
settings.lfoFltMod = ccToLFOFltMod(preset->lfoFltMod); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Channel::noteOn(int note, int velocity) { |
|
|
|
|
for(int i = -1; i <= 1; ++i) { |
|
|
|
|
int range = 2 * (settings.unison - 1); |
|
|
|
|
for(int i = -range; i <= range; i += 4) { |
|
|
|
|
Voice* const voice = voiceManager->get(number); |
|
|
|
|
voice->assign(&settings); |
|
|
|
|
voice->noteOn(note, i); |
|
|
|
|
voice->noteOn(midiToNote(note), i * settings.oscDetune, range ? 0.5f + 0.5f * i / range : 0.5f); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Channel::noteOff(int note) { |
|
|
|
|
Voice** voices = voiceManager->getChannelVoices(number); |
|
|
|
|
for(Voice** voice = voices; *voice != NULL; ++voice) { |
|
|
|
|
if((*voice)->note == note) { |
|
|
|
|
if((*voice)->note == midiToNote(note)) { |
|
|
|
|
(*voice)->noteOff(); |
|
|
|
|
}
|
|
|
|
|
} |
|
|
|
@ -74,7 +85,7 @@ void Channel::noteOff(int note) { |
|
|
|
|
void Channel::control(int code, int value) { |
|
|
|
|
switch(code) { |
|
|
|
|
case CC_VOLUME: // Volume (Standard MIDI)
|
|
|
|
|
volume = value / 127.0; |
|
|
|
|
volume = value / 127.f; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case CC_FLT_ATK: // Filter Attack Time
|
|
|
|
@ -86,7 +97,7 @@ void Channel::control(int code, int value) { |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case CC_FLT_SUS: // Filter Sustain
|
|
|
|
|
settings.modEnv.sustain = value / 127.0; |
|
|
|
|
settings.modEnv.sustain = value / 127.f; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case CC_FLT_REL: // Filter Release Time
|
|
|
|
@ -94,7 +105,7 @@ void Channel::control(int code, int value) { |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case CC_FLT_Q: // Timbre / Harmonic Content (Standard MIDI)
|
|
|
|
|
settings.filter.res = value / 31.75; |
|
|
|
|
settings.filter.res = value / 31.75f; |
|
|
|
|
printf("Q=%f\n", M_SQRT1_2 + (double) settings.filter.res); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
@ -107,7 +118,7 @@ void Channel::control(int code, int value) { |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case CC_FLT_FRQ: // Brightness (Standard MIDI)
|
|
|
|
|
settings.filter.freq = value / 127.0; |
|
|
|
|
settings.filter.freq = (float) FILTER_CV_MAX * value / 127.f; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case CC_AMP_DEC: // Decay Time
|
|
|
|
@ -115,23 +126,23 @@ void Channel::control(int code, int value) { |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case CC_AMP_SUS: // Sustain
|
|
|
|
|
settings.ampEnv.sustain = value / 127.0; |
|
|
|
|
settings.ampEnv.sustain = value / 127.f; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case CC_OSC_DET: // Detune (Standard MIDI)
|
|
|
|
|
settings.oscDetune = value / 254.0; |
|
|
|
|
settings.oscDetune = value / 254.f; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case CC_OSC2PIT: // Oscillator 2 Pitch
|
|
|
|
|
settings.osc2Pitch = floorf(value * (13.0 / 128.0)); |
|
|
|
|
settings.osc2Pitch = floorf(value * (13.f / 128.f)); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case CC_MOD_FLT: // Mod Envelope Filter Gain
|
|
|
|
|
settings.modEnvFltGain = value / 127.0; |
|
|
|
|
settings.modEnvFltGain = (float) FILTER_CV_MAX * value / 127.f; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case CC_KEY_TRK: // Filter Key Tracking
|
|
|
|
|
settings.keyTrack = value / 127.0; |
|
|
|
|
settings.keyTrack = value / 127.f; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case CC_LFO_FRQ: // LFO Frequency
|
|
|
|
@ -143,7 +154,36 @@ void Channel::control(int code, int value) { |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case CC_LFO_FLT: // LFO Filter Modulation
|
|
|
|
|
settings.lfoFltMod = (value - 64) / 126.0; |
|
|
|
|
settings.lfoFltMod = ccToLFOFltMod(value); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case CC_UNISON: // Unison Amount
|
|
|
|
|
settings.unison = 1 + floorf(value * 4.f / 128.f); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case CC_OSC_MIX: // Oscillator 1/2 Mix
|
|
|
|
|
settings.oscMix = value / 127.f; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case CC_OSC1MDE: // Oscillator 1 Mode
|
|
|
|
|
settings.osc1Mode = Oscillator::Mode(floorf(3.f * value / 128.f)); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case CC_OSC2MDE: // Oscillator 2 Mode
|
|
|
|
|
settings.osc2Mode = Oscillator::Mode(floorf(3.f * value / 128.f)); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case CC_FLT_TYP: // Filter Type
|
|
|
|
|
settings.filter.type = Filter::Type(floorf(3.f * value / 128.f)); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case CC_FLT_SLP: // Filter Slope
|
|
|
|
|
settings.filter.slope = Filter::Slope(floorf(2.f * value / 128.f)); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
// LFO delay
|
|
|
|
|
// Reverb Time
|
|
|
|
|
// Reverb Brightness
|
|
|
|
|
// Reverb Density
|
|
|
|
|
} |
|
|
|
|
} |