AVAudioRecorder生成奇怪的Wav文件错误的标题

问题描述

如何从AVAudioRecorder文件中获取唯一的PCM数据? 这些是我用来记录文件的设置:

        let settings : [String : Any] = [
            AVFormatIDKey: Int(kAudioFormatLinearPCM),AVSampleRateKey: Int(stethoscopeSampleRateDefault),AVNumberOfChannelsKey: 1,AVEncoderAudioQualityKey: AVAudioQuality.medium.rawValue,]

此结果是带有奇怪头的奇怪wav文件。 如何仅从其中提取PCM数据?

解决方法

wav文件中的实际声音数据在该文件的“数据”子块中-this format description可以帮助您可视化要导航的结构。但也许令您感到困扰的是,Apple在声音数据之前还包含一个名为“ fllr”的额外子块,因此您也必须超越它。幸运的是,每个子块都有一个id和大小,因此查找数据子块仍然相对简单。

  1. 使用FileHandle
  2. 打开文件
  3. 搜索第12个字节,它使您越过标题并将您放在第一个子块的开头(应为fmt)。
  4. 读取4个字节并转换为字符串,然后再读取4个字节并转换为整数。字符串是子块名称,整数是该子块的大小。如果字符串不是“数据”,则向前搜索“大小”字节数,然后重复步骤3。
  5. 读取文件的其余部分-这是您的PCM数据。
,

在杰米的指导下,我设法解决了这个问题。这是我的代码:

    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
    }

这是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
}

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...