use std::marker::PhantomData;
use crate::error::{check, null_handle_error, to_cstring, Result};
use crate::ffi;
use crate::options::WriteOptions;
use crate::samples::channel_pointers;
pub struct AudioEncoder {
handle: *mut ffi::AvfEncoder,
_not_sync: PhantomData<std::cell::Cell<()>>,
}
impl AudioEncoder {
pub fn new(options: &WriteOptions) -> Result<Self> {
let (raw, _strings) = options.to_ffi()?;
let handle = unsafe { ffi::avf_encoder_new(&raw) };
if handle.is_null() {
return Err(null_handle_error());
}
Ok(Self {
handle,
_not_sync: PhantomData,
})
}
pub fn save(&mut self, path: &str, samples: &[Vec<f32>]) -> Result<()> {
let path = to_cstring(path)?;
let (pointers, num_samples) = channel_pointers(samples)?;
check(unsafe {
ffi::avf_encoder_save(
self.handle,
path.as_ptr(),
pointers.as_ptr(),
pointers.len() as i32,
num_samples,
)
})
}
}
impl std::fmt::Debug for AudioEncoder {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("AudioEncoder").finish_non_exhaustive()
}
}
impl Drop for AudioEncoder {
fn drop(&mut self) {
unsafe { ffi::avf_encoder_free(self.handle) };
}
}
unsafe impl Send for AudioEncoder {}
pub fn save_audio(path: &str, samples: &[Vec<f32>], options: &WriteOptions) -> Result<()> {
let path = to_cstring(path)?;
let (raw, _strings) = options.to_ffi()?;
let (pointers, num_samples) = channel_pointers(samples)?;
check(unsafe {
ffi::avf_save_audio(
path.as_ptr(),
pointers.as_ptr(),
pointers.len() as i32,
num_samples,
&raw,
)
})
}