annotate dsp/transforms/FFTqm.cpp @ 209:ccd2019190bf msvc

Some MSVC fixes, including (temporarily, probably) renaming the FFT source file to avoid getting it mixed up with the Vamp SDK one in our object dir
author Chris Cannam
date Thu, 01 Feb 2018 16:34:08 +0000
parents dsp/transforms/FFT.cpp@7ab3539e92e3
children
rev   line source
cannam@0 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
cannam@0 2
cannam@0 3 /*
cannam@0 4 QM DSP Library
cannam@0 5
cannam@0 6 Centre for Digital Music, Queen Mary, University of London.
cannam@0 7 */
cannam@0 8
cannam@0 9 #include "FFT.h"
cannam@55 10
cannam@55 11 #include "maths/MathUtilities.h"
cannam@55 12
Chris@129 13 #include "kiss_fft.h"
Chris@129 14 #include "kiss_fftr.h"
Chris@129 15
cannam@0 16 #include <cmath>
cannam@0 17
cannam@55 18 #include <iostream>
cannam@55 19
Chris@129 20 #include <stdexcept>
Chris@129 21
Chris@129 22 class FFT::D
Chris@129 23 {
Chris@129 24 public:
Chris@129 25 D(int n) : m_n(n) {
Chris@129 26 m_planf = kiss_fft_alloc(m_n, 0, NULL, NULL);
Chris@129 27 m_plani = kiss_fft_alloc(m_n, 1, NULL, NULL);
Chris@129 28 m_kin = new kiss_fft_cpx[m_n];
Chris@129 29 m_kout = new kiss_fft_cpx[m_n];
Chris@129 30 }
Chris@129 31
Chris@129 32 ~D() {
Chris@129 33 kiss_fft_free(m_planf);
Chris@129 34 kiss_fft_free(m_plani);
Chris@129 35 delete[] m_kin;
Chris@129 36 delete[] m_kout;
Chris@129 37 }
Chris@129 38
Chris@129 39 void process(bool inverse,
Chris@129 40 const double *ri,
Chris@129 41 const double *ii,
Chris@129 42 double *ro,
Chris@129 43 double *io) {
Chris@129 44
Chris@129 45 for (int i = 0; i < m_n; ++i) {
Chris@129 46 m_kin[i].r = ri[i];
Chris@129 47 m_kin[i].i = (ii ? ii[i] : 0.0);
Chris@129 48 }
Chris@129 49
Chris@129 50 if (!inverse) {
Chris@129 51
Chris@129 52 kiss_fft(m_planf, m_kin, m_kout);
Chris@129 53
Chris@129 54 for (int i = 0; i < m_n; ++i) {
Chris@129 55 ro[i] = m_kout[i].r;
Chris@129 56 io[i] = m_kout[i].i;
Chris@129 57 }
Chris@129 58
Chris@129 59 } else {
Chris@129 60
Chris@129 61 kiss_fft(m_plani, m_kin, m_kout);
Chris@129 62
Chris@129 63 double scale = 1.0 / m_n;
Chris@129 64
Chris@129 65 for (int i = 0; i < m_n; ++i) {
Chris@129 66 ro[i] = m_kout[i].r * scale;
Chris@129 67 io[i] = m_kout[i].i * scale;
Chris@129 68 }
Chris@129 69 }
Chris@129 70 }
Chris@129 71
Chris@129 72 private:
Chris@129 73 int m_n;
Chris@129 74 kiss_fft_cfg m_planf;
Chris@129 75 kiss_fft_cfg m_plani;
Chris@129 76 kiss_fft_cpx *m_kin;
Chris@129 77 kiss_fft_cpx *m_kout;
Chris@129 78 };
Chris@129 79
Chris@114 80 FFT::FFT(int n) :
Chris@129 81 m_d(new D(n))
cannam@0 82 {
cannam@0 83 }
cannam@0 84
cannam@0 85 FFT::~FFT()
cannam@0 86 {
Chris@129 87 delete m_d;
cannam@0 88 }
cannam@0 89
Chris@129 90 void
Chris@129 91 FFT::process(bool inverse,
Chris@129 92 const double *p_lpRealIn, const double *p_lpImagIn,
Chris@129 93 double *p_lpRealOut, double *p_lpImagOut)
Chris@129 94 {
Chris@129 95 m_d->process(inverse,
Chris@129 96 p_lpRealIn, p_lpImagIn,
Chris@129 97 p_lpRealOut, p_lpImagOut);
Chris@129 98 }
Chris@129 99
Chris@129 100 class FFTReal::D
Chris@129 101 {
Chris@129 102 public:
Chris@129 103 D(int n) : m_n(n) {
Chris@129 104 if (n % 2) {
Chris@129 105 throw std::invalid_argument
Chris@129 106 ("nsamples must be even in FFTReal constructor");
Chris@129 107 }
Chris@129 108 m_planf = kiss_fftr_alloc(m_n, 0, NULL, NULL);
Chris@129 109 m_plani = kiss_fftr_alloc(m_n, 1, NULL, NULL);
Chris@129 110 m_c = new kiss_fft_cpx[m_n];
Chris@129 111 }
Chris@129 112
Chris@129 113 ~D() {
Chris@129 114 kiss_fftr_free(m_planf);
Chris@129 115 kiss_fftr_free(m_plani);
Chris@129 116 delete[] m_c;
Chris@129 117 }
Chris@129 118
Chris@129 119 void forward(const double *ri, double *ro, double *io) {
Chris@129 120
Chris@129 121 kiss_fftr(m_planf, ri, m_c);
Chris@129 122
Chris@129 123 for (int i = 0; i <= m_n/2; ++i) {
Chris@129 124 ro[i] = m_c[i].r;
Chris@129 125 io[i] = m_c[i].i;
Chris@129 126 }
Chris@129 127
Chris@129 128 for (int i = 0; i + 1 < m_n/2; ++i) {
Chris@129 129 ro[m_n - i - 1] = ro[i + 1];
Chris@129 130 io[m_n - i - 1] = -io[i + 1];
Chris@129 131 }
Chris@129 132 }
Chris@129 133
Chris@131 134 void forwardMagnitude(const double *ri, double *mo) {
Chris@131 135
Chris@131 136 double *io = new double[m_n];
Chris@131 137
Chris@131 138 forward(ri, mo, io);
Chris@131 139
Chris@131 140 for (int i = 0; i < m_n; ++i) {
Chris@131 141 mo[i] = sqrt(mo[i] * mo[i] + io[i] * io[i]);
Chris@131 142 }
Chris@131 143
Chris@131 144 delete[] io;
Chris@131 145 }
Chris@131 146
Chris@129 147 void inverse(const double *ri, const double *ii, double *ro) {
Chris@129 148
Chris@170 149 // kiss_fftr.h says
Chris@170 150 // "input freqdata has nfft/2+1 complex points"
Chris@170 151
Chris@170 152 for (int i = 0; i < m_n/2 + 1; ++i) {
Chris@129 153 m_c[i].r = ri[i];
Chris@129 154 m_c[i].i = ii[i];
Chris@129 155 }
Chris@129 156
Chris@129 157 kiss_fftri(m_plani, m_c, ro);
Chris@129 158
Chris@129 159 double scale = 1.0 / m_n;
Chris@129 160
Chris@129 161 for (int i = 0; i < m_n; ++i) {
Chris@129 162 ro[i] *= scale;
Chris@129 163 }
Chris@129 164 }
Chris@129 165
Chris@129 166 private:
Chris@129 167 int m_n;
Chris@129 168 kiss_fftr_cfg m_planf;
Chris@129 169 kiss_fftr_cfg m_plani;
Chris@129 170 kiss_fft_cpx *m_c;
Chris@129 171 };
Chris@129 172
Chris@114 173 FFTReal::FFTReal(int n) :
Chris@129 174 m_d(new D(n))
cannam@0 175 {
cannam@64 176 }
cannam@0 177
cannam@64 178 FFTReal::~FFTReal()
cannam@64 179 {
Chris@129 180 delete m_d;
cannam@64 181 }
cannam@64 182
cannam@64 183 void
Chris@129 184 FFTReal::forward(const double *ri, double *ro, double *io)
cannam@64 185 {
Chris@129 186 m_d->forward(ri, ro, io);
cannam@64 187 }
cannam@64 188
Chris@114 189 void
Chris@131 190 FFTReal::forwardMagnitude(const double *ri, double *mo)
Chris@131 191 {
Chris@131 192 m_d->forwardMagnitude(ri, mo);
Chris@131 193 }
Chris@131 194
Chris@131 195 void
Chris@129 196 FFTReal::inverse(const double *ri, const double *ii, double *ro)
Chris@114 197 {
Chris@129 198 m_d->inverse(ri, ii, ro);
Chris@114 199 }
Chris@114 200
cannam@64 201
Chris@129 202