/** * Quantization of pitch and codebook gains * * @param code input : fixed codebook vector * @param g_coeff input : correlation factors * @param l_subfr input : fcb vector length * @param gain_pit output: quantized acb gain * @param gain_code output: quantized fcb gain * @param tameflag input : flag set to 1 if taming is needed * @return quantizer index */ public int qua_gain( float[] code, float[] g_coeff, int l_subfr, FloatReference gain_pit, FloatReference gain_code, int tameflag ) { var FLT_MAX_G729 = Ld8k.FLT_MAX_G729; var GP0999 = Ld8k.GP0999; var GPCLIP2 = Ld8k.GPCLIP2; var NCAN1 = Ld8k.NCAN1; var NCAN2 = Ld8k.NCAN2; var NCODE2 = Ld8k.NCODE2; var gbk1 = TabLd8k.gbk1; var gbk2 = TabLd8k.gbk2; var map1 = TabLd8k.map1; var map2 = TabLd8k.map2; /* * MA prediction is performed on the innovation energy (in dB with mean * * removed). * * An initial predicted gain, g_0, is first determined and the correction * * factor alpha = gain / g_0 is quantized. * * The pitch gain and the correction factor are vector quantized and the * * mean-squared weighted error criterion is used in the quantizer search. * * CS Codebook , fast pre-selection version * */ int i, j, index1 = 0, index2 = 0; int cand1, cand2; float gcode0; float dist, dist_min, g_pitch, g_code; var best_gain = new float[2]; float tmp; /*---------------------------------------------------* *- energy due to innovation -* *- predicted energy -* *- predicted codebook gain => gcode0[exp_gcode0] -* *---------------------------------------------------*/ gcode0 = Gainpred.gain_predict(past_qua_en, code, l_subfr); /*-- pre-selection --*/ tmp = -1.0f / (4.0f * g_coeff[0] * g_coeff[2] - g_coeff[4] * g_coeff[4]); best_gain[0] = (2.0f * g_coeff[2] * g_coeff[1] - g_coeff[3] * g_coeff[4]) * tmp; best_gain[1] = (2.0f * g_coeff[0] * g_coeff[3] - g_coeff[1] * g_coeff[4]) * tmp; if (tameflag == 1) { if (best_gain[0] > GPCLIP2) { best_gain[0] = GPCLIP2; } } /*----------------------------------------------* * - presearch for gain codebook - * *----------------------------------------------*/ var cand1Ref = new IntReference(); var cand2Ref = new IntReference(); gbk_presel(best_gain, cand1Ref, cand2Ref, gcode0); cand1 = cand1Ref.value; cand2 = cand2Ref.value; /*-- selection --*/ dist_min = FLT_MAX_G729; if (tameflag == 1) { for (i = 0; i < NCAN1; i++) { for (j = 0; j < NCAN2; j++) { g_pitch = gbk1[cand1 + i][0] + gbk2[cand2 + j][0]; if (g_pitch < GP0999) { g_code = gcode0 * (gbk1[cand1 + i][1] + gbk2[cand2 + j][1]); dist = g_pitch * g_pitch * g_coeff[0] + g_pitch * g_coeff[1] + g_code * g_code * g_coeff[2] + g_code * g_coeff[3] + g_pitch * g_code * g_coeff[4]; if (dist < dist_min) { dist_min = dist; index1 = cand1 + i; index2 = cand2 + j; } } } } } else { for (i = 0; i < NCAN1; i++) { for (j = 0; j < NCAN2; j++) { g_pitch = gbk1[cand1 + i][0] + gbk2[cand2 + j][0]; g_code = gcode0 * (gbk1[cand1 + i][1] + gbk2[cand2 + j][1]); dist = g_pitch * g_pitch * g_coeff[0] + g_pitch * g_coeff[1] + g_code * g_code * g_coeff[2] + g_code * g_coeff[3] + g_pitch * g_code * g_coeff[4]; if (dist < dist_min) { dist_min = dist; index1 = cand1 + i; index2 = cand2 + j; } } } } gain_pit.value = gbk1[index1][0] + gbk2[index2][0]; g_code = gbk1[index1][1] + gbk2[index2][1]; gain_code.value = g_code * gcode0; /*----------------------------------------------* * update table of past quantized energies * *----------------------------------------------*/ Gainpred.gain_update(past_qua_en, g_code); return(map1[index1] * NCODE2 + map2[index2]); }
/** * Decode the adaptive and fixed codebook gains. * * @param index input : quantizer index * @param code input : fixed code book vector * @param l_subfr input : subframe size * @param bfi input : bad frame indicator good = 0 * @param gain_pit output: quantized acb gain * @param gain_code output: quantized fcb gain */ public void dec_gain( int index, float[] code, int l_subfr, int bfi, FloatReference gain_pit, FloatReference gain_code ) { var NCODE2 = Ld8k.NCODE2; var gbk1 = TabLd8k.gbk1; var gbk2 = TabLd8k.gbk2; var imap1 = TabLd8k.imap1; var imap2 = TabLd8k.imap2; int index1, index2; float gcode0, g_code; /*----------------- Test erasure ---------------*/ if (bfi != 0) { gain_pit.value *= 0.9f; if (gain_pit.value > 0.9f) { gain_pit.value = 0.9f; } gain_code.value *= 0.98f; /*----------------------------------------------* * update table of past quantized energies * * (frame erasure) * *----------------------------------------------*/ Gainpred.gain_update_erasure(past_qua_en); return; } /*-------------- Decode pitch gain ---------------*/ index1 = imap1[index / NCODE2]; index2 = imap2[index % NCODE2]; gain_pit.value = gbk1[index1][0] + gbk2[index2][0]; /*-------------- Decode codebook gain ---------------*/ /*---------------------------------------------------* *- energy due to innovation -* *- predicted energy -* *- predicted codebook gain => gcode0[exp_gcode0] -* *---------------------------------------------------*/ gcode0 = Gainpred.gain_predict(past_qua_en, code, l_subfr); /*-----------------------------------------------------------------* * *gain_code = (gbk1[indice1][1]+gbk2[indice2][1]) * gcode0; * *-----------------------------------------------------------------*/ g_code = gbk1[index1][1] + gbk2[index2][1]; gain_code.value = g_code * gcode0; /*----------------------------------------------* * update table of past quantized energies * *----------------------------------------------*/ Gainpred.gain_update(past_qua_en, g_code); }