Istream:每个样本读取和wav格式位

istream::read and wav format bits per sample

本文关键字:wav 格式 读取 样本 Istream      更新时间:2023-10-16

下面是我用来读取16位和32位每个示例波的代码,工作得很好。

我的问题是,我如何读取剩余的8位无符号,24位有符号和32位float波?

读取一个16位有符号wav的样本:

short buffer;
file.read( ( char * ) &readbuffer, 2 );

读取一个32位带符号wav的示例:

int buffer;
file.read( ( char * ) &readbuffer, 4 );

您对目标机器做了一些假设。根据微软WAV格式,所有样本数据都是小端数据。您还希望各种数据类型的大小符合您的要求,但情况可能并非总是如此。

但是由于您当前的例程为您工作,我们暂时不会关注它(但您可能应该在某个时候修复这些东西)

32位float

如果我们忘记了可怕的尾字符和非标准类型大小,使用其他代码作为模板,32位浮点数情况变得相对简单:

float buffer;
file.read( ( char * ) &buffer, 4 );

这个问题更详细地讨论了从二进制源中读取浮点数。

x位unsigned

因为我们知道你的机器正确地解释了16位和32位的情况,我们可以假设它是小端序的。这意味着你可以把所有内容都读入一个unsigned int,它已经初始化为零,剩下的字节已经为你正确填充了:

unsigned int buffer = 0;
file.read( ( char * ) &buffer, 1 );   // 8bit unsigned integer
buffer = 0;
file.read( ( char * ) &buffer, 3 );   // 24bit unsigned integer

x位带符号

最后,如果读取的是有符号整数,则需要根据刚刚读取的数字的值填充缓冲区变量的剩余字节:

  • 如果数字是正数,可以直接输入0
  • 如果该数字为负(设置了最高有效字节的最高位),则使用xFF字节填充。

此代码适用于24位有符号整数:

long buffer;
int number_of_bytes = 3;             // 24 bit signed integer
file.read( (char *) &buffer, number_of_bytes);
// Determine the padding byte
unsigned char padding_byte = 0;
if ( ((char*) &buffer)[number_of_bytes - 1] & 128) {
    padding_byte = 255;
}
// Pad the data
for (int i = number_of_bytes; i < sizeof(buffer); i++) {
    ((char*) &buffer)[i] = padding_byte;
}

,我觉得我应该再次指出这段代码在某些机器上会失败,因为您没有检查端序。但是要解决这个问题,您需要做的就是检查运行代码的机器的端序,如果您在大端序的机器上,则颠倒字节的顺序。