#include #include #include #include #include #include #include #include #include #include #include #include #include #include "scope.h" spectrum_buffer_manager_class::spectrum_buffer_manager_class() { my_formatted_spectrum_buffer = NULL; } spectrum_buffer_manager_class::~spectrum_buffer_manager_class() { if (my_formatted_spectrum_buffer != NULL) { free(my_formatted_spectrum_buffer); } } int spectrum_buffer_manager_class::initialize_spectrum(int horizontal_size, int vertical_size, Sint16 *main_buffer) { // This is the formatted buffer that will be fed to the display my_formatted_spectrum_buffer = (int *)malloc ((sizeof(int) * AUDIO_BUFFER_SIZE)); if (my_formatted_spectrum_buffer == NULL) { printf ("cannot allocate formatted spectrum spectrum buffer\n"); perror ("error is"); return 1; } //Allocate output fftw buffer if ((output_fftw = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * FFT_BUFFER_SIZE * 2)) == NULL) { printf ("cannot allocate fftw output buffer\n"); perror ("error is"); return 1; } //Allocate input fftw buffer if ((input_fftw = (double*) fftw_malloc(sizeof(double) * FFT_BUFFER_SIZE)) == NULL) { printf ("cannot allocate fftw input buffer\n"); perror ("error is"); return 1; } // Now lets attempt to perform an fftw plan if ((my_fftw_plan = fftw_plan_dft_r2c_1d(FFT_BUFFER_SIZE, input_fftw, output_fftw, FFTW_MEASURE)) == NULL) { printf ("cannot fftw plan"); perror ("error is"); return 1; } // my_read_spectrum_index is which chunk we will put the read buffer into my_read_spectrum_index = 0; // index to read the individual elements into the fftw input buffer read_buffer_counter = 0; // my_output_fft_buffer_index is used to flip output buffer // members all to negative for display purposes my_output_fft_buffer_index = 0; my_spectrum_horizontal_size = horizontal_size; my_spectrum_vertical_size = vertical_size; // The main buffer is the read buffer from main buffer read my_main_buffer = main_buffer; return 0; } // Returns address for formatted fft buffer for ready to display // Return NULL for waiting for buffer fill int *spectrum_buffer_manager_class::process_spectrum() { // Fill the fftw input array // Fill in section corresponging to the current read_buffer_counter input_fftw_write_position = input_fftw + my_read_spectrum_index; for (read_buffer_counter = 0; read_buffer_counter < READ_BUFFER_SIZE; read_buffer_counter += 1) { main_buffer_hold = (Sint16)(*(my_main_buffer + read_buffer_counter) * SPECTRUM_VOLUME); *(input_fftw_write_position + read_buffer_counter) = (double)main_buffer_hold; } /* prep for next time */ my_read_spectrum_index += 1; // Are we still working on filling this buffer? if (my_read_spectrum_index < FFT_NUMBER_READ_BUFFERS) { // Lets wait return NULL; } else // Done filling up fft buffer - lets process { // First, reset the spectrum index to 0 my_read_spectrum_index = 0; // Perform the fft fftw_execute(my_fftw_plan); // Now grab the real part of the complex output for (my_output_fft_buffer_index = 0; my_output_fft_buffer_index < my_spectrum_horizontal_size; my_output_fft_buffer_index += 1) { *(my_formatted_spectrum_buffer + my_output_fft_buffer_index) = (int)(output_fftw[(FFT_START_BUCKET + (my_output_fft_buffer_index))][0] * SPECTRUM_VOLUME); if (*(my_formatted_spectrum_buffer + my_output_fft_buffer_index) > 0 ) { // Flip any positive values to negative because negative causes location // to go up on the sdl coordinate system *(my_formatted_spectrum_buffer + my_output_fft_buffer_index) = - *(my_formatted_spectrum_buffer + my_output_fft_buffer_index); } } } return my_formatted_spectrum_buffer; }