【问题标题】:Head related impulse response for binaural audio双耳音频的头部相关脉冲响应
【发布时间】:2022-01-11 14:11:32
【问题描述】:

我正在处理音频数字信号处理和双耳音频处理。 我还在学习基础知识。 目前的想法是进行反卷积并获得脉冲响应。

请看附件截图

正在发生的事情的详细描述:

在这里,一个指数扫描信号被采集并通过扬声器回放。使用麦克风录制回放。使用零填充(可能是原始长度的两倍)扩展记录的信号,并且原始指数扫描信号也被扩展。两者都采用 FFT(扩展记录和扩展原始),它们的 FFT 被划分,我们得到房间传递函数。最后,采用逆FFT并进行一些加窗以获得脉冲响应。

我的问题:

我很难在 python 中实现这个图。你将如何划分两个 FFT?可能吗?我可能可以执行所有步骤,例如零填充和 fft,但我想我没有走正确的路。我不明白窗口和丢弃后半部分选项。

请任何有他/她知识的人告诉我如何用扫描信号在 python 中实现这个?只是一个小例子也有助于用很少的情节获得一个想法。请帮忙。

图片来源:http://www.four-audio.com/data/MF/aes-swp-english.pdf

提前致谢, 耆那教

【问题讨论】:

  • 一般来说,与编写软件一样,一种方法是先解决一个更简单的问题,然后再爬上复杂的山......将一个已知信号(例如正弦波)输入您的 FFT 代码以转换数据从时域到频域...绘制输入信号和输出,以确认您可以正确识别 FFT 调用输出中的相同频率作为源频率...然后使用此频域信号作为输入反向 FFT 调用应输出与原始源正弦波非常相似的时域......一旦工作开始增加复杂性
  • 在学习如何编写代码时,它不是为了获得解决方案,而是在学习如何解决问题和避免使用库或其他人的罐头解决方案对你没有帮助......而是编写代码自己算法(可能除了 FFT 调用)......事实上,我鼓励你自己从头开始编写自己的逆 FFT 代码,而不需要任何库......学习编码类似于学习数学,它都是关于知识层的,并且是跳跃超过一层会在您的知识上留下空白......目标是在从问题到解决方案的路径中没有这样的空白

标签: python audio signal-processing fft acoustics


【解决方案1】:

这有点超出我的想象,但也许以下建议会有所帮助。

首先,我在 Steve Smith 的书 The Scientist and Engineer's Guide to Digital Signal Processing 中看到了非常有用的示例代码。这包括范围操作,从卷积基础到 FFT 算法本身。示例代码是 BASIC,而不是 Python。但是 BASIC 是完全可读的,应该很容易翻译。

我不完全确定您描述的具体计算,但是这个领域的许多操作(在处理多个信号时)结果只是简单地使用了构成元素的加法或减法。要获得权威的答案,我认为您会在 Stack Overflow 的 Signal Processing 论坛或 DSP Related 的论坛之一上获得更好的运气。

如果您确实在其他地方得到了答案,最好在这里回顾一下或完全删除此问题以减少混乱。

【讨论】:

    【解决方案2】:

    是的,划分两个 FFT 谱是可能的,实际上在 python 中很容易实现(但有一些警告)。 简单地说:由于两个时间信号的卷积对应于将它们的光谱相乘,反之则可以通过光谱的分割来实现反卷积。

    这是一个使用 numpy 进行简单反卷积的示例:

    x是你的激励扫频信号,y是录制的扫频信号,你想从中得到脉冲响应。)

    import numpy as np
    from numpy.fft import rfft, irfft
    
    # define length of FFT (zero padding): at least double length of input
    input_length = np.size(x)
    n = np.ceil(np.log2(input_length)) + 1
    N_fft = int(pow(2, n))
    
    # transform 
    # real fft: N real input -> N/2+1 complex output (single sided spectrum)
    # real ifft: N/2+1 complex input -> N real output
    X_f = rfft(x, N_fft)
    Y_f = rfft(x, N_fft)
    
    # deconvolve
    H = Y_f / X_f
    
    # backward transform
    h = irfft(H, N_fft)
    
    # truncate to original length
    h = h[:input_length]
    

    这个简单的解决方案是一种实用的解决方案,但可以(并且应该)改进。一个问题是,在 X_f 具有低幅度的那些频率下,您将获得本底噪声的提升。例如,如果您的指数正弦扫描从 100Hz 开始,对于低于该频率的频率区间,您会得到(几乎)零的除法。一个简单的可能解决方案是首先反转 X_f,应用带限滤波器(高通+低通)来移除“增强区域”,然后将其与 Y_f 相乘:

    # deconvolve
    Xinv_f = 1 / X_f
    Xinv_f = Xinv_f * bandlimit_filter
    H = Y_f * Xinv_f
    

    关于失真: 指数正弦扫描的一个很好的特性是测量过程中产生的谐波失真(例如,由于扬声器中的非线性)将产生较小的“侧面”响应去卷积后的“主”响应之前(参见@987654321 @ 更多细节)。这些侧面响应是失真产物,可以通过时间窗口简单地去除。如果“主”响应没有延迟(从 t=0 开始),这些侧响应将出现在整个 iFFT 的末尾,因此您可以通过将后半部分窗口化来删除它们。

    从信号理论的角度来看,我不能保证这是 100% 正确的,但我认为它说明了这一点并且有效;)

    【讨论】:

      猜你喜欢
      • 2013-06-06
      • 2011-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-13
      • 2012-09-02
      相关资源
      最近更新 更多