如何在C ++中正确读取wav文件采样率?

时间:2012-12-05 01:25:05

标签: c++ hex

出于好奇心,同时学习波形文件格式和C ++,我偶然发现了page详细说明波形格式的规范布局

现在,我尝试编写一个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”?

提前感谢一大堆!

2 个答案:

答案 0 :(得分:3)

最简单的方法如下:

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

正如您可能怀疑的那样,假设您的系统是小端的。要修复您的示例,您必须避免在转换为long时发生的符号扩展。声明buffer类型的unsigned char。请参阅以下内容。

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);

答案 1 :(得分:1)

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

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