如何在C++中正确读取波形文件采样率

How to properly read in wave file sample rate in C++?

本文关键字:读取 波形 文件 采样率 C++      更新时间:2023-10-16

只是出于好奇,同时学习波形文件格式和C++,我偶然发现了这个页面,详细介绍了波形格式的规范布局

现在,我尝试编写一个C++程序来读取采样率

char buffer[4];
// already read other values before reading sample rate
inFile.read(buffer, 4);
// conversion using little endian
sampleRate = (long) buffer[0] + ((long) buffer[1] << 8) + ((long) buffer[2] << 16) + ((long) buffer[3] << 24);

在十六进制编辑器中,我可以看到我的样本波文件具有 44 ac 00 00 的采样率,转换为 44100 速率。但是,使用上面的代码,我总是以-21436结束

经过一些调试,事实证明原始十六进制值"ac"应该在 dec 中转换为 172,但C++假定十六进制值为 "ffffffac",在 dec 中转换为 -84。如果C++只是假设它是普通的"ac",我最终会得到正确的采样率值。

所以问题是,我如何从波形文件中读取数据并实际获得正确的采样率?我必须做一些魔法来去除前导的"f"吗?

提前感谢一堆!

最简单的方法如下:

// simply store bytes directly into sampleRate
long sampleRate = 0;
inFile.read(&sampleRate, 4);

正如您可能怀疑的那样,这假设您的系统是小字节序。若要修复示例,必须避免在投射为 long 时发生的符号扩展。声明类型 unsigned charbuffer。请参阅以下内容。

unsigned char buffer[4];
inFile.read(buffer, 4);
long sampleRate = (long)buffer[0] + ((long)buffer[1] << 8) + ((long)buffer[2] << 16) + ((long)buffer[3] << 24);

有两种方法可以修复代码。首先是通过使所有内容无符号来确保始终使用无符号算术。第二种是使用位掩码来删除符号扩展。

sampleRate = ((long) buffer[0] & 0xff) + (((long) buffer[1] << 8) & 0xff00) + (((long) buffer[2] << 16) & 0xff0000) + ((long) buffer[3] << 24);