gpt4 book ai didi

ios - AVAudioFile.write(来自 :) fails when buffer contains interleaved audio

转载 作者:行者123 更新时间:2023-12-01 16:05:50 25 4
gpt4 key购买 nike

我尝试在进行一些处理后写出一个音频文件,但出现错误。我已将错误减少到这个简单的独立案例:

import Foundation
import AVFoundation

do {
let inputFileURL = URL(fileURLWithPath: "/Users/andrewmadsen/Desktop/test.m4a")
let file = try AVAudioFile(forReading: inputFileURL, commonFormat: .pcmFormatFloat32, interleaved: true)
guard let buffer = AVAudioPCMBuffer(pcmFormat: file.processingFormat, frameCapacity: AVAudioFrameCount(file.length)) else {
throw NSError()
}
buffer.frameLength = buffer.frameCapacity
try file.read(into: buffer)

let tempURL =
URL(fileURLWithPath: NSTemporaryDirectory())
.appendingPathComponent("com.openreelsoftware.AudioWriteTest")
.appendingPathComponent(UUID().uuidString)
.appendingPathExtension("caf")
let fm = FileManager.default
let dirURL = tempURL.deletingLastPathComponent()
if !fm.fileExists(atPath: dirURL.path, isDirectory: nil) {
try fm.createDirectory(at: dirURL, withIntermediateDirectories: true, attributes: nil)
}

var settings = buffer.format.settings
settings[AVAudioFileTypeKey] = kAudioFileCAFType
let tempFile = try AVAudioFile(forWriting: tempURL, settings: settings)
try tempFile.write(from: buffer)

} catch {
print(error)
}

当这段代码运行时,tempFile.write(from: buffer) 调用会抛出一个错误:

Error Domain=com.apple.coreaudio.avfaudio Code=-50 "(null)" UserInfo={failed call=ExtAudioFileWrite(_imp->_extAudioFile, buffer.frameLength, buffer.audioBufferList)}

test.m4a 是一个立体声 44.1 KHz AAC 文件(来自 iTunes 商店),但其他格式(AIFF 和 WAV)的其他立体声文件也会出现故障。

如果我将 interleaved 参数更改为 false,代码不会失败,而是正确地将原始音频保存到新文件中在创建原始输入 AVAudioFile(文件)时。但是,在这种情况下,控制台会记录以下消息:

Audio files cannot be non-interleaved. Ignoring setting AVLinearPCMIsNonInterleaved YES.

尽管有消息说文件必须交错,但写入非交错缓冲区却工作正常,而写入交错缓冲区失败,这似乎很奇怪且令人困惑。这与我的预期相反。

我知道使用普通 AVAudioFile(forReading:) 初始值设定项读取文件而不指定格式默认为使用非交错(即“标准” AVAudioFormat 在文件的实际采样率和 channel 数)。这是否意味着我真的必须在尝试写入之前将交错音频转换为非交错音频?

值得注意的是,在出现此问题的实际程序中,我正在做的事情比简单地读入文件并再次写回文件要复杂得多,而且我确实需要处理交错的音频。不过,我已经确认,对于交错的立体声音频,原始的、更复杂的代码也失败。

我需要做一些棘手的事情才能让 AVAudioFile 写出包含交错 PCM 音频的缓冲区吗?

最佳答案

这里的混淆是有两种格式在起作用:输出文件的格式,以及您将写入的缓冲区的格式(处理格式)。初始化器 AVAudioFile(forWriting: settings:) 不允许您选择处理格式并且默认为去交错,因此您的错误。

This opens the file for writing using the standard format (deinterleaved floating point).

您需要使用另一个初始化程序:AVAudioFile(forWriting:settings: commonFormat:interleaved:),其最后两个参数指定处理格式(参数名称可能更清楚)。

var settings: [String : Any] = [:]

settings[AVFormatIDKey] = kAudioFormatMPEG4AAC
settings[AVAudioFileTypeKey] = kAudioFileCAFType
settings[AVSampleRateKey] = buffer.format.sampleRate
settings[AVNumberOfChannelsKey] = 2
settings[AVLinearPCMIsFloatKey] = (buffer.format.commonFormat == .pcmFormatInt32)

let tempFile = try AVAudioFile(forWriting: tempURL, settings: settings, commonFormat: buffer.format.commonFormat, interleaved: buffer.format.isInterleaved)
try tempFile.write(from: buffer)

附言将缓冲区格式设置直接传递给 AVAudioFile 会得到一个 LPCM caf 文件,这可能是你不想要的,因此我重建了文件设置。

关于ios - AVAudioFile.write(来自 :) fails when buffer contains interleaved audio,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60801572/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com