ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

rdft.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 // Based on eos' (I)RDFT code which is in turn
00024 // Based upon the (I)RDFT code in FFmpeg
00025 // Copyright (c) 2009 Alex Converse <alex dot converse at gmail dot com>
00026 
00027 #include "common/rdft.h"
00028 
00029 namespace Common {
00030 
00031 RDFT::RDFT(int bits, TransformType trans) : _bits(bits), _sin(1 << bits), _cos(1 << bits), _fft(nullptr) {
00032     assert((_bits >= 4) && (_bits <= 16));
00033 
00034     _inverse        = trans == IDFT_C2R || trans == DFT_C2R;
00035     _signConvention = trans == IDFT_R2C || trans == DFT_C2R ? 1 : -1;
00036 
00037     _fft = new FFT(bits - 1, trans == IDFT_C2R || trans == IDFT_R2C);
00038 
00039     int n = 1 << bits;
00040 
00041     _tSin = _sin.getTable() + (trans == DFT_R2C || trans == DFT_C2R) * (n >> 2);
00042     _tCos = _cos.getTable();
00043 }
00044 
00045 RDFT::~RDFT() {
00046     delete _fft;
00047 }
00048 
00049 void RDFT::calc(float *data) {
00050     const int n = 1 << _bits;
00051 
00052     const float k1 = 0.5f;
00053     const float k2 = 0.5f - _inverse;
00054 
00055     if (!_inverse) {
00056         _fft->permute((Complex *)data);
00057         _fft->calc   ((Complex *)data);
00058     }
00059 
00060     Complex ev, od;
00061 
00062     /* i=0 is a special case because of packing, the DC term is real, so we
00063        are going to throw the N/2 term (also real) in with it. */
00064 
00065     ev.re = data[0];
00066 
00067     data[0] = ev.re + data[1];
00068     data[1] = ev.re - data[1];
00069 
00070     int i;
00071     for (i = 1; i < (n >> 2); i++) {
00072         int i1 = 2 * i;
00073         int i2 = n - i1;
00074 
00075         /* Separate even and odd FFTs */
00076         ev.re =  k1 * (data[i1    ] + data[i2   ]);
00077         od.im = -k2 * (data[i1    ] - data[i2   ]);
00078         ev.im =  k1 * (data[i1 + 1] - data[i2 + 1]);
00079         od.re =  k2 * (data[i1 + 1] + data[i2 + 1]);
00080 
00081         /* Apply twiddle factors to the odd FFT and add to the even FFT */
00082         data[i1    ] =  ev.re + od.re * _tCos[i] - od.im * _tSin[i];
00083         data[i1 + 1] =  ev.im + od.im * _tCos[i] + od.re * _tSin[i];
00084         data[i2    ] =  ev.re - od.re * _tCos[i] + od.im * _tSin[i];
00085         data[i2 + 1] = -ev.im + od.im * _tCos[i] + od.re * _tSin[i];
00086     }
00087 
00088     data[2 * i + 1] = _signConvention * data[2 * i + 1];
00089 
00090     if (_inverse) {
00091         data[0] *= k1;
00092         data[1] *= k1;
00093 
00094         _fft->permute((Complex *)data);
00095         _fft->calc   ((Complex *)data);
00096     }
00097 
00098 }
00099 
00100 } // End of namespace Common


Generated on Sat Mar 16 2019 05:01:51 for ResidualVM by doxygen 1.7.1
curved edge   curved edge