spek

Acoustic spectrum analyser https://github.com/alexkay/spek spek.cc
git clone http://git.hanabi.in/repos/spek.git
Log | Files | Refs | README

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 }