去年,我问了一个关于如何将演讲保存到文件中的问题。Stack Overflow Question - Recording speech synthesis to a saved file
感谢kakaiikaka的回答。虽然它确实工作,但缓冲时有一点错误。下列程式码会隔离问题。在iOS 16中,虽然有一个错误,但它确实能按预期工作。我所拥有的完成处理程序按预期打印。下面的错误会打印20次左右。
2023-06-17 15:35:33.811838-0400录音语音修复[3899:1958883] [AXTTSComon] TTSP延迟回退入队完整音频队列缓冲区:错误-66686将缓冲区入队
iOS 17(第一个测试版)有一个更多描述性的错误,它不起作用。完成处理程序不打印。下面的错误会打印大约20次。
输入数据处理器返回了不一致的512个数据包,长度为2,048字节;每个数据包2个字节,实际上是1,024个数据包
我假设这是同一个问题。修复iOS 16的错误也会修复iOS 17的错误。我的假设可能是错的。
//
// ContentView.swift
// RecordSpeechFix
//
// Created by Dennis Sargent on 6/16/23.
//
import AVFoundation
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text("Record Speech")
}
.padding()
.onTapGesture {
saveSpeechUtteranceToFile(phrase: "This produces warnings.") {
print("In iOS 16, this will print. In iOS17, this will not.")
}
}
}
func documentsDirectory(fileName: String, ext: String) -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let documentsDirectoryURL = paths[0]
return documentsDirectoryURL.appendingPathComponent("\(fileName).\(ext)")
}
let synthesizer = AVSpeechSynthesizer()
func saveSpeechUtteranceToFile(phrase: String, completionHandler: @escaping () -> ()) {
let fileURL = documentsDirectory(fileName: "Test", ext: ".caf")
let utterance = AVSpeechUtterance(string: phrase)
utterance.voice = AVSpeechSynthesisVoice(language: "en-US")
utterance.rate = 0.50
utterance.volume = 1.0
var output: AVAudioFile?
synthesizer.write(utterance) {(buffer: AVAudioBuffer) in
guard let pcmBuffer = buffer as? AVAudioPCMBuffer else {
fatalError("unknown buffer type: \(buffer)")
}
if pcmBuffer.frameLength == 0 {
// Done
completionHandler()
} else {
do{
if output == nil {
try output = AVAudioFile(
forWriting: fileURL,
settings: pcmBuffer.format.settings,
commonFormat: .pcmFormatInt16,
interleaved: false)
}
try output?.write(from: pcmBuffer)
}catch {
print("Buffer has an error")
}
}
}
}
}
字符串
我对一般的录音不太熟悉。似乎存在某种缓冲问题。你知道需要什么设置来清除这些错误吗?
1条答案
按热度按时间eivnm1vs1#
iOS 17将AVAudioPCMBuffer格式从Int16更改为Float32。只有苹果知道这是否是故意的。这破坏了所有使用https://stackoverflow.com/a/58118583/5280117代码片段的应用程序
解决方法有两种:
1.将AVAudioFile创建从固定的.pcmFormatInt16更改为与AVAudioPCMBuffer格式匹配的格式。
1.对于Float32格式的缓冲区,将done test从bufferLength 0更改为<= 1。它们显然吐出了长度为1的最终缓冲区(内容为00)。
以下是我在iOS 17 beta 4和iOS 16.6上运行的代码:
字符串