[英]AVAudioRecorder generates strange Wav file(wrong header)
How can I get the only the PCM data from AVAudioRecorder file?如何从 AVAudioRecorder 文件中获取唯一的 PCM 数据? these are the settings I use to record the file:
这些是我用来记录文件的设置:
let settings : [String : Any] = [
AVFormatIDKey: Int(kAudioFormatLinearPCM),
AVSampleRateKey: Int(stethoscopeSampleRateDefault),
AVNumberOfChannelsKey: 1,
AVEncoderAudioQualityKey: AVAudioQuality.medium.rawValue,
]
the outcome of this is strange wav file with strange header.这样做的结果是带有奇怪标题的奇怪 wav 文件。 How can I extract only the PCM data out of it?
如何仅从中提取 PCM 数据?
The actual sound data in a wav file is in the "data" subchunk of that file - this format description might help you visualize the structure you'll have to navigate. wav 文件中的实际声音数据位于该文件的“数据”子块中 -这种格式描述可能会帮助您可视化您必须导航的结构。 But maybe what's tripping you up is that Apple includes an extra subchunk called "fllr" which precedes the sound data, so you have to seek past that too.
但也许让您感到困惑的是,Apple 在声音数据之前包含了一个名为“fllr”的额外子块,因此您也必须寻找过去。 Fortunately every subchunk is given an id and size, so finding the data subchunk is still relatively straightforward.
幸运的是,每个子块都有一个 id 和大小,因此找到数据子块仍然相对简单。
FileHandle
FileHandle
打开文件With Jamie's guidance I managed to solve this.在杰米的指导下,我设法解决了这个问题。 Here is my code:
这是我的代码:
func extractSubchunks(data:Data) -> RiffFile?{
var data = data
var chunks = [SubChunk]()
let position = data.subdata(in: 8..<12)
let filelength = Int(data.subdata(in: 4..<8).uint32)
let wave = String(bytes: position, encoding: .utf8) ?? "NoName"
guard wave == "WAVE" else {
print("File is \(wave) not WAVE")
return nil
}
data.removeSubrange(0..<12)
print("Found chunks")
while data.count != 0{
let position = data.subdata(in: 0..<4)
let length = Int(data.subdata(in: 4..<8).uint32)
guard let current = String(bytes: position, encoding: .utf8) else{
return nil
}
data.removeSubrange(0..<8)
let chunkData = data.subdata(in: 0..<length)
data.removeSubrange(0..<length)
let subchunk = SubChunk(name: current, size: length, data: chunkData)
chunks.append(subchunk)
print(subchunk.debugDescription)
}
let riff = RiffFile(size: filelength, subChunks: chunks)
return riff
}
Here's the definition for RiffFile and SubChunk structs:这是 RiffFile 和 SubChunk 结构的定义:
struct RiffFile {
var size : Int
var subChunks : [SubChunk]
}
struct SubChunk {
var debugDescription: String {
return "name : \(name) size : \(size) dataAssignedsize : \(data.count)"
}
var name : String
var size : Int
var data : Data
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.