数字音频分辨率和下采样

时间:2018-04-03 03:09:55

标签: c++ audio byte wav truncate

我无法在c ++中找出这种行为。尝试通过执行以下操作来修改音频增益的内容:

  1. 加载到wav文件中 - 这有效,我可以正确播放音频。

  2. 遍历文件的数据块。对于每个样本,将每个值乘以一个数字,比如说0.2。足够改变样本,但不足以溢出原始位深度。如果四舍五入将大多数样本强制为0,那就没问题了。

  3. 将新值保存回数据块。

  4. 以下是相关代码:

    #include <iostream>
    
    
    
    int main(int argc, char** argv) {
        FILE* file = fopen(filename.c_str(), "rb+");
        if (file == NULL) return 1;
        fseek(file, 0, SEEK_END);
        _size = ftell(file);
        char* _data = new char[_size];
        fseek(file, 0, SEEK_SET);
        int bytes_read = fread(_data, sizeof(char), _size, file);
        fclose(file);
    
        _header = (WaveHeader*)_data;
        _bytesPerSample = _header->bitsPerSample / 8;   
    
        for (int i = 44; i < _size; i += _bytesPerSample) {
    
            int sampleValue = readSample(i, bytesPerSample);
            int newValue = sampleValue * 0.01; // Ignoring the glaring truncating and rounding problems here
            memset(&_data[i],0, bytesPerSample); // Trying everything, just in case
            writeSample(i, newValue, bytesPerSample);
            int check = readSample(i, bytesPerSample);
            if( check != newValue) {
                std::cout << "Mismatched value. Expected " << newValue << ", actual " << check << std::endl;
            }
         }
    }    
    

    以下是读/写示例方法。可以使用强制转换来编写值而不是使用这些读/写方法,但我不知道c ++中的任何3字节int类型。

    // Samples are in little-endian
    int readSample(const int position, const int sampleSize) {
    int result = 0;
    for (int n = sampleSize; n >= 0; n--)
      result = (result << 8) + _data[position + n];
    return result;
    
    void writeSample(const int position, const int value, const int sampleSize) {
    memcpy(&_data[position], &value, sampleSize);
    

    几乎有效。发生的情况是检查值具有较低的字节正确,但是高位字节与原始值相同 Original: -3813, Modified: -38, Checked: -294 使用bitset检查出来,我看到了

    Original: 10011100111101111001111  
    Checked:  10011011000000100111101  
    Modified: 11111111000000100111101
    

    我不知道为什么&#34;检查&#34;的底部2个字节是正确的,最重要的是不变的。

    编辑:错误在于:

    for (int n = sampleSize; n >= 0; n--)
      result = (result << 8) + _data[position + n];
    return result;
    

    这是读取太多字节,应该是

    for (int n = sampleSize-1; n >= 0; n--)
    

0 个答案:

没有答案