use core::mem::ManuallyDrop;
use core::ptr::NonNull;
use super::super::signals::synth_signal::SynthSignal;
use super::sound_effect::SoundEffect;
use crate::capi_state::CApiState;
use crate::ctypes::*;
pub struct BitCrusher {
effect: ManuallyDrop<SoundEffect>,
ptr: NonNull<CBitCrusher>,
amount_modulator: Option<SynthSignal>,
undersampling_modulator: Option<SynthSignal>,
}
impl BitCrusher {
pub fn new() -> Self {
let ptr = unsafe { Self::fns().newBitCrusher.unwrap()() };
BitCrusher {
effect: ManuallyDrop::new(SoundEffect::from_ptr(ptr as *mut CSoundEffect)),
ptr: NonNull::new(ptr).unwrap(),
amount_modulator: None,
undersampling_modulator: None,
}
}
pub fn set_amount(&mut self, amount: f32) {
unsafe { Self::fns().setAmount.unwrap()(self.cptr_mut(), amount) }
}
pub fn set_amount_modulator<T: AsRef<SynthSignal>>(&mut self, signal: Option<&T>) {
let modulator_ptr = signal.map_or_else(core::ptr::null_mut, |signal| {
signal.as_ref().cptr() as *mut _
});
unsafe { Self::fns().setAmountModulator.unwrap()(self.cptr_mut(), modulator_ptr) }
self.amount_modulator = signal.map(|signal| signal.as_ref().clone());
}
pub fn amount_modulator(&mut self) -> Option<&SynthSignal> {
self.amount_modulator.as_ref()
}
pub fn set_undersampling(&mut self, undersampling: f32) {
unsafe { Self::fns().setUndersampling.unwrap()(self.cptr_mut(), undersampling) }
}
pub fn set_undersampling_modulator<T: AsRef<SynthSignal>>(&mut self, signal: Option<&T>) {
let modulator_ptr = signal.map_or_else(core::ptr::null_mut, |signal|
signal.as_ref().cptr() as *mut _);
unsafe { Self::fns().setUndersampleModulator.unwrap()(self.cptr_mut(), modulator_ptr) }
self.undersampling_modulator = signal.map(|signal| signal.as_ref().clone());
}
pub fn undersampling_modulator(&mut self) -> Option<&SynthSignal> {
self.undersampling_modulator.as_ref()
}
pub(crate) fn cptr_mut(&mut self) -> *mut CBitCrusher {
self.ptr.as_ptr()
}
pub(crate) fn fns() -> &'static craydate_sys::playdate_sound_effect_bitcrusher {
unsafe { &*(*CApiState::get().csound.effect).bitcrusher }
}
}
impl Drop for BitCrusher {
fn drop(&mut self) {
unsafe { ManuallyDrop::drop(&mut self.effect) };
unsafe { Self::fns().freeBitCrusher.unwrap()(self.cptr_mut()) }
}
}
impl AsRef<SoundEffect> for BitCrusher {
fn as_ref(&self) -> &SoundEffect {
&self.effect
}
}
impl AsMut<SoundEffect> for BitCrusher {
fn as_mut(&mut self) -> &mut SoundEffect {
&mut self.effect
}
}