use super::super::Channel;
use num_derive::FromPrimitive;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, FromPrimitive)]
#[repr(u8)]
pub enum GeneratorType {
StartAddrOfs = 0,
EndAddrOfs = 1,
StartLoopAddrOfs = 2,
EndLoopAddrOfs = 3,
StartAddrCoarseOfs = 4,
ModLfoToPitch = 5,
VibLfoToPitch = 6,
ModEnvToPitch = 7,
FilterFc = 8,
FilterQ = 9,
ModLfoToFilterFc = 10,
ModEnvToFilterFc = 11,
EndAddrCoarseOfs = 12,
ModLfoToVol = 13,
Unused = 14,
ChorusSend = 15,
ReverbSend = 16,
Pan = 17,
Unused2 = 18,
Unused3 = 19,
Unused4 = 20,
ModLfoDelay = 21,
ModLfoFreq = 22,
VibLfoDelay = 23,
VibLfoFreq = 24,
ModEnvDelay = 25,
ModEnvAttack = 26,
ModEnvHold = 27,
ModEnvDecay = 28,
ModEnvSustain = 29,
ModEnvRelease = 30,
KeyToModEnvHold = 31,
KeyToModEnvDecay = 32,
VolEnvDelay = 33,
VolEnvAttack = 34,
VolEnvHold = 35,
VolEnvDecay = 36,
VolEnvSustain = 37,
VolEnvRelease = 38,
KeyToVolEnvHold = 39,
KeyToVolEnvDecay = 40,
Instrument = 41,
Reserved1 = 42,
KeyRange = 43,
VelRange = 44,
StartLoopAddrCoarseOfs = 45,
KeyNum = 46,
Velocity = 47,
Attenuation = 48,
Reserved2 = 49,
EndLoopAddrCoarseOfs = 50,
CoarseTune = 51,
FineTune = 52,
SampleId = 53,
SampleMode = 54,
Reserved3 = 55,
ScaleTune = 56,
ExclusiveClass = 57,
OverrideRootKey = 58,
Pitch = 59,
Last = 60,
}
#[derive(Copy, Default, Debug, PartialEq, Clone)]
pub struct Generator {
pub flags: u8,
pub val: f64,
pub mod_0: f64,
pub nrpn: f64,
}
const GEN_ABS_NRPN: u8 = 2;
const GEN_UNUSED: u8 = 0;
#[derive(Copy, Clone)]
struct GenInfo {
_num: GeneratorType,
_init: i8,
nrpn_scale: i8,
_min: f32,
_max: f32,
def: f32,
}
static GEN_INFO: [GenInfo; 60] = [
GenInfo {
_num: GeneratorType::StartAddrOfs,
_init: 1,
nrpn_scale: 1,
_min: 0.0,
_max: 1e10f32,
def: 0.0,
},
GenInfo {
_num: GeneratorType::EndAddrOfs,
_init: 1,
nrpn_scale: 1,
_min: -1e10f32,
_max: 0.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::StartLoopAddrOfs,
_init: 1,
nrpn_scale: 1,
_min: -1e10f32,
_max: 1e10f32,
def: 0.0,
},
GenInfo {
_num: GeneratorType::EndLoopAddrOfs,
_init: 1,
nrpn_scale: 1,
_min: -1e10f32,
_max: 1e10f32,
def: 0.0,
},
GenInfo {
_num: GeneratorType::StartAddrCoarseOfs,
_init: 0,
nrpn_scale: 1,
_min: 0.0,
_max: 1e10f32,
def: 0.0,
},
GenInfo {
_num: GeneratorType::ModLfoToPitch,
_init: 1,
nrpn_scale: 2,
_min: -12000.0,
_max: 12000.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::VibLfoToPitch,
_init: 1,
nrpn_scale: 2,
_min: -12000.0,
_max: 12000.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::ModEnvToPitch,
_init: 1,
nrpn_scale: 2,
_min: -12000.0,
_max: 12000.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::FilterFc,
_init: 1,
nrpn_scale: 2,
_min: 1500.0,
_max: 13500.0,
def: 13500.0,
},
GenInfo {
_num: GeneratorType::FilterQ,
_init: 1,
nrpn_scale: 1,
_min: 0.0,
_max: 960.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::ModLfoToFilterFc,
_init: 1,
nrpn_scale: 2,
_min: -12000.0,
_max: 12000.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::ModEnvToFilterFc,
_init: 1,
nrpn_scale: 2,
_min: -12000.0,
_max: 12000.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::EndAddrCoarseOfs,
_init: 0,
nrpn_scale: 1,
_min: -1e10f32,
_max: 0.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::ModLfoToVol,
_init: 1,
nrpn_scale: 1,
_min: -960.0,
_max: 960.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::Unused,
_init: 0,
nrpn_scale: 0,
_min: 0.0,
_max: 0.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::ChorusSend,
_init: 1,
nrpn_scale: 1,
_min: 0.0,
_max: 1000.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::ReverbSend,
_init: 1,
nrpn_scale: 1,
_min: 0.0,
_max: 1000.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::Pan,
_init: 1,
nrpn_scale: 1,
_min: -500.0,
_max: 500.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::Unused2,
_init: 0,
nrpn_scale: 0,
_min: 0.0,
_max: 0.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::Unused3,
_init: 0,
nrpn_scale: 0,
_min: 0.0,
_max: 0.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::Unused4,
_init: 0,
nrpn_scale: 0,
_min: 0.0,
_max: 0.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::ModLfoDelay,
_init: 1,
nrpn_scale: 2,
_min: -12000.0,
_max: 5000.0,
def: -12000.0,
},
GenInfo {
_num: GeneratorType::ModLfoFreq,
_init: 1,
nrpn_scale: 4,
_min: -16000.0,
_max: 4500.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::VibLfoDelay,
_init: 1,
nrpn_scale: 2,
_min: -12000.0,
_max: 5000.0,
def: -12000.0,
},
GenInfo {
_num: GeneratorType::VibLfoFreq,
_init: 1,
nrpn_scale: 4,
_min: -16000.0,
_max: 4500.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::ModEnvDelay,
_init: 1,
nrpn_scale: 2,
_min: -12000.0,
_max: 5000.0,
def: -12000.0,
},
GenInfo {
_num: GeneratorType::ModEnvAttack,
_init: 1,
nrpn_scale: 2,
_min: -12000.0,
_max: 8000.0,
def: -12000.0,
},
GenInfo {
_num: GeneratorType::ModEnvHold,
_init: 1,
nrpn_scale: 2,
_min: -12000.0,
_max: 5000.0,
def: -12000.0,
},
GenInfo {
_num: GeneratorType::ModEnvDecay,
_init: 1,
nrpn_scale: 2,
_min: -12000.0,
_max: 8000.0,
def: -12000.0,
},
GenInfo {
_num: GeneratorType::ModEnvSustain,
_init: 0,
nrpn_scale: 1,
_min: 0.0,
_max: 1000.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::ModEnvRelease,
_init: 1,
nrpn_scale: 2,
_min: -12000.0,
_max: 8000.0,
def: -12000.0,
},
GenInfo {
_num: GeneratorType::KeyToModEnvHold,
_init: 0,
nrpn_scale: 1,
_min: -1200.0,
_max: 1200.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::KeyToModEnvDecay,
_init: 0,
nrpn_scale: 1,
_min: -1200.0,
_max: 1200.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::VolEnvDelay,
_init: 1,
nrpn_scale: 2,
_min: -12000.0,
_max: 5000.0,
def: -12000.0,
},
GenInfo {
_num: GeneratorType::VolEnvAttack,
_init: 1,
nrpn_scale: 2,
_min: -12000.0,
_max: 8000.0,
def: -12000.0,
},
GenInfo {
_num: GeneratorType::VolEnvHold,
_init: 1,
nrpn_scale: 2,
_min: -12000.0,
_max: 5000.0,
def: -12000.0,
},
GenInfo {
_num: GeneratorType::VolEnvDecay,
_init: 1,
nrpn_scale: 2,
_min: -12000.0,
_max: 8000.0,
def: -12000.0,
},
GenInfo {
_num: GeneratorType::VolEnvSustain,
_init: 0,
nrpn_scale: 1,
_min: 0.0f32,
_max: 1440.0f32,
def: 0.0f32,
},
GenInfo {
_num: GeneratorType::VolEnvRelease,
_init: 1,
nrpn_scale: 2,
_min: -12000.0,
_max: 8000.0,
def: -12000.0,
},
GenInfo {
_num: GeneratorType::KeyToVolEnvHold,
_init: 0,
nrpn_scale: 1,
_min: -1200.0,
_max: 1200.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::KeyToVolEnvDecay,
_init: 0,
nrpn_scale: 1,
_min: -1200.0,
_max: 1200.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::Instrument,
_init: 0,
nrpn_scale: 0,
_min: 0.0,
_max: 0.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::Reserved1,
_init: 0,
nrpn_scale: 0,
_min: 0.0,
_max: 0.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::KeyRange,
_init: 0,
nrpn_scale: 0,
_min: 0.0,
_max: 127.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::VelRange,
_init: 0,
nrpn_scale: 0,
_min: 0.0,
_max: 127.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::StartLoopAddrCoarseOfs,
_init: 0,
nrpn_scale: 1,
_min: -1e10f32,
_max: 1e10f32,
def: 0.0,
},
GenInfo {
_num: GeneratorType::KeyNum,
_init: 1,
nrpn_scale: 0,
_min: 0.0,
_max: 127.0,
def: -1.0,
},
GenInfo {
_num: GeneratorType::Velocity,
_init: 1,
nrpn_scale: 1,
_min: 0.0,
_max: 127.0,
def: -1.0,
},
GenInfo {
_num: GeneratorType::Attenuation,
_init: 1,
nrpn_scale: 1,
_min: 0.0,
_max: 1440.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::Reserved2,
_init: 0,
nrpn_scale: 0,
_min: 0.0,
_max: 0.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::EndLoopAddrCoarseOfs,
_init: 0,
nrpn_scale: 1,
_min: -1e10f32,
_max: 1e10f32,
def: 0.0,
},
GenInfo {
_num: GeneratorType::CoarseTune,
_init: 0,
nrpn_scale: 1,
_min: -120.0,
_max: 120.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::FineTune,
_init: 0,
nrpn_scale: 1,
_min: -99.0,
_max: 99.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::SampleId,
_init: 0,
nrpn_scale: 0,
_min: 0.0,
_max: 0.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::SampleMode,
_init: 0,
nrpn_scale: 0,
_min: 0.0,
_max: 0.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::Reserved3,
_init: 0,
nrpn_scale: 0,
_min: 0.0,
_max: 0.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::ScaleTune,
_init: 0,
nrpn_scale: 1,
_min: 0.0,
_max: 1200.0,
def: 100.0,
},
GenInfo {
_num: GeneratorType::ExclusiveClass,
_init: 0,
nrpn_scale: 0,
_min: 0.0,
_max: 0.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::OverrideRootKey,
_init: 1,
nrpn_scale: 0,
_min: 0.0,
_max: 127.0,
def: -1.0,
},
GenInfo {
_num: GeneratorType::Pitch,
_init: 1,
nrpn_scale: 0,
_min: 0.0,
_max: 127.0,
def: 0.0,
},
];
pub(crate) fn get_default_values() -> [Generator; 60] {
let mut out = [Generator::default(); 60];
for (id, gen) in out.iter_mut().enumerate() {
gen.flags = GEN_UNUSED;
gen.mod_0 = 0.0;
gen.nrpn = 0.0;
gen.val = GEN_INFO[id].def as f64;
}
out
}
pub(crate) fn gen_init(channel: &Channel) -> [Generator; 60] {
let mut out = get_default_values();
for (id, gen) in out.iter_mut().enumerate() {
gen.nrpn = channel.gen(id) as f64;
if channel.gen_abs(id) != 0 {
gen.flags = GEN_ABS_NRPN;
}
}
out
}
pub(crate) fn gen_scale_nrpn(gen: i16, data: i32) -> f32 {
let value = data as f32 - 8192.0;
let value = if value < -8192.0 {
-8192.0
} else if value > 8192.0 {
8192.0
} else {
value
};
value * GEN_INFO[gen as usize].nrpn_scale as f32
}