diff options
Diffstat (limited to 'xbmc/utils/rfft.cpp')
| -rw-r--r-- | xbmc/utils/rfft.cpp | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/xbmc/utils/rfft.cpp b/xbmc/utils/rfft.cpp new file mode 100644 index 0000000..871eea7 --- /dev/null +++ b/xbmc/utils/rfft.cpp | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2015-2018 Team Kodi | ||
| 3 | * This file is part of Kodi - https://kodi.tv | ||
| 4 | * | ||
| 5 | * SPDX-License-Identifier: GPL-2.0-or-later | ||
| 6 | * See LICENSES/README.md for more information. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include "rfft.h" | ||
| 10 | |||
| 11 | #if defined(TARGET_WINDOWS) && !defined(_USE_MATH_DEFINES) | ||
| 12 | #define _USE_MATH_DEFINES | ||
| 13 | #endif | ||
| 14 | #include <math.h> | ||
| 15 | |||
| 16 | RFFT::RFFT(int size, bool windowed) : | ||
| 17 | m_size(size), m_windowed(windowed) | ||
| 18 | { | ||
| 19 | m_cfg = kiss_fftr_alloc(m_size,0,nullptr,nullptr); | ||
| 20 | } | ||
| 21 | |||
| 22 | RFFT::~RFFT() | ||
| 23 | { | ||
| 24 | // we don' use kiss_fftr_free here because | ||
| 25 | // its hardcoded to free and doesn't pay attention | ||
| 26 | // to SIMD (which might be used during kiss_fftr_alloc | ||
| 27 | //in the C'tor). | ||
| 28 | KISS_FFT_FREE(m_cfg); | ||
| 29 | } | ||
| 30 | |||
| 31 | void RFFT::calc(const float* input, float* output) | ||
| 32 | { | ||
| 33 | // temporary buffers | ||
| 34 | std::vector<kiss_fft_scalar> linput(m_size), rinput(m_size); | ||
| 35 | std::vector<kiss_fft_cpx> loutput(m_size), routput(m_size); | ||
| 36 | |||
| 37 | for (size_t i=0;i<m_size;++i) | ||
| 38 | { | ||
| 39 | linput[i] = input[2*i]; | ||
| 40 | rinput[i] = input[2*i+1]; | ||
| 41 | } | ||
| 42 | |||
| 43 | if (m_windowed) | ||
| 44 | { | ||
| 45 | hann(linput); | ||
| 46 | hann(rinput); | ||
| 47 | } | ||
| 48 | |||
| 49 | // transform channels | ||
| 50 | kiss_fftr(m_cfg, &linput[0], &loutput[0]); | ||
| 51 | kiss_fftr(m_cfg, &rinput[0], &routput[0]); | ||
| 52 | |||
| 53 | auto&& filter = [&](kiss_fft_cpx& data) | ||
| 54 | { | ||
| 55 | return sqrt(data.r*data.r+data.i*data.i) * 2.0/m_size * (m_windowed?sqrt(8.0/3.0):1.0); | ||
| 56 | }; | ||
| 57 | |||
| 58 | // interleave while taking magnitudes and normalizing | ||
| 59 | for (size_t i=0;i<m_size/2;++i) | ||
| 60 | { | ||
| 61 | output[2*i] = filter(loutput[i]); | ||
| 62 | output[2*i+1] = filter(routput[i]); | ||
| 63 | } | ||
| 64 | } | ||
| 65 | |||
| 66 | #include <iostream> | ||
| 67 | |||
| 68 | void RFFT::hann(std::vector<kiss_fft_scalar>& data) | ||
| 69 | { | ||
| 70 | for (size_t i=0;i<data.size();++i) | ||
| 71 | data[i] *= 0.5*(1.0-cos(2*M_PI*i/(data.size()-1))); | ||
| 72 | } | ||
