use crate::settings::DEFAULT_TONE_SAMPLE_BITS;
pub type ToneSample = u32;
pub type ToneGain = f32;
#[derive(PartialEq, Copy, Clone)]
pub enum ToneMode {
Wavetable,
ShortPeriodNoise,
LongPeriodNoise,
}
impl From<u32> for ToneMode {
fn from(index: u32) -> Self {
match index {
1 => Self::ShortPeriodNoise,
2 => Self::LongPeriodNoise,
_ => Self::Wavetable,
}
}
}
impl From<ToneMode> for u32 {
fn from(mode: ToneMode) -> Self {
match mode {
ToneMode::Wavetable => 0,
ToneMode::ShortPeriodNoise => 1,
ToneMode::LongPeriodNoise => 2,
}
}
}
pub struct Tone {
pub mode: ToneMode,
pub sample_bits: u32,
pub wavetable: Vec<ToneSample>,
pub gain: ToneGain,
cached_wavetable: Vec<ToneSample>,
waveform: Vec<f32>,
}
pub type SharedTone = shared_type!(Tone);
impl Tone {
pub fn new() -> SharedTone {
new_shared_type!(Self {
mode: ToneMode::Wavetable,
sample_bits: DEFAULT_TONE_SAMPLE_BITS,
wavetable: Vec::new(),
cached_wavetable: Vec::new(),
waveform: Vec::new(),
gain: 1.0,
})
}
pub(crate) fn waveform(&mut self) -> &Vec<f32> {
if self.wavetable != self.cached_wavetable {
assert!(self.sample_bits <= 32);
self.cached_wavetable = self.wavetable.clone();
self.waveform.clear();
self.waveform.reserve(self.wavetable.len());
let max_sample = (1 << self.sample_bits) - 1;
for &sample in &self.wavetable {
assert!(sample <= max_sample);
self.waveform
.push((sample as f32 / max_sample as f32) * 2.0 - 1.0);
}
}
&self.waveform
}
}