annotate dsp/transforms/FFT.cpp @ 189:e4a57215ddee

Fix compiler warnings with -Wall -Wextra
author Chris Cannam
date Mon, 28 Sep 2015 12:33:17 +0100
parents 7ab3539e92e3
children 0307327a3869
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