我正在尝试进行快速 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/