C++读取16bit 48kHz单声道PCM文件偶现采样值错误如何解决?
问题根因
- short数组索引逻辑错误
你循环中使用的i是字节数组的下标,步长为2,对应第n个采样时,n = i / 2,但你直接将i作为shortValue的下标赋值,导致shortValue数组只有偶数下标位置存储了正确的采样值,所有奇数下标位置都是未初始化的垃圾值,这正好对应你遇到的「仅个别采样异常、异常采样后下一个采样恢复正常」的现象。你提到的错误采样编号276467为奇数,完全符合该错误的特征。 - 存在有符号char的符号扩展风险
绝大多数C++编译器默认char为有符号类型,当存储高8位的bytes[i+1]最高位为1时,执行位运算前会先做符号扩展为int类型,最终会导致拼接出来的采样值错误。
修复方案
1. 修正索引逻辑
将采样值存入shortValue数组时使用正确的下标,同时对字节做无符号转换避免符号扩展,修正后的转换代码如下:
// 注意shortValue数组的长度应为 bytesSize / 2 for(int i = 0; i < bytesSize - 1; i += 2) { int sampleIndex = i / 2; // 先转uint8_t避免符号扩展 uint8_t lowByte = static_cast<uint8_t>(bytes[i]); uint8_t highByte = static_cast<uint8_t>(bytes[i + 1]); shortValue[sampleIndex] = static_cast<short>(lowByte | (highByte << 8)); }
2. 可选优化:浮点数转换兼容最小值范围
16位有符号PCM的取值范围是-32768 ~ 32767,你当前除以32767的逻辑会导致-32768转换后超出[-1, 1]范围,可调整为:
amplitude[i] = static_cast<float>(shortValue[i]) / 32768.0f;
内容的提问来源于stack exchange,提问作者Saliom
相关产品推荐
相关产品推荐

