我正在使用声学模拟器,它为我输入的任何(正实际)频率提供(复杂的)频率响应。
我想生成一个1024点的脉冲响应。
我相信我有基本的技巧:https://dsp.stackexchange.com/questions/13883/convert-frequency-response-to-impulse-response
但是,我想从命令行实现它。
模拟器生成一个看起来像这样的文件(注意我缩短了数字以使其更具可读性):
# Run name = pro-ch0-pc1-gmr
# Run owner = umby
# Cfg file = sphere_source.cfg
# Frequency = 0.000000 + i*1077.566280 (171.5000 Hz)
#
# 1 2 3 4 5 6 7 8 9 10 11 12 13
# imic xm ym zm re(inc) im(inc) abs(inc) re(scat) im(scat) abs(scat) re(tot) im(tot) abs(tot)
0 +1.4E+00 +0.0E+00 +9.4E-02 -9.8E-04 -5.2E-02 +5.2E-02 -5.4E-03 +1.2E-02 +1.3E-02 -6.4E-03 -4.0E-02 +4.0E-02
1 +1.4E+00 +0.0E+00 +1.8E-01 -3.8E-03 -5.2E-02 +5.2E-02 -5.1E-03 +1.3E-02 +1.3E-02 -9.0E-03 -3.9E-02 +4.0E-02
:
:
etc
第二列是以弧度/秒为单位的角频率
第三列是以Hz为单位的频率
第11列和第12列是Re(z)和Im(z),即此频率的频率响应的实部和虚部
第13列是频率响应的幅度,我猜这可以与前两列之一一起丢弃
所以我的问题是:如何处理这个文件并获得一个脉冲响应?
答案 0 :(得分:3)
这是将频率响应转换为脉冲响应的必要代码(它包含一个测试信号;信号被转换到频域然后恢复,证明算法确实有效):
import numpy
#http://stackoverflow.com/questions/9062387/ifft-of-symmetric-spectrum/9062837#9062837
# test
waveform = [1,2,3,4,5,6]
print( waveform )
fullSpectrum = list( numpy.fft.fft( foo ) )
for w in fullSpectrum:
print w
# In my practical application, I would be receiving frequencies DC through Nyquist,
# i.e. the half of the spectrum containing the positive frequencies, and I would
# need to reconstitute the negative frequencies using symmetry:
#
DC_to_Nyquist = list( numpy.fft.fft( foo ) )[0:4]
# RESTORE FULL SPECTRUM BY SYMMETRY
DC = DC_to_Nyquist[0].real + 0j
nyquist = DC_to_Nyquist[-1].real + 0j
# discard DC and Nyquist from list
Z = DC_to_Nyquist[1:-1]
Z_reverse = Z[::-1]
Z_conj_reverse = [ w.conjugate() for w in Z_reverse ]
spectrum = [DC] + Z + [nyquist] + Z_conj_reverse
print( "\nSpectrum" )
for w in spectrum:
print( w )
# INVERSE FFT
timedomain = list( numpy.fft.ifft( spectrum ) )
#ir = [s.real for s in timedomain]
print( "\nTimedomain" )
for w in timedomain:
print w
这是样板代码,用于从输入文件中提取复数:
#!/usr/bin/python
import sys
import csv
infile = sys.argv[1]
Z = [ ]
with open( infile ) as f_in:
lines = csv.reader( f_in, delimiter=' ', skipinitialspace=True )
for n, line in enumerate( lines ):
if n > 6:
re = float( line[11] )
im = float( line[12] )
Z.append( complex( re, im ) )
print( Z )
编辑:更好的是:
Z_conj_reverse = [ w.conjugate() for w in reversed( Z ) ]