aic_sdk/lib.rs
1//! Rust bindings for the ai-coustics SDK.
2//!
3//! The SDK requires a license key. Generate one at
4//! [developers.ai-coustics.com](https://developers.ai-coustics.com).
5//!
6//! # Installation
7//!
8//! ```bash
9//! cargo add aic-sdk --features download-lib
10//! ```
11//!
12//! `download-lib` fetches the matching native library during the build. See [`docs::linking`] for
13//! the alternatives and for how the library is found at run time.
14//!
15//! # Quick start
16//!
17//! ```rust,no_run
18//! use aic_sdk::{include_model, ProcessorConfig, Model, Processor};
19//!
20//! // Embed model at compile time (or use Model::from_file to load at runtime)
21//! static MODEL: &[u8] = include_model!("path/to/model.aicmodel");
22//!
23//! fn main() -> Result<(), Box<dyn std::error::Error>> {
24//! // Get your license key from the environment variable
25//! let license_key = std::env::var("AIC_SDK_LICENSE")?;
26//!
27//! // Load the embedded model (or download manually at https://artifacts.ai-coustics.io/)
28//! let model = Model::from_buffer(MODEL)?;
29//!
30//! // Get optimal configuration based on the selected model
31//! let config = ProcessorConfig::optimal(&model);
32//!
33//! // Create a processor and initialize it
34//! let mut processor = Processor::new(&model, &license_key)?.with_config(&config)?;
35//!
36//! // Process mono audio
37//! let mut audio_block = vec![0.0f32; config.block_size];
38//! processor.process(&mut audio_block)?;
39//!
40//! Ok(())
41//! }
42//! ```
43//!
44//! # Where to go next
45//!
46//! [`docs::guide`] walks through the API, [`docs::examples`] has complete programs, and
47//! [`docs::linking`] covers how the native library is linked and found.
48//!
49//! Models and their IDs are listed at
50//! [artifacts.ai-coustics.io](https://artifacts.ai-coustics.io); the product documentation lives at
51//! [docs.ai-coustics.com](https://docs.ai-coustics.com).
52//!
53//! # License
54//!
55//! This Rust wrapper is distributed under the Apache 2.0 license.
56//! The core C SDK is distributed under the proprietary AIC-SDK license.
57//!
58//! `NOTICE.txt` in this crate lists the third-party software distributed with the SDK.
59#![cfg_attr(docsrs, feature(doc_cfg))]
60
61use aic_sdk_sys::{aic_get_compatible_model_version, aic_get_sdk_version, aic_set_sdk_wrapper_id};
62use std::ffi::CStr;
63
64#[cfg(feature = "runtime-linking")]
65use std::path::Path;
66
67// `test_support` is shared verbatim with the integration tests, which reach the SDK as `aic_sdk`;
68// the alias lets the same file resolve inside this crate too.
69#[cfg(test)]
70extern crate self as aic_sdk;
71
72pub mod docs;
73
74mod analyzer;
75mod energy_vad;
76mod error;
77mod file_analyzer;
78mod model;
79mod processor;
80#[cfg(feature = "async")]
81#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
82mod processor_async;
83#[cfg(test)]
84mod test_support;
85mod vad;
86#[cfg(feature = "async")]
87#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
88mod vad_async;
89
90pub use analyzer::*;
91pub use energy_vad::*;
92pub use error::*;
93pub use file_analyzer::*;
94pub use model::*;
95pub use processor::*;
96#[cfg(feature = "async")]
97#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
98pub use processor_async::*;
99pub use vad::*;
100#[cfg(feature = "async")]
101#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
102pub use vad_async::*;
103
104#[cfg(feature = "runtime-linking")]
105#[cfg_attr(docsrs, doc(cfg(feature = "runtime-linking")))]
106pub use aic_sdk_sys::DynamicLoadingError;
107
108/// Loads the AIC dynamic library from `path` when the `runtime-linking` feature is enabled.
109///
110/// This is optional. With `runtime-linking`, the library is loaded automatically on first use
111/// from the platform default name (`libaic.so` / `libaic.dylib` / `aic.dll`) via the OS loader
112/// search path. Call this only to pick a specific file, and do so before the first SDK call.
113///
114/// # Safety
115///
116/// `path` must point to an AIC dynamic library that is ABI-compatible with this crate's bundled
117/// `aic.h` header. Loading an incompatible library can cause undefined behavior when SDK functions
118/// are called.
119#[cfg(feature = "runtime-linking")]
120#[cfg_attr(docsrs, doc(cfg(feature = "runtime-linking")))]
121pub unsafe fn load_library<P: AsRef<Path>>(path: P) -> Result<(), DynamicLoadingError> {
122 unsafe { aic_sdk_sys::load_library(path) }
123}
124
125/// Returns whether an AIC dynamic library has already been loaded.
126#[cfg(feature = "runtime-linking")]
127#[cfg_attr(docsrs, doc(cfg(feature = "runtime-linking")))]
128pub fn is_library_loaded() -> bool {
129 aic_sdk_sys::is_library_loaded()
130}
131
132/// Returns the version of the SDK.
133///
134/// # Note
135/// This is not necessarily the same as this crate's version.
136///
137/// # Returns
138///
139/// Returns the SDK version string, or `"unknown"` if it cannot be decoded.
140///
141/// # Example
142///
143/// ```rust
144/// let version = aic_sdk::get_sdk_version();
145/// println!("ai-coustics SDK version: {version}");
146/// ```
147pub fn get_sdk_version() -> &'static str {
148 // SAFETY:
149 // - FFI call returns a pointer to a static C string owned by the SDK.
150 // - The pointer can never be null, so no check is necessary.
151 // - This function can be called from any thread.
152 let version_ptr = unsafe { aic_get_sdk_version() };
153
154 // SAFETY:
155 // - SDK returns a null-terminated static string.
156 unsafe { CStr::from_ptr(version_ptr).to_str().unwrap_or("unknown") }
157}
158
159/// Returns the model version compatible with the SDK.
160pub fn get_compatible_model_version() -> u32 {
161 // SAFETY:
162 // - FFI call takes no arguments and returns a plain integer.
163 // - This function can be called from any thread.
164 unsafe { aic_get_compatible_model_version() }
165}
166
167/// This function is only used to identify SDKs by ai-coustics and should not be called by users of this crate.
168///
169/// # Safety
170///
171/// Callers must use the wrapper ID assigned to them by ai-coustics.
172pub unsafe fn set_sdk_id(id: u32) {
173 // SAFETY:
174 // - This FFI call has no safety requirements.
175 // - This function can be called from any thread.
176 unsafe { aic_set_sdk_wrapper_id(id) }
177}