AudioPlayback
AudioPlayback is part of the AgentSquadAudio product. It accepts PCM16 @ 24 kHz frames, converts them to float32, and schedules them on an AVAudioPlayerNode for continuous playback. flush() provides an instant barge-in cut by discarding all buffered audio.
import AgentSquadAudiopublic init(sampleRate: Double = 24_000)| Parameter | Default | Notes |
|---|---|---|
sampleRate | 24_000 | Sample rate in Hz for the internal float32 AVAudioFormat. Must match the PCM16 frames the runtime will enqueue. |
Public surface
Section titled “Public surface”public func start() async throws // attaches player node, starts engine (iOS: activates audio session)public func enqueue(_ pcm16: Data) async // schedules one PCM16 frame for playbackpublic func flush() async // discards all scheduled/playing buffers — instant barge-in cutpublic func stop() async // stops player and enginestart() is idempotent — a second call before stop() is a no-op.
enqueue converts the incoming PCM16 bytes to float32 samples and schedules the resulting buffer via AVAudioPlayerNode.scheduleBuffer(_:completionHandler:). It returns immediately without waiting for the buffer to finish playing, so callers are never serialised to real-time playback speed.
flush() calls player.stop() then player.play() to discard all scheduled buffers and re-arm the player for the next enqueue call — no interruption to the downstream pipeline.
VoiceAudioSession (iOS only)
Section titled “VoiceAudioSession (iOS only)”On iOS, start() calls the internal VoiceAudioSession.activate() helper, which configures the shared AVAudioSession:
category: .playAndRecordmode: .voiceChatoptions: [.defaultToSpeaker, .allowBluetoothHFP]If MicCapture.start() was already called first, the session is already active and this is a no-op. On macOS the call is compiled out and the system default audio device is used.
let playback = AudioPlayback()try await playback.start()
// Feed frames as they arrive from the realtime runtimeawait playback.enqueue(pcm16Frame)
// User interrupts — discard buffered audio instantlyawait playback.flush()
await playback.stop()Wiring to the voice runtime
Section titled “Wiring to the voice runtime”let runtime = RealtimeRuntime( input: MicCapture(), output: AudioPlayback(), // ... other config)The runtime drives start, enqueue, flush, and stop from its single event pump, so AudioPlayback is never called concurrently by the runtime.
Related pages
Section titled “Related pages”- Audio overview — the
AudioOutputprotocol and how it fits into the runtime - MicCapture — the companion
AudioInputbuilt-in - Custom audio — rolling your own
AudioOutputconformance - Voice overview — the
RealtimeRuntimethat consumesAudioPlayback