You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用Torchaudio或SciPy实现类Audacity的高通滤波器以消除鼓音频的直流偏移与结尾爆音

解决鼓音频分割后的直流偏移与爆音问题(匹配Audacity高通滤波效果)

首先咱们得揪出问题根源:你当前代码里用的滤波器参数和Audacity默认的高通滤波器完全不匹配!Audacity自带的高通滤波器默认是1阶(6dB/倍频程)巴特沃斯滤波器,截止频率15Hz,但你的SciPy代码用了5阶滤波器,Torchaudio的highpass_biquad是2阶双二阶滤波器,这就导致滤波效果和Audacity不一样,自然没法解决爆音问题。

下面给你两种解决方案,一种是最直接的直流偏移消除法,另一种是完全匹配Audacity效果的滤波实现:

方案1:直接消除直流偏移(简单高效,优先推荐)

直流偏移本质就是信号里的恒定直流分量,直接给每个通道减去自身的均值,就能快速解决问题,效果和极低频高通滤波近似,还不用折腾滤波器参数:

import librosa
import torch

# 加载24位44.1kHz的立体声音频
wav, sample_rate = librosa.load(path, sr=None, mono=False)
wav_tensor = torch.from_numpy(wav)

# 对每个通道单独减去均值,消除直流偏移
wav_filtered = wav_tensor - wav_tensor.mean(dim=1, keepdim=True)

这个方法能直接解决结尾爆音,因为爆音就是直流偏移导致的波形突变。

方案2:完全匹配Audacity的1阶巴特沃斯高通滤波器

如果你一定要和Audacity的滤波效果完全一致,就需要严格匹配它的参数:

SciPy实现(完美对齐Audacity)

from scipy import signal
import librosa

wav, sample_rate = librosa.load(path, sr=None, mono=False)
cutoff_freq = 15.0

# 构造1阶巴特沃斯高通滤波器,完全匹配Audacity默认设置
b, a = signal.butter(N=1, Wn=cutoff_freq, btype='high', fs=sample_rate)
# 使用filtfilt做零相位滤波(和Audacity的"线性相位"效果一致)
wav_filtered = signal.filtfilt(b, a, wav, axis=0)

这里用filtfilt是因为它会对信号正向、反向各滤波一次,消除相位偏移,和Audacity里选择“线性相位”的效果完全同步;如果不需要线性相位,直接用signal.lfilter即可。

Torchaudio实现

Torchaudio的highpass_biquad是2阶双二阶滤波器,要实现1阶巴特沃斯高通,我们可以手动计算系数用lfilter实现,或者用highpass_biquad近似:

方法A:手动构造1阶滤波器系数

import torch
import torchaudio.functional as F
import librosa

wav, sample_rate = librosa.load(path, sr=None, mono=False)
wav_tensor = torch.from_numpy(wav)
cutoff_freq = 15.0

# 计算1阶巴特沃斯高通滤波器的系数
omega = 2 * torch.pi * cutoff_freq / sample_rate
alpha = torch.tan(omega / 2)
b = torch.tensor([alpha, -alpha]) / (1 + alpha)
a = torch.tensor([1, (alpha - 1)/(alpha + 1)])

# 对每个通道应用滤波
wav_filtered = F.lfilter(wav_tensor, a, b, dim=0)

方法B:用highpass_biquad近似(2阶巴特沃斯)

如果不想手动算系数,也可以用highpass_biquad,设置Q值为0.7071(巴特沃斯滤波器的标准Q值),虽然是2阶,但也能有效消除直流偏移,效果和Audacity的1阶差异很小:

from torchaudio.functional import highpass_biquad
import librosa
import torch

wav, sample_rate = librosa.load(path, sr=None, mono=False)
wav_tensor = torch.from_numpy(wav)
cutoff_freq = 15.0
q = 0.7071  # 巴特沃斯滤波器的Q值

wav_filtered = highpass_biquad(wav_tensor, sample_rate, cutoff_freq, q)

验证小贴士

处理完之后,你可以检查波形是否以0为中心,播放时有没有结尾爆音。如果还有问题,注意:

  • 要对每个分割后的瞬态音频片段单独处理,而不是原文件整体
  • 加载24位音频时,librosa默认转成float32,精度足够,导出时记得保存回24位WAV格式
  • 立体声要确保左右通道分别处理,不要混为一谈

内容的提问来源于stack exchange,提问作者cbhower

火山引擎 最新活动