annotate dsp/transforms/DCT.cpp @ 191:857ca50ca25f

Add DCT
author Chris Cannam
date Wed, 07 Oct 2015 09:55:35 +0100
parents
children fdaa63607c15
rev   line source
Chris@191 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@191 2
Chris@191 3 /*
Chris@191 4 QM DSP Library
Chris@191 5
Chris@191 6 Centre for Digital Music, Queen Mary, University of London.
Chris@191 7 This file by Chris Cannam.
Chris@191 8
Chris@191 9 This program is free software; you can redistribute it and/or
Chris@191 10 modify it under the terms of the GNU General Public License as
Chris@191 11 published by the Free Software Foundation; either version 2 of the
Chris@191 12 License, or (at your option) any later version. See the file
Chris@191 13 COPYING included with this distribution for more information.
Chris@191 14 */
Chris@191 15
Chris@191 16 #include "DCT.h"
Chris@191 17
Chris@191 18 #include <cmath>
Chris@191 19
Chris@191 20 DCT::DCT(int n) :
Chris@191 21 m_n(n),
Chris@191 22 m_scaled(n, 0.0),
Chris@191 23 m_time2(n*4, 0.0),
Chris@191 24 m_freq2r(n*4, 0.0),
Chris@191 25 m_freq2i(n*4, 0.0),
Chris@191 26 m_fft(n*4)
Chris@191 27 {
Chris@191 28 m_scale = m_n * sqrt(2.0 / m_n);
Chris@191 29 }
Chris@191 30
Chris@191 31 DCT::~DCT()
Chris@191 32 {
Chris@191 33 }
Chris@191 34
Chris@191 35 void
Chris@191 36 DCT::forward(const double *in, double *out)
Chris@191 37 {
Chris@191 38 for (int i = 0; i < m_n; ++i) {
Chris@191 39 m_time2[i*2 + 1] = in[i];
Chris@191 40 m_time2[m_n*4 - i*2 - 1] = in[i];
Chris@191 41 }
Chris@191 42
Chris@191 43 m_fft.forward(m_time2.data(), m_freq2r.data(), m_freq2i.data());
Chris@191 44
Chris@191 45 for (int i = 0; i < m_n; ++i) {
Chris@191 46 out[i] = m_freq2r[i];
Chris@191 47 }
Chris@191 48 }
Chris@191 49
Chris@191 50 void
Chris@191 51 DCT::forwardUnitary(const double *in, double *out)
Chris@191 52 {
Chris@191 53 forward(in, out);
Chris@191 54 for (int i = 0; i < m_n; ++i) {
Chris@191 55 out[i] /= m_scale;
Chris@191 56 }
Chris@191 57 out[0] /= sqrt(2.0);
Chris@191 58 }
Chris@191 59
Chris@191 60 void
Chris@191 61 DCT::inverse(const double *in, double *out)
Chris@191 62 {
Chris@191 63 for (int i = 0; i < m_n; ++i) {
Chris@191 64 m_freq2r[i] = in[i];
Chris@191 65 }
Chris@191 66 for (int i = 0; i < m_n; ++i) {
Chris@191 67 m_freq2r[m_n*2 - i] = -in[i];
Chris@191 68 }
Chris@191 69 m_freq2r[m_n] = 0.0;
Chris@191 70
Chris@191 71 for (int i = 0; i <= m_n*2; ++i) {
Chris@191 72 m_freq2i[i] = 0.0;
Chris@191 73 }
Chris@191 74
Chris@191 75 m_fft.inverse(m_freq2r.data(), m_freq2i.data(), m_time2.data());
Chris@191 76
Chris@191 77 for (int i = 0; i < m_n; ++i) {
Chris@191 78 out[i] = m_time2[i*2 + 1];
Chris@191 79 }
Chris@191 80 }
Chris@191 81
Chris@191 82 void
Chris@191 83 DCT::inverseUnitary(const double *in, double *out)
Chris@191 84 {
Chris@191 85 for (int i = 0; i < m_n; ++i) {
Chris@191 86 m_scaled[i] = in[i] * m_scale;
Chris@191 87 }
Chris@191 88 m_scaled[0] *= sqrt(2.0);
Chris@191 89 inverse(m_scaled.data(), out);
Chris@191 90 }
Chris@191 91