0

我正在尝试读取 24 位二进制数据,该数据存储在 2's Complement 的波形文件中。它以小端方式存储。我正在尝试将 3 个字符数组重新解释为 int32_t,然后将其转换为双精度。我已经非常接近了,但它以某种方式无法正常工作。

if (wavHead.getBits_per_Sample() == 24) {
        unsigned char int24[3];
        while (!is.eof()) {
            int32_t val = 0;
            is.read((char *) &int24, sizeof(char) * 3); //ifstream
            if(int24[2] & 0x80) {
                val = 0xff;         //Checking for sign (MSB) and inverting it to bitshift to int32 MSB
                int24[2] &= ~(0x80);
            }
            val = (val << 8) | ((u_int32_t)int24[2]);
            val = (val << 8) | ((u_int32_t)int24[1]);
            val = (val << 8) | ((u_int32_t)int24[0]);

            cout << val / 8388608.0 << endl;
            data.push_back(val / 8388608.0);
        }
    }

这是信号图。它应该是一个简单的 440 Hz 正弦音,但它没有居中并且看起来有点可疑: 波形文件的图

4

1 回答 1

0

这是错误的:

int24[2] &= ~(0x80);

考虑数字 -1,编码为 3 个字节为 FF FF FF。我们想要的结果val是 0xFFFFFFFF,其中没有未设置的位,这通常适用:当符号扩展时,您要扩展的位本身不会改变。重置它会将 -8388608 的偏移量添加到负值,因此将 -1.0 的偏移量添加到负结果(与绘图匹配)。只需删除该行就可以了。这是另一种符号扩展的方法(还有其他方法):

// note: nothing before this, the sign extension is applied *after* rebuilding
val = (u_int32_t)int24[2];
val = (val << 8) | ((u_int32_t)int24[1]);
val = (val << 8) | ((u_int32_t)int24[0]);
val = (val ^ (1 << 23)) - (1 << 23);
于 2021-04-02T11:55:21.887 回答