annotate ext/kissfft/tools/fftutil.c @ 184:76ec2365b250

Bring in kissfft into this repo (formerly a subrepo, but the remote is not responding)
author Chris Cannam
date Tue, 21 Jul 2015 07:34:15 +0100
parents
children
rev   line source
Chris@184 1 /*
Chris@184 2 Copyright (c) 2003-2004, Mark Borgerding
Chris@184 3
Chris@184 4 All rights reserved.
Chris@184 5
Chris@184 6 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Chris@184 7
Chris@184 8 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Chris@184 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.
Chris@184 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.
Chris@184 11
Chris@184 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.
Chris@184 13 */
Chris@184 14
Chris@184 15 #include <stdlib.h>
Chris@184 16 #include <math.h>
Chris@184 17 #include <stdio.h>
Chris@184 18 #include <string.h>
Chris@184 19 #include <unistd.h>
Chris@184 20
Chris@184 21 #include "kiss_fft.h"
Chris@184 22 #include "kiss_fftndr.h"
Chris@184 23
Chris@184 24 static
Chris@184 25 void fft_file(FILE * fin,FILE * fout,int nfft,int isinverse)
Chris@184 26 {
Chris@184 27 kiss_fft_cfg st;
Chris@184 28 kiss_fft_cpx * buf;
Chris@184 29 kiss_fft_cpx * bufout;
Chris@184 30
Chris@184 31 buf = (kiss_fft_cpx*)malloc(sizeof(kiss_fft_cpx) * nfft );
Chris@184 32 bufout = (kiss_fft_cpx*)malloc(sizeof(kiss_fft_cpx) * nfft );
Chris@184 33 st = kiss_fft_alloc( nfft ,isinverse ,0,0);
Chris@184 34
Chris@184 35 while ( fread( buf , sizeof(kiss_fft_cpx) * nfft ,1, fin ) > 0 ) {
Chris@184 36 kiss_fft( st , buf ,bufout);
Chris@184 37 fwrite( bufout , sizeof(kiss_fft_cpx) , nfft , fout );
Chris@184 38 }
Chris@184 39 free(st);
Chris@184 40 free(buf);
Chris@184 41 free(bufout);
Chris@184 42 }
Chris@184 43
Chris@184 44 static
Chris@184 45 void fft_filend(FILE * fin,FILE * fout,int *dims,int ndims,int isinverse)
Chris@184 46 {
Chris@184 47 kiss_fftnd_cfg st;
Chris@184 48 kiss_fft_cpx *buf;
Chris@184 49 int dimprod=1,i;
Chris@184 50 for (i=0;i<ndims;++i)
Chris@184 51 dimprod *= dims[i];
Chris@184 52
Chris@184 53 buf = (kiss_fft_cpx *) malloc (sizeof (kiss_fft_cpx) * dimprod);
Chris@184 54 st = kiss_fftnd_alloc (dims, ndims, isinverse, 0, 0);
Chris@184 55
Chris@184 56 while (fread (buf, sizeof (kiss_fft_cpx) * dimprod, 1, fin) > 0) {
Chris@184 57 kiss_fftnd (st, buf, buf);
Chris@184 58 fwrite (buf, sizeof (kiss_fft_cpx), dimprod, fout);
Chris@184 59 }
Chris@184 60 free (st);
Chris@184 61 free (buf);
Chris@184 62 }
Chris@184 63
Chris@184 64
Chris@184 65
Chris@184 66 static
Chris@184 67 void fft_filend_real(FILE * fin,FILE * fout,int *dims,int ndims,int isinverse)
Chris@184 68 {
Chris@184 69 int dimprod=1,i;
Chris@184 70 kiss_fftndr_cfg st;
Chris@184 71 void *ibuf;
Chris@184 72 void *obuf;
Chris@184 73 int insize,outsize; // size in bytes
Chris@184 74
Chris@184 75 for (i=0;i<ndims;++i)
Chris@184 76 dimprod *= dims[i];
Chris@184 77 insize = outsize = dimprod;
Chris@184 78 int rdim = dims[ndims-1];
Chris@184 79
Chris@184 80 if (isinverse)
Chris@184 81 insize = insize*2*(rdim/2+1)/rdim;
Chris@184 82 else
Chris@184 83 outsize = outsize*2*(rdim/2+1)/rdim;
Chris@184 84
Chris@184 85 ibuf = malloc(insize*sizeof(kiss_fft_scalar));
Chris@184 86 obuf = malloc(outsize*sizeof(kiss_fft_scalar));
Chris@184 87
Chris@184 88 st = kiss_fftndr_alloc(dims, ndims, isinverse, 0, 0);
Chris@184 89
Chris@184 90 while ( fread (ibuf, sizeof(kiss_fft_scalar), insize, fin) > 0) {
Chris@184 91 if (isinverse) {
Chris@184 92 kiss_fftndri(st,
Chris@184 93 (kiss_fft_cpx*)ibuf,
Chris@184 94 (kiss_fft_scalar*)obuf);
Chris@184 95 }else{
Chris@184 96 kiss_fftndr(st,
Chris@184 97 (kiss_fft_scalar*)ibuf,
Chris@184 98 (kiss_fft_cpx*)obuf);
Chris@184 99 }
Chris@184 100 fwrite (obuf, sizeof(kiss_fft_scalar), outsize,fout);
Chris@184 101 }
Chris@184 102 free(st);
Chris@184 103 free(ibuf);
Chris@184 104 free(obuf);
Chris@184 105 }
Chris@184 106
Chris@184 107 static
Chris@184 108 void fft_file_real(FILE * fin,FILE * fout,int nfft,int isinverse)
Chris@184 109 {
Chris@184 110 kiss_fftr_cfg st;
Chris@184 111 kiss_fft_scalar * rbuf;
Chris@184 112 kiss_fft_cpx * cbuf;
Chris@184 113
Chris@184 114 rbuf = (kiss_fft_scalar*)malloc(sizeof(kiss_fft_scalar) * nfft );
Chris@184 115 cbuf = (kiss_fft_cpx*)malloc(sizeof(kiss_fft_cpx) * (nfft/2+1) );
Chris@184 116 st = kiss_fftr_alloc( nfft ,isinverse ,0,0);
Chris@184 117
Chris@184 118 if (isinverse==0) {
Chris@184 119 while ( fread( rbuf , sizeof(kiss_fft_scalar) * nfft ,1, fin ) > 0 ) {
Chris@184 120 kiss_fftr( st , rbuf ,cbuf);
Chris@184 121 fwrite( cbuf , sizeof(kiss_fft_cpx) , (nfft/2 + 1) , fout );
Chris@184 122 }
Chris@184 123 }else{
Chris@184 124 while ( fread( cbuf , sizeof(kiss_fft_cpx) * (nfft/2+1) ,1, fin ) > 0 ) {
Chris@184 125 kiss_fftri( st , cbuf ,rbuf);
Chris@184 126 fwrite( rbuf , sizeof(kiss_fft_scalar) , nfft , fout );
Chris@184 127 }
Chris@184 128 }
Chris@184 129 free(st);
Chris@184 130 free(rbuf);
Chris@184 131 free(cbuf);
Chris@184 132 }
Chris@184 133
Chris@184 134 static
Chris@184 135 int get_dims(char * arg,int * dims)
Chris@184 136 {
Chris@184 137 char *p0;
Chris@184 138 int ndims=0;
Chris@184 139
Chris@184 140 do{
Chris@184 141 p0 = strchr(arg,',');
Chris@184 142 if (p0)
Chris@184 143 *p0++ = '\0';
Chris@184 144 dims[ndims++] = atoi(arg);
Chris@184 145 // fprintf(stderr,"dims[%d] = %d\n",ndims-1,dims[ndims-1]);
Chris@184 146 arg = p0;
Chris@184 147 }while (p0);
Chris@184 148 return ndims;
Chris@184 149 }
Chris@184 150
Chris@184 151 int main(int argc,char ** argv)
Chris@184 152 {
Chris@184 153 int isinverse=0;
Chris@184 154 int isreal=0;
Chris@184 155 FILE *fin=stdin;
Chris@184 156 FILE *fout=stdout;
Chris@184 157 int ndims=1;
Chris@184 158 int dims[32];
Chris@184 159 dims[0] = 1024; /*default fft size*/
Chris@184 160
Chris@184 161 while (1) {
Chris@184 162 int c=getopt(argc,argv,"n:iR");
Chris@184 163 if (c==-1) break;
Chris@184 164 switch (c) {
Chris@184 165 case 'n':
Chris@184 166 ndims = get_dims(optarg,dims);
Chris@184 167 break;
Chris@184 168 case 'i':isinverse=1;break;
Chris@184 169 case 'R':isreal=1;break;
Chris@184 170 case '?':
Chris@184 171 fprintf(stderr,"usage options:\n"
Chris@184 172 "\t-n d1[,d2,d3...]: fft dimension(s)\n"
Chris@184 173 "\t-i : inverse\n"
Chris@184 174 "\t-R : real input samples, not complex\n");
Chris@184 175 exit (1);
Chris@184 176 default:fprintf(stderr,"bad %c\n",c);break;
Chris@184 177 }
Chris@184 178 }
Chris@184 179
Chris@184 180 if ( optind < argc ) {
Chris@184 181 if (strcmp("-",argv[optind]) !=0)
Chris@184 182 fin = fopen(argv[optind],"rb");
Chris@184 183 ++optind;
Chris@184 184 }
Chris@184 185
Chris@184 186 if ( optind < argc ) {
Chris@184 187 if ( strcmp("-",argv[optind]) !=0 )
Chris@184 188 fout = fopen(argv[optind],"wb");
Chris@184 189 ++optind;
Chris@184 190 }
Chris@184 191
Chris@184 192 if (ndims==1) {
Chris@184 193 if (isreal)
Chris@184 194 fft_file_real(fin,fout,dims[0],isinverse);
Chris@184 195 else
Chris@184 196 fft_file(fin,fout,dims[0],isinverse);
Chris@184 197 }else{
Chris@184 198 if (isreal)
Chris@184 199 fft_filend_real(fin,fout,dims,ndims,isinverse);
Chris@184 200 else
Chris@184 201 fft_filend(fin,fout,dims,ndims,isinverse);
Chris@184 202 }
Chris@184 203
Chris@184 204 if (fout!=stdout) fclose(fout);
Chris@184 205 if (fin!=stdin) fclose(fin);
Chris@184 206
Chris@184 207 return 0;
Chris@184 208 }