如何用AVAudioBuffer将样本数组写入24位音频文件?
我在用AVAudioEngine快速写入24位wav文件时遇到了麻烦。 对于我的用法,我的输入是一个Float数组。 我有输入文件的音频格式(用AVAudioFile检索)。如何用AVAudioBuffer将样本数组写入24位音频文件?
所以,我需要将我的输入Float数组转换为可写入缓冲区的值。另外,我想找到正确的渠道来写我的数据。 我的代码正在与16位和32位的文件,但我不知道如何处理24页的文件... 这就是:
//Static func to write audiofile
fileprivate func writeAudioFile(to outputURL : URL,
withFormat format : AVAudioFormat,
fromSamples music : [Float])
{
var outputFormatSettings = format.settings
guard let bufferFormat = AVAudioFormat(settings: outputFormatSettings) else{
return
}
var audioFile : AVAudioFile?
do{
audioFile = try AVAudioFile(forWriting: outputURL,
settings: outputFormatSettings,
commonFormat: format.commonFormat,
interleaved: true)
} catch let error as NSError {
print("error:", error.localizedDescription)
}
let frameCount = music.count/Int(format.channelCount)
let outputBuffer = AVAudioPCMBuffer(pcmFormat: bufferFormat,
frameCapacity: AVAudioFrameCount(frameCount))
//We write the data in the right channel
guard let bitDepth = (outputFormatSettings["AVLinearPCMBitDepthKey"] as? Int) else {
return
}
switch bitDepth {
case 16:
for i in 0..<music.count {
var floatValue = music[i]
if(floatValue > 1){
floatValue = 1
}
if(floatValue < -1){
floatValue = -1
}
let value = floatValue * Float(Int16.max)
outputBuffer?.int16ChannelData!.pointee[i] = Int16(value)
}
case 24:
//Here I am not sure of what I do ... Could'nt find the right channel !
for i in 0..<music.count {
outputBuffer?.floatChannelData!.pointee[i] = music[i]
}
case 32:
for i in 0..<music.count {
outputBuffer?.floatChannelData!.pointee[i] = music[i]
}
default:
return
}
outputBuffer?.frameLength = AVAudioFrameCount(frameCount)
do{
try audioFile?.write(from: outputBuffer!)
} catch let error as NSError {
print("error:", error.localizedDescription)
return
}
}
由于通过提前如果有人有怎样的想法处理这个(事情 !
在C语言中表示一个24位的int不是很有趣,所以在Swift中我确信这是一件非常痛苦的事情,并且没有任何API支持它。你最好的选择是转换成更方便的格式进行处理。
AVAudioFile有两种格式和一个内部转换器之间进行转换。其fileFormat表示磁盘上文件的格式,而其processingformat表示读取lpcm数据时的格式,以及写入时将接受的lpcm数据的格式。
典型的工作流程是选择标准processingFormat,使用这种格式完成所有的处理,并让AVAudioFile转换和从文件格式读取和写入磁盘。所有的音频单元API都接受非交错格式,所以我倾向于对所有处理格式使用非交错格式。
下面是一个复制音频文件的前半部分的示例。它没有解决你现有的代码,但说明了一个更常见的方法:
func halfCopy(src: URL, dst: URL) throws {
let srcFile = try AVAudioFile(forReading: src) //This opens the file for reading using the standard format (deinterleaved floating point).
let dstFile = try AVAudioFile(forWriting: dst,
settings: srcFile.fileFormat.settings,
commonFormat: srcFile.processingFormat.commonFormat,
interleaved: srcFile.processingFormat.isInterleaved) //AVAudioFile(forReading: src) always returns a non-interleaved processing format, this will be false
let frameCount = AVAudioFrameCount(srcFile.length)/2 // Copying first half of file
guard let buffer = AVAudioPCMBuffer(pcmFormat: srcFile.processingFormat,
frameCapacity: frameCount) else {
fatalError("Derp")
}
try srcFile.read(into: buffer, frameCount: frameCount)
try dstFile.write(from: buffer)
}
谢谢,我会接受你的回答,因为看起来对我来说没有简单的解决方案......我会尽力处理它! – NicoC
是音乐:[浮动]立体声/交错还是单声道? – dave234
它可以是立体声或单声道,当立体声被交错时。 – NicoC