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
|