读取16位wav文件并将其标准化为Matlab

时间:2015-07-10 13:19:44

标签: c++ matlab audio

Matlab有一个名为audioread的函数,我试图在C ++中重现,但仅适用于wav文件。我可以读取一个wav文件并从中获取双精度值,但这些值似乎与Matlab函数返回的值不同。我的情况与this guy非常相似。我的阅读文件的代码:

    vector<double> rawAudioSignal;

    std::basic_ifstream<uint8_t> inputStream(path.c_str(), std::ifstream::binary);
    if (inputStream) {
        // get length of file:
        inputStream.seekg(0, inputStream.end);
        int fileLength = inputStream.tellg();
        // go back to start of stream
        inputStream.seekg(0, inputStream.beg);

        uint8_t *buffer = new uint8_t[fileLength];
        inputStream.read((uint8_t *)buffer, fileLength);
        inputStream.close();

        const int wavHeaderSize = 44;
        for (size_t i = wavHeaderSize; i < fileLength; i += 2)
        {
            // removes those huge 65000+ value spikes
            int c = ((char)buffer[i + 1]) << 8 | 
                ((unsigned char)buffer[i]);

            // failed attempts
            //int c = (buffer[i + 1] << 8 | buffer[i]); // little endian
            //int c = (buffer[i] << 8 | buffer[i + 1]); // big endian

            // failed normalizations
            //rawAudioSignal.push_back((c / 32768.0) - 1);
            //rawAudioSignal.push_back(((c - 32768.0) / 32768.0));
            rawAudioSignal.push_back(c);
        }
        delete[] buffer;
    }

rawAudioSignal中的所有值都是从-5到5的整数,但在Matlab中,数字从-1到1,其中此特定文件的最低Matlab值为-0.2511且最高是0.3846。我不知道Matlab功能正常化的数量或它的规范化程度。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:3)

样本是-32768到32767范围内的16位,您希望它们缩放到-1.0到1.0。这样做的方法是除以32768.0(-32768 / 32768.0 == -1,32767 / 32768.0略小于1)。

在从字节到int的转换中你有正确的基本想法所以我怀疑某些转换可能会解决你的问题。尝试在左移之前将单个字节转换为int,以防止可能的溢出。将其分成多个语句并在调试器中观察。

int c = ((int)buffer[i+1]) << 8 | buffer[i];