annotate dsp/transforms/DCT.cpp @ 415:4ae4229a074a

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