Mercurial > hg > qm-dsp
comparison ext/kissfft/test/mk_test.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 import FFT | |
4 import sys | |
5 import random | |
6 import re | |
7 j=complex(0,1) | |
8 | |
9 def randvec(n,iscomplex): | |
10 if iscomplex: | |
11 return [ | |
12 int(random.uniform(-32768,32767) ) + j*int(random.uniform(-32768,32767) ) | |
13 for i in range(n) ] | |
14 else: | |
15 return [ int(random.uniform(-32768,32767) ) for i in range(n) ] | |
16 | |
17 def c_format(v,round=0): | |
18 if round: | |
19 return ','.join( [ '{%d,%d}' %(int(c.real),int(c.imag) ) for c in v ] ) | |
20 else: | |
21 s= ','.join( [ '{%.60f ,%.60f }' %(c.real,c.imag) for c in v ] ) | |
22 return re.sub(r'\.?0+ ',' ',s) | |
23 | |
24 def test_cpx( n,inverse ,short): | |
25 v = randvec(n,1) | |
26 scale = 1 | |
27 if short: | |
28 minsnr=30 | |
29 else: | |
30 minsnr=100 | |
31 | |
32 if inverse: | |
33 tvecout = FFT.inverse_fft(v) | |
34 if short: | |
35 scale = 1 | |
36 else: | |
37 scale = len(v) | |
38 else: | |
39 tvecout = FFT.fft(v) | |
40 if short: | |
41 scale = 1.0/len(v) | |
42 | |
43 tvecout = [ c * scale for c in tvecout ] | |
44 | |
45 | |
46 s="""#define NFFT %d""" % len(v) + """ | |
47 { | |
48 double snr; | |
49 kiss_fft_cpx test_vec_in[NFFT] = { """ + c_format(v) + """}; | |
50 kiss_fft_cpx test_vec_out[NFFT] = {""" + c_format( tvecout ) + """}; | |
51 kiss_fft_cpx testbuf[NFFT]; | |
52 void * cfg = kiss_fft_alloc(NFFT,%d,0,0);""" % inverse + """ | |
53 | |
54 kiss_fft(cfg,test_vec_in,testbuf); | |
55 snr = snr_compare(test_vec_out,testbuf,NFFT); | |
56 printf("DATATYPE=" xstr(kiss_fft_scalar) ", FFT n=%d, inverse=%d, snr = %g dB\\n",NFFT,""" + str(inverse) + """,snr); | |
57 if (snr<""" + str(minsnr) + """) | |
58 exit_code++; | |
59 free(cfg); | |
60 } | |
61 #undef NFFT | |
62 """ | |
63 return s | |
64 | |
65 def compare_func(): | |
66 s=""" | |
67 #define xstr(s) str(s) | |
68 #define str(s) #s | |
69 double snr_compare( kiss_fft_cpx * test_vec_out,kiss_fft_cpx * testbuf, int n) | |
70 { | |
71 int k; | |
72 double sigpow,noisepow,err,snr,scale=0; | |
73 kiss_fft_cpx err; | |
74 sigpow = noisepow = .000000000000000000000000000001; | |
75 | |
76 for (k=0;k<n;++k) { | |
77 sigpow += test_vec_out[k].r * test_vec_out[k].r + | |
78 test_vec_out[k].i * test_vec_out[k].i; | |
79 C_SUB(err,test_vec_out[k],testbuf[k].r); | |
80 noisepow += err.r * err.r + err.i + err.i; | |
81 | |
82 if (test_vec_out[k].r) | |
83 scale += testbuf[k].r / test_vec_out[k].r; | |
84 } | |
85 snr = 10*log10( sigpow / noisepow ); | |
86 scale /= n; | |
87 if (snr<10) | |
88 printf( "\\npoor snr, try a scaling factor %f\\n" , scale ); | |
89 return snr; | |
90 } | |
91 """ | |
92 return s | |
93 | |
94 def main(): | |
95 | |
96 from getopt import getopt | |
97 opts,args = getopt(sys.argv[1:],'s') | |
98 opts = dict(opts) | |
99 short = int( opts.has_key('-s') ) | |
100 | |
101 fftsizes = args | |
102 if not fftsizes: | |
103 fftsizes = [ 1800 ] | |
104 print '#include "kiss_fft.h"' | |
105 print compare_func() | |
106 print "int main() { int exit_code=0;\n" | |
107 for n in fftsizes: | |
108 n = int(n) | |
109 print test_cpx(n,0,short) | |
110 print test_cpx(n,1,short) | |
111 print """ | |
112 return exit_code; | |
113 } | |
114 """ | |
115 | |
116 if __name__ == "__main__": | |
117 main() |