annotate src/ext/kissfft/tools/kiss_fftr.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_fftr.h"
c@174 16 #include "_kiss_fft_guts.h"
c@174 17
c@174 18 struct kiss_fftr_state{
c@174 19 kiss_fft_cfg substate;
c@174 20 kiss_fft_cpx * tmpbuf;
c@174 21 kiss_fft_cpx * super_twiddles;
c@174 22 #ifdef USE_SIMD
c@174 23 void * pad;
c@174 24 #endif
c@174 25 };
c@174 26
c@174 27 kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem)
c@174 28 {
c@174 29 int i;
c@174 30 kiss_fftr_cfg st = NULL;
c@174 31 size_t subsize, memneeded;
c@174 32
c@174 33 if (nfft & 1) {
c@174 34 fprintf(stderr,"Real FFT optimization must be even.\n");
c@174 35 return NULL;
c@174 36 }
c@174 37 nfft >>= 1;
c@174 38
c@174 39 kiss_fft_alloc (nfft, inverse_fft, NULL, &subsize);
c@174 40 memneeded = sizeof(struct kiss_fftr_state) + subsize + sizeof(kiss_fft_cpx) * ( nfft * 3 / 2);
c@174 41
c@174 42 if (lenmem == NULL) {
c@174 43 st = (kiss_fftr_cfg) KISS_FFT_MALLOC (memneeded);
c@174 44 } else {
c@174 45 if (*lenmem >= memneeded)
c@174 46 st = (kiss_fftr_cfg) mem;
c@174 47 *lenmem = memneeded;
c@174 48 }
c@174 49 if (!st)
c@174 50 return NULL;
c@174 51
c@174 52 st->substate = (kiss_fft_cfg) (st + 1); /*just beyond kiss_fftr_state struct */
c@174 53 st->tmpbuf = (kiss_fft_cpx *) (((char *) st->substate) + subsize);
c@174 54 st->super_twiddles = st->tmpbuf + nfft;
c@174 55 kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize);
c@174 56
c@174 57 for (i = 0; i < nfft/2; ++i) {
c@174 58 double phase =
c@174 59 -3.14159265358979323846264338327 * ((double) (i+1) / nfft + .5);
c@174 60 if (inverse_fft)
c@174 61 phase *= -1;
c@174 62 kf_cexp (st->super_twiddles+i,phase);
c@174 63 }
c@174 64 return st;
c@174 65 }
c@174 66
c@174 67 void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata)
c@174 68 {
c@174 69 /* input buffer timedata is stored row-wise */
c@174 70 int k,ncfft;
c@174 71 kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc;
c@174 72
c@174 73 if ( st->substate->inverse) {
c@174 74 fprintf(stderr,"kiss fft usage error: improper alloc\n");
c@174 75 exit(1);
c@174 76 }
c@174 77
c@174 78 ncfft = st->substate->nfft;
c@174 79
c@174 80 /*perform the parallel fft of two real signals packed in real,imag*/
c@174 81 kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf );
c@174 82 /* The real part of the DC element of the frequency spectrum in st->tmpbuf
c@174 83 * contains the sum of the even-numbered elements of the input time sequence
c@174 84 * The imag part is the sum of the odd-numbered elements
c@174 85 *
c@174 86 * The sum of tdc.r and tdc.i is the sum of the input time sequence.
c@174 87 * yielding DC of input time sequence
c@174 88 * The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1...
c@174 89 * yielding Nyquist bin of input time sequence
c@174 90 */
c@174 91
c@174 92 tdc.r = st->tmpbuf[0].r;
c@174 93 tdc.i = st->tmpbuf[0].i;
c@174 94 C_FIXDIV(tdc,2);
c@174 95 CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i);
c@174 96 CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i);
c@174 97 freqdata[0].r = tdc.r + tdc.i;
c@174 98 freqdata[ncfft].r = tdc.r - tdc.i;
c@174 99 #ifdef USE_SIMD
c@174 100 freqdata[ncfft].i = freqdata[0].i = _mm_set1_ps(0);
c@174 101 #else
c@174 102 freqdata[ncfft].i = freqdata[0].i = 0;
c@174 103 #endif
c@174 104
c@174 105 for ( k=1;k <= ncfft/2 ; ++k ) {
c@174 106 fpk = st->tmpbuf[k];
c@174 107 fpnk.r = st->tmpbuf[ncfft-k].r;
c@174 108 fpnk.i = - st->tmpbuf[ncfft-k].i;
c@174 109 C_FIXDIV(fpk,2);
c@174 110 C_FIXDIV(fpnk,2);
c@174 111
c@174 112 C_ADD( f1k, fpk , fpnk );
c@174 113 C_SUB( f2k, fpk , fpnk );
c@174 114 C_MUL( tw , f2k , st->super_twiddles[k-1]);
c@174 115
c@174 116 freqdata[k].r = HALF_OF(f1k.r + tw.r);
c@174 117 freqdata[k].i = HALF_OF(f1k.i + tw.i);
c@174 118 freqdata[ncfft-k].r = HALF_OF(f1k.r - tw.r);
c@174 119 freqdata[ncfft-k].i = HALF_OF(tw.i - f1k.i);
c@174 120 }
c@174 121 }
c@174 122
c@174 123 void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata)
c@174 124 {
c@174 125 /* input buffer timedata is stored row-wise */
c@174 126 int k, ncfft;
c@174 127
c@174 128 if (st->substate->inverse == 0) {
c@174 129 fprintf (stderr, "kiss fft usage error: improper alloc\n");
c@174 130 exit (1);
c@174 131 }
c@174 132
c@174 133 ncfft = st->substate->nfft;
c@174 134
c@174 135 st->tmpbuf[0].r = freqdata[0].r + freqdata[ncfft].r;
c@174 136 st->tmpbuf[0].i = freqdata[0].r - freqdata[ncfft].r;
c@174 137 C_FIXDIV(st->tmpbuf[0],2);
c@174 138
c@174 139 for (k = 1; k <= ncfft / 2; ++k) {
c@174 140 kiss_fft_cpx fk, fnkc, fek, fok, tmp;
c@174 141 fk = freqdata[k];
c@174 142 fnkc.r = freqdata[ncfft - k].r;
c@174 143 fnkc.i = -freqdata[ncfft - k].i;
c@174 144 C_FIXDIV( fk , 2 );
c@174 145 C_FIXDIV( fnkc , 2 );
c@174 146
c@174 147 C_ADD (fek, fk, fnkc);
c@174 148 C_SUB (tmp, fk, fnkc);
c@174 149 C_MUL (fok, tmp, st->super_twiddles[k-1]);
c@174 150 C_ADD (st->tmpbuf[k], fek, fok);
c@174 151 C_SUB (st->tmpbuf[ncfft - k], fek, fok);
c@174 152 #ifdef USE_SIMD
c@174 153 st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0);
c@174 154 #else
c@174 155 st->tmpbuf[ncfft - k].i *= -1;
c@174 156 #endif
c@174 157 }
c@174 158 kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata);
c@174 159 }