comparison src/vamp-hostsdk/PluginInputDomainAdapter.cpp @ 337:d5c5a52e6c9f

Make the simple base-fft implementation accessible for use by plugins as well. Bump version to 2.4
author Chris Cannam
date Thu, 12 Jul 2012 11:37:31 +0100
parents 50df48a51c97
children 92b1fbb1cc87
comparison
equal deleted inserted replaced
336:50df48a51c97 337:d5c5a52e6c9f
67 * its first invocation unless the host has saved and restored FFTW 67 * its first invocation unless the host has saved and restored FFTW
68 * wisdom (see the FFTW documentation). 68 * wisdom (see the FFTW documentation).
69 */ 69 */
70 #ifdef HAVE_FFTW3 70 #ifdef HAVE_FFTW3
71 #include <fftw3.h> 71 #include <fftw3.h>
72 #else
73 #include "../vamp-sdk/FFTimpl.cpp"
72 #endif 74 #endif
73 75
74 76
75 _VAMP_SDK_HOSTSPACE_BEGIN(PluginInputDomainAdapter.cpp) 77 _VAMP_SDK_HOSTSPACE_BEGIN(PluginInputDomainAdapter.cpp)
76 78
121 fftw_plan m_plan; 123 fftw_plan m_plan;
122 fftw_complex *m_cbuf; 124 fftw_complex *m_cbuf;
123 #else 125 #else
124 double *m_ro; 126 double *m_ro;
125 double *m_io; 127 double *m_io;
126 void fft(unsigned int n, bool inverse,
127 double *ri, double *ii, double *ro, double *io);
128 #endif 128 #endif
129 129
130 FeatureSet processShiftingTimestamp(const float *const *inputBuffers, RealTime timestamp); 130 FeatureSet processShiftingTimestamp(const float *const *inputBuffers, RealTime timestamp);
131 FeatureSet processShiftingData(const float *const *inputBuffers, RealTime timestamp); 131 FeatureSet processShiftingData(const float *const *inputBuffers, RealTime timestamp);
132 132
599 return m_plugin->process(m_freqbuf, timestamp); 599 return m_plugin->process(m_freqbuf, timestamp);
600 } 600 }
601 601
602 #ifndef HAVE_FFTW3 602 #ifndef HAVE_FFTW3
603 603
604 void
605 PluginInputDomainAdapter::Impl::fft(unsigned int n, bool inverse,
606 double *ri, double *ii, double *ro, double *io)
607 {
608 if (!ri || !ro || !io) return;
609
610 unsigned int bits;
611 unsigned int i, j, k, m;
612 unsigned int blockSize, blockEnd;
613
614 double tr, ti;
615
616 if (n < 2) return;
617 if (n & (n-1)) return;
618
619 double angle = 2.0 * M_PI;
620 if (inverse) angle = -angle;
621
622 for (i = 0; ; ++i) {
623 if (n & (1 << i)) {
624 bits = i;
625 break;
626 }
627 }
628
629 int table[n];
630
631 for (i = 0; i < n; ++i) {
632 m = i;
633 for (j = k = 0; j < bits; ++j) {
634 k = (k << 1) | (m & 1);
635 m >>= 1;
636 }
637 table[i] = k;
638 }
639
640 if (ii) {
641 for (i = 0; i < n; ++i) {
642 ro[table[i]] = ri[i];
643 io[table[i]] = ii[i];
644 }
645 } else {
646 for (i = 0; i < n; ++i) {
647 ro[table[i]] = ri[i];
648 io[table[i]] = 0.0;
649 }
650 }
651
652 blockEnd = 1;
653
654 for (blockSize = 2; blockSize <= n; blockSize <<= 1) {
655
656 double delta = angle / (double)blockSize;
657 double sm2 = -sin(-2 * delta);
658 double sm1 = -sin(-delta);
659 double cm2 = cos(-2 * delta);
660 double cm1 = cos(-delta);
661 double w = 2 * cm1;
662 double ar[3], ai[3];
663
664 for (i = 0; i < n; i += blockSize) {
665
666 ar[2] = cm2;
667 ar[1] = cm1;
668
669 ai[2] = sm2;
670 ai[1] = sm1;
671
672 for (j = i, m = 0; m < blockEnd; j++, m++) {
673
674 ar[0] = w * ar[1] - ar[2];
675 ar[2] = ar[1];
676 ar[1] = ar[0];
677
678 ai[0] = w * ai[1] - ai[2];
679 ai[2] = ai[1];
680 ai[1] = ai[0];
681
682 k = j + blockEnd;
683 tr = ar[0] * ro[k] - ai[0] * io[k];
684 ti = ar[0] * io[k] + ai[0] * ro[k];
685
686 ro[k] = ro[j] - tr;
687 io[k] = io[j] - ti;
688
689 ro[j] += tr;
690 io[j] += ti;
691 }
692 }
693
694 blockEnd = blockSize;
695 }
696
697 if (inverse) {
698
699 double denom = (double)n;
700
701 for (i = 0; i < n; i++) {
702 ro[i] /= denom;
703 io[i] /= denom;
704 }
705 }
706 }
707
708 #endif 604 #endif
709 605
710 } 606 }
711 607
712 } 608 }