Implement Phase 1: Global hotkey, HUD, and audio capture

Add complete listening UX without STT:
- Global hotkey manager with ⌘⇧V, push-to-talk and toggle modes
- Floating HUD with real-time RMS audio visualization
- AVAudioEngine capture with 16kHz mono PCM conversion
- 10-minute dictation timeout with ESC cancellation
- Optional start/stop sounds and microphone permissions
- Permission management for accessibility and input monitoring

All Phase 1 acceptance criteria met.
This commit is contained in:
Felipe M 2025-09-18 20:06:46 +02:00
parent 1db16227b2
commit 6e768a7753
Signed by: fmartingr
GPG key ID: CCFBC5637D4000A8
10 changed files with 1005 additions and 51 deletions

View file

@ -0,0 +1,51 @@
import Foundation
import AVFoundation
import AppKit
import CoreUtils
public class SoundManager: ObservableObject {
private let logger = Logger(category: "SoundManager")
@Published public var soundsEnabled: Bool = true
private var startSound: AVAudioPlayer?
private var stopSound: AVAudioPlayer?
public init() {
setupSounds()
}
private func setupSounds() {
// Use system sounds for now
// In a future version, we could bundle custom sound files
setupSystemSounds()
}
private func setupSystemSounds() {
// We'll use NSSound for system sounds since AVAudioPlayer requires files
// These are just placeholders - in a real implementation we'd bundle sound files
logger.info("Sound manager initialized with system sounds")
}
public func playStartSound() {
guard soundsEnabled else { return }
logger.debug("Playing start sound")
// Use a subtle system sound for start
NSSound(named: "Glass")?.play()
}
public func playStopSound() {
guard soundsEnabled else { return }
logger.debug("Playing stop sound")
// Use a different system sound for stop
NSSound(named: "Blow")?.play()
}
public func playErrorSound() {
logger.debug("Playing error sound")
// Always play error sound regardless of settings
NSSound(named: "Funk")?.play()
}
}