diff --git a/apps/ios/Sources/Voice/TalkModeManager.swift b/apps/ios/Sources/Voice/TalkModeManager.swift index a06154037..fefefe68f 100644 --- a/apps/ios/Sources/Voice/TalkModeManager.swift +++ b/apps/ios/Sources/Voice/TalkModeManager.swift @@ -39,6 +39,8 @@ final class TalkModeManager: NSObject { private var mainSessionKey: String = "main" private var fallbackVoiceId: String? private var lastPlaybackWasPCM: Bool = false + var pcmPlayer: PCMStreamingAudioPlaying = PCMStreamingAudioPlayer.shared + var mp3Player: StreamingAudioPlaying = StreamingAudioPlayer.shared private var bridge: BridgeSession? private let silenceWindow: TimeInterval = 0.7 @@ -502,10 +504,10 @@ final class TalkModeManager: NSObject { let result: StreamingPlaybackResult if let sampleRate { self.lastPlaybackWasPCM = true - result = await PCMStreamingAudioPlayer.shared.play(stream: stream, sampleRate: sampleRate) + result = await self.pcmPlayer.play(stream: stream, sampleRate: sampleRate) } else { self.lastPlaybackWasPCM = false - result = await StreamingAudioPlayer.shared.play(stream: stream) + result = await self.mp3Player.play(stream: stream) } self.logger .info( @@ -554,14 +556,14 @@ final class TalkModeManager: NSObject { private func stopSpeaking(storeInterruption: Bool = true) { guard self.isSpeaking else { return } let interruptedAt = self.lastPlaybackWasPCM - ? PCMStreamingAudioPlayer.shared.stop() - : StreamingAudioPlayer.shared.stop() + ? self.pcmPlayer.stop() + : self.mp3Player.stop() if storeInterruption { self.lastInterruptedAtSeconds = interruptedAt } _ = self.lastPlaybackWasPCM - ? StreamingAudioPlayer.shared.stop() - : PCMStreamingAudioPlayer.shared.stop() + ? self.mp3Player.stop() + : self.pcmPlayer.stop() TalkSystemSpeechSynthesizer.shared.stop() self.isSpeaking = false } diff --git a/apps/macos/Sources/Clawdis/TalkModeRuntime.swift b/apps/macos/Sources/Clawdis/TalkModeRuntime.swift index 73f76b1cf..124dbc76a 100644 --- a/apps/macos/Sources/Clawdis/TalkModeRuntime.swift +++ b/apps/macos/Sources/Clawdis/TalkModeRuntime.swift @@ -64,6 +64,8 @@ actor TalkModeRuntime { private var apiKey: String? private var fallbackVoiceId: String? private var lastPlaybackWasPCM: Bool = false + var pcmPlayer: PCMStreamingAudioPlaying = PCMStreamingAudioPlayer.shared + var mp3Player: StreamingAudioPlaying = StreamingAudioPlayer.shared private let silenceWindow: TimeInterval = 0.7 private let minSpeechRMS: Double = 1e-3 @@ -538,10 +540,10 @@ actor TalkModeRuntime { let result: StreamingPlaybackResult if let sampleRate { self.lastPlaybackWasPCM = true - result = await PCMStreamingAudioPlayer.shared.play(stream: stream, sampleRate: sampleRate) + result = await self.pcmPlayer.play(stream: stream, sampleRate: sampleRate) } else { self.lastPlaybackWasPCM = false - result = await StreamingAudioPlayer.shared.play(stream: stream) + result = await self.mp3Player.play(stream: stream) } self.ttsLogger .info( @@ -642,11 +644,11 @@ actor TalkModeRuntime { let usePCM = self.lastPlaybackWasPCM let interruptedAt = await MainActor.run { let primary = usePCM - ? PCMStreamingAudioPlayer.shared.stop() - : StreamingAudioPlayer.shared.stop() + ? self.pcmPlayer.stop() + : self.mp3Player.stop() _ = usePCM - ? StreamingAudioPlayer.shared.stop() - : PCMStreamingAudioPlayer.shared.stop() + ? self.mp3Player.stop() + : self.pcmPlayer.stop() return primary } await TalkSystemSpeechSynthesizer.shared.stop() diff --git a/apps/shared/ClawdisKit/Sources/ClawdisKit/AudioStreamingProtocols.swift b/apps/shared/ClawdisKit/Sources/ClawdisKit/AudioStreamingProtocols.swift new file mode 100644 index 000000000..a211a4b3a --- /dev/null +++ b/apps/shared/ClawdisKit/Sources/ClawdisKit/AudioStreamingProtocols.swift @@ -0,0 +1,16 @@ +import Foundation + +@MainActor +public protocol StreamingAudioPlaying { + func play(stream: AsyncThrowingStream) async -> StreamingPlaybackResult + func stop() -> Double? +} + +@MainActor +public protocol PCMStreamingAudioPlaying { + func play(stream: AsyncThrowingStream, sampleRate: Double) async -> StreamingPlaybackResult + func stop() -> Double? +} + +extension StreamingAudioPlayer: StreamingAudioPlaying {} +extension PCMStreamingAudioPlayer: PCMStreamingAudioPlaying {}