extern crate spandsp_sys;
use std::os::raw::c_int;
use std::ptr::NonNull;
use crate::error::{Result, SpanDspError};
pub struct GoertzelDescriptor {
inner: spandsp_sys::goertzel_descriptor_t,
}
impl GoertzelDescriptor {
pub fn new(freq: f32, samples: usize) -> Self {
let mut desc = spandsp_sys::goertzel_descriptor_t::default();
unsafe {
spandsp_sys::make_goertzel_descriptor(&mut desc, freq, samples as c_int);
}
Self { inner: desc }
}
pub fn as_mut_ptr(&mut self) -> *mut spandsp_sys::goertzel_descriptor_t {
&mut self.inner
}
}
pub struct GoertzelDetector {
ptr: NonNull<spandsp_sys::goertzel_state_t>,
}
impl GoertzelDetector {
pub fn new(desc: &mut GoertzelDescriptor) -> Result<Self> {
let ptr = unsafe { spandsp_sys::goertzel_init(std::ptr::null_mut(), desc.as_mut_ptr()) };
let ptr = NonNull::new(ptr).ok_or(SpanDspError::InitFailed)?;
Ok(Self { ptr })
}
pub fn reset(&mut self) {
unsafe {
spandsp_sys::goertzel_reset(self.ptr.as_ptr());
}
}
pub fn update(&mut self, amp: &[i16]) -> usize {
let samples = amp.len().min(c_int::MAX as usize) as c_int;
unsafe { spandsp_sys::goertzel_update(self.ptr.as_ptr(), amp.as_ptr(), samples) as usize }
}
pub fn result(&mut self) -> f32 {
unsafe { spandsp_sys::goertzel_result(self.ptr.as_ptr()) }
}
pub fn as_ptr(&self) -> *mut spandsp_sys::goertzel_state_t {
self.ptr.as_ptr()
}
}
impl Drop for GoertzelDetector {
fn drop(&mut self) {
unsafe {
spandsp_sys::goertzel_free(self.ptr.as_ptr());
}
}
}