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