//--------------------------------------------------------------------------// // Funcion: filtro // // // // Descripcion: Funcion que filtra la señal de entrada para darle forma. Va // // haciendiendo la convolucion entre los símbolos muestreados // // y los coeficientes del filtro pero también se le añade // // retraso. Paraf filtrar la señal los valores tienen que ser // // de tipo fract32 y es por eso por lo que se hace la // // conversiónde float a fract32 y viceversa // // // // Parametros de entrada: Ninguno // // // // Parametros de salida: Ninguno // // // //--------------------------------------------------------------------------// void filtro () { for(indice_muestras=0 ; indice_muestras<NUM_SOBREMUESTREADOS ; indice_muestras++) { left_in_fr32_real[indice_muestras]=float_to_fr32(simbolo_muestreado_real[indice_muestras]/VALOR_MAX_CONSTELACION); left_in_fr32_imag[indice_muestras]=float_to_fr32(simbolo_muestreado_imag[indice_muestras]/VALOR_MAX_CONSTELACION); } for (indice_retraso = 0; indice_retraso < COEFICIENTES_FILTRO; indice_retraso++) { retraso[indice_retraso] = 0; } fir_init(state,filter_fr32,retraso,COEFICIENTES_FILTRO,0); fir_fr32(left_in_fr32_real,left_out_fr32_real,NUM_FILTRADOS_1,&state); for (indice_retraso = 0; indice_retraso < COEFICIENTES_FILTRO; indice_retraso++) { retraso[indice_retraso] = 0; } fir_init(state,filter_fr32,retraso,COEFICIENTES_FILTRO,0); fir_fr32(left_in_fr32_imag,left_out_fr32_imag,NUM_FILTRADOS_1,&state); for(indice_muestrasFiltradas=0 ; indice_muestrasFiltradas<NUM_FILTRADOS_1 ; indice_muestrasFiltradas++) { left_out_float_real[indice_muestrasFiltradas] = VALOR_MAX_CONSTELACION*fr32_to_float(left_out_fr32_real[indice_muestrasFiltradas]); left_out_float_imag[indice_muestrasFiltradas] = VALOR_MAX_CONSTELACION*fr32_to_float(left_out_fr32_imag[indice_muestrasFiltradas]); } }
void mel_filter(fract32 power_fr[], float energy_melband[], int block_exponent) { int scale = 1 << block_exponent*2; int bank_num; for (bank_num = 0; bank_num < BANK_NUM; bank_num++) { int offset = bank_border[bank_num]/125; int L = bank_border[bank_num+2]/125 - bank_border[bank_num]/125; int bank_gain_offset; switch (bank_num) { case 0: bank_gain_offset = bank_border[0]/125; break; case 1: bank_gain_offset = bank_border[2]/125 - bank_border[0]/125; break; default: bank_gain_offset = bank_border[bank_num+1]/125 + bank_border[bank_num]/125 - bank_border[1]/125 - bank_border[0]/125; } int index; for (index = 0; index < L; index++) { fract32 temp = mult_fr1x32x32(power_fr[index+offset+1], bank_gain[index+bank_gain_offset]); energy_melband[bank_num] = energy_melband[bank_num] + fr32_to_float(temp); } energy_melband[bank_num] = energy_melband[bank_num] * scale; energy_melband[bank_num] = log10f(energy_melband[bank_num]); } }
void module_process_frame(const f32* in, f32* out) { static fract32* const pIn[4] = { &in0, &in1, &in2, &in3 }; u32 frame; u8 chan; // i/o buffers are (sometimes) interleaved in portaudio, // so need to introduce 1-sample delay for x-channel processing // static int _in0, _in1, _in2, _in3; for(frame=0; frame<BLOCKSIZE; frame++) { calc_frame(); for(chan=0; chan<NUMCHANNELS; chan++) { // stereo interleaved *out++ = fr32_to_float(frameVal); *(pIn[chan]) = float_to_fr32(*in++); } } }
float calc_energy(fract32 data[], int arr_length) { int shift = 9; // shift = log_2(arr_length) fract32 energy_fr = float_to_fr32(0.0); int index; for (index = 0; index < arr_length; index++) { fract32 temp = mult_fr1x32x32(data[index], data[index]); temp = shl_fr1x32(temp, -shift); // right shift in case of overflow energy_fr = add_fr1x32(energy_fr, temp); } float energy = fr32_to_float(energy_fr) * (1<<shift); return energy; }