使用 C 编写 wav 文件期间的量化噪声

Posted

技术标签:

【中文标题】使用 C 编写 wav 文件期间的量化噪声【英文标题】:Quantization noise during writing wav file using C 【发布时间】:2018-06-18 11:23:28 【问题描述】:

我只是想编写一个用于读写 Wav 文件的库(只需要它用于音频处理),​​就像测试一样,我从 Wave 文件中读取样本将它们转换为双精度(只需将它们标准化为 -1 ~ 1),除了将它们转换回整数,根据每个样本的位数(假设 Wav 文件每个样本有 N 位,我将它们除以 2^(N-1)-1 并在之后乘以相同的因子恢复它)

但问题是,我得到一个带有背景噪音的 wav 文件(id 说它看起来像量化噪音),我不知道为什么,你能帮我找出来吗?

图书馆在这里:https://pastebin.com/mz5TWMPN 头文件为:https://pastebin.com/Lr2tbmnv

一个演示主要功能是这样的:

#include <stdio.h>
#include <math.h>
#include "wavreader.h"

#define FRAMESIZE 512

int main()


    FILE *fh;
    FILE *fhWrite;
    struct WavHeader * header;
    struct WavHeader * newHeader;
    double frame[FRAMESIZE];
    int iBytesWritten;
    int i;
    char test;
    fh = fopen("D:/ArbeitsOrdner/advanced_pacev/Audiosample/spfg.wav", "rb+");
    if (fh == NULL)
    
        printf("Failed to open organ.wav\n");
        return 1;
    

    fhWrite = fopen("D:/ArbeitsOrdner/MyC/test_organ.wav", "wb+");
    if (fhWrite == NULL)
    
        printf("Failed to create test_organ.wav\n");
        return 1;
    

    header = readWaveHeader(fh);
    printWaveHeader(header);

    newHeader = createWaveHeader(header->iChannels, header->iSampleRate, header->iBitsPerSample);
    WaveWriteHeader(fhWrite, newHeader);

    while (WaveReadFrame(fh, header, FRAMESIZE, frame) != -1)
    
        iBytesWritten = WaveWriteFrame(fhWrite, newHeader, FRAMESIZE, frame);
        if (iBytesWritten < 0)
        
            printf("Error occured while writing to new file\n");
            return 1;
        
        

    WaveWriteHeader(fhWrite, newHeader);

    fclose(fhWrite);
    fclose(fh);

    return 0;

【问题讨论】:

i divided them through 2^(N-1)-1 除以二的幂(右移)对我来说似乎更自然。 好吧,由于c不直接支持^功能,左移是最快的方法。但他们都做你知道的事情 当您将样本相除然后相乘时,您不会丢失一些有用的信息吗?可以显示这些操作吗? 在理想情况下,因为我没有额外的操作,我不会丢失任何信息,因为样本是离散的,它们只有2^N级,所以标准化它们应该是可以的,因为你不会得到像 1.2/(2^(N-1)-1) 这样的东西,因为它们已经是离散的,因此将它们与基数相乘也应该可以这样。但实际上由于浮点的系统错误(不确定性),是的,有可能丢失信息。 【参考方案1】:

感谢您查看此帖子。我自己发现了问题,就是我使用 char 而不是 unsigned char 来处理原始数据(原始字节)。通过将它们转换为 int16 或 int32,我没有考虑符号位。这意味着它们在转换过程中的值并不完全相同。

解决方案是: 要么保留签名字符并使用:

buffer[i] & 0xff

获取正确的原始数据进行转换,或将 char 类型更改为 unsigned char:

unsgiend char * buffer;

【讨论】:

以上是关于使用 C 编写 wav 文件期间的量化噪声的主要内容,如果未能解决你的问题,请参考以下文章

不同量化电平数对信号有啥影响

是否可以在 Numpy 矢量化广播操作期间访问当前索引?

通过 C 中的 FFT 将 1000Hz 噪声添加到 wav 文件

实时音频编解码之十三 Opus编码-SILK编码-噪声整形分析

实时音频编解码之五 噪声整形

[概念]PCM文件&WAV文件头