use super::super::Channel;
macro_rules! u8_to_enum {
(
$(#[$meta:meta])*
$vis:vis enum $name:ident {
$($(#[$vmeta:meta])* $vname:ident $(= $val:expr)?,)*
}
) => {
$(#[$meta])*
$vis enum $name {
$($(#[$vmeta])* $vname $(= $val)?,)*
}
impl $name {
pub const fn const_try_from(v: u8) -> Option<Self> {
match v {
$(x if x == $name::$vname as u8 => Some($name::$vname),)*
_ => None,
}
}
}
}
}
u8_to_enum!(
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[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,
}
);
impl GeneratorType {
pub const fn last() -> u8 {
60
}
}
impl TryFrom<u8> for GeneratorType {
type Error = ();
fn try_from(v: u8) -> Result<Self, Self::Error> {
Self::const_try_from(v).ok_or(())
}
}
impl TryFrom<soundfont::raw::GeneratorType> for GeneratorType {
type Error = ();
fn try_from(value: soundfont::raw::GeneratorType) -> Result<Self, Self::Error> {
Self::const_try_from(value as u8).ok_or(())
}
}
impl GeneratorType {
pub fn iter() -> impl Iterator<Item = Self> {
(0..Self::last())
.map(Self::const_try_from)
.map(Option::unwrap)
}
}
#[derive(Copy, Default, Debug, PartialEq, Clone)]
pub struct Generator {
pub flags: u8,
pub val: f64,
pub mod_0: f64,
pub nrpn: f64,
}
#[derive(Clone, Debug)]
pub struct GeneratorList([Generator; 60]);
impl Default for GeneratorList {
fn default() -> Self {
Self(get_default_values())
}
}
impl GeneratorList {
pub fn new(channel: &Channel) -> Self {
let mut out = Self::default();
for (gen, ty) in out.0.iter_mut().zip(GeneratorType::iter()) {
gen.nrpn = channel.gen(ty) as f64;
if channel.gen_abs(ty) != 0 {
gen.flags = GEN_ABS_NRPN;
}
}
out
}
}
impl std::ops::Index<GeneratorType> for GeneratorList {
type Output = Generator;
fn index(&self, index: GeneratorType) -> &Self::Output {
&self.0[index as usize]
}
}
impl std::ops::IndexMut<GeneratorType> for GeneratorList {
fn index_mut(&mut self, index: GeneratorType) -> &mut Self::Output {
&mut self.0[index as usize]
}
}
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: 1e10,
def: 0.0,
},
GenInfo {
_num: GeneratorType::EndAddrOfs,
_init: 1,
nrpn_scale: 1,
_min: -1e10,
_max: 0.0,
def: 0.0,
},
GenInfo {
_num: GeneratorType::StartLoopAddrOfs,
_init: 1,
nrpn_scale: 1,
_min: -1e10,
_max: 1e10,
def: 0.0,
},
GenInfo {
_num: GeneratorType::EndLoopAddrOfs,
_init: 1,
nrpn_scale: 1,
_min: -1e10,
_max: 1e10,
def: 0.0,
},
GenInfo {
_num: GeneratorType::StartAddrCoarseOfs,
_init: 0,
nrpn_scale: 1,
_min: 0.0,
_max: 1e10,
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: -1e10,
_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.0,
_max: 1440.0,
def: 0.0,
},
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: -1e10,
_max: 1e10,
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: -1e10,
_max: 1e10,
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,
},
];
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_scale_nrpn(gen: i16, data: i32) -> f32 {
let value = data as f32 - 8192.0;
let value = value.clamp(-8192.0, 8192.0);
value * GEN_INFO[gen as usize].nrpn_scale as f32
}