fix: stabilize voice wake test
parent
135a52020c
commit
daca3a5fc9
|
|
@ -1365,7 +1365,7 @@ actor MicLevelMonitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func push(level: Double) {
|
private func push(level: Double) {
|
||||||
smoothedLevel = (smoothedLevel * 0.65) + (level * 0.35)
|
smoothedLevel = (smoothedLevel * 0.45) + (level * 0.55)
|
||||||
guard let update else { return }
|
guard let update else { return }
|
||||||
let value = smoothedLevel
|
let value = smoothedLevel
|
||||||
Task { @MainActor in update(value) }
|
Task { @MainActor in update(value) }
|
||||||
|
|
@ -1393,7 +1393,6 @@ final class VoiceWakeTester {
|
||||||
private let audioEngine = AVAudioEngine()
|
private let audioEngine = AVAudioEngine()
|
||||||
private var recognitionRequest: SFSpeechAudioBufferRecognitionRequest?
|
private var recognitionRequest: SFSpeechAudioBufferRecognitionRequest?
|
||||||
private var recognitionTask: SFSpeechRecognitionTask?
|
private var recognitionTask: SFSpeechRecognitionTask?
|
||||||
private let audioQueue = DispatchQueue(label: "com.steipete.clawdis.voicewake.audio", qos: .userInitiated)
|
|
||||||
|
|
||||||
init(locale: Locale = .current) {
|
init(locale: Locale = .current) {
|
||||||
self.recognizer = SFSpeechRecognizer(locale: locale)
|
self.recognizer = SFSpeechRecognizer(locale: locale)
|
||||||
|
|
@ -1426,12 +1425,16 @@ final class VoiceWakeTester {
|
||||||
inputNode.removeTap(onBus: 0)
|
inputNode.removeTap(onBus: 0)
|
||||||
inputNode.installTap(onBus: 0, bufferSize: 2048, format: format) { [weak self] buffer, _ in
|
inputNode.installTap(onBus: 0, bufferSize: 2048, format: format) { [weak self] buffer, _ in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
self.enqueueBuffer(buffer)
|
Task { @MainActor in
|
||||||
|
self.recognitionRequest?.append(buffer)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
audioEngine.prepare()
|
audioEngine.prepare()
|
||||||
try audioEngine.start()
|
try audioEngine.start()
|
||||||
onUpdate(.listening)
|
DispatchQueue.main.async {
|
||||||
|
onUpdate(.listening)
|
||||||
|
}
|
||||||
|
|
||||||
guard let request = recognitionRequest else { return }
|
guard let request = recognitionRequest else { return }
|
||||||
|
|
||||||
|
|
@ -1440,7 +1443,7 @@ final class VoiceWakeTester {
|
||||||
let text = result?.bestTranscription.formattedString ?? ""
|
let text = result?.bestTranscription.formattedString ?? ""
|
||||||
let matched = Self.matches(text: text, triggers: triggers)
|
let matched = Self.matches(text: text, triggers: triggers)
|
||||||
let errorMessage = error?.localizedDescription
|
let errorMessage = error?.localizedDescription
|
||||||
DispatchQueue.main.async {
|
Task { @MainActor in
|
||||||
self.handleResult(matched: matched, text: text, isFinal: result?.isFinal ?? false, errorMessage: errorMessage, onUpdate: onUpdate)
|
self.handleResult(matched: matched, text: text, isFinal: result?.isFinal ?? false, errorMessage: errorMessage, onUpdate: onUpdate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1455,13 +1458,6 @@ final class VoiceWakeTester {
|
||||||
audioEngine.inputNode.removeTap(onBus: 0)
|
audioEngine.inputNode.removeTap(onBus: 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func enqueueBuffer(_ buffer: AVAudioPCMBuffer) {
|
|
||||||
audioQueue.async { [weak self] in
|
|
||||||
guard let self else { return }
|
|
||||||
self.recognitionRequest?.append(buffer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func handleResult(
|
private func handleResult(
|
||||||
matched: Bool,
|
matched: Bool,
|
||||||
text: String,
|
text: String,
|
||||||
|
|
@ -1879,11 +1875,13 @@ struct VoiceWakeSettings: View {
|
||||||
micID: state.voiceWakeMicID.isEmpty ? nil : state.voiceWakeMicID,
|
micID: state.voiceWakeMicID.isEmpty ? nil : state.voiceWakeMicID,
|
||||||
localeID: state.voiceWakeLocaleID,
|
localeID: state.voiceWakeLocaleID,
|
||||||
onUpdate: { newState in
|
onUpdate: { newState in
|
||||||
self.testState = newState
|
DispatchQueue.main.async { [self] in
|
||||||
if case .detected = newState { self.isTesting = false }
|
testState = newState
|
||||||
if case .failed = newState { self.isTesting = false }
|
if case .detected = newState { isTesting = false }
|
||||||
if case .detected = newState { Task { await restartMeter() } }
|
if case .failed = newState { isTesting = false }
|
||||||
if case .failed = newState { Task { await restartMeter() } }
|
if case .detected = newState { Task { await restartMeter() } }
|
||||||
|
if case .failed = newState { Task { await restartMeter() } }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
// timeout after 10s
|
// timeout after 10s
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue