Added FFT code
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#include <math.h>
|
||||
#include <cstring> // memset
|
||||
#include <fftw3.h>
|
||||
|
||||
#include "utility/buffer.hpp"
|
||||
|
||||
class FFT_Visualizer {
|
||||
public:
|
||||
FFT_Visualizer(
|
||||
size_t width,
|
||||
size_t height,
|
||||
|
||||
// Advanced options you probably shouldn't touch
|
||||
double HZ_MIN = 20,
|
||||
double HZ_MAX = 20000,
|
||||
uint32_t DFT_TOTAL_SIZE = 1 << 15,
|
||||
// #define conf_spectrum_dft_size 2 (between 1 and 5, inclusive)
|
||||
uint32_t DFT_NONZERO_SIZE = (2048 * (2*2 + 4)),
|
||||
double GAIN = 10
|
||||
);
|
||||
|
||||
~FFT_Visualizer();
|
||||
|
||||
void update(
|
||||
const Buffer& buf
|
||||
);
|
||||
|
||||
size_t compute_buffer_output_size() const;
|
||||
|
||||
const std::vector<size_t>& get_output() {
|
||||
return output;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
///
|
||||
// Visualizer parameters
|
||||
///
|
||||
|
||||
// How many bars this visualizer will generate
|
||||
const size_t width;
|
||||
// Resolution of this visualizer's bars.
|
||||
const size_t height;
|
||||
// Leftmost frequency in spectrum
|
||||
const double HZ_MIN;
|
||||
// Rightmost frequency in spectrum
|
||||
const double HZ_MAX;
|
||||
// Not sure what this does
|
||||
const uint32_t DFT_TOTAL_SIZE;
|
||||
// Not sure what this does, either
|
||||
const uint32_t DFT_NONZERO_SIZE;
|
||||
// Visualization spectrum gain
|
||||
// tune if bars are too small
|
||||
const double GAIN;
|
||||
// Not sure what this does
|
||||
const double DYNAMIC_RANGE;
|
||||
|
||||
|
||||
///
|
||||
// FFTW resources
|
||||
///
|
||||
|
||||
fftw_plan plan;
|
||||
// How many output values fftw will give us
|
||||
size_t fftw_results;
|
||||
// Input array. This is filled with buffer data
|
||||
// that has been filtered through a window.
|
||||
double* fftw_input;
|
||||
// FFT output array.
|
||||
fftw_complex *fftw_output;
|
||||
|
||||
///
|
||||
// Intermediate values
|
||||
///
|
||||
|
||||
// The magnitudes of the complex values fftw returns.
|
||||
std::vector<double> freq_magnitudes;
|
||||
// An array of frequency bins, scaled logarithmically.
|
||||
std::vector<double> logspace;
|
||||
// Nearly-complete output.
|
||||
// This is necessary because some frequency bins
|
||||
// may be empty, and need to be interpolated
|
||||
std::vector<
|
||||
std::pair<
|
||||
size_t,
|
||||
double
|
||||
>
|
||||
> partial_output;
|
||||
|
||||
|
||||
// Output vector, with empty bins interpolated.
|
||||
// The maximum possible value of an element in this
|
||||
// vector is `height`.
|
||||
std::vector<size_t> output;
|
||||
|
||||
|
||||
///
|
||||
// Helper methods
|
||||
// See definition for docs.
|
||||
///
|
||||
|
||||
void GenLogspace();
|
||||
double Bin2Hz(size_t bin) const;
|
||||
|
||||
void ApplyWindow(
|
||||
double *output,
|
||||
const int16_t *input,
|
||||
ssize_t samples
|
||||
) const;
|
||||
|
||||
double Interpolate(
|
||||
size_t x,
|
||||
size_t h_idx
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user