diff options
author | Daniil Cherednik <dan.cherednik@gmail.com> | 2024-06-17 20:12:45 +0000 |
---|---|---|
committer | Daniil Cherednik <dan.cherednik@gmail.com> | 2024-06-17 22:21:52 +0200 |
commit | 23a4e5f1dd7ce24f65a2af0598d1f92af4b5c424 (patch) | |
tree | 8a259ca8363c5b15fd3605b760518cb37e6ac63c /src/lib/mdct/mdct.h | |
parent | 73dbd1609445a0142e1e138b6b44ec6d1925cbb8 (diff) | |
download | atracdenc-23a4e5f1dd7ce24f65a2af0598d1f92af4b5c424.tar.gz |
[refactoring] move some libraries in to library directory
Diffstat (limited to 'src/lib/mdct/mdct.h')
-rw-r--r-- | src/lib/mdct/mdct.h | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/src/lib/mdct/mdct.h b/src/lib/mdct/mdct.h new file mode 100644 index 0000000..59b9af7 --- /dev/null +++ b/src/lib/mdct/mdct.h @@ -0,0 +1,182 @@ +/* + * This file is part of AtracDEnc. + * + * AtracDEnc is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * AtracDEnc is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with AtracDEnc; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +#include "config.h" +#include "fft/kissfft_impl/kiss_fft.h" +#include <vector> +#include <type_traits> + +namespace NMDCT { + +static_assert(sizeof(kiss_fft_scalar) == sizeof(TFloat), "size of fft_scalar is not equal to size of TFloat"); + +class TMDCTBase { +protected: + const size_t N; + const std::vector<TFloat> SinCos; + kiss_fft_cpx* FFTIn; + kiss_fft_cpx* FFTOut; + kiss_fft_cfg FFTPlan; + TMDCTBase(size_t n, TFloat scale); + virtual ~TMDCTBase(); +}; + + +template<size_t TN, typename TIO = TFloat> +class TMDCT : public TMDCTBase { + std::vector<TIO> Buf; +public: + TMDCT(float scale = 1.0) + : TMDCTBase(TN, scale) + , Buf(TN/2) + { + } + const std::vector<TIO>& operator()(const TIO* in) { + + const size_t n2 = N >> 1; + const size_t n4 = N >> 2; + const size_t n34 = 3 * n4; + const size_t n54 = 5 * n4; + const TFloat* cos = &SinCos[0]; + const TFloat* sin = &SinCos[1]; + + TFloat *xr, *xi, r0, i0; + TFloat c, s; + size_t n; + + xr = (TFloat*)FFTIn; + xi = (TFloat*)FFTIn + 1; + for (n = 0; n < n4; n += 2) { + r0 = in[n34 - 1 - n] + in[n34 + n]; + i0 = in[n4 + n] - in[n4 - 1 - n]; + + c = cos[n]; + s = sin[n]; + + xr[n] = r0 * c + i0 * s; + xi[n] = i0 * c - r0 * s; + } + + for (; n < n2; n += 2) { + r0 = in[n34 - 1 - n] - in[n - n4]; + i0 = in[n4 + n] + in[n54 - 1 - n]; + + c = cos[n]; + s = sin[n]; + + xr[n] = r0 * c + i0 * s; + xi[n] = i0 * c - r0 * s; + } + + kiss_fft(FFTPlan, FFTIn, FFTOut); + + xr = (TFloat*)FFTOut; + xi = (TFloat*)FFTOut + 1; + for (n = 0; n < n2; n += 2) { + r0 = xr[n]; + i0 = xi[n]; + + c = cos[n]; + s = sin[n]; + + Buf[n] = - r0 * c - i0 * s; + Buf[n2 - 1 -n] = - r0 * s + i0 * c; + } + + return Buf; + } +}; + +template<size_t TN, typename TIO = TFloat> +class TMIDCT : public TMDCTBase { + std::vector<TIO> Buf; +public: + TMIDCT(float scale = TN) + : TMDCTBase(TN, scale/2) + , Buf(TN) + {} + const std::vector<TIO>& operator()(const TIO* in) { + + const size_t n2 = N >> 1; + const size_t n4 = N >> 2; + const size_t n34 = 3 * n4; + const size_t n54 = 5 * n4; + const TFloat* cos = &SinCos[0]; + const TFloat* sin = &SinCos[1]; + + TFloat *xr, *xi, r0, i0, r1, i1; + TFloat c, s; + size_t n; + + xr = (TFloat*)FFTIn; + xi = (TFloat*)FFTIn + 1; + + for (n = 0; n < n2; n += 2) { + r0 = in[n]; + i0 = in[n2 - 1 - n]; + + c = cos[n]; + s = sin[n]; + + xr[n] = -2.0 * (i0 * s + r0 * c); + xi[n] = -2.0 * (i0 * c - r0 * s); + } + + kiss_fft(FFTPlan, FFTIn, FFTOut); + + xr = (TFloat*)FFTOut; + xi = (TFloat*)FFTOut + 1; + + for (n = 0; n < n4; n += 2) { + r0 = xr[n]; + i0 = xi[n]; + + c = cos[n]; + s = sin[n]; + + r1 = r0 * c + i0 * s; + i1 = r0 * s - i0 * c; + + Buf[n34 - 1 - n] = r1; + Buf[n34 + n] = r1; + Buf[n4 + n] = i1; + Buf[n4 - 1 - n] = -i1; + } + + for (; n < n2; n += 2) { + r0 = xr[n]; + i0 = xi[n]; + + c = cos[n]; + s = sin[n]; + + r1 = r0 * c + i0 * s; + i1 = r0 * s - i0 * c; + + Buf[n34 - 1 - n] = r1; + Buf[n - n4] = -r1; + Buf[n4 + n] = i1; + Buf[n54 - 1 - n] = i1; + } + return Buf; + } +}; + +} //namespace NMDCT |