static void volume_process(MSFilter *f){ mblk_t *m; Volume *v=(Volume*)f->data; float target_gain; /* Important notice: any processes called herein can modify v->target_gain, at * end of this function apply_gain() is called, thus: later process calls can * override this target gain, and order must be well thought out */ if (v->agc_enabled || v->peer!=NULL){ mblk_t *om; int nbytes=v->nsamples*2; ms_bufferizer_put_from_queue(v->buffer,f->inputs[0]); while(ms_bufferizer_get_avail(v->buffer)>=nbytes){ om=allocb(nbytes,0); ms_bufferizer_read(v->buffer,om->b_wptr,nbytes); om->b_wptr+=nbytes; update_energy((int16_t*)om->b_rptr, v->nsamples, v); target_gain = v->static_gain; if (v->peer) /* this ptr set = echo limiter enable flag */ target_gain = volume_echo_avoider_process(v, om); /* Multiply with gain from echo limiter, not "choose smallest". Why? * Remote talks, local echo suppress via mic path, but still audible in * remote speaker. AGC operates fully, too (local speaker close to local mic!); * having agc gain reduction also contribute to total reduction makes sense. */ if (v->agc_enabled) target_gain/= volume_agc_process(v, om); if (v->noise_gate_enabled) volume_noise_gate_process(v, v->level_pk, om); apply_gain(v, om, target_gain); ms_queue_put(f->outputs[0],om); } }else{ /*light processing: no agc. Work in place in the input buffer*/ while((m=ms_queue_get(f->inputs[0]))!=NULL){ update_energy((int16_t*)m->b_rptr, (m->b_wptr - m->b_rptr) / 2, v); target_gain = v->static_gain; if (v->noise_gate_enabled) volume_noise_gate_process(v, v->level_pk, m); apply_gain(v, m, target_gain); ms_queue_put(f->outputs[0],m); } } }
void iir_coeff::convert_to_ab() { float_type hpf_z_gain = 0; float_type hpf_p_gain = 0; float_type z_gain = 0; gain = (float_type)1.0; z_root_to_ab(zeros); z_gain = gain; hpf_z_gain = hpf_gain; gain = 1.0; hpf_gain = 1.0; z_root_to_ab(poles); hpf_p_gain = hpf_gain; gain /= z_gain; if (odd) gain *= 0.5 * (1.0 - real(poles[0])); hpf_gain = hpf_p_gain / hpf_z_gain; if (lpf == filter_type::high) gain = hpf_gain; state = filter_state::s3; // in Z-domain 2nd order A/B coefficients a_tf = p2_to_poly(poles); b_tf = p2_to_poly(zeros); // Apply gain to b coefficents apply_gain(gain); }
static sf_count_t sample_rate_convert (SNDFILE *infile, SNDFILE *outfile, int converter, double src_ratio, int channels, double * gain, int normalize) { static float input [BUFFER_LEN] ; static float output [BUFFER_LEN] ; SRC_STATE *src_state ; SRC_DATA src_data ; int error ; double max = 0.0 ; sf_count_t output_count = 0 ; sf_seek (infile, 0, SEEK_SET) ; sf_seek (outfile, 0, SEEK_SET) ; /* Initialize the sample rate converter. */ if ((src_state = src_new (converter, channels, &error)) == NULL) { printf ("\n\nError : src_new() failed : %s.\n\n", src_strerror (error)) ; exit (1) ; } ; src_data.end_of_input = 0 ; /* Set this later. */ /* Start with zero to force load in while loop. */ src_data.input_frames = 0 ; src_data.data_in = input ; src_data.src_ratio = src_ratio ; src_data.data_out = output ; src_data.output_frames = BUFFER_LEN /channels ; while (1) { /* If the input buffer is empty, refill it. */ if (src_data.input_frames == 0) { src_data.input_frames = sf_readf_float (infile, input, BUFFER_LEN / channels) ; src_data.data_in = input ; /* The last read will not be a full buffer, so snd_of_input. */ if (src_data.input_frames < BUFFER_LEN / channels) src_data.end_of_input = SF_TRUE ; } ; if ((error = src_process (src_state, &src_data))) { printf ("\nError : %s\n", src_strerror (error)) ; exit (1) ; } ; /* Terminate if done. */ if (src_data.end_of_input && src_data.output_frames_gen == 0) break ; max = apply_gain (src_data.data_out, src_data.output_frames_gen, channels, max, *gain) ; /* Write output. */ sf_writef_float (outfile, output, src_data.output_frames_gen) ; output_count += src_data.output_frames_gen ; src_data.data_in += src_data.input_frames_used * channels ; src_data.input_frames -= src_data.input_frames_used ; } ; src_delete (src_state) ; if (normalize && max > 1.0) { *gain = 1.0 / max ; printf ("\nOutput has clipped. Restarting conversion to prevent clipping.\n\n") ; return -1 ; } ; return output_count ; } /* sample_rate_convert */
void iir_coeff::set_bandpass_gain() { double w = 2.0*M_PI*get_center(); float_type gain = freqz_mag(w); apply_gain(1.0 / gain); }