#pragma once #include #include #include #include #include // memset #include #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& 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 freq_magnitudes; // An array of frequency bins, scaled logarithmically. std::vector 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 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 ); };