121 lines
2.4 KiB
C++
121 lines
2.4 KiB
C++
#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
|
|
///
|
|
|
|
// Horizontal resolution
|
|
const size_t width;
|
|
// Vertical resolution
|
|
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
|
|
);
|
|
}; |