annotate ext/kissfft/tools/kfc.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 #include "kfc.h"
c@409 2
c@409 3 /*
c@409 4 Copyright (c) 2003-2004, Mark Borgerding
c@409 5
c@409 6 All rights reserved.
c@409 7
c@409 8 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
c@409 9
c@409 10 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
c@409 11 * 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 12 * 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 13
c@409 14 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 15 */
c@409 16
c@409 17
c@409 18 typedef struct cached_fft *kfc_cfg;
c@409 19
c@409 20 struct cached_fft
c@409 21 {
c@409 22 int nfft;
c@409 23 int inverse;
c@409 24 kiss_fft_cfg cfg;
c@409 25 kfc_cfg next;
c@409 26 };
c@409 27
c@409 28 static kfc_cfg cache_root=NULL;
c@409 29 static int ncached=0;
c@409 30
c@409 31 static kiss_fft_cfg find_cached_fft(int nfft,int inverse)
c@409 32 {
c@409 33 size_t len;
c@409 34 kfc_cfg cur=cache_root;
c@409 35 kfc_cfg prev=NULL;
c@409 36 while ( cur ) {
c@409 37 if ( cur->nfft == nfft && inverse == cur->inverse )
c@409 38 break;/*found the right node*/
c@409 39 prev = cur;
c@409 40 cur = prev->next;
c@409 41 }
c@409 42 if (cur== NULL) {
c@409 43 /* no cached node found, need to create a new one*/
c@409 44 kiss_fft_alloc(nfft,inverse,0,&len);
c@409 45 #ifdef USE_SIMD
c@409 46 int padding = (16-sizeof(struct cached_fft)) & 15;
c@409 47 // make sure the cfg aligns on a 16 byte boundary
c@409 48 len += padding;
c@409 49 #endif
c@409 50 cur = (kfc_cfg)KISS_FFT_MALLOC((sizeof(struct cached_fft) + len ));
c@409 51 if (cur == NULL)
c@409 52 return NULL;
c@409 53 cur->cfg = (kiss_fft_cfg)(cur+1);
c@409 54 #ifdef USE_SIMD
c@409 55 cur->cfg = (kiss_fft_cfg) ((char*)(cur+1)+padding);
c@409 56 #endif
c@409 57 kiss_fft_alloc(nfft,inverse,cur->cfg,&len);
c@409 58 cur->nfft=nfft;
c@409 59 cur->inverse=inverse;
c@409 60 cur->next = NULL;
c@409 61 if ( prev )
c@409 62 prev->next = cur;
c@409 63 else
c@409 64 cache_root = cur;
c@409 65 ++ncached;
c@409 66 }
c@409 67 return cur->cfg;
c@409 68 }
c@409 69
c@409 70 void kfc_cleanup(void)
c@409 71 {
c@409 72 kfc_cfg cur=cache_root;
c@409 73 kfc_cfg next=NULL;
c@409 74 while (cur){
c@409 75 next = cur->next;
c@409 76 free(cur);
c@409 77 cur=next;
c@409 78 }
c@409 79 ncached=0;
c@409 80 cache_root = NULL;
c@409 81 }
c@409 82 void kfc_fft(int nfft, const kiss_fft_cpx * fin,kiss_fft_cpx * fout)
c@409 83 {
c@409 84 kiss_fft( find_cached_fft(nfft,0),fin,fout );
c@409 85 }
c@409 86
c@409 87 void kfc_ifft(int nfft, const kiss_fft_cpx * fin,kiss_fft_cpx * fout)
c@409 88 {
c@409 89 kiss_fft( find_cached_fft(nfft,1),fin,fout );
c@409 90 }
c@409 91
c@409 92 #ifdef KFC_TEST
c@409 93 static void check(int nc)
c@409 94 {
c@409 95 if (ncached != nc) {
c@409 96 fprintf(stderr,"ncached should be %d,but it is %d\n",nc,ncached);
c@409 97 exit(1);
c@409 98 }
c@409 99 }
c@409 100
c@409 101 int main(void)
c@409 102 {
c@409 103 kiss_fft_cpx buf1[1024],buf2[1024];
c@409 104 memset(buf1,0,sizeof(buf1));
c@409 105 check(0);
c@409 106 kfc_fft(512,buf1,buf2);
c@409 107 check(1);
c@409 108 kfc_fft(512,buf1,buf2);
c@409 109 check(1);
c@409 110 kfc_ifft(512,buf1,buf2);
c@409 111 check(2);
c@409 112 kfc_cleanup();
c@409 113 check(0);
c@409 114 return 0;
c@409 115 }
c@409 116 #endif