从 16 位 PCM 中去除 C++ 中的音频噪声(嘶嘶声)

Posted

技术标签:

【中文标题】从 16 位 PCM 中去除 C++ 中的音频噪声(嘶嘶声)【英文标题】:Removing audio noise (hissing) in C++ from 16bit PCM 【发布时间】:2016-07-04 01:16:28 【问题描述】:

我一直在查看堆栈溢出的帖子,但我不明白如何从麦克风抓取的音频中删除嘶嘶声。

我实现了一个简单的低通滤波器,但我一定是做错了什么。

unsigned short *buf = "audio data in PCM format";
double out_sample = 0;
int sample_size = "number of samples of audio";
for (int n = 0; n < sample_size/2; n++)

    out_sample = (out_sample * 90 + buf[n] * 10) / 100;
    buf[n] = (unsigned short) out_sample;

以上内容会产生真正损坏的音频。

我知道我需要对 PCM 数据进行低通滤波器。谁能阐明我做错了什么。

提前致谢。

【问题讨论】:

为什么是sample_size/2?我也不熟悉您以out_sample 提供的 LPF,这取决于您以前的所有示例。您还应该意识到您在时域而不是频域内“移动”。 您拥有的是一个具有缓慢指数衰减的 IIR(无限脉冲响应)滤波器。这是一个相当重的LPF。此外,数据的结构需要更清晰。 sample_size/2 建议您正在处理可能是交错的立体声数据,这是 PCM 的典型特征,但您的代码没有显示这一点。这会把事情搞得一团糟。 此外,还有一些免费的应用程序可以向您显示麦克风的噪音频谱。您应该基于此定制您的 LPF。此外,可以在相对安静的时期应用动态增益以最小化噪声。这些都不是很难,但您可能应该获得一些工具来生成所需的过滤器。 Octave 或 Matlab 擅长这一点。 【参考方案1】:

PCM 数据几乎总是签名数据。您可能会看到每个负值突然被视为巨大值 (>32768) 的影响。然后通过您的“低通滤波器”将其过滤为双值。假设您一开始的 DC 偏移量为零,您的滤波器将产生接近 32768 的 DC 平均值,但顶部有一个相当不可预测且在声学上不敏感的信号。

【讨论】:

以上是关于从 16 位 PCM 中去除 C++ 中的音频噪声(嘶嘶声)的主要内容,如果未能解决你的问题,请参考以下文章

从 MATLAB 中的波形音频文件中去除噪声

从线性 PCM 中提取音频通道

将 PCM 16 位音频转换为 PCM 8 位

PCM音频实时播放:音频字节数组(16/8位)转为PCM ArrayBuffer流

VLC如何在普通PC上播放24位PCM音频?

生成的正弦波 pcm 声音中的静态噪声