refactor: inject audio players

This commit is contained in:
Peter Steinberger
2025-12-30 13:46:14 +01:00
parent bc0a6fffd1
commit 9fb74399c8
3 changed files with 32 additions and 12 deletions

View File

@@ -39,6 +39,8 @@ final class TalkModeManager: NSObject {
private var mainSessionKey: String = "main" private var mainSessionKey: String = "main"
private var fallbackVoiceId: String? private var fallbackVoiceId: String?
private var lastPlaybackWasPCM: Bool = false private var lastPlaybackWasPCM: Bool = false
var pcmPlayer: PCMStreamingAudioPlaying = PCMStreamingAudioPlayer.shared
var mp3Player: StreamingAudioPlaying = StreamingAudioPlayer.shared
private var bridge: BridgeSession? private var bridge: BridgeSession?
private let silenceWindow: TimeInterval = 0.7 private let silenceWindow: TimeInterval = 0.7
@@ -502,10 +504,10 @@ final class TalkModeManager: NSObject {
let result: StreamingPlaybackResult let result: StreamingPlaybackResult
if let sampleRate { if let sampleRate {
self.lastPlaybackWasPCM = true self.lastPlaybackWasPCM = true
result = await PCMStreamingAudioPlayer.shared.play(stream: stream, sampleRate: sampleRate) result = await self.pcmPlayer.play(stream: stream, sampleRate: sampleRate)
} else { } else {
self.lastPlaybackWasPCM = false self.lastPlaybackWasPCM = false
result = await StreamingAudioPlayer.shared.play(stream: stream) result = await self.mp3Player.play(stream: stream)
} }
self.logger self.logger
.info( .info(
@@ -554,14 +556,14 @@ final class TalkModeManager: NSObject {
private func stopSpeaking(storeInterruption: Bool = true) { private func stopSpeaking(storeInterruption: Bool = true) {
guard self.isSpeaking else { return } guard self.isSpeaking else { return }
let interruptedAt = self.lastPlaybackWasPCM let interruptedAt = self.lastPlaybackWasPCM
? PCMStreamingAudioPlayer.shared.stop() ? self.pcmPlayer.stop()
: StreamingAudioPlayer.shared.stop() : self.mp3Player.stop()
if storeInterruption { if storeInterruption {
self.lastInterruptedAtSeconds = interruptedAt self.lastInterruptedAtSeconds = interruptedAt
} }
_ = self.lastPlaybackWasPCM _ = self.lastPlaybackWasPCM
? StreamingAudioPlayer.shared.stop() ? self.mp3Player.stop()
: PCMStreamingAudioPlayer.shared.stop() : self.pcmPlayer.stop()
TalkSystemSpeechSynthesizer.shared.stop() TalkSystemSpeechSynthesizer.shared.stop()
self.isSpeaking = false self.isSpeaking = false
} }

View File

@@ -64,6 +64,8 @@ actor TalkModeRuntime {
private var apiKey: String? private var apiKey: String?
private var fallbackVoiceId: String? private var fallbackVoiceId: String?
private var lastPlaybackWasPCM: Bool = false private var lastPlaybackWasPCM: Bool = false
var pcmPlayer: PCMStreamingAudioPlaying = PCMStreamingAudioPlayer.shared
var mp3Player: StreamingAudioPlaying = StreamingAudioPlayer.shared
private let silenceWindow: TimeInterval = 0.7 private let silenceWindow: TimeInterval = 0.7
private let minSpeechRMS: Double = 1e-3 private let minSpeechRMS: Double = 1e-3
@@ -538,10 +540,10 @@ actor TalkModeRuntime {
let result: StreamingPlaybackResult let result: StreamingPlaybackResult
if let sampleRate { if let sampleRate {
self.lastPlaybackWasPCM = true self.lastPlaybackWasPCM = true
result = await PCMStreamingAudioPlayer.shared.play(stream: stream, sampleRate: sampleRate) result = await self.pcmPlayer.play(stream: stream, sampleRate: sampleRate)
} else { } else {
self.lastPlaybackWasPCM = false self.lastPlaybackWasPCM = false
result = await StreamingAudioPlayer.shared.play(stream: stream) result = await self.mp3Player.play(stream: stream)
} }
self.ttsLogger self.ttsLogger
.info( .info(
@@ -642,11 +644,11 @@ actor TalkModeRuntime {
let usePCM = self.lastPlaybackWasPCM let usePCM = self.lastPlaybackWasPCM
let interruptedAt = await MainActor.run { let interruptedAt = await MainActor.run {
let primary = usePCM let primary = usePCM
? PCMStreamingAudioPlayer.shared.stop() ? self.pcmPlayer.stop()
: StreamingAudioPlayer.shared.stop() : self.mp3Player.stop()
_ = usePCM _ = usePCM
? StreamingAudioPlayer.shared.stop() ? self.mp3Player.stop()
: PCMStreamingAudioPlayer.shared.stop() : self.pcmPlayer.stop()
return primary return primary
} }
await TalkSystemSpeechSynthesizer.shared.stop() await TalkSystemSpeechSynthesizer.shared.stop()

View File

@@ -0,0 +1,16 @@
import Foundation
@MainActor
public protocol StreamingAudioPlaying {
func play(stream: AsyncThrowingStream<Data, Error>) async -> StreamingPlaybackResult
func stop() -> Double?
}
@MainActor
public protocol PCMStreamingAudioPlaying {
func play(stream: AsyncThrowingStream<Data, Error>, sampleRate: Double) async -> StreamingPlaybackResult
func stop() -> Double?
}
extension StreamingAudioPlayer: StreamingAudioPlaying {}
extension PCMStreamingAudioPlayer: PCMStreamingAudioPlaying {}