Model

Struct Model 

Source
pub struct Model<'a> { /* private fields */ }
Expand description

High-level wrapper for the ai-coustics audio enhancement model.

This struct provides a safe, Rust-friendly interface to the underlying C library. It handles memory management automatically and converts C-style error codes to Rust Result types.

§Sharing and Multi-threading

Model is Send and Sync, so you can share it across threads. It does not implement Clone, so wrap it in an Arc if you need shared ownership.

§Example

let model = Model::from_file("/path/to/model.aicmodel").unwrap();
let config = ProcessorConfig::optimal(&model).with_num_channels(2);
let mut processor = Processor::new(&model, &license_key).unwrap();
processor.initialize(&config).unwrap();
let mut audio_buffer = vec![0.0f32; config.num_channels as usize * config.num_frames];
processor.process_interleaved(&mut audio_buffer).unwrap();

§Multi-threaded Example

let model = Arc::new(Model::from_file("/path/to/model.aicmodel").unwrap());

// Spawn multiple threads, each with its own processor but sharing the same model
let handles: Vec<_> = (0..4)
    .map(|i| {
        let model_clone = Arc::clone(&model);
        thread::spawn(move || {
            let license_key = std::env::var("AIC_SDK_LICENSE").unwrap();
            let mut processor = Processor::new(&model_clone, &license_key).unwrap();
            // Process audio in this thread...
        })
    })
    .collect();

for handle in handles {
    handle.join().unwrap();
}

Implementations§

Source§

impl<'a> Model<'a>

Source

pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Model<'static>, AicError>

Creates a new audio enhancement model instance.

Multiple models can be created to process different audio streams simultaneously or to switch between different enhancement algorithms during runtime.

§Arguments
  • path - Filesystem path to a model file.
§Returns

Returns a Result containing the new Model instance or an AicError if creation fails.

§Example
let model = Model::from_file("/path/to/model.aicmodel").unwrap();
Source

pub fn from_buffer(buffer: &'a [u8]) -> Result<Self, AicError>

Creates a new model instance from an in-memory buffer.

The buffer must be 64-byte aligned.

Consider using include_model! to embed a model file at compile time with the correct alignment.

§Arguments
  • buffer - Raw bytes of the model file.
§Returns

Returns a Result containing the new Model instance or an AicError if creation fails.

§Example
static MODEL: &'static [u8] = include_model!("/path/to/model.aicmodel");
let model = Model::from_buffer(MODEL).unwrap();
Source

pub fn id(&self) -> &str

Returns the model identifier string.

Source

pub fn optimal_sample_rate(&self) -> u32

Retrieves the native sample rate of the processor’s model.

Each model is optimized for a specific sample rate, which determines the frequency range of the enhanced audio output. While you can process audio at any sample rate, understanding the model’s native rate helps predict the enhancement quality.

How sample rate affects enhancement:

  • Models trained at lower sample rates (e.g., 8 kHz) can only enhance frequencies up to their Nyquist limit (4 kHz for 8 kHz models)
  • When processing higher sample rate input (e.g., 48 kHz) with a lower-rate model, only the lower frequency components will be enhanced

Enhancement blending: When enhancement strength is set below 1.0, the enhanced signal is blended with the original, maintaining the full frequency spectrum of your input while adding the model’s noise reduction capabilities to the lower frequencies.

Sample rate and optimal frames relationship: When using different sample rates than the model’s native rate, the optimal number of frames (returned by optimal_num_frames) will change. The model’s output delay remains constant regardless of sample rate as long as you use the optimal frame count for that rate.

Recommendation: For maximum enhancement quality across the full frequency spectrum, match your input sample rate to the model’s native rate when possible.

§Returns

Returns the model’s native sample rate.

§Example
let optimal_sample_rate = model.optimal_sample_rate();
println!("Optimal sample rate: {optimal_sample_rate} Hz");
Source

pub fn optimal_num_frames(&self, sample_rate: u32) -> usize

Retrieves the optimal number of frames for the selected model at a given sample rate.

Using the optimal number of frames minimizes latency by avoiding internal buffering.

When you use a different frame count than the optimal value, the model will introduce additional buffering latency on top of its base processing delay.

The optimal frame count varies based on the sample rate. Each model operates on a fixed time window duration, so the required number of frames changes with sample rate. For example, a model designed for 10 ms processing windows requires 480 frames at 48 kHz, but only 160 frames at 16 kHz to capture the same duration of audio.

Call this function with your intended sample rate before calling Processor::initialize to determine the best frame count for minimal latency.

§Arguments
  • sample_rate - The sample rate in Hz for which to calculate the optimal frame count.
§Returns

Returns the optimal frame count.

§Example
let optimal_frames = model.optimal_num_frames(sample_rate);
println!("Optimal frame count: {optimal_frames}");

Trait Implementations§

Source§

impl<'a> Drop for Model<'a>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl<'a> Send for Model<'a>

Source§

impl<'a> Sync for Model<'a>

Auto Trait Implementations§

§

impl<'a> Freeze for Model<'a>

§

impl<'a> RefUnwindSafe for Model<'a>

§

impl<'a> Unpin for Model<'a>

§

impl<'a> UnwindSafe for Model<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.