spek-fft.cc (1108B)
1 #include <cmath> 2 3 #define __STDC_CONSTANT_MACROS 4 extern "C" { 5 #include <libavcodec/avfft.h> 6 } 7 8 #include "spek-fft.h" 9 10 class FFTPlanImpl : public FFTPlan 11 { 12 public: 13 FFTPlanImpl(int nbits); 14 ~FFTPlanImpl() override; 15 16 void execute() override; 17 18 private: 19 struct RDFTContext *cx; 20 }; 21 22 std::unique_ptr<FFTPlan> FFT::create(int nbits) 23 { 24 return std::unique_ptr<FFTPlan>(new FFTPlanImpl(nbits)); 25 } 26 27 FFTPlanImpl::FFTPlanImpl(int nbits) : FFTPlan(nbits), cx(av_rdft_init(nbits, DFT_R2C)) 28 { 29 } 30 31 FFTPlanImpl::~FFTPlanImpl() 32 { 33 av_rdft_end(this->cx); 34 } 35 36 void FFTPlanImpl::execute() 37 { 38 av_rdft_calc(this->cx, this->get_input()); 39 40 // Calculate magnitudes. 41 int n = this->get_input_size(); 42 float n2 = n * n; 43 this->set_output(0, 10.0f * log10f(this->get_input(0) * this->get_input(0) / n2)); 44 this->set_output(n / 2, 10.0f * log10f(this->get_input(1) * this->get_input(1) / n2)); 45 for (int i = 1; i < n / 2; i++) { 46 float re = this->get_input(i * 2); 47 float im = this->get_input(i * 2 + 1); 48 this->set_output(i, 10.0f * log10f((re * re + im * im) / n2)); 49 } 50 }