use std::ffi::c_float;
use std::ffi::c_uint;
extern "C" {
fn pks_asp_is_installed() -> std::ffi::c_int;
fn pks_asp_open_reader() -> *mut std::ffi::c_void;
fn pks_asp_sample_rate(r: *mut std::ffi::c_void) -> c_uint;
fn pks_asp_channels(r: *mut std::ffi::c_void) -> c_uint;
fn pks_asp_drop_count(r: *mut std::ffi::c_void) -> u64;
fn pks_asp_timeline_reject_callback_count(r: *mut std::ffi::c_void) -> u64;
fn pks_asp_read_frames(
r: *mut std::ffi::c_void,
out: *mut c_float,
frame_count: c_uint,
out_source_frame_position: *mut u64,
) -> c_uint;
fn pks_asp_close_reader(r: *mut std::ffi::c_void);
}
pub fn asp_is_installed() -> bool {
unsafe { pks_asp_is_installed() != 0 }
}
pub struct AspReader(*mut std::ffi::c_void);
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct AspReadBatch {
pub frame_count: u32,
pub source_frame_position_frames: u64,
}
unsafe impl Send for AspReader {}
impl AspReader {
pub fn open() -> Option<Self> {
let ptr = unsafe { pks_asp_open_reader() };
if ptr.is_null() {
None
} else {
Some(Self(ptr))
}
}
pub fn sample_rate(&self) -> u32 {
unsafe { pks_asp_sample_rate(self.0) }
}
pub fn channels(&self) -> u32 {
unsafe { pks_asp_channels(self.0) }
}
pub fn drop_count(&self) -> u64 {
unsafe { pks_asp_drop_count(self.0) }
}
pub fn timeline_reject_callback_count(&self) -> u64 {
unsafe { pks_asp_timeline_reject_callback_count(self.0) }
}
pub fn read_frames(&mut self, buf: &mut [f32], frame_count: u32) -> AspReadBatch {
let mut source_frame_position = 0u64;
let frame_count = unsafe {
pks_asp_read_frames(
self.0,
buf.as_mut_ptr(),
frame_count,
&mut source_frame_position,
)
};
AspReadBatch {
frame_count,
source_frame_position_frames: source_frame_position,
}
}
}
impl Drop for AspReader {
fn drop(&mut self) {
unsafe { pks_asp_close_reader(self.0) }
}
}