use std::ffi::c_char;
use std::os::raw::c_int;
use std::ptr;
use audio_cpp_sys::*;
use crate::error::Error;
use crate::ffi;
use crate::session::Session;
use crate::types::{Backend, Capabilities, ModelMetadata, RunMode, TaskKind};
pub struct Model {
raw: *mut audiocpp_model,
}
unsafe impl Send for Model {}
unsafe impl Sync for Model {}
impl Model {
pub(crate) fn from_raw(raw: *mut audiocpp_model) -> Self {
Self { raw }
}
pub fn metadata(&self) -> Result<ModelMetadata, Error> {
let mut out: *mut c_char = ptr::null_mut();
ffi::check_rc(unsafe { audiocpp_model_metadata_json(self.raw, &mut out) })?;
let json = unsafe { ffi::take_string(out)? };
serde_json::from_str(&json).map_err(Error::from)
}
pub fn capabilities(&self) -> Result<Capabilities, Error> {
let mut out: *mut c_char = ptr::null_mut();
ffi::check_rc(unsafe { audiocpp_model_capabilities_json(self.raw, &mut out) })?;
let json = unsafe { ffi::take_string(out)? };
serde_json::from_str(&json).map_err(Error::from)
}
pub fn create_task_session(
&self,
task: TaskKind,
mode: RunMode,
backend: Backend,
device: i32,
threads: i32,
session_options: Option<&str>,
) -> Result<Session, Error> {
let task_c = ffi::cstring(task.as_str())?;
let mode_c = ffi::cstring(mode.as_str())?;
let backend_c = ffi::cstring(backend.as_str())?;
let options_c = session_options.map(ffi::cstring).transpose()?;
let raw = unsafe {
audiocpp_model_create_task_session(
self.raw,
task_c.as_ptr() as *const c_char,
mode_c.as_ptr() as *const c_char,
backend_c.as_ptr() as *const c_char,
device as c_int,
threads as c_int,
options_c.as_ref().map_or(ptr::null(), |s| s.as_ptr() as *const c_char),
)
};
if raw.is_null() {
return Err(Error::NullHandle(ffi::last_error()));
}
Ok(Session::from_raw(raw))
}
}
impl Drop for Model {
fn drop(&mut self) {
unsafe {
audiocpp_model_free(self.raw);
}
}
}