feat(clients): event sound effects + optional text-to-speech
Add audible cues and optional spoken announcements for session events (join/leave, channel + PM sent/recv, login, logout/connection-lost, mic on/off, voice-activity, PTT) across all three clients, driven off the shared C ABI vc_event stream so the mapping stays consistent. TTS is off by default; when enabled it announces events and reads message/PM bodies aloud. Master toggles + a sound-volume slider; the per-utterance voice-activity and PTT cues default off. WAVs ship from assets/sounds/. Windows (built + verified): new VoiceCat.App/Notifications/ layer (FeedbackSettings -> %AppData%\VoiceCat\feedback.json, SoundPlayerPool via System.Media.SoundPlayer, SpeechAnnouncer via Prismatoid 0.3.0, EventFeedback dispatcher); MainForm hooks; NotificationSettingsForm under Settings > Notifications; csproj adds the Prismatoid PackageRef and copies the WAVs into sounds\. macOS + iOS (written, not yet built -- needs a Mac): shared VoiceCatCore/Feedback/ (SoundEvent, EventFeedback = AVAudioPlayer pool + native AVSpeechSynthesizer, FeedbackSettings over UserDefaults); WAVs bundled via Package.swift resources (.process). Hooks in SessionState/ AppState (iOS) and MainWindowController (macOS); settings UI in SettingsView (iOS) and SettingsWindowController (macOS). No core/server code touched; ctest --preset dev unaffected. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
43
clients/apple/Sources/VoiceCatCore/Feedback/SoundEvent.swift
Normal file
43
clients/apple/Sources/VoiceCatCore/Feedback/SoundEvent.swift
Normal file
@@ -0,0 +1,43 @@
|
||||
// SoundEvent — the cross-platform set of audible event cues. Each maps to a WAV bundled as an
|
||||
// SPM resource (Sources/VoiceCatCore/Sounds/, copied from assets/sounds/). The same logical set
|
||||
// is mirrored in the Windows client (clients/windows/.../Notifications/SoundEvent.cs) so feedback
|
||||
// stays consistent across platforms.
|
||||
|
||||
import Foundation
|
||||
|
||||
public enum SoundEvent: CaseIterable, Sendable {
|
||||
case channelJoin // another user joined my channel
|
||||
case channelLeave // another user left my channel
|
||||
case channelRecv // channel text message from someone else
|
||||
case channelSent // channel text message I sent
|
||||
case pmRecv // private message received
|
||||
case pmSent // private message I sent
|
||||
case login // connected / authenticated
|
||||
case logout // clean disconnect
|
||||
case connectionLost // unexpected disconnect
|
||||
case voiceOn // my microphone stream started
|
||||
case voiceOff // my microphone stream stopped
|
||||
case vaStart // my voice-activity began (off by default)
|
||||
case vaStop // my voice-activity ended (off by default)
|
||||
case ptt // push-to-talk engaged (off by default)
|
||||
|
||||
/// Resource name (without extension) as bundled in Sources/VoiceCatCore/Sounds/.
|
||||
var resourceName: String {
|
||||
switch self {
|
||||
case .channelJoin: return "channel_join"
|
||||
case .channelLeave: return "channel_leave"
|
||||
case .channelRecv: return "channel_recv"
|
||||
case .channelSent: return "channel_sent"
|
||||
case .pmRecv: return "pm_recv"
|
||||
case .pmSent: return "pm_sent"
|
||||
case .login: return "login"
|
||||
case .logout: return "logout"
|
||||
case .connectionLost: return "connection_lost"
|
||||
case .voiceOn: return "voice_on"
|
||||
case .voiceOff: return "voice_off"
|
||||
case .vaStart: return "va_start"
|
||||
case .vaStop: return "va_stop"
|
||||
case .ptt: return "ptt"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user