python - FFT 快速卷积 : How To Apply Window to minimize crackling

标签 python audio signal-processing fft convolution

我正在尝试进行快速 fft 卷积(fft blocksize=1024 个样本) 带有正弦波的耳机相关脉冲响应(L=512 样本) 音频信号。在这里您可以看到脉冲响应图:

http://fs2.directupload.net/images/150617/fc9j6cs7.png

我将波形音频信号分成 block 大小 M=513 的 block 。然后我将每个波 block 和 hrtf zeroppaded 到 1024 个样本,应用 fft、乘法和 ifft。您可以在下图中看到一个 block 的结果:

http://fs1.directupload.net/images/150617/bxoe9fkm.png

在此之后,我在每个 block 上滑动了 513 个样本 时间尺度比最后一个 block (Hop Size = 0)更远,并将其添加到旧 block ,这给出了正确的卷积输出。

在这里您可以看到(简化版的)5 个添加的输出 block 的 python 代码:

# set iteration counter to 0
blocknumber = 0 
# read in audio file
_, audiodata = scipy.io.wavefile.read("filename_audio_wave")
_, hrtf_block =  scipy.io.wavefile.read("filename_hrtf_wave")
while blocknumber <5:

    # set blocksizes
    fft_blocksize = 1024
    audio_blocksize = 513
    hrtf_blocksize = 512
    binaural = np.zeros((fft_blocksize*5, ), dtype=np.int16)

    # Do zeropadding: zeropad hrtf and audio
    hrtf_block_zeropadded = np.zeros((fft_blocksize, ), dtype = 'int16')
    hrtf_block_zeropadded[0:hrtf_blocksize, ] = hrtf_block
    sp_block_sp_zeropadded = np.zeros((fft_blocksize, ), dtype = 'int16')
    sp_block_sp_zeropadded[0:sp_blocksize, ] = audiodata[blocknumber*audio_blocksize : (blocknumber+1)*audio_blocksize, ]

    # bring time domain input to to frequency domain
    hrtf_block_fft = fft(hrtf_block_zeropadded, fft_blocksize)
    audio_block_fft = fft(audio_block_zeropadded, fft_blocksize)

    binaural_block_frequency = hrtf_block_fft * audio_block_fft
    binaural_block = ifft(binaural_block_frequency, fft_blocksize).real

    # add the block to the other blocks
    slide_forward_samples = 513
    binaural[blocknumber*slide_forward_samples : blocknumber*slide_forward_samples+fft_blocksize, ] += binaural_block
    blocknumber+=1

在下一步中,我想用稍微不同的方式对每个 block 进行卷积 脉冲响应是什么导致了 block 之间的噼啪声。我发现我必须应用一个窗口并让卷积 block 重叠。我不知道该怎么做。你能给我一些建议吗?

假设我们想要达到 50% 的重叠并使用汉明窗口。

  • 每个 block 现在需要包含前一个 block 的样本的 50% 是否正确?
  • 我必须在哪里应用窗口?我必须在 fft 之前应用它吗 对音频信号 block (窗口大小:513 个样本)或 ifft 输出(窗口大小 1024:样本)?
  • 我需要多少样本来滑动 fft 输出信号 有 50% 重叠的时间尺度?

非常感谢您的帮助

最佳答案

使用带有重叠-添加/保存快速卷积的窗口很少是正确的过滤方法。但是如果你想尝试:

请注意,一系列 Von Hann 窗口,偏移其长度的一半,总和为单位增益,除了最开始或结束的地方。

因此,将数据窗口长度从 513 更改为 512,使用 256 的偏移量(单位增益为 512 的一半),使用 Von Hann 窗口(汉明将改变增益),填充超过 512 窗口长度的任何值加上脉冲响应长度,并使用重叠添加/保存余数(可能在几个输入窗口段上携带尾部)。

513 不好,因为最接近半偏移量的整数会在所有重叠窗口的总增益中引起一些波动。

您还可以使用 1/4 窗口偏移,这将使增益加倍,并在后期处理中调整此 2X 增益。等等

关于python - FFT 快速卷积 : How To Apply Window to minimize crackling,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30887309/

相关文章:

python - 相当于 Python 中的 Matlab filter2(filter, image, 'valid')

actionscript-3 - AS3 Air — 检查 Zip 以获取音频文件

python - 如何生成嘈杂的模拟时间序列或信号(在 Python 中)

audio - 音频分析合成中的重叠添加

python - Django 包含标签语法错误

Python 列表内存错误

iphone - 使用MFMailComposeViewController发送.wav文件

iOS:Objective -C 如何在应用程序处于后台模式时更改推送通知声音有效负载?

python - 执行 FFT 和峰值检测后如何获取 BPM

python - 我正在使用 pandas 从数据框中提取两列,但一列成为索引,然后在尝试访问该列时出现关键错误