use rill_core::Transcendental;
#[derive(Debug, Clone, Copy)]
pub struct ModeParams<T: Transcendental> {
pub freq_ratio: T,
pub amplitude: T,
pub decay_time: T,
}
#[derive(Debug, Clone)]
pub struct ModalParams<T: Transcendental, const MAX_MODES: usize> {
pub num_modes: usize,
pub modes: [ModeParams<T>; MAX_MODES],
pub fundamental: T,
pub damping: T,
}
impl<T: Transcendental, const MAX_MODES: usize> Default for ModalParams<T, MAX_MODES> {
fn default() -> Self {
let default_mode = ModeParams {
freq_ratio: T::ONE,
amplitude: T::ONE,
decay_time: T::from_f32(1.0),
};
Self {
num_modes: 1,
modes: [default_mode; MAX_MODES],
fundamental: T::from_f32(440.0),
damping: T::ONE,
}
}
}
pub fn bell_modes<T: Transcendental, const MAX_MODES: usize>() -> ModalParams<T, MAX_MODES> {
let ratios = [1.0, 2.76, 5.40, 8.93, 13.34];
let amplitudes = [1.0, 0.67, 0.34, 0.12, 0.06];
let decays = [2.0, 1.5, 0.8, 0.3, 0.1];
let mut modes = [ModeParams {
freq_ratio: T::ONE,
amplitude: T::ZERO,
decay_time: T::from_f32(0.01),
}; MAX_MODES];
let limit = 5.min(MAX_MODES);
for i in 0..limit {
modes[i] = ModeParams {
freq_ratio: T::from_f64(ratios[i]),
amplitude: T::from_f64(amplitudes[i]),
decay_time: T::from_f64(decays[i]),
};
}
ModalParams {
num_modes: limit,
modes,
fundamental: T::from_f32(440.0),
damping: T::ONE,
}
}
pub fn marimba_modes<T: Transcendental, const MAX_MODES: usize>() -> ModalParams<T, MAX_MODES> {
let ratios = [1.0, 4.0, 9.0];
let amplitudes = [1.0, 0.5, 0.2];
let decays = [3.0, 1.5, 0.5];
let mut modes = [ModeParams {
freq_ratio: T::ONE,
amplitude: T::ZERO,
decay_time: T::from_f32(0.01),
}; MAX_MODES];
let limit = 3.min(MAX_MODES);
for i in 0..limit {
modes[i] = ModeParams {
freq_ratio: T::from_f64(ratios[i]),
amplitude: T::from_f64(amplitudes[i]),
decay_time: T::from_f64(decays[i]),
};
}
ModalParams {
num_modes: limit,
modes,
fundamental: T::from_f32(440.0),
damping: T::ONE,
}
}