Rev 2097 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* fft.cc
* DIN Is Noise is copyright (c) 2006-2025 Jagannathan Sampath
* DIN Is Noise is released under GNU Public License 2.0
* For more information, please visit https://dinisnoise.org/
*/
#include "fft.h"
#include "multi_curve.h"
#include "solver.h"
#include <math.h>
#include "viewwin.h"
#include "widget.h"
#include <algorithm>
#include <fstream>
using namespace std;
extern ofstream dlog;
extern viewport view;
fft::fft () : lev ("fft_levels") {
dx = 1. / NUM_SAMPLES ;
x = 0;
cfg = kiss_fft_alloc (NUM_SAMPLES, 0, 0, 0);
dlog << "+++ FFT setup complete +++ " << endl;
}
void fft::setup () {
widget* ctrls [] = {&ab_fold, &lev, &l_title};
widget_load ("d_fft", ctrls, 3);
ab_fold.set_dir (arrow_button::right);
ab_fold.set_listener (this);
l_title.set_text ("FFT");
l_title.add_child (&ab_fold);
l_title.add_child (&lev);
l_title.set_moveable (1);
lev.hide ();
}
void fft::update () {
l_title.update ();
ab_fold.update ();
}
int fft::handle_input () {
int r = ab_fold.handle_input ();
if (r) return r;
r = l_title.handle_input ();
if (r) return r;
if (lev.visible) r = lev.handle_input ();
return r;
}
void fft::draw () {
widget* ctrls [] = {&ab_fold, &lev, &l_title};
for (int i = 0; i < 3; ++i) {
widget* ctrl = ctrls[i];
if (ctrl->visible) ctrl->draw ();
}
}
fft::~fft () {
kiss_fft_free (cfg);
widget* ctrls [] = {&ab_fold, &lev, &l_title};
widget_save ("d_fft", ctrls, 3);
dlog << "--- destroyed fft ---" << endl;
}
void fft::go (multi_curve* crv) {
// do fft on a bezier multi curve
solver s (crv);
x = 0;
s (x, dx, NUM_SAMPLES, in);
for (int i = 0; i < NUM_SAMPLES; ++i) {
cx_in[i].r = in[i];
cx_in[i].i = 0;
}
kiss_fft (cfg, cx_in, cx_out);
harms.clear ();
for (int i = 1; i < NUM_SAMPLES; ++i) {
float x = cx_out[i].r;
float y = cx_out[i].i;
float x2 = x*x;
float y2 = y*y;
harms.push_back (sqrt (x2 + y2));
}
float m0 = *min_element (harms.begin(), harms.end());
float m1 = *max_element (harms.begin(), harms.end());
float mm = m1 - m0;
if (m1 == m0) return;
lev.clear_hgt_val ();
for (int i = 0, j = harms.size(); i < j; ++i) {
float dm = harms[i] - m0;
float y = dm / mm;
lev.set_only (i, y);
}
}