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