One object per stream
State belongs to the object, not to the model. Create one processor, VAD, or collector and analyzer pair per stream, pass that stream’s blocks to it in order, and reuse the same model handle across all of them. Interleaving two streams through one object mixes their history and produces unstable output. This is also why the two sides of a call, or the channels of a multi-channel input that represent independent streams, each need their own object. See Audio Format.Resetting state
Reset clears the internal buffers and history of one object while keeping its audio configuration. The object stays initialized, so you can continue processing immediately afterwards without reinitializing.
Call reset when the audio you are about to pass is not a continuation of the audio you passed before:
- The stream was interrupted, or a caller reconnected
- You are seeking in a file or a recording
- You are reusing the object for a new call or a new stream
- A long gap in the audio makes the previous content irrelevant
Resetting is per object. If you run enhancement, VAD, and analysis side by side on one stream, reset all of them when that stream is interrupted.
Real-time safety
The audio path is designed to run inside a real-time callback. Setup, analysis, and anything that talks to our backend is not.
Each object is also single-threaded with respect to itself: do not call
process on one processor from two threads at once. Parallelize across streams with one object per stream instead. See Performance.
Contexts
Control and query APIs live on a separate context handle rather than on the audio object itself, so they can be used from a different thread than the one running audio:aic_processor_context_destroy does not destroy the processor, and a context may be destroyed before or after the object it controls, in any order.