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