use crate::{arc, cat, cf, cm, define_cf_type, define_opts, mt, os};
use std::ptr::NonNull;
#[cfg(not(target_os = "watchos"))]
define_cf_type!(
#[doc(alias = "MTAudioProcessingTapRef")]
Tap(cf::Type)
);
define_opts!(
#[doc(alias = "MTAudioProcessingTapCreationFlags")]
pub CreationFlags(u32)
);
impl CreationFlags {
#[doc(alias = "kMTAudioProcessingTapCreationFlag_PreEffects")]
pub const PRE_EFFECTS: Self = Self(1 << 0);
#[doc(alias = "kMTAudioProcessingTapCreationFlag_PostEffects")]
pub const POST_EFFECTS: Self = Self(1 << 1);
}
define_opts!(
#[doc(alias = "MTAudioProcessingTapFlags")]
pub Flags(u32)
);
impl Flags {
#[doc(alias = "kMTAudioProcessingTapFlag_StartOfStream")]
pub const START_OF_STREAM: Self = Self(1 << 8);
#[doc(alias = "kMTAudioProcessingTapFlag_EndOfStream")]
pub const END_OF_STREAM: Self = Self(1 << 9);
}
#[doc(alias = "MTAudioProcessingTapInitCallback")]
pub type InitCb<T = std::ffi::c_void> = extern "C-unwind" fn(
tap: &mut mt::AudioProcessingTap,
client_info: *mut T,
tap_storage_out: NonNull<*mut std::ffi::c_void>,
);
#[doc(alias = "MTAudioProcessingTapFinalizeCallback")]
pub type FinalizeCb = extern "C-unwind" fn(tap: &mut mt::AudioProcessingTap);
#[doc(alias = "MTAudioProcessingTapPrepareCallback")]
pub type PrepareCb = extern "C-unwind" fn(
tap: &mut mt::AudioProcessingTap,
frames_max: cm::ItemCount,
processing_format: &cat::AudioStreamBasicDesc,
);
#[doc(alias = "MTAudioProcessingTapUnprepareCallback")]
pub type UnprepareCb = extern "C-unwind" fn(tap: &mut mt::AudioProcessingTap);
#[doc(alias = "MTAudioProcessingTapProcessCallback")]
pub type ProcessCb<const N: usize = 1> = extern "C-unwind" fn(
tap: &mut mt::AudioProcessingTap,
frames_n: cm::ItemCount,
flags: mt::AudioProcessingTapFlags,
buf_list_in_out: &mut cat::AudioBufList<N>,
frames_n_out: &mut cm::ItemCount,
flags_out: &mut Flags,
);
#[doc(alias = "MTAudioProcessingTapCallbacksVersion")]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[repr(transparent)]
pub struct CbsVersion(pub std::ffi::c_int);
impl CbsVersion {
#[doc(alias = "kMTAudioProcessingTapCallbacksVersion_0")]
pub const V0: Self = Self(0);
}
#[doc(alias = "MTAudioProcessingTapCallbacks")]
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct Cbs<T, const N: usize = 1> {
pub version: CbsVersion,
pub client_info: *mut T,
pub init: Option<InitCb<T>>,
pub finalize: Option<FinalizeCb>,
pub prepare: Option<PrepareCb>,
pub unprepare: Option<UnprepareCb>,
pub process: ProcessCb,
}
impl<T, const N: usize> Default for Cbs<T, N> {
fn default() -> Self {
Self {
version: CbsVersion::V0,
client_info: std::ptr::null_mut(),
init: Default::default(),
finalize: Default::default(),
prepare: Default::default(),
unprepare: Default::default(),
process: default_process,
}
}
}
extern "C-unwind" fn default_process(
tap: &mut mt::AudioProcessingTap,
frames_n: cm::ItemCount,
_flags: mt::AudioProcessingTapFlags,
buf_list_in_out: &mut cat::AudioBufList,
frames_n_out: &mut cm::ItemCount,
flags_out: &mut mt::AudioProcessingTapFlags,
) {
tap.src_audio_unchecked(
frames_n,
buf_list_in_out,
flags_out,
std::ptr::null_mut(),
frames_n_out,
);
}
#[cfg(not(target_os = "watchos"))]
impl Tap {
#[inline]
pub fn type_id() -> cf::TypeId {
unsafe { MTAudioProcessingTapGetTypeID() }
}
#[doc(alias = "MTAudioProcessingTapCreate")]
pub fn with_callbacks_in<T, const N: usize>(
callbacks: &Cbs<T, N>,
flags: CreationFlags,
allocator: Option<&cf::Allocator>,
) -> os::Result<Option<arc::R<Tap>>> {
unsafe {
os::result_init(|t| {
MTAudioProcessingTapCreate(allocator, std::mem::transmute(callbacks), flags, t)
})
}
}
#[doc(alias = "MTAudioProcessingTapCreate")]
pub fn with_callbacks<T, const N: usize>(
callbacks: &Cbs<T, N>,
flags: CreationFlags,
) -> os::Result<arc::R<Tap>> {
unsafe { std::mem::transmute(Self::with_callbacks_in(callbacks, flags, None)) }
}
#[doc(alias = "MTAudioProcessingTapGetSourceAudio")]
#[inline]
pub fn src_audio<const N: usize>(
&mut self,
frames_n: cm::ItemCount,
buf_list_in_out: &mut cat::AudioBufList<N>,
flags_out: *mut Flags,
time_range_out: *mut cm::TimeRange,
frames_n_out: *mut cm::ItemCount,
) -> os::Result {
self.src_audio_unchecked(
frames_n,
buf_list_in_out,
flags_out,
time_range_out,
frames_n_out,
)
.result()
}
#[doc(alias = "MTAudioProcessingTapGetSourceAudio")]
#[inline]
pub fn src_audio_unchecked<const N: usize>(
&mut self,
frames_n: cm::ItemCount,
buf_list_in_out: &mut cat::AudioBufList<N>,
flags: *mut Flags,
time_range_out: *mut cm::TimeRange,
frames_n_out: *mut cm::ItemCount,
) -> os::Status {
unsafe {
MTAudioProcessingTapGetSourceAudio(
self,
frames_n,
std::mem::transmute(buf_list_in_out),
flags,
time_range_out,
frames_n_out,
)
}
}
#[doc(alias = "MTAudioProcessingTapGetStorage")]
#[inline]
pub fn storage(&self) -> *const std::ffi::c_void {
unsafe { MTAudioProcessingTapGetStorage(self) }
}
#[doc(alias = "MTAudioProcessingTapGetStorage")]
#[inline]
pub fn storage_mut(&mut self) -> *mut std::ffi::c_void {
unsafe { MTAudioProcessingTapGetStorage(self) }
}
}
#[cfg(not(target_os = "watchos"))]
#[link(name = "MediaToolbox", kind = "framework")]
unsafe extern "C-unwind" {
fn MTAudioProcessingTapGetTypeID() -> cf::TypeId;
fn MTAudioProcessingTapCreate(
allocator: Option<&cf::Allocator>,
callbacks: *const Cbs<std::ffi::c_void>,
flags: CreationFlags,
tap_out: *mut Option<arc::R<Tap>>,
) -> os::Status;
fn MTAudioProcessingTapGetSourceAudio(
tap: &mut Tap,
frames_n: cm::ItemCount,
buf_list_in_out: &mut cat::AudioBufList,
flags: *mut Flags,
time_range_out: *mut cm::TimeRange,
frames_n_out: *mut cm::ItemCount,
) -> os::Status;
fn MTAudioProcessingTapGetStorage(tap: &Tap) -> *mut std::ffi::c_void;
}
#[cfg(test)]
mod tests {
use crate::mt;
#[test]
fn basics() {
let _type_id = mt::AudioProcessingTap::type_id();
}
}