每个样本的istream :: read和wav格式位

时间:2013-01-01 14:21:19

标签: c++ wav istream

下面是我用来读取16位和32位每个样本wavs的代码,它们工作正常。

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

阅读16位签名wav的一个示例:

short buffer;

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

读取32位签名wav的一个样本:

int buffer;

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

1 个答案:

答案 0 :(得分:1)

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

但是,由于您当前的惯例对您有用,我们暂时不会关注它(但您可能应该在某些时候解决这些问题)

32位浮点数

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

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

This question涵盖了从二进制源中读取浮点数的更多细节。

x位无符号

由于我们知道您的机器正确地解释了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;
}

同样,我觉得我应该指出,这些代码在某些机器上会失败,因为你没有检查endian-ness。但是你需要做的就是运行代码的机器的check the endian-ness,如果你在大端机器上,则反转字节的顺序。