From deb7a6484a08bea3580311ccbe7e7d2dac8ff02d Mon Sep 17 00:00:00 2001 From: Alex Nork Date: Tue, 24 Feb 2026 16:38:35 -0500 Subject: [PATCH] feat: request 16kHz mono format in AlwaysOnAudioMonitor audio tap Co-Authored-By: Claude --- .../Voice/WakeWord/AlwaysOnAudioMonitor.swift | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/clients/macos/vellum-assistant/Features/Voice/WakeWord/AlwaysOnAudioMonitor.swift b/clients/macos/vellum-assistant/Features/Voice/WakeWord/AlwaysOnAudioMonitor.swift index 791f86a1918..0f542161343 100644 --- a/clients/macos/vellum-assistant/Features/Voice/WakeWord/AlwaysOnAudioMonitor.swift +++ b/clients/macos/vellum-assistant/Features/Voice/WakeWord/AlwaysOnAudioMonitor.swift @@ -96,13 +96,20 @@ final class AlwaysOnAudioMonitor: ObservableObject { throw AudioMonitorError.noInputChannels } - // Install a tap using the hardware format for low-latency capture. - // The buffer is available for the WakeWordEngine to consume via its - // own internal processing (the engine's start() primes it for detection). + // Porcupine requires 16kHz mono Int16 PCM. Request 16kHz mono Float32 from + // AVAudioEngine (which handles resampling internally); the tap callback + // converts Float32 → Int16 before feeding the wake word engine. + let targetFormat = AVAudioFormat( + commonFormat: .pcmFormatFloat32, + sampleRate: 16000, + channels: 1, + interleaved: false + )! + inputNode.installTap( onBus: 0, bufferSize: Self.bufferSize, - format: hwFormat + format: targetFormat ) { [weak self] buffer, _ in guard let self else { return } guard let floatData = buffer.floatChannelData else { return }