Быстрая свертка FFT: как применить окно, чтобы минимизировать потрескивание
Я пытаюсь сделать быструю свертку fft (размер блока fft=1024 выборки) из импульсная характеристика, связанная с головкой (L=512 отсчетов) с синусоидальной волной аудиосигнал. Здесь вы можете увидеть график импульсной реакции:
Http://fs2.directupload.net/images/150617/fc9j6cs7.png
Я разбил звуковой сигнал волны на блоки с размером блока M=513. Затем я обнулил каждый волновой блок и hrtf до 1024 образцов, применил fft, умножение и ifft. Вы можете увидеть результат один блок на следующем рисунке:
Http://fs1.directupload.net/images/150617/bxoe9fkm.png
После этого я сдвинул каждый блок 513 образцов на масштаб времени дальше последнего блока (размер прыжка = 0) и добавил его к старому блоку, что дало правильный свернутый вывод.
Здесь вы можете увидеть (упрощенную версию) кода python для 5 добавленных выходных блоков:
# 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
На следующем шаге я хотел свернуть каждый блок с помощью slighty different импульс реакция, которая привела к треску шума между блоками. Я обнаружил, что мне нужно применить окно и позволить свернутым блокам перекрываться. Я не знал, как именно это сделать. Не могли бы вы дать мне несколько советов?
Будем считать, что мы хотим достичь перекрытия в 50% и использовать окно Хэмминга.
- Правильно ли, что каждый блок должен содержать теперь 50% образцов предыдущего блока?
- где я должен применить окно? Должен ли я применять его до того, как быстрое преобразование Фурье свертка на блоках звукового сигнала (размер окна: 513 сэмплов) или на вывод ifft (windowsize 1024: samples)?
- и сколько выборок мне нужно, чтобы сдвинуть выходной сигнал fft на шкала времени с 50% перекрытием?
Большое Спасибо за вашу помощь
2 ответа:
Использование окна с перекрытием-добавление / сохранение быстрой свертки редко является правильным способом фильтрации. Но если вы хотите попробовать:
Обратите внимание, что последовательность окон фон-Ханна, смещенная на половину их длины, суммирует выигрыш в единицу, за исключением самого начала или конца.Поэтому измените длину окна данных с 513 на 512, используйте смещение 256 (половина 512 для усиления unity), используйте окно фон Ханна (Хэмминг изменит усиление), накладку на что-либо по длине окна 512 плюс импульс длина ответа, и использовать перекрытие add / save с остатком (возможно, перенося хвост над несколькими сегментами окна ввода).
513 не годится, потому что ближайшее целое число к половинному смещению вызовет некоторую пульсацию в суммированном усилении всех перекрывающихся окон.Вы также можете использовать смещение 1/4 окна, которое удвоит коэффициент усиления и отрегулирует этот коэффициент усиления в 2 раза при постобработке. и т.д.