xoreos  0.0.5
rdft.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 /* Based on the (I)RDFT code in FFmpeg (<https://ffmpeg.org/)>, which
26  * is released under the terms of version 2 or later of the GNU Lesser
27  * General Public License.
28  *
29  * The original copyright note in libavcodec/rdft.c reads as follows:
30  *
31  * (I)RDFT transforms
32  * Copyright (c) 2009 Alex Converse <alex dot converse at gmail dot com>
33  *
34  * This file is part of FFmpeg.
35  *
36  * FFmpeg is free software; you can redistribute it and/or
37  * modify it under the terms of the GNU Lesser General Public
38  * License as published by the Free Software Foundation; either
39  * version 2.1 of the License, or (at your option) any later version.
40  *
41  * FFmpeg is distributed in the hope that it will be useful,
42  * but WITHOUT ANY WARRANTY; without even the implied warranty of
43  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
44  * Lesser General Public License for more details.
45  *
46  * You should have received a copy of the GNU Lesser General Public
47  * License along with FFmpeg; if not, write to the Free Software
48  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
49  */
50 
51 #include <cassert>
52 
53 #include "src/common/maths.h"
54 #include "src/common/sinetables.h"
56 #include "src/common/fft.h"
57 #include "src/common/rdft.h"
58 
59 namespace Common {
60 
61 RDFT::RDFT(int bits, TransformType trans) : _bits(bits) {
62  assert ((_bits >= 4) && (_bits <= 16));
63 
64  _inverse = trans == IDFT_C2R || trans == DFT_C2R;
65  _signConvention = trans == IDFT_R2C || trans == DFT_C2R ? 1 : -1;
66 
67  _fft.reset(new FFT(bits - 1, trans == IDFT_C2R || trans == IDFT_R2C));
68 
69  int n = 1 << bits;
70 
71  _tSin = getSineTable(bits) + (trans == DFT_R2C || trans == DFT_C2R) * (n >> 2);
72  _tCos = getCosineTable(bits);
73 }
74 
76 }
77 
78 void RDFT::calc(float *data) {
79  const int n = 1 << _bits;
80 
81  const float k1 = 0.5f;
82  const float k2 = 0.5f - (_inverse ? 1.0f : 0.0f);
83 
84  if (!_inverse) {
85  _fft->permute(reinterpret_cast<Complex *>(data));
86  _fft->calc (reinterpret_cast<Complex *>(data));
87  }
88 
89  Complex ev, od;
90 
91  /* i=0 is a special case because of packing, the DC term is real, so we
92  are going to throw the N/2 term (also real) in with it. */
93 
94  ev.re = data[0];
95 
96  data[0] = ev.re + data[1];
97  data[1] = ev.re - data[1];
98 
99  int i;
100  for (i = 1; i < (n >> 2); i++) {
101  int i1 = 2 * i;
102  int i2 = n - i1;
103 
104  /* Separate even and odd FFTs */
105  ev.re = k1 * (data[i1 ] + data[i2 ]);
106  od.im = -k2 * (data[i1 ] - data[i2 ]);
107  ev.im = k1 * (data[i1 + 1] - data[i2 + 1]);
108  od.re = k2 * (data[i1 + 1] + data[i2 + 1]);
109 
110  /* Apply twiddle factors to the odd FFT and add to the even FFT */
111  data[i1 ] = ev.re + od.re * _tCos[i] - od.im * _tSin[i];
112  data[i1 + 1] = ev.im + od.im * _tCos[i] + od.re * _tSin[i];
113  data[i2 ] = ev.re - od.re * _tCos[i] + od.im * _tSin[i];
114  data[i2 + 1] = -ev.im + od.im * _tCos[i] + od.re * _tSin[i];
115  }
116 
117  data[2 * i + 1] = _signConvention * data[2 * i + 1];
118 
119  if (_inverse) {
120  data[0] *= k1;
121  data[1] *= k1;
122 
123  _fft->permute(reinterpret_cast<Complex *>(data));
124  _fft->calc (reinterpret_cast<Complex *>(data));
125  }
126 
127 }
128 
129 } // End of namespace Common
TransformType
Definition: rdft.h:66
A complex number.
Definition: maths.h:61
const float * _tSin
Definition: rdft.h:83
ScopedPtr< FFT > _fft
Definition: rdft.h:86
Definition: 2dafile.h:39
RDFT(int bits, TransformType trans)
Definition: rdft.cpp:61
float im
Definition: maths.h:62
Mathematical helpers.
const float * _tCos
Definition: rdft.h:84
const float * getSineTable(int bits)
float re
Definition: maths.h:62
Static sine tables.
(Inverse) Real Discrete Fourier Transform.
int _bits
Definition: rdft.h:79
void calc(float *data)
Definition: rdft.cpp:78
int _signConvention
Definition: rdft.h:81
(Inverse) Fast Fourier Transform.
Definition: fft.h:66
const float * getCosineTable(int bits)
(Inverse) Fast Fourier Transform.
Static cosine tables.
bool _inverse
Definition: rdft.h:80