Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ final class PorcupineWakeWordEngine: WakeWordEngine {

private var binding: PorcupineBinding?
private var frameBuffer: [Int16] = []
private let frameLength: Int = 512
private var frameLength: Int = 512

/// Guards `binding` and `frameBuffer` for thread safety between
/// the main thread (`start`/`stop`) and the audio thread (`processAudioFrame`).
Expand Down Expand Up @@ -107,10 +107,14 @@ final class PorcupineWakeWordEngine: WakeWordEngine {
return
}

// 7. Commit state
// 7. Query actual frame length from binding
let actualFrameLength = Int(newBinding.frameLength)

// 8. Commit state
withLock {
self.binding = newBinding
self.frameBuffer = []
self.frameLength = actualFrameLength
self.hasLoggedProcessError = false
}
isRunning = true
Expand All @@ -131,6 +135,7 @@ final class PorcupineWakeWordEngine: WakeWordEngine {
// MARK: - Audio processing (audio thread)

func processAudioFrame(_ frame: [Int16]) {
var shouldNotify = false
withLock {
guard binding != nil else { return }
frameBuffer.append(contentsOf: frame)
Expand All @@ -142,7 +147,7 @@ final class PorcupineWakeWordEngine: WakeWordEngine {
do {
let keywordIndex = try binding!.process(pcm: chunk)
if keywordIndex >= 0 {
onWakeWordDetected?(1.0)
shouldNotify = true
}
} catch {
if !hasLoggedProcessError {
Expand All @@ -154,6 +159,9 @@ final class PorcupineWakeWordEngine: WakeWordEngine {
}
}
}
if shouldNotify {
onWakeWordDetected?(1.0)
Comment on lines +162 to +163
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Emit wake-word callback for every detected chunk

Using a single shouldNotify flag means processAudioFrame now emits at most one callback per invocation even if the while loop detects keywords in multiple buffered chunks. This drops detections whenever one audio callback contains enough samples for multiple Porcupine frames (for example after scheduling jitter or if the user repeats the wake word quickly), which changes behavior from per-detection signaling to per-call signaling and can miss legitimate wake events.

Useful? React with 👍 / 👎.

}
}

// MARK: - Lock helpers
Expand Down