aboutsummaryrefslogtreecommitdiffstats
path: root/kiss/kfc.c
diff options
context:
space:
mode:
Diffstat (limited to 'kiss/kfc.c')
-rw-r--r--kiss/kfc.c109
1 files changed, 109 insertions, 0 deletions
diff --git a/kiss/kfc.c b/kiss/kfc.c
new file mode 100644
index 0000000..a405d9b
--- /dev/null
+++ b/kiss/kfc.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2003-2004, Mark Borgerding. All rights reserved.
+ * This file is part of KISS FFT - https://github.com/mborgerding/kissfft
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * See COPYING file for more information.
+ */
+
+#include "kfc.h"
+
+typedef struct cached_fft *kfc_cfg;
+
+struct cached_fft
+{
+ int nfft;
+ int inverse;
+ kiss_fft_cfg cfg;
+ kfc_cfg next;
+};
+
+static kfc_cfg cache_root=NULL;
+static int ncached=0;
+
+static kiss_fft_cfg find_cached_fft(int nfft,int inverse)
+{
+ size_t len;
+ kfc_cfg cur=cache_root;
+ kfc_cfg prev=NULL;
+ while ( cur ) {
+ if ( cur->nfft == nfft && inverse == cur->inverse )
+ break;/*found the right node*/
+ prev = cur;
+ cur = prev->next;
+ }
+ if (cur== NULL) {
+ /* no cached node found, need to create a new one*/
+ kiss_fft_alloc(nfft,inverse,0,&len);
+#ifdef USE_SIMD
+ int padding = (16-sizeof(struct cached_fft)) & 15;
+ // make sure the cfg aligns on a 16 byte boundary
+ len += padding;
+#endif
+ cur = (kfc_cfg)KISS_FFT_MALLOC((sizeof(struct cached_fft) + len ));
+ if (cur == NULL)
+ return NULL;
+ cur->cfg = (kiss_fft_cfg)(cur+1);
+#ifdef USE_SIMD
+ cur->cfg = (kiss_fft_cfg) ((char*)(cur+1)+padding);
+#endif
+ kiss_fft_alloc(nfft,inverse,cur->cfg,&len);
+ cur->nfft=nfft;
+ cur->inverse=inverse;
+ cur->next = NULL;
+ if ( prev )
+ prev->next = cur;
+ else
+ cache_root = cur;
+ ++ncached;
+ }
+ return cur->cfg;
+}
+
+void kfc_cleanup(void)
+{
+ kfc_cfg cur=cache_root;
+ kfc_cfg next=NULL;
+ while (cur){
+ next = cur->next;
+ free(cur);
+ cur=next;
+ }
+ ncached=0;
+ cache_root = NULL;
+}
+void kfc_fft(int nfft, const kiss_fft_cpx * fin,kiss_fft_cpx * fout)
+{
+ kiss_fft( find_cached_fft(nfft,0),fin,fout );
+}
+
+void kfc_ifft(int nfft, const kiss_fft_cpx * fin,kiss_fft_cpx * fout)
+{
+ kiss_fft( find_cached_fft(nfft,1),fin,fout );
+}
+
+#ifdef KFC_TEST
+static void check(int nc)
+{
+ if (ncached != nc) {
+ fprintf(stderr,"ncached should be %d,but it is %d\n",nc,ncached);
+ exit(1);
+ }
+}
+
+int main(void)
+{
+ kiss_fft_cpx buf1[1024],buf2[1024];
+ memset(buf1,0,sizeof(buf1));
+ check(0);
+ kfc_fft(512,buf1,buf2);
+ check(1);
+ kfc_fft(512,buf1,buf2);
+ check(1);
+ kfc_ifft(512,buf1,buf2);
+ check(2);
+ kfc_cleanup();
+ check(0);
+ return 0;
+}
+#endif