1

下面是我用来读取每个样本 wav 的 16 位和 32 位的代码,它们工作得很好。

我的问题是,如何读取剩余的 8 位无符号、24 位有符号和 32 位浮点wav?

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

short buffer;

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

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

int buffer;

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

1 回答 1

1

您正在对目标机器做出一些假设。根据 Microsoft WAV 格式,所有样本数据都是 little-endian。您还期望各种数据类型具有您想要的大小,但情况并非总是如此。

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

32 位浮点数

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

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

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

x 位无符号

由于我们知道您的机器正确地解释了 16 位和 32 位的情况,我们可以假设它是小端。这意味着您可以将所有内容读入一个已初始化为零的无符号整数,并且剩余的字节已经为您正确填充:

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

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

于 2013-01-01T15:32:27.717 回答