基于倒谱的音频重构异常排查:重构音频含大量白噪声
排查音频倒谱重构噪声的方向
缺失逆预加重处理
你对原信号做了pre-emphasis提升高频,但重构后没有执行逆操作,导致高频分量被过度放大,听起来类似白噪声。需要在重构后添加逆预加重:# 重构后添加逆预加重 x_reconstructed = lfilter([1], [1, -preemph], x_reconstructed)倒谱提升破坏实信号对称性
实信号的倒谱具有共轭对称性(c_real[n] = c_real[-n],c_imag[n] = -c_imag[-n]),但你当前的lifter生成逻辑是非对称的,破坏了这种对称性,导致逆FFT后引入数值噪声。修改lifter的生成代码,保证对称性:def lifter(c_real, c_imag, lifter_order=22): c = c_real + 1j * c_imag c[0] = 0 # 可选,视需求保留DC分量 n = np.arange(len(c)) # 生成对称的提升窗口 lifter_win = np.zeros_like(n) half_len = len(lifter_win) // 2 + 1 lifter_win[:half_len] = 1 + (lifter_order / 2) * np.sin(np.pi * n[:half_len] / lifter_order) if len(lifter_win) > half_len: lifter_win[half_len:] = lifter_win[:len(lifter_win)-half_len][::-1] c_liftered = lifter_win * c return c_liftered.real, c_liftered.imag数值稳定性问题(log计算的极小值)
当音频频谱的幅度极小时,np.log(np.abs(X))会产生数值不稳定的结果,后续exp操作会引入误差。给幅度添加极小的偏移量避免log(0):def complex_cepstrum(x, nfft=None): if nfft is None: nfft = len(x) X = np.fft.fft(x, n=nfft) # 添加epsilon避免log极小值 logX = np.log(np.abs(X) + 1e-12) c = np.fft.ifft(logX, n=nfft) return c.real, c.imag, np.angle(X)复杂倒谱的实现逻辑偏差
你当前的实现拆分了幅度谱对数和相位的处理,正确的复杂倒谱应该直接对复频谱取对数后做逆FFT,这样能完整保留频谱信息,减少相位拼接带来的误差。修改复杂倒谱和逆过程的实现:def complex_cepstrum(x, nfft=None): if nfft is None: nfft = len(x) X = np.fft.fft(x, n=nfft) # 处理极小值避免log报错 X[np.abs(X) < 1e-12] = 1e-12 logX = np.log(X) c = np.fft.ifft(logX, n=nfft) return c.real, c.imag def inverse_complex_cepstrum(c_real, c_imag, n=None): if n is None: n = len(c_real) c = c_real + 1j * c_imag logX = np.fft.fft(c, n=n) X = np.exp(logX) # 强制共轭对称,消除数值误差 X = (X + np.conj(np.flip(X))) / 2 x = np.fft.ifft(X, n=n).real return x注意使用这个实现时,不需要单独传递相位参数,调用时改为:
# 计算复杂倒谱 c_real, c_imag = complex_cepstrum(x) # 提升 c_liftered_real, c_liftered_imag = lifter(c_real, c_imag) # 重构 x_reconstructed = inverse_complex_cepstrum(c_liftered_real, c_liftered_imag)
内容的提问来源于stack exchange,提问作者pm200107
相关产品推荐
相关产品推荐

