From 73841bc2dabb4d8412c414f6130e60a6a193edb1 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Mon, 12 Sep 2022 16:03:40 +0800 Subject: [PATCH] Implement voice switching during playback This assumes voices are approx the same duration, which is more accurate than rebuilding durations off of the estimates. --- .../AudioSession/AudioController.swift | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/apple/OmnivoreKit/Sources/Services/AudioSession/AudioController.swift b/apple/OmnivoreKit/Sources/Services/AudioSession/AudioController.swift index a280f6098..0fb438ad0 100644 --- a/apple/OmnivoreKit/Sources/Services/AudioSession/AudioController.swift +++ b/apple/OmnivoreKit/Sources/Services/AudioSession/AudioController.swift @@ -209,6 +209,32 @@ public class AudioController: NSObject, ObservableObject, AVAudioPlayerDelegate @AppStorage(UserDefaultKey.textToSpeechCurrentVoice.rawValue) public var currentVoice = "en-US-JennyNeural" { didSet { voiceList = generateVoiceList() + + var currentIdx = 0 + var currentOffset = 0.0 + if let player = self.player, let item = self.player?.currentItem as? SpeechPlayerItem { + currentIdx = item.speechItem.audioIdx + currentOffset = CMTimeGetSeconds(player.currentTime()) + } + player?.removeAllItems() + + downloadAndPlayFrom(currentIdx, currentOffset) + } + } + + private func downloadAndPlayFrom(_ currentIdx: Int, _ currentOffset: Double) { + playbackTask?.cancel() + + if let pageId = item?.id { + Task { + self.document = try? await downloadSpeechFile(pageId: pageId, priority: .high) + DispatchQueue.main.async { + let synthesizer = SpeechSynthesizer(appEnvironment: self.appEnvironment, networker: self.networker, document: self.document!) + self.durations = synthesizer.estimatedDurations(forSpeed: self.playbackRate) + self.synthesizer = synthesizer + self.synthesizeFrom(start: currentIdx, playWhenReady: self.state == .playing, atOffset: currentOffset) + } + } } }