> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ai-coustics.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Streams and state

> How SDK objects hold per-stream state, when to reset it and which calls are real-time safe.

SDK audio objects retain history: enhancement state, voice activity detection (VAD) history or an analysis window. Manage each object's state across processing, resets and teardown.

## One object per stream

Create one processor, VAD or collector/analyzer pair per stream and pass its blocks in order. Objects can share a [model handle](/reference/sdk/models#loading-and-reusing-models), but each owns its processing state.

Interleaving streams mixes their history and produces unstable output. Give each side of a call or other independent channel its own object. See [audio format](/reference/concepts/audio-format#independent-streams-stored-as-channels).

## Resetting state

Reset clears history and internal buffers while preserving audio configuration. The object stays initialized.

| Object | Call | What it clears |
| - | - | - |
| Processor | `processor.get_context().reset()`<br />`aic_processor_context_reset` | The processor's internal buffers and enhancement state. It does not touch a VAD. |
| VAD | `vad.get_context().reset()`<br />`aic_vad_context_reset` | The VAD's state, plus the published speech decision and raw probability, which drop to `false` and `0.0` immediately rather than returning stale values. |
| Analyzer pair | `analyzer.reset()`<br />`aic_analyzer_reset` | The analyzer's state **and** the audio buffered by its paired collector. The collector stays initialized. |

Reset at a discontinuity:

* 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

Skipping reset carries unrelated history into the next stream and can cause enhancement artifacts or incorrect VAD and analysis results.

<Note>
  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.
</Note>

Reset is not a replacement for reinitialization. Changing the sample rate or the maximum block size requires initializing the object again, which allocates memory and must not happen on a real-time audio thread. See [Block size](/reference/concepts/audio-format#block-size).

## Real-time safety

The native core audio path is designed for a real-time callback. The table describes core operations; language bindings and application code add their own allocation, locking and scheduling behavior. Python `Processor.process()` copies its input and creates an output array, so the native guarantee does not make the Python call allocation-free. Keep setup, analysis and network operations off a real-time callback.

| Call | Real-time safe |
| - | - |
| `process` on a processor or VAD, `buffer` on a collector | Yes |
| Reset, on any object | Yes |
| Reading or writing parameters through a context | Yes |
| Reading the audio delay or the prediction delay | Yes |
| Creating an object, or `initialize` | No, it allocates memory |
| `analyze_buffered` on an analyzer | No, it runs an expensive model |
| `update_bearer_token` | No, it locks a mutex and allocates |
| `terminate_session` | No, termination can block during cleanup |

<Warning>
  Analysis work can exceed a real-time frame budget. The collector and analyzer are separate so you can schedule analysis away from the audio callback. See [Real-time analysis](/models/audio-insight/real-time-analysis#two-objects-two-threads).
</Warning>

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](/reference/concepts/performance#parallel-processing).

## Contexts

Use a context handle to control and query an object from a different thread than the audio thread:

```python theme={null}
proc_ctx = processor.get_context()
vad_ctx = vad.get_context()

proc_ctx.set_parameter(aic.ProcessorParameter.EnhancementLevel, 0.8)
print(vad_ctx.is_speech_detected())
```

Create a context once during setup and keep it for as long as you need it. In C, contexts are independent handles: `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.

## Ordering, cancellation and teardown

For asynchronous bindings, await each stream's processing call before submitting its next frame. A per-instance lock prevents concurrent mutation; it does not promise that concurrently submitted frames execute in audio order. Use separate instances to parallelize independent streams.

Keep queues bounded. Cancelling a Python await does not establish that already-running native work has stopped or that its state changes were rolled back. Stop admitting frames, resolve in-flight work and then reset, reinitialize or dispose of the stream. Prefer a new instance when the processing boundary is uncertain.

Reset clears audio history; it does not create a new authorization session or reverse `terminate_session()`. Stop submitting audio before requesting termination. Processing may be disabled after the termination call returns, so its return is not permission to submit another frame. Termination and object destruction may block while session work drains, so perform them on a control thread. Stop refresh and analysis tasks during shutdown and release contexts according to your binding's ownership rules.

For reconnects, choose one owner to coordinate stopping input, settling work, clearing each object's state and restarting the warmup/sample counters. Avoid resetting while another application task is still submitting frames from the previous call.

## Verify stream isolation

Using the same fixed fixtures and configuration, compare two independent instances run separately with the same two instances scheduled concurrently. Each output should match its own reference within your chosen numerical tolerance; one stream's reset must not alter the other.

Include repeated reset, a reconnect, a final partial block and cancellation in your integration checks. Check errors and teardown completion as well as sample counts. See [deployment verification](/production/deployment#verify-the-deployment).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.