summaryrefslogtreecommitdiffstats
path: root/xbmc/utils/rfft.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/utils/rfft.cpp')
-rw-r--r--xbmc/utils/rfft.cpp72
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
16RFFT::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
22RFFT::~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
31void 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
68void 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}