Engineering School, 2nd year
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

158 lines
4.0 KiB

#ifndef _BEATDETECTSEF_H_
#define _BEATDETECTSEF_H_
// to test
#define AUDIO_MEMORY_LENGTH 128
#define COEF 2.0
#define SAMPLE_RATE 44100
#define FRAME_NUM_SAMPLE 512 // number of samples in each frame
#define OVERLAP 0 // number of reused sample from last round
#define BEEP_LENGTH 0
// number of coef of the real to complex fft
#define FFT_NUM_SAMPLE ((FRAME_NUM_SAMPLE / 2) + 1)
#define FIR_ORDER 8 // order of the differentiator filter, indicates the
// of past spectrograms to remember.
/**
* This structure aims to store the data from previous iterations
* of the function energy_flux_positive_variation as it need some
* history of the past value...
*/
struct sef_data {
// a FIFO containing the FIR_ORDER last spectrograms
// managed as an always circular buffer
float * spectrograms_spl;
// index of the "last in" (more recent) of the FIFO
// use it (% FIR_ORDER)
int last_spectrogram;
// array of hanning window coef
float * hanning_spl;
float * in_spl;
fftwf_complex * fft_spl;
// stored data about the way to efficiently compute fft
fftwf_plan plan;
};
typedef struct sef_data SEF_data;
struct shifted_array {
float * buffer;
float * last_in;
float total;
int length;
};
typedef struct shifted_array Shifted_array;
/**
* Initialize the past_data structure. To be call only
* once before using sef_variation. Don't forget to call
* destroy_sef when the structure become useless.
*
* @past_data
*/
void init_sef(SEF_data * past_data);
/**
* Compute the spectral energy flux variation, given the last spectrograms.
* and the new samples copy in the in_spl field of the past_data struct
*
* @param sef_data
* @return the sum of positive per-frequency variations
*/
float sef_variation (SEF_data * sef_data);
/**
* Release the past_data structure. To be call only
* once after using sef_variation for the last time.
*
* @past_data
*/
void destroy_sef(SEF_data * past_data);
void cpx_sample_to_spectral_energetic_density(fftwf_complex * fft_cpx_samples, float * fft_abs_sample, int num_samples);
void buffer_to_samples(signed short int * buffer, float * samples, int num_samples);
void apply_window(float * samples, float * window, int num_samples);
void write_buffer(signed short int * buffer, int frame_size);
void read_buffer(signed short int * buffer, int frame_size);
void add_beep_to_output(signed short int * output_buffer, signed short int * beep_buffer, int beep_buffer_length);
void make_beep(signed short int * beep_buffer, int beep_buffer_length, int freq);
// Shifted array stuff
void shifted_array_init(Shifted_array * array, int length);
void shifted_array_destroy(Shifted_array * array);
float shifted_array_mean(Shifted_array * array);
float shifted_array_total(Shifted_array * array);
float shifted_array_push(Shifted_array * array, float value);
/**
* To retrieve a value in the shifted array. Index 0 is the
* oldest value, that is to say the next removed value. On the
* contrary, index length - 1 is the more recent value
*
* @param array
* @param index
*/
float shifted_array_value_at(Shifted_array * array, int index);
void test_shifted_array();
#endif /* _BEATDETECTSEF_H_ */
/**
* Return the shift for wich the auto correlation is max,
* so the periodicity.
*
* @param peaks
* @param min_shift
* @param max_shift
*/
int compute_periodicity(Shifted_array * peaks, int min_shift, int max_shift);
/**
* Return the phase.
* @param peaks the sef peaks.
* @param impulses a memory area large enough to store same numbers
* of item as the peaks array
* @param shift the tempo, in frames (returned by compute_periodicity)
* @return the phase, in frames
*/
int compute_phase(Shifted_array * peaks, float * impulses, int shift);
/**
* Generate a train of impulses.
*
* @param impulses a memory area large enough to store same numbers
* of item as the peaks array
* @param length the length of the buffer
* @param shift the tempo, in frames (returned by compute_periodicity)
*/
void generate_impulses_train(float * impulses, int length, int shift);