Mercurial > hg > qm-dsp
comparison ext/kissfft/tools/fftutil.c @ 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 /* | |
2 Copyright (c) 2003-2004, Mark Borgerding | |
3 | |
4 All rights reserved. | |
5 | |
6 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: | |
7 | |
8 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. | |
9 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. | |
10 * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. | |
11 | |
12 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
13 */ | |
14 | |
15 #include <stdlib.h> | |
16 #include <math.h> | |
17 #include <stdio.h> | |
18 #include <string.h> | |
19 #include <unistd.h> | |
20 | |
21 #include "kiss_fft.h" | |
22 #include "kiss_fftndr.h" | |
23 | |
24 static | |
25 void fft_file(FILE * fin,FILE * fout,int nfft,int isinverse) | |
26 { | |
27 kiss_fft_cfg st; | |
28 kiss_fft_cpx * buf; | |
29 kiss_fft_cpx * bufout; | |
30 | |
31 buf = (kiss_fft_cpx*)malloc(sizeof(kiss_fft_cpx) * nfft ); | |
32 bufout = (kiss_fft_cpx*)malloc(sizeof(kiss_fft_cpx) * nfft ); | |
33 st = kiss_fft_alloc( nfft ,isinverse ,0,0); | |
34 | |
35 while ( fread( buf , sizeof(kiss_fft_cpx) * nfft ,1, fin ) > 0 ) { | |
36 kiss_fft( st , buf ,bufout); | |
37 fwrite( bufout , sizeof(kiss_fft_cpx) , nfft , fout ); | |
38 } | |
39 free(st); | |
40 free(buf); | |
41 free(bufout); | |
42 } | |
43 | |
44 static | |
45 void fft_filend(FILE * fin,FILE * fout,int *dims,int ndims,int isinverse) | |
46 { | |
47 kiss_fftnd_cfg st; | |
48 kiss_fft_cpx *buf; | |
49 int dimprod=1,i; | |
50 for (i=0;i<ndims;++i) | |
51 dimprod *= dims[i]; | |
52 | |
53 buf = (kiss_fft_cpx *) malloc (sizeof (kiss_fft_cpx) * dimprod); | |
54 st = kiss_fftnd_alloc (dims, ndims, isinverse, 0, 0); | |
55 | |
56 while (fread (buf, sizeof (kiss_fft_cpx) * dimprod, 1, fin) > 0) { | |
57 kiss_fftnd (st, buf, buf); | |
58 fwrite (buf, sizeof (kiss_fft_cpx), dimprod, fout); | |
59 } | |
60 free (st); | |
61 free (buf); | |
62 } | |
63 | |
64 | |
65 | |
66 static | |
67 void fft_filend_real(FILE * fin,FILE * fout,int *dims,int ndims,int isinverse) | |
68 { | |
69 int dimprod=1,i; | |
70 kiss_fftndr_cfg st; | |
71 void *ibuf; | |
72 void *obuf; | |
73 int insize,outsize; // size in bytes | |
74 | |
75 for (i=0;i<ndims;++i) | |
76 dimprod *= dims[i]; | |
77 insize = outsize = dimprod; | |
78 int rdim = dims[ndims-1]; | |
79 | |
80 if (isinverse) | |
81 insize = insize*2*(rdim/2+1)/rdim; | |
82 else | |
83 outsize = outsize*2*(rdim/2+1)/rdim; | |
84 | |
85 ibuf = malloc(insize*sizeof(kiss_fft_scalar)); | |
86 obuf = malloc(outsize*sizeof(kiss_fft_scalar)); | |
87 | |
88 st = kiss_fftndr_alloc(dims, ndims, isinverse, 0, 0); | |
89 | |
90 while ( fread (ibuf, sizeof(kiss_fft_scalar), insize, fin) > 0) { | |
91 if (isinverse) { | |
92 kiss_fftndri(st, | |
93 (kiss_fft_cpx*)ibuf, | |
94 (kiss_fft_scalar*)obuf); | |
95 }else{ | |
96 kiss_fftndr(st, | |
97 (kiss_fft_scalar*)ibuf, | |
98 (kiss_fft_cpx*)obuf); | |
99 } | |
100 fwrite (obuf, sizeof(kiss_fft_scalar), outsize,fout); | |
101 } | |
102 free(st); | |
103 free(ibuf); | |
104 free(obuf); | |
105 } | |
106 | |
107 static | |
108 void fft_file_real(FILE * fin,FILE * fout,int nfft,int isinverse) | |
109 { | |
110 kiss_fftr_cfg st; | |
111 kiss_fft_scalar * rbuf; | |
112 kiss_fft_cpx * cbuf; | |
113 | |
114 rbuf = (kiss_fft_scalar*)malloc(sizeof(kiss_fft_scalar) * nfft ); | |
115 cbuf = (kiss_fft_cpx*)malloc(sizeof(kiss_fft_cpx) * (nfft/2+1) ); | |
116 st = kiss_fftr_alloc( nfft ,isinverse ,0,0); | |
117 | |
118 if (isinverse==0) { | |
119 while ( fread( rbuf , sizeof(kiss_fft_scalar) * nfft ,1, fin ) > 0 ) { | |
120 kiss_fftr( st , rbuf ,cbuf); | |
121 fwrite( cbuf , sizeof(kiss_fft_cpx) , (nfft/2 + 1) , fout ); | |
122 } | |
123 }else{ | |
124 while ( fread( cbuf , sizeof(kiss_fft_cpx) * (nfft/2+1) ,1, fin ) > 0 ) { | |
125 kiss_fftri( st , cbuf ,rbuf); | |
126 fwrite( rbuf , sizeof(kiss_fft_scalar) , nfft , fout ); | |
127 } | |
128 } | |
129 free(st); | |
130 free(rbuf); | |
131 free(cbuf); | |
132 } | |
133 | |
134 static | |
135 int get_dims(char * arg,int * dims) | |
136 { | |
137 char *p0; | |
138 int ndims=0; | |
139 | |
140 do{ | |
141 p0 = strchr(arg,','); | |
142 if (p0) | |
143 *p0++ = '\0'; | |
144 dims[ndims++] = atoi(arg); | |
145 // fprintf(stderr,"dims[%d] = %d\n",ndims-1,dims[ndims-1]); | |
146 arg = p0; | |
147 }while (p0); | |
148 return ndims; | |
149 } | |
150 | |
151 int main(int argc,char ** argv) | |
152 { | |
153 int isinverse=0; | |
154 int isreal=0; | |
155 FILE *fin=stdin; | |
156 FILE *fout=stdout; | |
157 int ndims=1; | |
158 int dims[32]; | |
159 dims[0] = 1024; /*default fft size*/ | |
160 | |
161 while (1) { | |
162 int c=getopt(argc,argv,"n:iR"); | |
163 if (c==-1) break; | |
164 switch (c) { | |
165 case 'n': | |
166 ndims = get_dims(optarg,dims); | |
167 break; | |
168 case 'i':isinverse=1;break; | |
169 case 'R':isreal=1;break; | |
170 case '?': | |
171 fprintf(stderr,"usage options:\n" | |
172 "\t-n d1[,d2,d3...]: fft dimension(s)\n" | |
173 "\t-i : inverse\n" | |
174 "\t-R : real input samples, not complex\n"); | |
175 exit (1); | |
176 default:fprintf(stderr,"bad %c\n",c);break; | |
177 } | |
178 } | |
179 | |
180 if ( optind < argc ) { | |
181 if (strcmp("-",argv[optind]) !=0) | |
182 fin = fopen(argv[optind],"rb"); | |
183 ++optind; | |
184 } | |
185 | |
186 if ( optind < argc ) { | |
187 if ( strcmp("-",argv[optind]) !=0 ) | |
188 fout = fopen(argv[optind],"wb"); | |
189 ++optind; | |
190 } | |
191 | |
192 if (ndims==1) { | |
193 if (isreal) | |
194 fft_file_real(fin,fout,dims[0],isinverse); | |
195 else | |
196 fft_file(fin,fout,dims[0],isinverse); | |
197 }else{ | |
198 if (isreal) | |
199 fft_filend_real(fin,fout,dims,ndims,isinverse); | |
200 else | |
201 fft_filend(fin,fout,dims,ndims,isinverse); | |
202 } | |
203 | |
204 if (fout!=stdout) fclose(fout); | |
205 if (fin!=stdin) fclose(fin); | |
206 | |
207 return 0; | |
208 } |