1use std::ffi::c_char;
4use std::os::raw::c_int;
5use std::ptr;
6
7use audio_cpp_sys::*;
8
9use crate::error::Error;
10use crate::ffi;
11use crate::registry::RegistryGuard;
12use crate::session::Session;
13use crate::types::{Backend, Capabilities, ModelMetadata, RunMode, TaskKind};
14
15pub struct Model {
20 raw: *mut audiocpp_model,
21 _guard: RegistryGuard,
23}
24
25unsafe impl Send for Model {}
29
30impl Model {
31 pub(crate) fn from_raw(raw: *mut audiocpp_model, guard: RegistryGuard) -> Self {
33 Self { raw, _guard: guard }
34 }
35
36 pub fn metadata(&self) -> Result<ModelMetadata, Error> {
42 let mut out: *mut c_char = ptr::null_mut();
43 ffi::check_rc(unsafe { audiocpp_model_metadata_json(self.raw, &mut out) })?;
44 let json = unsafe { ffi::take_string(out)? };
45 serde_json::from_str(&json).map_err(Error::from)
46 }
47
48 pub fn capabilities(&self) -> Result<Capabilities, Error> {
54 let mut out: *mut c_char = ptr::null_mut();
55 ffi::check_rc(unsafe { audiocpp_model_capabilities_json(self.raw, &mut out) })?;
56 let json = unsafe { ffi::take_string(out)? };
57 serde_json::from_str(&json).map_err(Error::from)
58 }
59
60 pub fn create_task_session(
71 &self,
72 task: TaskKind,
73 mode: RunMode,
74 backend: Backend,
75 device: i32,
76 threads: i32,
77 session_options: Option<&str>,
78 ) -> Result<Session, Error> {
79 let task_c = ffi::cstring(task.as_str())?;
80 let mode_c = ffi::cstring(mode.as_str())?;
81 let backend_c = ffi::cstring(backend.as_str())?;
82 let options_c = session_options.map(ffi::cstring).transpose()?;
83
84 let raw = unsafe {
85 audiocpp_model_create_task_session(
86 self.raw,
87 task_c.as_ptr() as *const c_char,
88 mode_c.as_ptr() as *const c_char,
89 backend_c.as_ptr() as *const c_char,
90 device as c_int,
91 threads as c_int,
92 options_c
93 .as_ref()
94 .map_or(ptr::null(), |s| s.as_ptr() as *const c_char),
95 )
96 };
97 if raw.is_null() {
98 return Err(Error::NullHandle(ffi::last_error()));
99 }
100 Ok(Session::from_raw(raw, self._guard.clone(), backend))
101 }
102}
103
104impl Drop for Model {
105 fn drop(&mut self) {
106 unsafe {
107 audiocpp_model_free(self.raw);
108 }
109 }
110}