예제 #1
0
        /**
         * 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]);
        }
예제 #2
0
        /**
         * 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);
        }