MicCapture
MicCapture is part of the AgentSquadAudio product. It taps AVAudioEngine’s input node, converts the hardware stream to PCM16 @ 24 kHz mono, and yields frames through a bounded AsyncStream<Data>.
import AgentSquadAudiopublic init(sampleRate: Double = 24_000, maxBufferedFrames: Int = 16)| Parameter | Default | Notes |
|---|---|---|
sampleRate | 24_000 | Target sample rate in Hz. Must match what the realtime runtime expects. |
maxBufferedFrames | 16 | Capacity of the internal AsyncStream. Under back-pressure the oldest frames are dropped — the tap thread never blocks. |
Public surface
Section titled “Public surface”public let frames: AsyncStream<Data> // yields PCM16 little-endian mono frames
public func start() async throws // installs tap, starts engine, requests mic permission (iOS)public func stop() async // stops engine, removes tap, finishes the streamstart() is idempotent — a second call before stop() is a no-op. Calling start() again after stop() is not supported; create a new instance.
MicCaptureError
Section titled “MicCaptureError”public enum MicCaptureError: Error, Equatable { case permissionDenied // user denied mic access (iOS only) case converterUnavailable // AVAudioConverter could not be initialised for the hardware format}iOS mic permission
Section titled “iOS mic permission”On iOS, start() requests microphone access before installing the tap:
- iOS 17+ — uses
AVAudioApplication.requestRecordPermission - iOS 16 — falls back to
AVAudioSession.requestRecordPermission(the deprecated overload; no compiler warning fires at the iOS 16 deployment floor)
If the user denies permission, start() throws MicCaptureError.permissionDenied.
VoiceAudioSession (iOS only)
Section titled “VoiceAudioSession (iOS only)”On iOS, start() calls the internal VoiceAudioSession.activate() helper before installing the tap. It configures the shared AVAudioSession:
category: .playAndRecordmode: .voiceChatoptions: [.defaultToSpeaker, .allowBluetoothHFP]VoiceAudioSession is idempotent — re-activating an already-active session is a no-op. On macOS the call is compiled out (#if os(iOS)) and the system default audio device is used.
let mic = MicCapture() // 24 kHz, 16-frame queuetry await mic.start()
for await frame in mic.frames { // frame: Data containing PCM16 little-endian mono samples}
await mic.stop()Wiring to the voice runtime
Section titled “Wiring to the voice runtime”Pass MicCapture directly to RealtimeRuntime — the runtime only cares about the AudioInput protocol:
let runtime = RealtimeRuntime( input: MicCapture(), output: AudioPlayback(), // ... other config)Related pages
Section titled “Related pages”- Audio overview — the
AudioInputprotocol and how it fits into the runtime - AudioPlayback — the companion
AudioOutputbuilt-in - Custom audio — rolling your own
AudioInputconformance - Voice overview — the
RealtimeRuntimethat consumesMicCapture