【问题标题】:convert 24 bit binary char array to double (reading binary wave data)将 24 位二进制字符数组转换为双精度(读取二进制波数据)
【发布时间】:2021-04-02 11:43:41
【问题描述】:

我正在尝试读取 24 位二进制数据,该数据存储在 2 的补码中的波形文件中。它以小端方式存储。 我正在尝试将 3 个 char 数组重新解释为 int32_t,然后将其转换为 double。 我已经很接近了,但不知何故无法正常工作。

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 正弦音,但它没有居中并且看起来有点可疑: plot of the wave file

【问题讨论】:

    标签: bit-shift waveform 24-bit


    【解决方案1】:

    这是错误的:

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

    【讨论】:

    • 谢谢!这就是诀窍。我应该多看看 2 的补码。
    猜你喜欢
    • 2011-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-05
    • 1970-01-01
    • 2021-02-24
    相关资源
    最近更新 更多