Я пытаюсь записать аудиофайл после некоторой обработки, и получаю ошибку. Я сократил ошибку до этого простого автономного случая:
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 кГц AA C (из магазина iTunes), хотя сбой происходит и с другими стереофайлами в других форматах (AIFF и WAV).
Код не произойдет сбой и вместо этого правильно сохранит исходное аудио в новый файл, если я изменю параметр interleaved
на false
при создании исходного ввода AVAudioFile
(file
). Однако в этом случае на консоль записывается следующее сообщение:
Audio files cannot be non-interleaved. Ignoring setting AVLinearPCMIsNonInterleaved YES.
Кажется странным и сбивающим с толку, что запись в буфер без чередования работает нормально, несмотря на сообщение о том, что файлы должны чередоваться, а запись чередуемого буфера не удалась. Это противоположно тому, что я ожидал.
Мне известно, что при чтении файла с использованием обычного инициализатора AVAudioFile(forReading:)
без указания формата по умолчанию используется не чередующийся (ie. "Стандарт" AVAudioFormat
при фактической частоте дискретизации файла и количестве каналов). Означает ли это, что мне действительно нужно преобразовать чересстрочное аудио в не чередующееся, прежде чем пытаться записать его?
Примечательно, что в реальной программе, где возникла эта проблема, я делаю нечто гораздо более сложное, чем просто чтение файла и запись его снова, и мне нужно обрабатывать чередующийся звук. Однако я подтвердил, что этот оригинальный, более сложный код также не работает только для чересстрочного стереозвука.
Есть ли что-то хитрое, что мне нужно сделать, чтобы заставить AVAudioFile
написать из буфера, содержащего чересстрочный звук PCM?