Skip to main content
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:

ComponentsScopePurpose
SDK InstanceGlobalShared connection to the Sanas server
Audio processorPer-threadIndependent audio processing
Threading EventPer-threadState synchronization
Thread PoolGlobalManages concurrent execution

Support

Need help? Contact our support team at support@sanas.ai or raise a ticket.