c@409
|
1 #!/usr/bin/env python
|
c@409
|
2
|
c@409
|
3 from Numeric import *
|
c@409
|
4 from FFT import *
|
c@409
|
5
|
c@409
|
6 def make_random(len):
|
c@409
|
7 import random
|
c@409
|
8 res=[]
|
c@409
|
9 for i in range(int(len)):
|
c@409
|
10 r=random.uniform(-1,1)
|
c@409
|
11 i=random.uniform(-1,1)
|
c@409
|
12 res.append( complex(r,i) )
|
c@409
|
13 return res
|
c@409
|
14
|
c@409
|
15 def slowfilter(sig,h):
|
c@409
|
16 translen = len(h)-1
|
c@409
|
17 return convolve(sig,h)[translen:-translen]
|
c@409
|
18
|
c@409
|
19 def nextpow2(x):
|
c@409
|
20 return 2 ** math.ceil(math.log(x)/math.log(2))
|
c@409
|
21
|
c@409
|
22 def fastfilter(sig,h,nfft=None):
|
c@409
|
23 if nfft is None:
|
c@409
|
24 nfft = int( nextpow2( 2*len(h) ) )
|
c@409
|
25 H = fft( h , nfft )
|
c@409
|
26 scraplen = len(h)-1
|
c@409
|
27 keeplen = nfft-scraplen
|
c@409
|
28 res=[]
|
c@409
|
29 isdone = 0
|
c@409
|
30 lastidx = nfft
|
c@409
|
31 idx0 = 0
|
c@409
|
32 while not isdone:
|
c@409
|
33 idx1 = idx0 + nfft
|
c@409
|
34 if idx1 >= len(sig):
|
c@409
|
35 idx1 = len(sig)
|
c@409
|
36 lastidx = idx1-idx0
|
c@409
|
37 if lastidx <= scraplen:
|
c@409
|
38 break
|
c@409
|
39 isdone = 1
|
c@409
|
40 Fss = fft(sig[idx0:idx1],nfft)
|
c@409
|
41 fm = Fss * H
|
c@409
|
42 m = inverse_fft(fm)
|
c@409
|
43 res.append( m[scraplen:lastidx] )
|
c@409
|
44 idx0 += keeplen
|
c@409
|
45 return concatenate( res )
|
c@409
|
46
|
c@409
|
47 def main():
|
c@409
|
48 import sys
|
c@409
|
49 from getopt import getopt
|
c@409
|
50 opts,args = getopt(sys.argv[1:],'rn:l:')
|
c@409
|
51 opts=dict(opts)
|
c@409
|
52
|
c@409
|
53 siglen = int(opts.get('-l',1e4 ) )
|
c@409
|
54 hlen =50
|
c@409
|
55
|
c@409
|
56 nfft = int(opts.get('-n',128) )
|
c@409
|
57 usereal = opts.has_key('-r')
|
c@409
|
58
|
c@409
|
59 print 'nfft=%d'%nfft
|
c@409
|
60 # make a signal
|
c@409
|
61 sig = make_random( siglen )
|
c@409
|
62 # make an impulse response
|
c@409
|
63 h = make_random( hlen )
|
c@409
|
64 #h=[1]*2+[0]*3
|
c@409
|
65 if usereal:
|
c@409
|
66 sig=[c.real for c in sig]
|
c@409
|
67 h=[c.real for c in h]
|
c@409
|
68
|
c@409
|
69 # perform MAC filtering
|
c@409
|
70 yslow = slowfilter(sig,h)
|
c@409
|
71 #print '<YSLOW>',yslow,'</YSLOW>'
|
c@409
|
72 #yfast = fastfilter(sig,h,nfft)
|
c@409
|
73 yfast = utilfastfilter(sig,h,nfft,usereal)
|
c@409
|
74 #print yfast
|
c@409
|
75 print 'len(yslow)=%d'%len(yslow)
|
c@409
|
76 print 'len(yfast)=%d'%len(yfast)
|
c@409
|
77 diff = yslow-yfast
|
c@409
|
78 snr = 10*log10( abs( vdot(yslow,yslow) / vdot(diff,diff) ) )
|
c@409
|
79 print 'snr=%s' % snr
|
c@409
|
80 if snr < 10.0:
|
c@409
|
81 print 'h=',h
|
c@409
|
82 print 'sig=',sig[:5],'...'
|
c@409
|
83 print 'yslow=',yslow[:5],'...'
|
c@409
|
84 print 'yfast=',yfast[:5],'...'
|
c@409
|
85
|
c@409
|
86 def utilfastfilter(sig,h,nfft,usereal):
|
c@409
|
87 import compfft
|
c@409
|
88 import os
|
c@409
|
89 open( 'sig.dat','w').write( compfft.dopack(sig,'f',not usereal) )
|
c@409
|
90 open( 'h.dat','w').write( compfft.dopack(h,'f',not usereal) )
|
c@409
|
91 if usereal:
|
c@409
|
92 util = './fastconvr'
|
c@409
|
93 else:
|
c@409
|
94 util = './fastconv'
|
c@409
|
95 cmd = 'time %s -n %d -i sig.dat -h h.dat -o out.dat' % (util, nfft)
|
c@409
|
96 print cmd
|
c@409
|
97 ec = os.system(cmd)
|
c@409
|
98 print 'exited->',ec
|
c@409
|
99 return compfft.dounpack(open('out.dat').read(),'f',not usereal)
|
c@409
|
100
|
c@409
|
101 if __name__ == "__main__":
|
c@409
|
102 main()
|