Handle multiple concurrent audio streams using sample files
Overview
This tutorial demonstrates how to process multiple concurrent audio streams using the Sanas SDK with dummy audio data. You’ll learn how to:
- Handle multiple simultaneous audio streams
- Share a single SDK instance across streams
- Manage per-stream processors and state
Use cases: Contact centers, conference platforms, multi-user applications, gaming voice chat servers
Prerequisites
Before you begin, ensure you have:
Complete Example: Processing Multiple Calls
This example processes multiple dummy audio data concurrently, simulating a multi-stream scenario:
import sanas_remote_sdk
import threading
import time
from concurrent.futures import ThreadPoolExecutor
def sleep_until(target_time):
"""Sleep until target time with precision"""
sleep_time = target_time - time.time()
if sleep_time > 0.001:
time.sleep(sleep_time - 0.001)
while time.time() < target_time:
pass
def process_call(call_id, sdk):
"""Process audio in a separate thread"""
call_ready = threading.Event()
def state_callback(state, reason):
print(f"Call {call_id} state: {state}")
if state == sanas_remote_sdk.ProcessorState.READY:
call_ready.set()
# Create processor for this stream
audio_params = sanas_remote_sdk.AudioParams()
audio_params.modelName = "desired_sanas_model"
audio_params.sampleRate = 8000
processor, result = sdk.CreateAudioProcessor(audio_params, state_callback)
if result == sanas_remote_sdk.CreateProcessorResult.SUCCESS:
if call_ready.wait(timeout=10):
print(f"Call {call_id} processing audio...")
first_chunk_time = time.time()
# Process 1500 chunks (30 seconds of audio at 8kHz)
for i in range(1500):
ideal_time = first_chunk_time + (i * 0.02)
sleep_until(ideal_time)
input_samples = [0.1] * 160 # Simulated audio data (e.g., from network stream)
output_samples = processor.ProcessSamples(input_samples)
sdk.DestroyAudioProcessor(processor)
# Initialize SDK once - shared across all streams
sdk = sanas_remote_sdk.CreateRemoteSDK()
init_params = sanas_remote_sdk.InitParams()
init_params.remoteEndpoint = "your_server_ip"
init_params.accountId = "your_account_id"
init_params.accountSecret = "your_account_secret"
init_params.secureMedia = False
sdk.Initialize(init_params)
# Process 4 concurrent audio streams
with ThreadPoolExecutor(max_workers=4) as executor:
futures = [executor.submit(process_call, i + 1, sdk) for i in range(4)]
for future in futures:
future.result()
sdk.Shutdown()
Note: This example uses a ThreadPoolExecutor for demonstration purposes. In production, use any concurrency model (threads, asyncio, etc.) - each stream just needs its own AudioProcessor and must maintain precise 20ms timing between chunks.
Key components:
| Components | Scope | Purpose |
|---|
| SDK Instance | Global | Shared connection to the Sanas server |
| Audio processor | Per-thread | Independent audio processing |
| Threading Event | Per-thread | State synchronization |
| Thread Pool | Global | Manages concurrent execution |
Support