module-equalizer-sink: fixed a bug w/ new zero-latency input scheme (that was an interesting/cool bug!)

This commit is contained in:
Jason Newton 2009-08-19 00:30:07 -07:00
parent 735c8ab6fb
commit 2f6fd32cc5

View file

@ -104,8 +104,6 @@ struct userdata {
size_t overlap_size;//window_size-R size_t overlap_size;//window_size-R
size_t samples_gathered; size_t samples_gathered;
//message //message
float X;
float *H;//frequency response filter (magnitude based)
float *W;//windowing function (time domain) float *W;//windowing function (time domain)
float *work_buffer, **input, **overlap_accum; float *work_buffer, **input, **overlap_accum;
fftwf_complex *output_window; fftwf_complex *output_window;
@ -113,7 +111,7 @@ struct userdata {
//size_t samplings; //size_t samplings;
float Xs[2]; float Xs[2];
float *Hs[2];//thread updatable copies float *Hs[2];//thread updatable copies of the freq response filters (magintude based)
pa_aupdate *a_H; pa_aupdate *a_H;
pa_memchunk conv_buffer; pa_memchunk conv_buffer;
pa_memblockq *input_q; pa_memblockq *input_q;
@ -284,7 +282,8 @@ static void dsp_logic(
float * restrict src,/*input data w/ overlap at start, float * restrict src,/*input data w/ overlap at start,
*automatically cycled in routine *automatically cycled in routine
*/ */
float * restrict overlap,//The size of the overlap float * restrict overlap,
const float X,//multipliar
const float * restrict H,//The freq. magnitude scalers filter const float * restrict H,//The freq. magnitude scalers filter
const float * restrict W,//The windowing function const float * restrict W,//The windowing function
fftwf_complex * restrict output_window,//The transformed window'd src fftwf_complex * restrict output_window,//The transformed window'd src
@ -294,15 +293,15 @@ static void dsp_logic(
memset(dst + u->window_size, 0, (u->fft_size - u->window_size) * sizeof(float)); memset(dst + u->window_size, 0, (u->fft_size - u->window_size) * sizeof(float));
//window the data //window the data
for(size_t j = 0; j < u->window_size; ++j){ for(size_t j = 0; j < u->window_size; ++j){
dst[j] = u->X * W[j] * src[j]; dst[j] = X * W[j] * src[j];
} }
//Processing is done here! //Processing is done here!
//do fft //do fft
fftwf_execute_dft_r2c(u->forward_plan, dst, output_window); fftwf_execute_dft_r2c(u->forward_plan, dst, output_window);
//perform filtering //perform filtering
for(size_t j = 0; j < FILTER_SIZE; ++j){ for(size_t j = 0; j < FILTER_SIZE; ++j){
u->output_window[j][0] *= u->H[j]; u->output_window[j][0] *= H[j];
u->output_window[j][1] *= u->H[j]; u->output_window[j][1] *= H[j];
} }
//inverse fft //inverse fft
fftwf_execute_dft_c2r(u->inverse_plan, output_window, dst); fftwf_execute_dft_c2r(u->inverse_plan, output_window, dst);
@ -326,7 +325,7 @@ static void dsp_logic(
//preseve the needed input for the next window's overlap //preseve the needed input for the next window's overlap
memmove(src, src + u->R, memmove(src, src + u->R,
((u->overlap_size + u->samples_gathered) - u->R)*sizeof(float) u->overlap_size * sizeof(float)
); );
} }
@ -347,11 +346,12 @@ typedef union float_vector {
// *automatically cycled in routine // *automatically cycled in routine
// */ // */
// float * restrict overlap,//The size of the overlap // float * restrict overlap,//The size of the overlap
// const float X,//multipliar
// const float * restrict H,//The freq. magnitude scalers filter // const float * restrict H,//The freq. magnitude scalers filter
// const float * restrict W,//The windowing function // const float * restrict W,//The windowing function
// fftwf_complex * restrict output_window,//The transformed window'd src // fftwf_complex * restrict output_window,//The transformed window'd src
// struct userdata *u){//Collection of constants // struct userdata *u){//Collection of constants
//float_vector_t x = {u->X, u->X, u->X, u->X}; //float_vector_t x = {X, X, X, X};
// const size_t window_size = PA_ROUND_UP(u->window_size,v_size); // const size_t window_size = PA_ROUND_UP(u->window_size,v_size);
// const size_t fft_h = PA_ROUND_UP(FILTER_SIZE, v_size / 2); // const size_t fft_h = PA_ROUND_UP(FILTER_SIZE, v_size / 2);
// //const size_t R = PA_ROUND_UP(u->R, v_size); // //const size_t R = PA_ROUND_UP(u->R, v_size);
@ -431,24 +431,32 @@ typedef union float_vector {
// //
// //preseve the needed input for the next window's overlap // //preseve the needed input for the next window's overlap
// memmove(src, src + u->R, // memmove(src, src + u->R,
// ((u->overlap_size+u->samples_gathered)+-u->R)*sizeof(float) // u->overlap_size * sizeof(float)
// ); // );
//} //}
static void process_samples(struct userdata *u, pa_memchunk *tchunk){ static void process_samples(struct userdata *u, pa_memchunk *tchunk){
size_t fs=pa_frame_size(&(u->sink->sample_spec)); size_t fs=pa_frame_size(&(u->sink->sample_spec));
float *dst; float *dst;
unsigned a_i;
float *H, X;
pa_assert(u->samples_gathered >= u->R); pa_assert(u->samples_gathered >= u->R);
tchunk->index = 0; tchunk->index = 0;
tchunk->length = u->R * fs; tchunk->length = u->R * fs;
tchunk->memblock = pa_memblock_new(u->sink->core->mempool, tchunk->length); tchunk->memblock = pa_memblock_new(u->sink->core->mempool, tchunk->length);
dst = ((float*)pa_memblock_acquire(tchunk->memblock)); dst = ((float*)pa_memblock_acquire(tchunk->memblock));
/* set the H filter */
a_i = pa_aupdate_read_begin(u->a_H);
X = u->Xs[a_i];
H = u->Hs[a_i];
for(size_t c=0;c < u->channels; c++) { for(size_t c=0;c < u->channels; c++) {
dsp_logic( dsp_logic(
u->work_buffer, u->work_buffer,
u->input[c], u->input[c],
u->overlap_accum[c], u->overlap_accum[c],
u->H, X,
H,
u->W, u->W,
u->output_window, u->output_window,
u u
@ -465,6 +473,8 @@ static void process_samples(struct userdata *u, pa_memchunk *tchunk){
} }
pa_memblock_release(tchunk->memblock); pa_memblock_release(tchunk->memblock);
u->samples_gathered -= u->R; u->samples_gathered -= u->R;
pa_aupdate_read_end(u->a_H);
} }
static void initialize_buffer(struct userdata *u, pa_memchunk *in){ static void initialize_buffer(struct userdata *u, pa_memchunk *in){
@ -492,7 +502,7 @@ static void input_buffer(struct userdata *u, pa_memchunk *in){
pa_assert_se( pa_assert_se(
u->input[c]+u->samples_gathered+samples <= u->input[c]+u->window_size u->input[c]+u->samples_gathered+samples <= u->input[c]+u->window_size
); );
pa_sample_clamp(PA_SAMPLE_FLOAT32NE, u->input[c]+u->overlap_size+u->samples_gathered, sizeof(float), src + c, fs, samples); pa_sample_clamp(PA_SAMPLE_FLOAT32NE, u->input[c]+u->samples_gathered, sizeof(float), src + c, fs, samples);
} }
u->samples_gathered += samples; u->samples_gathered += samples;
pa_memblock_release(in->memblock); pa_memblock_release(in->memblock);
@ -503,7 +513,6 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk
struct userdata *u; struct userdata *u;
size_t fs; size_t fs;
struct timeval start, end; struct timeval start, end;
unsigned a_i;
pa_memchunk tchunk; pa_memchunk tchunk;
pa_sink_input_assert_ref(i); pa_sink_input_assert_ref(i);
pa_assert_se(u = i->userdata); pa_assert_se(u = i->userdata);
@ -554,15 +563,11 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk
pa_assert(u->fft_size >= u->window_size); pa_assert(u->fft_size >= u->window_size);
pa_assert(u->R < u->window_size); pa_assert(u->R < u->window_size);
/* set the H filter */ /* set the H filter */
a_i = pa_aupdate_read_begin(u->a_H);
u->X = u->Xs[a_i];
u->H = u->Hs[a_i];
pa_rtclock_get(&start); pa_rtclock_get(&start);
/* process a block */ /* process a block */
process_samples(u, chunk); process_samples(u, chunk);
pa_rtclock_get(&end); pa_rtclock_get(&end);
pa_log_debug("Took %0.6f seconds to process", (double) pa_timeval_diff(&end, &start) / PA_USEC_PER_SEC); pa_log_debug("Took %0.6f seconds to process", (double) pa_timeval_diff(&end, &start) / PA_USEC_PER_SEC);
pa_aupdate_read_end(u->a_H);
pa_assert(chunk->memblock); pa_assert(chunk->memblock);
//pa_log_debug("gave %ld", chunk->length/fs); //pa_log_debug("gave %ld", chunk->length/fs);
@ -1162,7 +1167,6 @@ enum equalizer_handler_index {
EQUALIZER_HANDLER_FILTERSAMPLERATE, EQUALIZER_HANDLER_FILTERSAMPLERATE,
EQUALIZER_HANDLER_N_COEFS, EQUALIZER_HANDLER_N_COEFS,
EQUALIZER_HANDLER_FILTER, EQUALIZER_HANDLER_FILTER,
EQUALIZER_HANDLER_PREAMP,
EQUALIZER_HANDLER_MAX EQUALIZER_HANDLER_MAX
}; };