use core::mem::ManuallyDrop;
use core::ptr::NonNull;
use super::super::effects::delay_line::DelayLine;
use super::super::signals::synth_signal::SynthSignal;
use super::sound_source::SoundSource;
use crate::capi_state::CApiState;
use crate::ctypes::*;
use crate::time::TimeDelta;
#[derive(Debug)]
pub struct DelayLineTap {
source: ManuallyDrop<SoundSource>,
ptr: NonNull<CDelayLineTap>,
delay_modulator: Option<SynthSignal>,
}
impl DelayLineTap {
pub(crate) fn new(delay_line: &mut DelayLine, delay: TimeDelta) -> Self {
let ptr =
unsafe { Self::fns().addTap.unwrap()(delay_line.cptr_mut(), delay.to_sample_frames()) };
DelayLineTap {
source: ManuallyDrop::new(SoundSource::from_ptr(ptr as *mut CSoundSource)),
ptr: NonNull::new(ptr).unwrap(),
delay_modulator: None,
}
}
pub fn set_delay(&mut self, delay: TimeDelta) {
unsafe { Self::fns().setTapDelay.unwrap()(self.cptr_mut(), delay.to_sample_frames()) }
}
pub fn set_delay_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().setTapDelayModulator.unwrap()(self.cptr_mut(), modulator_ptr) }
self.delay_modulator = signal.map(|signal| signal.as_ref().clone());
}
pub fn delay_modulator(&mut self) -> Option<&SynthSignal> {
self.delay_modulator.as_ref()
}
pub fn set_channels_flipped(&mut self, flipped: bool) {
unsafe { Self::fns().setTapChannelsFlipped.unwrap()(self.cptr_mut(), flipped as i32) }
}
pub(crate) fn cptr_mut(&mut self) -> *mut CDelayLineTap {
self.ptr.as_ptr()
}
pub(crate) fn fns() -> &'static craydate_sys::playdate_sound_effect_delayline {
unsafe { &*(*CApiState::get().csound.effect).delayline }
}
}
impl Drop for DelayLineTap {
fn drop(&mut self) {
unsafe { ManuallyDrop::drop(&mut self.source) };
unsafe { Self::fns().freeTap.unwrap()(self.cptr_mut()) }
}
}
impl AsRef<SoundSource> for DelayLineTap {
fn as_ref(&self) -> &SoundSource {
&self.source
}
}
impl AsMut<SoundSource> for DelayLineTap {
fn as_mut(&mut self) -> &mut SoundSource {
&mut self.source
}
}