HRESULT TaudioFilterHeadphone::process(TfilterQueue::iterator it,TsampleFormat &fmt,void *samples0,size_t numsamples,const TfilterSettingsAudio *cfg0) { const TmixerSettings *cfg=(const TmixerSettings*)cfg0; if (!p_sys || oldfmt!=fmt || olddim!=cfg->headphone_dim) { oldfmt=fmt; olddim=cfg->headphone_dim; done(); /* Allocate the memory needed to store the module's structure */ p_sys=(aout_filter_sys_t*)malloc(sizeof(aout_filter_sys_t)); p_sys->i_overflow_buffer_size=0; p_sys->p_overflow_buffer=NULL; p_sys->i_nb_atomic_operations=0; p_sys->p_atomic_operations=NULL; inited=p_sys->Init(fmt,cfg)>=0; } if (inited) { float *p_in=(float*)init(cfg,fmt,samples0,numsamples); unsigned int i_input_nb=fmt.nchannels; fmt.setChannels(2); float *p_out=(float*)alloc_buffer(fmt,numsamples,buf); unsigned int i_output_nb=fmt.nchannels; /* Slide the overflow buffer */ byte_t *p_overflow = p_sys->p_overflow_buffer; size_t i_overflow_size = p_sys->i_overflow_buffer_size; size_t i_out_size=numsamples*fmt.blockAlign(); memset ( p_out , 0 , i_out_size ); if ( i_out_size > i_overflow_size ) { memcpy ( p_out , p_overflow , i_overflow_size ); } else { memcpy ( p_out , p_overflow , i_out_size ); } byte_t *p_slide = p_sys->p_overflow_buffer; while ( p_slide < p_overflow + i_overflow_size ) { if ( p_slide + i_out_size < p_overflow + i_overflow_size ) { memset ( p_slide , 0 , i_out_size ); if ( p_slide + 2 * i_out_size < p_overflow + i_overflow_size ) { memcpy ( p_slide , p_slide + i_out_size , i_out_size ); } else { memcpy ( p_slide , p_slide + i_out_size , p_overflow + i_overflow_size - ( p_slide + i_out_size ) ); } } else { memset ( p_slide , 0 , p_overflow + i_overflow_size - p_slide ); } p_slide += i_out_size; } /* apply the atomic operations */ for ( unsigned int i = 0 ; i < p_sys->i_nb_atomic_operations ; i++ ) { /* shorter variable names */ int i_source_channel_offset = p_sys->p_atomic_operations[i].i_source_channel_offset; int i_dest_channel_offset = p_sys->p_atomic_operations[i].i_dest_channel_offset; unsigned int i_delay = p_sys->p_atomic_operations[i].i_delay; double d_amplitude_factor = p_sys->p_atomic_operations[i].d_amplitude_factor; if ( numsamples > i_delay ) { unsigned int j; /* current buffer coefficients */ for ( j = 0 ; j < numsamples - i_delay ; j++ ) { p_out[ (i_delay+j)*i_output_nb + i_dest_channel_offset ] += float(p_in[ j * i_input_nb + i_source_channel_offset ] * d_amplitude_factor); } /* overflow buffer coefficients */ for ( j = 0 ; j < i_delay ; j++ ) { ((float*)p_overflow)[ j*i_output_nb + i_dest_channel_offset ] += float(p_in[ (numsamples - i_delay + j) * i_input_nb + i_source_channel_offset ] * d_amplitude_factor); } } else { /* overflow buffer coefficients only */ for ( unsigned int j = 0 ; j < numsamples ; j++ ) { ((float*)p_overflow)[ (i_delay - numsamples + j) * i_output_nb + i_dest_channel_offset ] += float(p_in[ j * i_input_nb + i_source_channel_offset ] * d_amplitude_factor); } } } samples0=p_out; } return parent->deliverSamples(++it,fmt,samples0,numsamples); }