Skip to main content
This tutorial walks through the core Sanas SDK flow using the sdk_example.py example. You’ll read a WAV file, run it through a model, and write the processed audio back out. Along the way you’ll use two shared helper modules — wav_utils.py (stdlib-only WAV I/O) and helpers.py (pipeline readiness and real-time pacing) — which every example depends on.
The SDK works with interleaved float32 PCM in [-1, 1]. You bring your own audio; the SDK never opens a microphone or speaker for you.

The core flow

Every audio-processing session follows the same five steps:
  1. create_sdkactivate_api_key (synchronous, returns an SdkResult)
  2. create_audio_processor with an audio_pipeline_state_notify callback
  3. Wait for PipelineState.RUNNING before feeding frames
  4. Feed 20 ms frames at real time, then drain the buffered tail with silence
  5. Save the processed audio
process_frame is synchronous and returns the processed frame directly. The model buffers ~50–100 ms internally, so the output lags the input. After the real audio is exhausted you push silence to pull the buffered tail back out.

Prerequisites

Set your credentials and pick an input file via environment variables and CLI flags:
Command-line flags: --model (model key, default VI_G_SE), --input, --output, and --pcm16 (opt into raw 16-bit PCM uplink — cloud inference only).

Step 1: Create and activate the SDK

Activation is inline and blocking. Always check the returned SdkResult before continuing.

Step 2: Load the input audio

load_samples (from helpers.py) wraps read_wav and returns the audio as an array('f') ready to slice into AudioFrames.
Under the hood, wav_utils.read_wav parses the WAV header directly (Python’s wave module only handles PCM) so it accepts both 16-bit PCM and 32-bit IEEE float input, including WAVE_FORMAT_EXTENSIBLE. It returns interleaved little-endian float32 regardless of host endianness.

Step 3: Build the processor with a state callback

The pipeline initializes asynchronously, so you must wait for PipelineState.RUNNING before feeding frames. PipelineWaiter (from helpers.py) bridges the audio_pipeline_state_notify callback to a waitable value.
A threading.Event only signals “something happened” and carries no value. PipelineWaiter uses a threading.Condition that notifies on every state change while keeping the latest state in last_state. Waiters wake on any transition and then inspect the value to decide whether to proceed (RUNNING), fail (NOT_RUNNING), or keep waiting. The state callback fires on a background thread, so publishing under a lock is required.

Step 4: Feed frames and drain the tail

Open the processor, wait for RUNNING, then hand off to feed_and_drain.
feed_and_drain splits the audio into fixed 20 ms chunks and calls process_frame on each. When realtime=True (the default), it paces the feed against a fixed monotonic schedule so timing self-corrects and doesn’t drift:
The final short chunk is padded with silence so no audio is dropped. After the input is exhausted, the helper drains the buffered tail. For low-latency models (NC/SE) it stops once the pipeline goes quiet (three consecutive empty frames); for high-latency pipelines you pass drain_seconds to pump silence for a fixed window instead.
sleep_until sleeps until ~1 ms before the deadline, then busy-waits the last millisecond for tighter pacing than a bare time.sleep().

Step 5: Save the output

save_wav clamps each sample to [-1, 1] and writes a 16-bit PCM WAV.

Full example

Next Steps

Processing a Single Stream

The core flow this benchmark scales up.

API Reference

Full SDK documentation for classes, enums, and callbacks.

Next Steps

Language Translation

Translate speech between languages and receive audio plus transcripts.

Processing Multiple Streams

Run many concurrent processors on one SDK instance.

References

SDK

SDK lifecycle methods including create_sdk, activate_api_key, and create_audio_processor.

AudioProcessor

process_frame method for audio processing.

Need Help?

Email Support

support@sanas.aiResponse time: 1 business day

Support Portal

Raise a support ticket for urgent issues