AVAudioPCMBuffer读取WAV文件后音频数组出现异常值的原因排查
问题分析与修复方案
导致异常值的核心原因
你的代码存在两个关键错误,直接引发了0和-32768这类异常值:
- 格式不匹配:手动创建
AVAudioFormat时指定了interleaved: false,但原WAV文件的PCM数据存储格式与该设置不兼容,导致数据被错误解析。 - 样本计数错误:读取数据时的计数逻辑未匹配音频实际的帧长度与格式,导致读取了多余的无效数据,出现填充的0值;而-32768是Int16的最小值,通常是格式不匹配引发的符号位解析错误。
修正后的代码
guard let audioURL = Bundle.main.url(forResource: "00001", withExtension: "wav") else { print("音频文件不存在") return } do { let audioFile = try AVAudioFile(forReading: audioURL) // 直接使用文件原生处理格式,避免手动指定格式出错 guard let format = audioFile.processingFormat else { print("无法获取音频格式信息") return } // 根据文件总帧数创建缓冲区 let buffer = AVAudioPCMBuffer(pcmFormat: format, frameCapacity: AVAudioFrameCount(audioFile.length)) try audioFile.read(into: buffer!) // 安全读取Int16格式的通道数据 guard let channelDataPtr = buffer?.int16ChannelData else { print("无法读取音频通道数据") return } let sampleCount = Int(buffer!.frameLength) let sampleArray = Array(UnsafeBufferPointer(start: channelDataPtr[0], count: sampleCount)) print(sampleArray) } catch { print("读取音频失败:\(error.localizedDescription)") }
关键修复说明
- 复用原生格式:放弃手动构造
AVAudioFormat,直接使用audioFile.processingFormat,确保与文件实际的交错/非交错、位深度、采样率完全匹配。 - 准确计算样本数:单声道音频的样本数等于总帧数,无需额外乘以通道数,避免读取无效数据。
- 增加安全校验:用
guard替代强制解包,添加错误捕获逻辑,避免崩溃同时排查问题。
额外排查步骤
- 用音频工具(如Audacity)打开WAV文件,确认波形是否正常,排除文件损坏的可能。
- 打印
audioFile.fileFormat查看文件详细格式,验证与代码中使用的格式是否一致。
内容的提问来源于stack exchange,提问作者newbie
相关产品推荐
相关产品推荐

