annotate src/ext/kissfft/tools/kiss_fftndr.c @ 196:da283326bcd3 tip master

Update plugin versions in RDF
author Chris Cannam <cannam@all-day-breakfast.com>
date Fri, 28 Feb 2020 09:43:02 +0000
parents 5ed6e970541b
children
rev   line source
c@174 1 /*
c@174 2 Copyright (c) 2003-2004, Mark Borgerding
c@174 3
c@174 4 All rights reserved.
c@174 5
c@174 6 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
c@174 7
c@174 8 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
c@174 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@174 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@174 11
c@174 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@174 13 */
c@174 14
c@174 15 #include "kiss_fftndr.h"
c@174 16 #include "_kiss_fft_guts.h"
c@174 17 #define MAX(x,y) ( ( (x)<(y) )?(y):(x) )
c@174 18
c@174 19 struct kiss_fftndr_state
c@174 20 {
c@174 21 int dimReal;
c@174 22 int dimOther;
c@174 23 kiss_fftr_cfg cfg_r;
c@174 24 kiss_fftnd_cfg cfg_nd;
c@174 25 void * tmpbuf;
c@174 26 };
c@174 27
c@174 28 static int prod(const int *dims, int ndims)
c@174 29 {
c@174 30 int x=1;
c@174 31 while (ndims--)
c@174 32 x *= *dims++;
c@174 33 return x;
c@174 34 }
c@174 35
c@174 36 kiss_fftndr_cfg kiss_fftndr_alloc(const int *dims,int ndims,int inverse_fft,void*mem,size_t*lenmem)
c@174 37 {
c@174 38 kiss_fftndr_cfg st = NULL;
c@174 39 size_t nr=0 , nd=0,ntmp=0;
c@174 40 int dimReal = dims[ndims-1];
c@174 41 int dimOther = prod(dims,ndims-1);
c@174 42 size_t memneeded;
c@174 43
c@174 44 (void)kiss_fftr_alloc(dimReal,inverse_fft,NULL,&nr);
c@174 45 (void)kiss_fftnd_alloc(dims,ndims-1,inverse_fft,NULL,&nd);
c@174 46 ntmp =
c@174 47 MAX( 2*dimOther , dimReal+2) * sizeof(kiss_fft_scalar) // freq buffer for one pass
c@174 48 + dimOther*(dimReal+2) * sizeof(kiss_fft_scalar); // large enough to hold entire input in case of in-place
c@174 49
c@174 50 memneeded = sizeof( struct kiss_fftndr_state ) + nr + nd + ntmp;
c@174 51
c@174 52 if (lenmem==NULL) {
c@174 53 st = (kiss_fftndr_cfg) malloc(memneeded);
c@174 54 }else{
c@174 55 if (*lenmem >= memneeded)
c@174 56 st = (kiss_fftndr_cfg)mem;
c@174 57 *lenmem = memneeded;
c@174 58 }
c@174 59 if (st==NULL)
c@174 60 return NULL;
c@174 61 memset( st , 0 , memneeded);
c@174 62
c@174 63 st->dimReal = dimReal;
c@174 64 st->dimOther = dimOther;
c@174 65 st->cfg_r = kiss_fftr_alloc( dimReal,inverse_fft,st+1,&nr);
c@174 66 st->cfg_nd = kiss_fftnd_alloc(dims,ndims-1,inverse_fft, ((char*) st->cfg_r)+nr,&nd);
c@174 67 st->tmpbuf = (char*)st->cfg_nd + nd;
c@174 68
c@174 69 return st;
c@174 70 }
c@174 71
c@174 72 void kiss_fftndr(kiss_fftndr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata)
c@174 73 {
c@174 74 int k1,k2;
c@174 75 int dimReal = st->dimReal;
c@174 76 int dimOther = st->dimOther;
c@174 77 int nrbins = dimReal/2+1;
c@174 78
c@174 79 kiss_fft_cpx * tmp1 = (kiss_fft_cpx*)st->tmpbuf;
c@174 80 kiss_fft_cpx * tmp2 = tmp1 + MAX(nrbins,dimOther);
c@174 81
c@174 82 // timedata is N0 x N1 x ... x Nk real
c@174 83
c@174 84 // take a real chunk of data, fft it and place the output at correct intervals
c@174 85 for (k1=0;k1<dimOther;++k1) {
c@174 86 kiss_fftr( st->cfg_r, timedata + k1*dimReal , tmp1 ); // tmp1 now holds nrbins complex points
c@174 87 for (k2=0;k2<nrbins;++k2)
c@174 88 tmp2[ k2*dimOther+k1 ] = tmp1[k2];
c@174 89 }
c@174 90
c@174 91 for (k2=0;k2<nrbins;++k2) {
c@174 92 kiss_fftnd(st->cfg_nd, tmp2+k2*dimOther, tmp1); // tmp1 now holds dimOther complex points
c@174 93 for (k1=0;k1<dimOther;++k1)
c@174 94 freqdata[ k1*(nrbins) + k2] = tmp1[k1];
c@174 95 }
c@174 96 }
c@174 97
c@174 98 void kiss_fftndri(kiss_fftndr_cfg st,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata)
c@174 99 {
c@174 100 int k1,k2;
c@174 101 int dimReal = st->dimReal;
c@174 102 int dimOther = st->dimOther;
c@174 103 int nrbins = dimReal/2+1;
c@174 104 kiss_fft_cpx * tmp1 = (kiss_fft_cpx*)st->tmpbuf;
c@174 105 kiss_fft_cpx * tmp2 = tmp1 + MAX(nrbins,dimOther);
c@174 106
c@174 107 for (k2=0;k2<nrbins;++k2) {
c@174 108 for (k1=0;k1<dimOther;++k1)
c@174 109 tmp1[k1] = freqdata[ k1*(nrbins) + k2 ];
c@174 110 kiss_fftnd(st->cfg_nd, tmp1, tmp2+k2*dimOther);
c@174 111 }
c@174 112
c@174 113 for (k1=0;k1<dimOther;++k1) {
c@174 114 for (k2=0;k2<nrbins;++k2)
c@174 115 tmp1[k2] = tmp2[ k2*dimOther+k1 ];
c@174 116 kiss_fftri( st->cfg_r,tmp1,timedata + k1*dimReal);
c@174 117 }
c@174 118 }