fix: hop audio to main actor

This commit is contained in:
Peter Steinberger
2025-12-30 14:22:03 +01:00
parent 973bd3a427
commit 3d6cc435ef

View File

@@ -64,8 +64,6 @@ 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
@@ -540,10 +538,10 @@ actor TalkModeRuntime {
let result: StreamingPlaybackResult let result: StreamingPlaybackResult
if let sampleRate { if let sampleRate {
self.lastPlaybackWasPCM = true self.lastPlaybackWasPCM = true
result = await self.pcmPlayer.play(stream: stream, sampleRate: sampleRate) result = await self.playPCM(stream: stream, sampleRate: sampleRate)
} else { } else {
self.lastPlaybackWasPCM = false self.lastPlaybackWasPCM = false
result = await self.mp3Player.play(stream: stream) result = await self.playMP3(stream: stream)
} }
self.ttsLogger self.ttsLogger
.info( .info(
@@ -642,15 +640,8 @@ actor TalkModeRuntime {
func stopSpeaking(reason: TalkStopReason) async { func stopSpeaking(reason: TalkStopReason) async {
let usePCM = self.lastPlaybackWasPCM let usePCM = self.lastPlaybackWasPCM
let interruptedAt = await MainActor.run { let interruptedAt = usePCM ? await self.stopPCM() : await self.stopMP3()
let primary = usePCM _ = usePCM ? await self.stopMP3() : await self.stopPCM()
? self.pcmPlayer.stop()
: self.mp3Player.stop()
_ = usePCM
? self.mp3Player.stop()
: self.pcmPlayer.stop()
return primary
}
await TalkSystemSpeechSynthesizer.shared.stop() await TalkSystemSpeechSynthesizer.shared.stop()
guard self.phase == .speaking else { return } guard self.phase == .speaking else { return }
if reason == .speech, let interruptedAt { if reason == .speech, let interruptedAt {
@@ -667,6 +658,31 @@ actor TalkModeRuntime {
await MainActor.run { TalkModeController.shared.updatePhase(.thinking) } await MainActor.run { TalkModeController.shared.updatePhase(.thinking) }
} }
// MARK: - Audio playback (MainActor helpers)
@MainActor
private func playPCM(
stream: AsyncThrowingStream<Data, Error>,
sampleRate: Double) async -> StreamingPlaybackResult
{
await PCMStreamingAudioPlayer.shared.play(stream: stream, sampleRate: sampleRate)
}
@MainActor
private func playMP3(stream: AsyncThrowingStream<Data, Error>) async -> StreamingPlaybackResult {
await StreamingAudioPlayer.shared.play(stream: stream)
}
@MainActor
private func stopPCM() -> Double? {
PCMStreamingAudioPlayer.shared.stop()
}
@MainActor
private func stopMP3() -> Double? {
StreamingAudioPlayer.shared.stop()
}
// MARK: - Config // MARK: - Config
private func reloadConfig() async { private func reloadConfig() async {