Commit 6b1b109e authored by Arnaud Blanchard's avatar Arnaud Blanchard
Browse files

Initial file

parents
cmake_minimum_required(VERSION 2.6)
subdirs(f_fftw)
\ No newline at end of file
fftw
====
Apply a fft on th signal using fftw3.
Install
=======
Install [blaar](blaar.org) then in the blaar directory:
OSX:
brew install fftw
git submodule add https://framagit.org/blaar/fftw
./install.sh fftw
Ubuntu:
sudo apt-get install fftw3-dev
git submodule add https://framagit.org/blaar/fftw
./install.sh fftw
Usage:
======
bin/f_fftw <blc_channel-in>
cmake_minimum_required(VERSION 2.6)
subdirs(f_fftw)
\ No newline at end of file
#include "blc_channel.h"
#include "blc_program.h"
#include <fftw3.h>
#include <unistd.h>
#include <math.h> //sqrtf
#include <pthread.h>
#define DEFAULT_OUTPUT_NAME "fourier<pid> or spectrum<pid>"
sem_t *sem_output, *sem_input;
int i=0;
struct timeval;
blc_channel input, output;
char const *display, *option_record;
int columns_nb=64, rows_nb=16;
FILE *record_file;
void spectrum_loop(int period){
size_t i;
fftwf_complex *intermediate;
fftwf_plan fftw_plan;
intermediate=fftwf_alloc_complex(output.total_length);
fftw_plan = fftwf_plan_dft_r2c_1d(input.total_length, input.floats, intermediate , FFTW_ESTIMATE);
BLC_COMMAND_LOOP(period*1000){
fftwf_execute(fftw_plan); /* repeat as needed */
FOR(i, output.total_length){
output.floats[i]=sqrtf(intermediate[i][0]*intermediate[i][0]+intermediate[i][1]*intermediate[i][1])/output.total_length;
}
if(display){
blc_fprint_float_graph(stderr, output.floats, output.total_length, "spectrum", columns_nb, rows_nb, 1, 0, "Frequency", "Intensity");
blc_eprint_cursor_up(rows_nb);
}
if (record_file) fprint_tsv_floats(record_file, output.floats, output.total_length);
}
fftwf_destroy_plan(fftw_plan);
blc_eprint_cursor_down(rows_nb);
}
void standard_loop(int period){
fftwf_plan fftw_plan;
fftw_plan = fftwf_plan_r2r_1d(input.total_length, input.floats, output.floats , FFTW_R2HC, FFTW_ESTIMATE);
BLC_COMMAND_LOOP(period*1000){
fftwf_execute(fftw_plan); /* repeat as needed */
if(display){
blc_fprint_float_graph(stderr, output.floats, output.total_length, "spectrum", columns_nb, rows_nb, 1, 0, "Frequency", "Intensity");
blc_eprint_cursor_up(rows_nb);
}
}
fftwf_destroy_plan(fftw_plan);
blc_eprint_cursor_down(rows_nb);
}
int main(int argc, char**argv){
char const *input_name, *output_name, *spectrum_option, *period_str;
int output_length, period;
blc_program_add_option(&output_name, 'o', "output", "string", "Channel containing the fast fourier transformation", DEFAULT_OUTPUT_NAME);
blc_program_add_option(&display, 'd', "display", NULL, "Display the result as text graph", NULL);
blc_program_add_option(&option_record, 'e', "export", "filename", "export data on file in parameter", NULL);
blc_program_add_option(&period_str, 'p', "period", "integer", "Period in ms (0 as fast as possible). No effect if input synchro.", "100");
blc_program_add_option(&spectrum_option, 's', "spectrum", NULL, "Get the square value of the fftw signal", NULL);
blc_program_add_parameter(&input_name, "input blc_channel", 1, "Channel containing the sound data", NULL);
blc_program_init(&argc, &argv, NULL);
//Open input channel and check the type of values
input.open(input_name, BLC_CHANNEL_READ);
if (input.type!='FL32') EXIT_ON_CHANNEL_ERROR(&input,"Input must be of type 'FL32'");
if (input.sem_new_data) {
period=0; //As fast as possible
}
else if (sscanf(period_str, "%d", &period)==0) EXIT_ON_ERROR("Interpretting period: '%s'", period_str);
if (strcmp(DEFAULT_OUTPUT_NAME, output_name)==0) {
if(spectrum_option) asprintf((char**)&output_name, ":spectrum%d", getpid());
else asprintf((char**)&output_name, ":fourier%d", getpid());
}
if (option_record) {
SYSTEM_ERROR_CHECK(record_file=fopen(option_record, "w"), NULL, "Problem creating '%s'", option_record);
printf("Recording in: '%s'\n", option_record);
}
//Create a channel or reopen a previous one.
if (spectrum_option) output_length=input.total_length/2+1;
else output_length=input.total_length;
output.create_or_open(output_name, BLC_CHANNEL_WRITE, 'FL32', 'NDEF', 1, output_length);
output.publish();
blc_loop_try_add_waiting_semaphore(input.sem_new_data);
blc_loop_try_add_waiting_semaphore(output.sem_ack_data);
blc_loop_try_add_posting_semaphore(input.sem_ack_data);
blc_loop_try_add_posting_semaphore(output.sem_new_data);
//Start the process depending on the fact we use the square of the values (spectrum) or directly the output
//We loop at a maximum speed of period micro seconds
if (spectrum_option) spectrum_loop(period);
else standard_loop(period);
if (record_file) SYSTEM_SUCCESS_CHECK(fclose(record_file), -1, NULL);
return EXIT_SUCCESS;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment