コード例 #1
0
Word32 quant_2p_2N1(                       /* (o) return (2*N)+1 bits         */
		Word16 pos1,                          /* (i) position of the pulse 1     */
		Word16 pos2,                          /* (i) position of the pulse 2     */
		Word16 N)                             /* (i) number of bits for position */
{
	Word16 mask, tmp;
	Word32 index;
	mask = (1 << N) - 1;              /* mask = ((1<<N)-1); */
	/*-------------------------------------------------------*
	 * Quantization of 2 pulses with 2*N+1 bits:             *
	 // 2×n + 1位2脉冲量化
	 *-------------------------------------------------------*/
	if (((pos2 ^ pos1) & NB_POS) == 0)
	{
		/* sign of 1st pulse == sign of 2th pulse */
		// 标志第一脉冲= =第二签名脉冲
		if(pos1 <= pos2)          /* ((pos1 - pos2) <= 0) */
		{
			/* index = ((pos1 & mask) << N) + (pos2 & mask); */
			index = L_deposit_l(add1((((Word16) (pos1 & mask)) << N), ((Word16) (pos2 & mask))));
		} else
		{
			/* ((pos2 & mask) << N) + (pos1 & mask); */
			index = L_deposit_l(add1((((Word16) (pos2 & mask)) << N), ((Word16) (pos1 & mask))));
		}
		if ((pos1 & NB_POS) != 0)
		{
			tmp = (N << 1);
			index = vo_L_add(index, (1L << tmp));       /* index += 1 << (2*N); */
		}
	} else
	{
		/* sign of 1st pulse != sign of 2th pulse */
		// 第一脉冲信号!=第二脉冲信号
		if (vo_sub((Word16) (pos1 & mask), (Word16) (pos2 & mask)) <= 0)
		{
			/* index = ((pos2 & mask) << N) + (pos1 & mask); */
			index = L_deposit_l(add1((((Word16) (pos2 & mask)) << N), ((Word16) (pos1 & mask))));
			if ((pos2 & NB_POS) != 0)
			{
				tmp = (N << 1);           /* index += 1 << (2*N); */
				index = vo_L_add(index, (1L << tmp));
			}
		} else
		{
			/* index = ((pos1 & mask) << N) + (pos2 & mask);	 */
			index = L_deposit_l(add1((((Word16) (pos1 & mask)) << N), ((Word16) (pos2 & mask))));
			if ((pos1 & NB_POS) != 0)
			{
				tmp = (N << 1);
				index = vo_L_add(index, (1 << tmp));    /* index += 1 << (2*N); */
			}
		}
	}
	return (index);
}
コード例 #2
0
ファイル: qsidgain.c プロジェクト: 2831942318/siphon
/*-------------------------------------------------------------------*
 * Function  Qua_Sidgain                                             *
 *           ~~~~~~~~~~~                                             *
 *-------------------------------------------------------------------*/
void Qua_Sidgain(
  Word16 *ener,     /* (i)   array of energies                   */
  Word16 *sh_ener,  /* (i)   corresponding scaling factors       */
  Word16 nb_ener,   /* (i)   number of energies or               */
  Word16 *enerq,    /* (o)   decoded energies in dB              */
  Word16 *idx       /* (o)   SID gain quantization index         */
)
{
  Word16 i;
  Word32 L_x;
  Word16 sh1, temp;
  Word16 hi, lo;
  Word32 L_acc;
  
  if(nb_ener == 0) {
    /* Quantize energy saved for frame erasure case                */
    /* L_x = average_ener                                          */
    L_acc = L_deposit_l(*ener);
    L_acc = L_shl(L_acc, *sh_ener); /* >> if *sh_ener < 0 */
    L_Extract(L_acc, &hi, &lo);
    L_x = Mpy_32_16(hi, lo, fact[0]);
    sh1 = 0;
  }
  else {
    
    /*
     * Compute weighted average of energies
     * ener[i] = enerR[i] x 2**sh_ener[i]
     * L_x = k[nb_ener] x SUM(i=0->nb_ener-1) enerR[i]
     * with k[nb_ener] =  fact_ener / nb_ener x L_FRAME x nbAcf
     */
    sh1 = sh_ener[0];
    for(i=1; i<nb_ener; i++) {
      if(sh_ener[i] < sh1) sh1 = sh_ener[i];
    }
    sh1 = add(sh1, (16-marg[nb_ener]));
    L_x = 0L;
    for(i=0; i<nb_ener; i++) {
      temp = sub(sh1, sh_ener[i]);
      L_acc = L_deposit_l(ener[i]);
      L_acc = L_shl(L_acc, temp);
      L_x = L_add(L_x, L_acc);
    }
    L_Extract(L_x, &hi, &lo);
    L_x = Mpy_32_16(hi, lo, fact[i]);
  }
  
  *idx = Quant_Energy(L_x, sh1, enerq);
  
  return;
}
コード例 #3
0
ファイル: q_pulse.c プロジェクト: Abhishekh-TEL/pdroid
Word32 quant_1p_N1(                        /* (o) return N+1 bits             */
		Word16 pos,                        /* (i) position of the pulse       */
		Word16 N)                          /* (i) number of bits for position */
{
	Word16 mask;
	Word32 index;

	mask = (1 << N) - 1;              /* mask = ((1<<N)-1); */
	/*-------------------------------------------------------*
	 * Quantization of 1 pulse with N+1 bits:                *
	 *-------------------------------------------------------*/
	index = L_deposit_l((Word16) (pos & mask));
	if ((pos & NB_POS) != 0)
	{
		index = vo_L_add(index, L_deposit_l(1 << N));   /* index += 1 << N; */
	}
	return (index);
}
コード例 #4
0
ファイル: dtx.c プロジェクト: huangjingpei/webrtc
static Word16 Cmp_filt(Word16 *RCoeff, Word16 sh_RCoeff, Word16 *acf,
                                        Word16 alpha, Word16 FracThresh)
{
  Word32 L_temp0, L_temp1;
  Word16 temp1, temp2, sh[2], ind;
  Word16 i;
  Word16 diff, flag;
  extern Flag Overflow;

  sh[0] = 0;
  sh[1] = 0;
  ind = 1;
  flag = 0;
  do {
    Overflow = 0;
    temp1 = shr(RCoeff[0], sh[0]);
    temp2 = shr(acf[0], sh[1]);
    L_temp0 = L_shr(L_mult(temp1, temp2),1);
    for(i=1; i <= M; i++) {
      temp1 = shr(RCoeff[i], sh[0]);
      temp2 = shr(acf[i], sh[1]);
      L_temp0 = L_mac(L_temp0, temp1, temp2);
    }
    if(Overflow != 0) {
      sh[(int)ind] = add(sh[(int)ind], 1);
      ind = sub(1, ind);
    }
    else flag = 1;
  } while (flag == 0);
  
  
  temp1 = mult_r(alpha, FracThresh);
  L_temp1 = L_add(L_deposit_l(temp1), L_deposit_l(alpha));
  temp1 = add(sh_RCoeff, 9);  /* 9 = Lpc_justif. * 2 - 16 + 1 */
  temp2 = add(sh[0], sh[1]);
  temp1 = sub(temp1, temp2);
  L_temp1 = L_shl(L_temp1, temp1);
  
  L_temp0 = L_sub(L_temp0, L_temp1);
  if(L_temp0 > 0L) diff = 1;
  else diff = 0;

  return(diff);
}
コード例 #5
0
ファイル: LSPGETQ.C プロジェクト: SibghatullahSheikh/codecs
void Lsp_stability(
  Word16 buf[]       /* (i/o) Q13 : quantized LSP parameters      */
)
{
  Word16 j;
  Word16 tmp;
  Word32 L_diff;
  Word32 L_acc, L_accb;

  for(j=0; j<M-1; j++) {
    L_acc = L_deposit_l( buf[j+1] );
    L_accb = L_deposit_l( buf[j] );
    L_diff = L_sub( L_acc, L_accb );

    if( L_diff < 0L ) {
      /* exchange buf[j]<->buf[j+1] */
      tmp      = buf[j+1];
      buf[j+1] = buf[j];
      buf[j]   = tmp;
    }
  }


  if( sub(buf[0], L_LIMIT) <0 ) {
    buf[0] = L_LIMIT;
    printf("lsp_stability warning Low \n");
  }
  for(j=0; j<M-1; j++) {
    L_acc = L_deposit_l( buf[j+1] );
    L_accb = L_deposit_l( buf[j] );
    L_diff = L_sub( L_acc, L_accb );

    if( L_sub(L_diff, GAP3)<0L ) {
      buf[j+1] = add( buf[j], GAP3 );
    }
  }

  if( sub(buf[M-1],M_LIMIT)>0 ) {
    buf[M-1] = M_LIMIT;
    printf("lsp_stability warning High \n");
  }
  return;
}
コード例 #6
0
ファイル: vad.cpp プロジェクト: nandohca/kista
void step_up (
    Word16 np,
    Word16 vpar[],
    Word16 aav1[]
)
{
    Word32 L_coef[9], L_work[9];
    Word16 temp;
    Word16 i, m;

    /*** Initialization of the step-up recursion ***/

    L_coef[0] = 0x20000000L;     
    L_coef[1] = L_shl (L_deposit_l (vpar[0]), 14);               

    /*** Loop on the LPC analysis order: ***/

    for (m = 2; m <= np; m++)
    {
        for (i = 1; i < m; i++)
        {
            temp = extract_h (L_coef[m - i]);
            L_work[i] = L_mac (L_coef[i], vpar[m - 1], temp);    
        }

        for (i = 1; i < m; i++)
        {
            L_coef[i] = L_work[i];                               
        }

        L_coef[m] = L_shl (L_deposit_l (vpar[m - 1]), 14);       
    }

    /*** Keep the aav1[0..np] in 15 bits ***/

    for (i = 0; i <= np; i++)
    {
        aav1[i] = extract_h (L_shr (L_coef[i], 3));              
    }

    return;
}
コード例 #7
0
Word32 quant_3p_3N1(                       /* (o) return (3*N)+1 bits         */
		Word16 pos1,                          /* (i) position of the pulse 1     */
		Word16 pos2,                          /* (i) position of the pulse 2     */
		Word16 pos3,                          /* (i) position of the pulse 3     */
		Word16 N)                             /* (i) number of bits for position */
{
	Word16 nb_pos;
	Word32 index;

	nb_pos =(1 <<(N - 1));            /* nb_pos = (1<<(N-1)); */
	/*-------------------------------------------------------*
	 * Quantization of 3 pulses with 3*N+1 bits:             *
	 // 3脉冲3×n + 1比特量化
	 *-------------------------------------------------------*/
	if (((pos1 ^ pos2) & nb_pos) == 0)
	{
		index = quant_2p_2N1(pos1, pos2, sub(N, 1));    /* index = quant_2p_2N1(pos1, pos2, (N-1)); */
		/* index += (pos1 & nb_pos) << N; */
		index = vo_L_add(index, (L_deposit_l((Word16) (pos1 & nb_pos)) << N));
		/* index += quant_1p_N1(pos3, N) << (2*N); */
		index = vo_L_add(index, (quant_1p_N1(pos3, N)<<(N << 1)));

	} else if (((pos1 ^ pos3) & nb_pos) == 0)
	{
		index = quant_2p_2N1(pos1, pos3, sub(N, 1));    /* index = quant_2p_2N1(pos1, pos3, (N-1)); */
		index = vo_L_add(index, (L_deposit_l((Word16) (pos1 & nb_pos)) << N));
		/* index += (pos1 & nb_pos) << N; */
		index = vo_L_add(index, (quant_1p_N1(pos2, N) << (N << 1)));
		/* index += quant_1p_N1(pos2, N) <<
		 * (2*N); */
	} else
	{
		index = quant_2p_2N1(pos2, pos3, (N - 1));    /* index = quant_2p_2N1(pos2, pos3, (N-1)); */
		/* index += (pos2 & nb_pos) << N;			 */
		index = vo_L_add(index, (L_deposit_l((Word16) (pos2 & nb_pos)) << N));
		/* index += quant_1p_N1(pos1, N) << (2*N);	 */
		index = vo_L_add(index, (quant_1p_N1(pos1, N) << (N << 1)));
	}
	return (index);
}
コード例 #8
0
/*
********************************************************************************
*                         PRIVATE PROGRAM CODE
********************************************************************************
*/
void MR475_quant_store_results(

    gc_predState *pred_st, /* i/o: gain predictor state struct               */
    const Word16 *p,       /* i  : pointer to selected quantizer table entry */
    Word16 gcode0,         /* i  : predicted CB gain,     Q(14 - exp_gcode0) */
    Word16 exp_gcode0,     /* i  : exponent of predicted CB gain,        Q0  */
    Word16 *gain_pit,      /* o  : Pitch gain,                           Q14 */
    Word16 *gain_cod       /* o  : Code gain,                            Q1  */
)
{

    Word16 g_code, exp, frac, tmp;
    Word32 L_tmp;

    Word16 qua_ener_MR122; /* o  : quantized energy error, MR122 version Q10 */
    Word16 qua_ener;       /* o  : quantized energy error,               Q10 */

    /* Read the quantized gains */
    *gain_pit = *p++;                
    g_code = *p++;                   

    /*------------------------------------------------------------------*
     *  calculate final fixed codebook gain:                            *
     *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                            *
     *                                                                  *
     *   gc = gc0 * g                                                   *
     *------------------------------------------------------------------*/

    L_tmp = L_mult(g_code, gcode0);
    L_tmp = L_shr(L_tmp, sub(10, exp_gcode0));
    *gain_cod = extract_h(L_tmp);

    /*------------------------------------------------------------------*
     *  calculate predictor update values and update gain predictor:    *
     *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    *
     *                                                                  *
     *   qua_ener       = log2(g)                                       *
     *   qua_ener_MR122 = 20*log10(g)                                   *
     *------------------------------------------------------------------*/

    Log2 (L_deposit_l (g_code), &exp, &frac); /* Log2(x Q12) = log2(x) + 12 */
    exp = sub(exp, 12);

    tmp = shr_r (frac, 5);
    qua_ener_MR122 = add (tmp, shl (exp, 10));

    L_tmp = Mpy_32_16(exp, frac, 24660); /* 24660 Q12 ~= 6.0206 = 20*log10(2) */
    qua_ener = round (L_shl (L_tmp, 13)); /* Q12 * Q0 = Q13 -> Q10 */

    gc_pred_update(pred_st, qua_ener_MR122, qua_ener);
}
コード例 #9
0
ファイル: pst.c プロジェクト: thecc4re/lumicall
/*----------------------------------------------------------------------------
 * filt_mu - tilt filtering with : (1 + mu z-1) * (1/1-|mu|)
 *   computes y[n] = (1/1-|mu|) (x[n]+mu*x[n-1])
 *----------------------------------------------------------------------------
 */
static void filt_mu(
    Word16 *sig_in,     /* input : input signal (beginning at sample -1) */
    Word16 *sig_out,    /* output: output signal */
    Word16 parcor0      /* input : parcor0 (mu = parcor0 * gamma3) */
)
{
    int n;
    Word16 mu, mu2, ga, temp;
    Word32 L_acc, L_temp, L_fact;
    Word16 fact, sh_fact1;
    Word16 *ptrs;

    if(parcor0 > 0) {
        mu      = mult_r(parcor0, GAMMA3_PLUS);
        /* GAMMA3_PLUS < 0.5 */
        sh_fact1 = 15;                   /* sh_fact + 1 */
        fact     = (Word16)0x4000;       /* 2**sh_fact */
        L_fact   = (Word32)0x00004000L;
    }
    else {
        mu       = mult_r(parcor0, GAMMA3_MINUS);
        /* GAMMA3_MINUS < 0.9375 */
        sh_fact1 = 12;                   /* sh_fact + 1 */
        fact     = (Word16)0x0800;       /* 2**sh_fact */
        L_fact   = (Word32)0x00000800L;
    }

    temp = sub(1, abs_s(mu));
    mu2  = add(32767, temp);    /* 2**15 (1 - |mu|) */
    ga   = div_s(fact, mu2);    /* 2**sh_fact / (1 - |mu|) */

    ptrs = sig_in;     /* points on sig_in(-1) */
    mu   = shr(mu, 1);          /* to avoid overflows   */

    for(n=0; n<L_SUBFR; n++) {
        temp   = *ptrs++;
        L_temp = L_deposit_l(*ptrs);
        L_acc  = L_shl(L_temp, 15);         /* sig_in(n) * 2**15 */
        L_temp = L_mac(L_acc, mu, temp);
        L_temp = L_add(L_temp, 0x00004000L);
        temp   = extract_l(L_shr(L_temp,15));
        /* ga x temp x 2 with rounding */
        L_temp = L_add(L_mult(temp, ga),L_fact);
        L_temp = L_shr(L_temp, sh_fact1); /* mult. temp x ga */
        sig_out[n] = sature(L_temp);
    }
    return;
}
コード例 #10
0
ファイル: calcexc.c プロジェクト: huangjingpei/webrtc
static Word16 Gauss(Word16 *seed)
{

/****  Xi = uniform v.a. in [-32768, 32767]       ****/
/****  Z = SUM(i=1->12) Xi / 2 x 32768 is N(0,1)  ****/
/****  output : Z x 512 < 2^12                    ****/

  Word16 i;
  Word16 temp;
  Word32 L_acc;
  
  L_acc = 0L;
  for(i=0; i<12; i++) {
    L_acc = L_add(L_acc, L_deposit_l(Random(seed)));
  }
  L_acc = L_shr(L_acc, 7);
  temp = extract_l(L_acc);
  return(temp);
}
コード例 #11
0
ファイル: calcexc.c プロジェクト: sippet/g729
static int16_t Gauss(int16_t *seed)
{

/****  Xi = uniform v.a. in [-32768, 32767]       ****/
/****  Z = SUM(i=1->12) Xi / 2 x 32768 is N(0,1)  ****/
/****  output : Z x 512 < 2^12                    ****/

  int16_t i;
  int16_t temp;
  int32_t L_acc;
  
  L_acc = 0L;
  for (i = 0; i < 12; i++) {
    L_acc = WebRtcSpl_AddSatW32(L_acc,
        L_deposit_l(WebRtcG729fix_Random(seed)));
  }
  L_acc = L_shr(L_acc, 7);
  temp = extract_l(L_acc);
  return(temp);
}
コード例 #12
0
ファイル: gainpred.c プロジェクト: 2831942318/siphon
/*---------------------------------------------------------------------------*
 * Function  Gain_update_erasure                                             *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                             *
 * update table of past quantized energies (frame erasure)                   *
 *---------------------------------------------------------------------------*
 *     av_pred_en = 0.0;                                                     *
 *     for (i = 0; i < 4; i++)                                               *
 *        av_pred_en += past_qua_en[i];                                      *
 *     av_pred_en = av_pred_en*0.25 - 4.0;                                   *
 *     if (av_pred_en < -14.0) av_pred_en = -14.0;                           *
 *---------------------------------------------------------------------------*/
void Gain_update_erasure(
   Word16 past_qua_en[]     /* (i) Q10 :Past quantized energies        */
)
{
   Word16  i, av_pred_en;
   Word32  L_tmp;

   L_tmp = 0;                                                     /* Q10 */
   for(i=0; i<4; i++)
      L_tmp = L_add( L_tmp, L_deposit_l( past_qua_en[i] ) );
   av_pred_en = extract_l( L_shr( L_tmp, 2 ) );
   av_pred_en = sub( av_pred_en, 4096 );                          /* Q10 */

   if( sub(av_pred_en, -14336) < 0 ){
      av_pred_en = -14336;                              /* 14336:14[Q10] */
   }

   for(i=3; i>0; i--){
      past_qua_en[i] = past_qua_en[i-1];
   }
   past_qua_en[0] = av_pred_en;
}
コード例 #13
0
ファイル: pstcp.c プロジェクト: Orange168/lumicall_new
/*----------------------------------------------------------------------------
 *   calc_st_filt -  computes impulse response of A(gamma2) / A(gamma1)
 *   controls gain : computation of energy impulse response as
 *                    SUMn  (abs (h[n])) and computes parcor0
 *----------------------------------------------------------------------------
 */
static void calc_st_filte(
 Word16 *apond2,     /* input : coefficients of numerator */
 Word16 *apond1,     /* input : coefficients of denominator */
 Word16 *parcor0,    /* output: 1st parcor calcul. on composed filter */
 Word16 *sig_ltp_ptr,    /* in/out: input of 1/A(gamma1) : scaled by 1/g0 */
 Word16  long_h_st,     /* input : impulse response length                   */
 Word16 m_pst               /* input : LPC order    */
)
{
    Word16 h[LONG_H_ST_E];
    Word32 L_temp, L_g0;
    Word16 g0, temp;
    Word16 i;

    /* compute i.r. of composed filter apond2 / apond1 */
    Syn_filte(m_pst, apond1, apond2, h, long_h_st, mem_zero, 0);

    /* compute 1st parcor */
    calc_rc0_he(h, parcor0, long_h_st);

    /* compute g0 */
    L_g0 = 0L;
    for(i=0; i<long_h_st; i++) {
        L_temp = L_deposit_l(abs_s(h[i]));
        L_g0   = L_add(L_g0, L_temp);
    }
    g0 = extract_h(L_shl(L_g0, 14));

    /* Scale signal input of 1/A(gamma1) */
    if(sub(g0, 1024)>0) {
        temp = div_s(1024, g0);     /* temp = 2**15 / gain0 */
        for(i=0; i<L_SUBFR; i++) {
            sig_ltp_ptr[i] = mult_r(sig_ltp_ptr[i], temp);
        }
    }

    return;
}
コード例 #14
0
ファイル: dtx.c プロジェクト: huangjingpei/webrtc
static void Calc_sum_acf(Word16 *acf, Word16 *sh_acf,
                         Word16 *sum, Word16 *sh_sum, Word16 nb)
{

  Word16 *ptr1;
  Word32 L_temp, L_tab[MP1];
  Word16 sh0, temp;
  Word16 i, j;
  
  /* Compute sum = sum of nb acfs */
  /* Find sh_acf minimum */
  sh0 = sh_acf[0];
  for(i=1; i<nb; i++) {
    if(sub(sh_acf[i], sh0) < 0) sh0 = sh_acf[i];
  }
  sh0 = add(sh0, 14);           /* 2 bits of margin */

  for(j=0; j<MP1; j++) {
    L_tab[j] = 0L;
  }
  ptr1 = acf;
  for(i=0; i<nb; i++) {
    temp = sub(sh0, sh_acf[i]);
    for(j=0; j<MP1; j++) {
      L_temp = L_deposit_l(*ptr1++);
      L_temp = L_shl(L_temp, temp); /* shift right if temp<0 */
      L_tab[j] = L_add(L_tab[j], L_temp);
    }
  } 
  temp = norm_l(L_tab[0]);
  for(i=0; i<=M; i++) {
    sum[i] = extract_h(L_shl(L_tab[i], temp));
  }
  temp = sub(temp, 16);
  *sh_sum = add(sh0, temp);
  return;
}
コード例 #15
0
ファイル: dec_gain.c プロジェクト: SibghatullahSheikh/codecs
/*---------------------------------------------------------------------------*
 * Function  Dec_gain                                                        *
 * ~~~~~~~~~~~~~~~~~~                                                        *
 * Decode the pitch and codebook gains                                       *
 *                                                                           *
 *---------------------------------------------------------------------------*
 * input arguments:                                                          *
 *                                                                           *
 *   index      :Quantization index                                          *
 *   code[]     :Innovative code vector                                      *
 *   L_subfr    :Subframe size                                               *
 *   bfi        :Bad frame indicator                                         *
 *                                                                           *
 * output arguments:                                                         *
 *                                                                           *
 *   gain_pit   :Quantized pitch gain                                        *
 *   gain_cod   :Quantized codebook gain                                     *
 *                                                                           *
 *---------------------------------------------------------------------------*/
void Dec_gain(
   Word16 index,        /* (i)     :Index of quantization.         */
   Word16 code[],       /* (i) Q13 :Innovative vector.             */
   Word16 L_subfr,      /* (i)     :Subframe length.               */
   Word16 bfi,          /* (i)     :Bad frame indicator            */
   Word16 *gain_pit,    /* (o) Q14 :Pitch gain.                    */
   Word16 *gain_cod     /* (o) Q1  :Code gain.                     */
)
{
   Word16  index1, index2, tmp;
   Word16  gcode0, exp_gcode0;
   Word32  L_gbk12, L_acc, L_accb;
   void    Gain_predict( Word16 past_qua_en[], Word16 code[], Word16 L_subfr,
                        Word16 *gcode0, Word16 *exp_gcode0 );
   void    Gain_update( Word16 past_qua_en[], Word32 L_gbk12 );
   void    Gain_update_erasure( Word16 past_qua_en[] );

        /* Gain predictor, Past quantized energies = -14.0 in Q10 */

   static Word16 past_qua_en[4] = { -14336, -14336, -14336, -14336 };


   /*-------------- Case of erasure. ---------------*/

   if(bfi != 0){
      *gain_pit = mult( *gain_pit, 29491 );      /* *0.9 in Q15 */
      if (sub( *gain_pit, 29491) > 0) *gain_pit = 29491;
      *gain_cod = mult( *gain_cod, 32111 );      /* *0.98 in Q15 */

     /*----------------------------------------------*
      * update table of past quantized energies      *
      *                              (frame erasure) *
      *----------------------------------------------*/
      Gain_update_erasure(past_qua_en);

      return;
   }

   /*-------------- Decode pitch gain ---------------*/

   index1 = imap1[ shr(index,NCODE2_B) ] ;
   index2 = imap2[ index & (NCODE2-1) ] ;
   *gain_pit = add( gbk1[index1][0], gbk2[index2][0] );

   /*-------------- Decode codebook gain ---------------*/

  /*---------------------------------------------------*
   *-  energy due to innovation                       -*
   *-  predicted energy                               -*
   *-  predicted codebook gain => gcode0[exp_gcode0]  -*
   *---------------------------------------------------*/

   Gain_predict( past_qua_en, code, L_subfr, &gcode0, &exp_gcode0 );

  /*-----------------------------------------------------------------*
   * *gain_code = (gbk1[indice1][1]+gbk2[indice2][1]) * gcode0;      *
   *-----------------------------------------------------------------*/

   L_acc = L_deposit_l( gbk1[index1][1] );
   L_accb = L_deposit_l( gbk2[index2][1] );
   L_gbk12 = L_add( L_acc, L_accb );                       /* Q13 */
   tmp = extract_l( L_shr( L_gbk12,1 ) );                  /* Q12 */
   L_acc = L_mult(tmp, gcode0);             /* Q[exp_gcode0+12+1] */

   L_acc = L_shl(L_acc, add( negate(exp_gcode0),(-12-1+1+16) ));
   *gain_cod = extract_h( L_acc );                          /* Q1 */

  /*----------------------------------------------*
   * update table of past quantized energies      *
   *----------------------------------------------*/
   Gain_update( past_qua_en, L_gbk12 );

   return;

}
コード例 #16
0
ファイル: postfilt.c プロジェクト: eager7/linux-kernel
void agc(
  Word16 *sig_in,   /* (i)     : postfilter input signal  */
  Word16 *sig_out,  /* (i/o)   : postfilter output signal */
  Word16 l_trm      /* (i)     : subframe size            */
)
{
#if 0 	
  static Word16 past_gain=4096;         /* past_gain = 1.0 (Q12) */
#endif  
  Word16 i, exp;
  Word16 gain_in, gain_out, g0, gain;                     /* Q12 */
  Word32 s;

  Word16 signal[L_SUBFR];

  /* calculate gain_out with exponent */

  for(i=0; i<l_trm; i++)
    signal[i] = shr(sig_out[i], 2);

  s = 0;
  for(i=0; i<l_trm; i++)
    s = L_mac(s, signal[i], signal[i]);

  if (s == 0) {
    pg729dec->ppost_filt->past_gain = 0;
    return;
  }
  exp = sub(norm_l(s), 1);
  if(exp>0)
  gain_out = round(L_shl(s, exp));
  else
  	gain_out = round(L_shr(s, abs_s(exp)));
  /* calculate gain_in with exponent */

  for(i=0; i<l_trm; i++)
    signal[i] = shr(sig_in[i], 2);

  s = 0;
  for(i=0; i<l_trm; i++)
    s = L_mac(s, signal[i], signal[i]);

  if (s == 0) {
    g0 = 0;
  }
  else {
    i = norm_l(s);
    if(i>=0)
    gain_in = round(L_shl(s, i));
    else
    	gain_in = round(L_shr(s, abs_s(i)));
    exp = sub(exp, i);

   /*---------------------------------------------------*
    *  g0(Q12) = (1-AGC_FAC) * sqrt(gain_in/gain_out);  *
    *---------------------------------------------------*/

    s = L_deposit_l(div_s(gain_out,gain_in));   /* Q15 */
    s = L_shl(s, 7);           /* s(Q22) = gain_out / gain_in */
    if(exp>0)
    s = L_shr(s, exp);         /* Q22, add exponent */
	else
		s = L_shl(s, abs_s(exp));

    /* i(Q12) = s(Q19) = 1 / sqrt(s(Q22)) */
    s = Inv_sqrt(s);           /* Q19 */
    i = round(L_shl(s,9));     /* Q12 */

    /* g0(Q12) = i(Q12) * (1-AGC_FAC)(Q15) */
    g0 = mult(i, AGC_FAC1);       /* Q12 */
  }

  /* compute gain(n) = AGC_FAC gain(n-1) + (1-AGC_FAC)gain_in/gain_out */
  /* sig_out(n) = gain(n) sig_out(n)                                   */

  gain = pg729dec->ppost_filt->past_gain;
  for(i=0; i<l_trm; i++) {
    gain = mult(gain, AGC_FAC);
    gain = add(gain, g0);
    sig_out[i] = extract_h(L_shl(L_mult(sig_out[i], gain), 3));
  }
  pg729dec->ppost_filt->past_gain = gain;

  return;
}
コード例 #17
0
ファイル: Util_cng.c プロジェクト: afxabc/resiprocate
/*
**
** Function:           Qua_SidGain()
**
** Description:        Quantization of Sid gain
**                     Pseudo-log quantizer in 3 segments
**                     1st segment : length = 16, resolution = 2
**                     2nd segment : length = 16, resolution = 4
**                     3rd segment : length = 32, resolution = 8
**                     quantizes a sum of energies
**
** Links to text:
**
** Arguments:
**
**  Word16 *Ener        table of the energies
**  Word16 *shEner      corresponding scaling factors
**  Word16 nq           if nq >= 1 : quantization of nq energies
**                      for SID gain calculation in function Cod_Cng()
**                      if nq = 0 : in function Comp_Info(),
**                      quantization of saved estimated excitation energy
**
** Outputs:             None
**
**
** Return value:       index of quantized energy
**
*/
Word16 Qua_SidGain(Word16 *Ener, Word16 *shEner, Word16 nq)
{
    Word16 temp, iseg, iseg_p1;
    Word16 j, j2, k, exp;
    Word32 L_x, L_y;
    Word16 sh1;
    Word32 L_acc;
    int i;

    if(nq == 0) {
         /* Quantize energy saved for frame erasure case                */
         /* L_x = 2 x average_ener                                      */
         temp = shl(*shEner, 1);
         temp = sub(16, temp);
         L_acc = L_deposit_l(*Ener);
         L_acc = L_shl(L_acc, temp); /* may overflow, and >> if temp < 0 */
         L_x = L_mls(L_acc, fact[0]);
    }

    else {

 /*
  * Compute weighted average of energies
  * Ener[i] = enerR[i] x 2**(shEner[i]-14)
  * L_x = k[nq] x SUM(i=0->nq-1) enerR[i]
  * with k[nq] =  2 x fact_mul x fact_mul / nq x Frame
  */
         sh1 = shEner[0];
         for(i=1; i<nq; i++) {
             if(shEner[i] < sh1) sh1 = shEner[i];
         }
         for(i=0, L_x=0L; i<nq; i++) {
             temp = sub(shEner[i], sh1);
             temp = shr(Ener[i], temp);
             temp = mult_r(fact[nq], temp);
             L_x = L_add(L_x, L_deposit_l(temp));
         }
         temp = sub(15, sh1);
         L_x = L_shl(L_x, temp);
    }

    /* Quantize L_x */
    if(L_x >= L_bseg[2]) return(63);

    /* Compute segment number iseg */
    if(L_x >= L_bseg[1]) {
        iseg = 2;
        exp = 4;
    }
    else {
        exp  = 3;
        if(L_x >= L_bseg[0]) iseg = 1;
        else iseg = 0;
    }

    iseg_p1 = add(iseg,1);
    j = shl(1, exp);
    k = shr(j,1);

    /* Binary search in segment iseg */
    for(i=0; i<exp; i++) {
        temp = add(base[iseg], shl(j, iseg_p1));
//        L_y = L_mult(temp, temp);
		L_MULT(temp, temp, L_y);
        if(L_x >= L_y) j = add(j, k);
        else j = sub(j, k);
        k = shr(k, 1);
    }

    temp = add(base[iseg], shl(j, iseg_p1));
    L_y = L_mult(temp, temp);
    L_y = L_sub(L_y, L_x);
    if(L_y <= 0L) {
        j2    = add(j, 1);
        temp  = add(base[iseg], shl(j2, iseg_p1));
        L_acc = L_mult(temp, temp);
        L_acc = L_sub(L_x, L_acc);
        if(L_y > L_acc) temp = add(shl(iseg,4), j);
        else temp = add(shl(iseg,4), j2);
    }
    else {
        j2    = sub(j, 1);
        temp  = add(base[iseg], shl(j2, iseg_p1));
        L_acc = L_mult(temp, temp);
        L_acc = L_sub(L_x, L_acc);
        if(L_y < L_acc) temp = add(shl(iseg,4), j);
        else temp = add(shl(iseg,4), j2);
    }
    return(temp);
}
コード例 #18
0
ファイル: encoder.c プロジェクト: avble/natClientEx
/***************************************************************************
 Function:    vector_huffman

 Syntax:      Word16 vector_huffman(Word16  category,     
                                    Word16  power_index,  
                                    Word16  *raw_mlt_ptr,  
                                    UWord32 *word_ptr)     
                                              
              inputs:     Word16  category
                          Word16  power_index
                          Word16  *raw_mlt_ptr
             
              outputs:    number_of_region_bits
                          *word_ptr
                                      

 Description: Huffman encoding for each region based on category and power_index  

 WMOPS:     7kHz |    24kbit    |     32kbit
          -------|--------------|----------------
            AVG  |    0.03      |     0.03
          -------|--------------|----------------  
            MAX  |    0.04      |     0.04
          -------|--------------|---------------- 

           14kHz |    24kbit    |     32kbit     |     48kbit
          -------|--------------|----------------|----------------
            AVG  |    0.03      |     0.03       |     0.03
          -------|--------------|----------------|----------------
            MAX  |    0.04      |     0.04       |     0.04
          -------|--------------|----------------|----------------

***************************************************************************/
Word16 vector_huffman(Word16 category,
                      Word16 power_index,
                      Word16 *raw_mlt_ptr,
                      UWord32 *word_ptr)
{
 

    Word16  inv_of_step_size_times_std_dev;
    Word16  j,n;
    Word16  k;
    Word16  number_of_region_bits;
    Word16  number_of_non_zero;
    Word16  vec_dim;
    Word16  num_vecs;
    Word16  kmax, kmax_plus_one;
    Word16  index,signs_index;
    Word16  *bitcount_table_ptr;
    UWord16 *code_table_ptr;
    Word32  code_bits;
    Word16  number_of_code_bits;
    UWord32 current_word;
    Word16  current_word_bits_free;
    
    Word32 acca;
    Word32 accb;
    Word16 temp;

    Word16 mytemp;			 /* new variable in Release 1.2 */
    Word16 myacca;			 /* new variable in Release 1.2 */


    /* initialize variables */
    vec_dim = vector_dimension[category];
    move16();

    num_vecs = number_of_vectors[category];
    move16();

    kmax = max_bin[category];
    move16();

    kmax_plus_one = add(kmax,1);
    move16();

    current_word = 0L;
    move16();

    current_word_bits_free = 32;
    move16();

    number_of_region_bits = 0;
    move16();

    /* set up table pointers */
    bitcount_table_ptr = (Word16 *)table_of_bitcount_tables[category];
    code_table_ptr = (UWord16 *) table_of_code_tables[category];

    /* compute inverse of step size * standard deviation */
    acca = L_mult(step_size_inverse_table[category],standard_deviation_inverse_table[power_index]);
    acca = L_shr_nocheck(acca,1);
    acca = L_add(acca,4096);
    acca = L_shr_nocheck(acca,13);

	/*
	 *  The next two lines are new to Release 1.2 
	 */
     
	mytemp = (Word16)(acca & 0x3);
    acca = L_shr_nocheck(acca,2);

    inv_of_step_size_times_std_dev = extract_l(acca);


    for (n=0; n<num_vecs; n++)
    {
        index = 0;
        move16();
        
        signs_index = 0;
        move16();
        
        number_of_non_zero = 0;
        move16();
        
        for (j=0; j<vec_dim; j++)
        {
            k = abs_s(*raw_mlt_ptr);
            
            acca = L_mult(k,inv_of_step_size_times_std_dev);
            acca = L_shr_nocheck(acca,1);
		    
			/*
			 *  The next four lines are new to Release 1.2
			 */

			myacca = (Word16)L_mult(k,mytemp);
			myacca = (Word16)L_shr_nocheck(myacca,1);
			myacca = (Word16)L_add(myacca,int_dead_zone_low_bits[category]);
			myacca = (Word16)L_shr_nocheck(myacca,2);

            acca = L_add(acca,int_dead_zone[category]);

			/*
			 *  The next two lines are new to Release 1.2
			 */

			acca = L_add(acca,myacca);
			acca = L_shr_nocheck(acca,13);

            k = extract_l(acca);

            test();
            if (k != 0)
            {
                number_of_non_zero = add(number_of_non_zero,1);
                signs_index = shl_nocheck(signs_index,1);
                
                test();
                if (*raw_mlt_ptr > 0)
                {
                    signs_index = add(signs_index,1);
                }
                
                temp = sub(k,kmax);
                test();
                if (temp > 0)
                {
                    k = kmax;
                    move16();
                }
            }
            acca = L_shr_nocheck(L_mult(index,(kmax_plus_one)),1);
            index = extract_l(acca);
            index = add(index,k);
            raw_mlt_ptr++;
        }

        code_bits = *(code_table_ptr+index);
        number_of_code_bits = add((*(bitcount_table_ptr+index)),number_of_non_zero);
        number_of_region_bits = add(number_of_region_bits,number_of_code_bits);

        acca = code_bits << number_of_non_zero;
        accb = L_deposit_l(signs_index);
        acca = L_add(acca,accb);
        code_bits = acca;
        move32();

        /* msb of codebits is transmitted first. */
        j = sub(current_word_bits_free,number_of_code_bits);
        test();
        if (j >= 0)
        {
            test();
            acca = code_bits << j;
            current_word = L_add(current_word,acca);
            current_word_bits_free = j;
            move16();
        }
        else
        {
            j = negate(j);
            acca = L_shr_nocheck(code_bits,j);
            current_word = L_add(current_word,acca);
            
            *word_ptr++ = current_word;
            move16();

            current_word_bits_free = sub(32,j);
            test();
            current_word = code_bits << current_word_bits_free;
        }
    }

    *word_ptr++ = current_word;
    move16();

    return (number_of_region_bits);
}
コード例 #19
0
ファイル: dec_gain.c プロジェクト: DanielGit/Intrisit8000
/*************************************************************************
 *
 *   FUNCTION:  Dec_gain()
 *
 *   PURPOSE: Decode the pitch and codebook gains
 *
 ************************************************************************/
void Dec_gain(
    gc_predState *pred_state, /* i/o: MA predictor state           */
    enum Mode mode,           /* i  : AMR mode                     */
    Word16 index,             /* i  : index of quantization.       */
    Word16 code[],            /* i  : Innovative vector.           */
    Word16 evenSubfr,         /* i  : Flag for even subframes      */     
    Word16 * gain_pit,        /* o  : Pitch gain.                  */
    Word16 * gain_cod         /* o  : Code gain.                   */
)
{
    const Word16 *p;
    Word16 frac, gcode0, exp, qua_ener, qua_ener_MR122;
    Word16 g_code;
    Word32 L_tmp;
    
    /* Read the quantized gains (table depends on mode) */
    index = shl (index, 2);
    
    test(); test(); test();
    if (    sub (mode, MR102) == 0
         || sub (mode, MR74) == 0
         || sub (mode, MR67) == 0)
    {
        p = &table_gain_highrates[index];                  move16 ();
        
        *gain_pit = *p++;                                  move16 ();
        g_code = *p++;                                     move16 ();
        qua_ener_MR122 = *p++;                             move16 ();
        qua_ener = *p;                                     move16 ();
    }
    else
    {
        test();
        if (sub (mode, MR475) == 0)
        {
            index = add (index, shl(sub(1, evenSubfr), 1));
            p = &table_gain_MR475[index];                  move16 ();
            
            *gain_pit = *p++;                              move16 ();
            g_code = *p++;                                 move16 ();
            
            /*---------------------------------------------------------*
             *  calculate predictor update values (not stored in 4.75  *
             *  quantizer table to save space):                        *
             *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  *
             *                                                         *
             *   qua_ener       = log2(g)                              *
             *   qua_ener_MR122 = 20*log10(g)                          *
             *---------------------------------------------------------*/

            /* Log2(x Q12) = log2(x) + 12 */
            Log2 (L_deposit_l (g_code), &exp, &frac); 
            exp = sub(exp, 12);
    
            qua_ener_MR122 = add (shr_r (frac, 5), shl (exp, 10));
    
            /* 24660 Q12 ~= 6.0206 = 20*log10(2) */
            L_tmp = Mpy_32_16(exp, frac, 24660);
            qua_ener = round (L_shl (L_tmp, 13)); /* Q12 * Q0 = Q13 -> Q10 */
        }
        else
        {
            p = &table_gain_lowrates[index];                move16 ();
            
            *gain_pit = *p++;                               move16 ();
            g_code = *p++;                                  move16 ();
            qua_ener_MR122 = *p++;                          move16 ();
            qua_ener = *p;                                  move16 ();
        }
    }
    
    /*-------------------------------------------------------------------*
     *  predict codebook gain                                            *
     *  ~~~~~~~~~~~~~~~~~~~~~                                            *
     *  gc0     = Pow2(int(d)+frac(d))                                   *
     *          = 2^exp + 2^frac                                         *
     *                                                                   *
     *  gcode0 (Q14) = 2^14*2^frac = gc0 * 2^(14-exp)                    *
     *-------------------------------------------------------------------*/

    gc_pred(pred_state, mode, code, &exp, &frac, NULL, NULL);

    gcode0 = extract_l(Pow2(14, frac));

    /*------------------------------------------------------------------*
     *  read quantized gains, update table of past quantized energies   *
     *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   *
     *  st->past_qua_en(Q10) = 20 * Log10(g_fac) / constant             *
     *                       = Log2(g_fac)                              *
     *                       = qua_ener                                 *
     *                                           constant = 20*Log10(2) *
     *------------------------------------------------------------------*/

    L_tmp = L_mult(g_code, gcode0);
    L_tmp = L_shr(L_tmp, sub(10, exp));
    *gain_cod = extract_h(L_tmp);

    /* update table of past quantized energies */

    gc_pred_update(pred_state, qua_ener_MR122, qua_ener);

    return;
}
コード例 #20
0
Word32 quant_4p_4N(                        /* (o) return 4*N bits             */
		Word16 pos[],                         /* (i) position of the pulse 1..4  */
		Word16 N)                             /* (i) number of bits for position */
{
	Word16 nb_pos, mask, n_1, tmp;
	Word16 posA[4], posB[4];
	Word32 i, j, k, index;

	n_1 = (Word16) (N - 1);
	nb_pos = (1 << n_1);                  /* nb_pos = (1<<n_1); */
	mask = vo_sub((1 << N), 1);              /* mask = ((1<<N)-1); */

	i = 0;
	j = 0;
	for (k = 0; k < 4; k++)
	{
		if ((pos[k] & nb_pos) == 0)
		{
			posA[i++] = pos[k];
		} else
		{
			posB[j++] = pos[k];
		}
	}

	switch (i)
	{
		case 0:
			tmp = vo_sub((N << 2), 3);           /* index = 1 << ((4*N)-3); */
			index = (1L << tmp);
			/* index += quant_4p_4N1(posB[0], posB[1], posB[2], posB[3], n_1); */
			index = vo_L_add(index, quant_4p_4N1(posB[0], posB[1], posB[2], posB[3], n_1));
			break;
		case 1:
			/* index = quant_1p_N1(posA[0], n_1) << ((3*n_1)+1); */
			tmp = add1((Word16)((vo_L_mult(3, n_1) >> 1)), 1);
			index = L_shl(quant_1p_N1(posA[0], n_1), tmp);
			/* index += quant_3p_3N1(posB[0], posB[1], posB[2], n_1); */
			index = vo_L_add(index, quant_3p_3N1(posB[0], posB[1], posB[2], n_1));
			break;
		case 2:
			tmp = ((n_1 << 1) + 1);         /* index = quant_2p_2N1(posA[0], posA[1], n_1) << ((2*n_1)+1); */
			index = L_shl(quant_2p_2N1(posA[0], posA[1], n_1), tmp);
			/* index += quant_2p_2N1(posB[0], posB[1], n_1); */
			index = vo_L_add(index, quant_2p_2N1(posB[0], posB[1], n_1));
			break;
		case 3:
			/* index = quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << N; */
			index = L_shl(quant_3p_3N1(posA[0], posA[1], posA[2], n_1), N);
			index = vo_L_add(index, quant_1p_N1(posB[0], n_1));        /* index += quant_1p_N1(posB[0], n_1); */
			break;
		case 4:
			index = quant_4p_4N1(posA[0], posA[1], posA[2], posA[3], n_1);
			break;
		default:
			index = 0;
			fprintf(stderr, "Error in function quant_4p_4N\n");
	}
	tmp = ((N << 2) - 2);               /* index += (i & 3) << ((4*N)-2); */
	index = vo_L_add(index, L_shl((L_deposit_l(i) & (3L)), tmp));

	return (index);
}
コード例 #21
0
ファイル: getext1k.c プロジェクト: arulk77/gpu.evrc
void GetExc800bps(
		/* 1 */ short *output,
		/* 2 */ short *best,
		/* 3 */ short scale,
		/* 4 */ short *input,
		/* 5 */ short length,
		/* 6 */ short flag,
		/* 7 */ short n)
{
	short k, j;
	short D;
	long tmp;
	long ltmp;
	short stmp;
	short *ptr;
	long sum, lscale;
	short ssum, sscale;
	static short Seed = 1234;
	static short Sum[NoOfSubFrames];
	short shft_scale;
	short shft_sum;
	short stemp1;

	if (!flag)
		Seed = 1234;

/*
 * sum is an integer value, not a fractional value.
 */
	/* Get energy of next sub frame */
	for (k = 0, sum = 0; k < length; k++)
	{
		sum = L_add(sum, L_deposit_l(abs_s(input[k])));
	}
	sum = L_shl(sum, 1);	/* correct for scaling */

	if (sum < SubFrameSize)
	{
		sum = fnLog10(L_deposit_h(scale));
		sum = L_negate(L_add(L_shl(sum, 3), 484942745));	/* add (log8)/4 = 484842745 (VALUE ADJUSTED TO BETTER MATCH FLOAT MODEL) */
	}
	else
	{
		lscale = L_mult(SubFrameSize, scale);
		shft_scale = norm_l(lscale); 
		sscale = round(L_shl(lscale, shft_scale)); 
		shft_sum = norm_l(sum) - 1; 
		ssum = round(L_shl(sum, shft_sum));

		/*
		 * The following divide/L_shl produced sum scaled down by 64.
		 * sum can have a max value of 40.xx in the sample data.
		 */
		/* sum = L_shl(L_divide(sum, lscale), (shft_scale + 7 - shft_sum)); */
		sum = L_deposit_h(shl(divide_s(ssum, sscale), (shft_scale - shft_sum)));
		/* sum = fnLog10(sum); */
		sum = L_add(fnLog10(sum), 141412467);   /* add log (2^7) scaled down by 32 */
		sum = L_add(L_shl(sum, 3), 969485490);	/* add (log8)/2 = 969685490 (VALUE ADJUSTED TO BETTER MATCH FLOAT MODEL) */
	}

	/*
	 * Sum scaled down by 4.
	 */
	Sum[n] = round(sum);

	/* Quantize if last frame */
	if (n == NoOfSubFrames - 1)
	{

		/* Quantize to 8 bits */
		for (k = 0, sum = 2147483647, ptr = Logqtbl; k < 256; k++)
		{
			for (j = 0, tmp = 0; j < 3; j++)
			{
				/*
				 * Sum and Logqtbl both scaled down by 4.
				 * Change Logqtbl to short if Lw not required. 
				 */
				D = sub(Sum[j], (*ptr++));
				tmp = L_mac(tmp, D, D);
			}

			if (tmp < sum)
			{
				ltmp = sum;
				sum = tmp;
				*best = k;
			}
		}

		for (j = 0; j < 3; j++)
		{
			Sum[j] = Powqtbl[*best * 3 + j];
		}

		/* Get excitation */
		j = FrameSize - ACBMemSize;
		for (k = 0; k < FrameSize - 1; k++)
		{
			if (k >= j)
			{
				stmp = e_ran_g(&Seed);
				stemp1 = k / (length - 1);
				output[k - j] = round(L_shr(L_mult(stmp, Sum[stemp1]), 5));
			}
		}
		stmp = e_ran_g(&Seed);
		output[k - j] = round(L_shr(L_mult(stmp, Sum[2]), 5));	/* last excitation */

	}
}
コード例 #22
0
ファイル: agc.c プロジェクト: NearZhxiAo/3730
/*
**************************************************************************
*
*  Function    : agc
*  Purpose     : Scales the postfilter output on a subframe basis
*
**************************************************************************
*/
int agc (
    agcState *st,      /* i/o : agc state                        */
    Word16 *sig_in,    /* i   : postfilter input signal  (l_trm) */
    Word16 *sig_out,   /* i/o : postfilter output signal (l_trm) */
    Word16 agc_fac,    /* i   : AGC factor                       */
    Word16 l_trm       /* i   : subframe size                    */
)
{
    Word16 i, exp;
    Word16 gain_in, gain_out, g0, gain;
    Word32 s;
            
    /* calculate gain_out with exponent */
    s = energy_new(sig_out, l_trm);  /* function result */
        
     
    if (s == 0)
    {
        st->past_gain = 0;           
        return 0;
    }
    exp = sub (norm_l (s), 1);
    gain_out = round (L_shl (s, exp));

    /* calculate gain_in with exponent */
    s = energy_new(sig_in, l_trm);    /* function result */
    
     
    if (s == 0)
    {
        g0 = 0;                  
    }
    else
    {
        i = norm_l (s);
        gain_in = round (L_shl (s, i));
        exp = sub (exp, i);

        /*---------------------------------------------------*
         *  g0 = (1-agc_fac) * sqrt(gain_in/gain_out);       *
         *---------------------------------------------------*/

        s = L_deposit_l (div_s (gain_out, gain_in));
        s = L_shl (s, 7);       /* s = gain_out / gain_in */
        s = L_shr (s, exp);     /* add exponent */

        s = Inv_sqrt (s);  /* function result */
        i = round (L_shl (s, 9));

        /* g0 = i * (1-agc_fac) */
        g0 = mult (i, sub (32767, agc_fac));
    }

    /* compute gain[n] = agc_fac * gain[n-1]
                        + (1-agc_fac) * sqrt(gain_in/gain_out) */
    /* sig_out[n] = gain[n] * sig_out[n]                        */

    gain = st->past_gain;            

    for (i = 0; i < l_trm; i++)
    {
        gain = mult (gain, agc_fac);
        gain = add (gain, g0);
        sig_out[i] = extract_h (L_shl (L_mult (sig_out[i], gain), 3));
                                 
    }

    st->past_gain = gain;            

    return 0;
}
コード例 #23
0
ファイル: encoder.c プロジェクト: avble/natClientEx
/***************************************************************************
 Function:    bits_to_words

 Syntax:      bits_to_words(UWord32 *region_mlt_bits,              
                            Word16  *region_mlt_bit_counts,                                                             
                            Word16  *drp_num_bits,                                                                      
                            UWord16 *drp_code_bits,                                                                     
                            Word16  *out_words,                                                                         
                            Word16  categorization_control,                                                                         
                            Word16  number_of_regions,
                            Word16  num_categorization_control_bits,
                            Word16  number_of_bits_per_frame)                                                           
                                                                   
                                                                   
 Description: Stuffs the bits into words for output

 WMOPS:     7kHz |    24kbit    |      32kbit
          -------|--------------|----------------
            AVG  |    0.09      |     0.12
          -------|--------------|----------------  
            MAX  |    0.10      |     0.13
          -------|--------------|---------------- 
          
           14kHz |    24kbit    |     32kbit     |     48kbit
          -------|--------------|----------------|----------------
            AVG  |    0.12      |     0.15       |     0.19
          -------|--------------|----------------|----------------
            MAX  |    0.14      |     0.17       |     0.21
          -------|--------------|----------------|----------------

***************************************************************************/
void bits_to_words(UWord32 *region_mlt_bits,
                   Word16  *region_mlt_bit_counts,
                   Word16  *drp_num_bits,
                   UWord16 *drp_code_bits,
                   Word16  *out_words,
                   Word16  categorization_control,
                   Word16  number_of_regions,
                   Word16  num_categorization_control_bits,
                   Word16  number_of_bits_per_frame)
{
    Word16  out_word_index = 0;
    Word16  j;
    Word16  region;
    Word16  out_word;
    Word16  region_bit_count;
    Word16  current_word_bits_left;
    UWord16 slice;
    Word16  out_word_bits_free = 16;
    UWord32 *in_word_ptr;
    UWord32 current_word;
    
    Word32  acca = 0;
    Word32  accb;
    Word16  temp;

    /* First set up the categorization control bits to look like one more set of region power bits. */
    out_word = 0;
    move16();

    drp_num_bits[number_of_regions] = num_categorization_control_bits;
    move16();
    
    drp_code_bits[number_of_regions] = (UWord16)categorization_control;
    move16();

    /* These code bits are right justified. */
    for (region=0; region <= number_of_regions; region++)
    {
        current_word_bits_left = drp_num_bits[region];
        move16();
        
        current_word = (UWord32)drp_code_bits[region];
        move16();
        
        j = sub(current_word_bits_left,out_word_bits_free);

        test();
        if (j >= 0)
        {
            temp = extract_l(L_shr_nocheck(current_word,j));
            out_word = add(out_word,temp);

            out_words[out_word_index++] = out_word;
            move16();
            
            out_word_bits_free = 16;
            move16();
            
            out_word_bits_free = sub(out_word_bits_free,j);
            
            acca = (current_word << out_word_bits_free);
            out_word = extract_l(acca);
        }
        else
        {
            j = negate(j);

            acca = (current_word << j);
            accb = L_deposit_l(out_word);
            acca = L_add(accb,acca);
            out_word = extract_l(acca);
            
            out_word_bits_free = sub(out_word_bits_free,current_word_bits_left);
        }
    }

    /* These code bits are left justified. */
    
    for (region=0;region<number_of_regions; region++)
    {
        accb = L_deposit_l(out_word_index);
        accb = L_shl_nocheck(accb,4);
        accb = L_sub(accb,number_of_bits_per_frame);
        test();
        if(accb < 0)        
        {
            temp = shl_nocheck(region,2);
            in_word_ptr = &region_mlt_bits[temp];
            region_bit_count = region_mlt_bit_counts[region];
            move16();

            temp = sub(32,region_bit_count);
            test();
            if(temp > 0)
                current_word_bits_left = region_bit_count;
            else
                current_word_bits_left = 32;

            current_word = *in_word_ptr++;
    
            acca = L_deposit_l(out_word_index);
            acca = L_shl_nocheck(acca,4);
            acca = L_sub(acca,number_of_bits_per_frame);
            
            /* from while loop */
            test();
            test();
            logic16(); 
            while ((region_bit_count > 0) && (acca < 0))
            {
                /* from while loop */
                test();
                test();
                logic16(); 
                
                temp = sub(current_word_bits_left,out_word_bits_free);
                test();
                if (temp >= 0)
                {
                    temp = sub(32,out_word_bits_free);
                    accb = LU_shr(current_word,temp);
                    slice = (UWord16)extract_l(accb);
                    
                    out_word = add(out_word,slice);
    
                    test();
                    current_word <<= out_word_bits_free;

                    current_word_bits_left = sub(current_word_bits_left,out_word_bits_free);
                    out_words[out_word_index++] = extract_l(out_word);
                    move16();

                    out_word = 0;
                    move16();

                    out_word_bits_free = 16;
                    move16();
                }
                else
                {
                    temp = sub(32,current_word_bits_left);
                    accb = LU_shr(current_word,temp);
                    slice = (UWord16)extract_l(accb);
                    
                    temp = sub(out_word_bits_free,current_word_bits_left);
                    test();
                    accb = slice << temp;
                    acca = L_deposit_l(out_word);
                    acca = L_add(acca,accb);
                    out_word = extract_l(acca);
                    out_word_bits_free = sub(out_word_bits_free,current_word_bits_left);
                    
                    current_word_bits_left = 0;
                    move16();
                }
    
                test();
                if (current_word_bits_left == 0)
                {
                    current_word = *in_word_ptr++;
                    region_bit_count = sub(region_bit_count,32);
                    
                    /* current_word_bits_left = MIN(32,region_bit_count); */
                    temp = sub(32,region_bit_count);
                    test();
                    if(temp > 0)
                        current_word_bits_left = region_bit_count;
                    else
                        current_word_bits_left = 32;
                    
                }
                acca = L_deposit_l(out_word_index);
                acca = L_shl_nocheck(acca,4);
                acca = L_sub(acca,number_of_bits_per_frame);
            }
            accb = L_deposit_l(out_word_index);
            accb = L_shl_nocheck(accb,4);
            accb = L_sub(accb,number_of_bits_per_frame);
        }
    }

    /* Fill out with 1's. */

    test();
    while (acca < 0)
    {
        test();
        current_word = 0x0000ffff;
        move32();

        temp = sub(16,out_word_bits_free);
        acca = LU_shr(current_word,temp);
        slice = (UWord16)extract_l(acca);

        out_word = add(out_word,slice);
        out_words[out_word_index++] = out_word;
        move16();

        out_word = 0;
        move16();
        
        out_word_bits_free = 16;
        move16();
        
        acca = L_deposit_l(out_word_index);
        acca = L_shl_nocheck(acca,4);
        acca = L_sub(acca,number_of_bits_per_frame);
    }
}
コード例 #24
0
//=============================================================================
//函数名称:Dec_gain
//函数功能:解码的音调和码书增益
//=============================================================================
void Dec_gain(
    gc_predState *pred_state, /* i/o: MA predictor state           */
    enum Mode mode,           /* i  : AMR mode                     */
    Word16 index,             /* i  : index of quantization.       */
    Word16 code[],            /* i  : Innovative vector.           */
    Word16 evenSubfr,         /* i  : Flag for even subframes      */
    Word16 * gain_pit,        /* o  : Pitch gain.                  */
    Word16 * gain_cod,        /* o  : Code gain.                   */
    Flag   * pOverflow
)
{
    const Word16 *p;
    Word16 frac;
    Word16 gcode0;
    Word16 exp;
    Word16 qua_ener;
    Word16 qua_ener_MR122;
    Word16 g_code;
    Word32 L_tmp;
    Word16 temp1;
    Word16 temp2;

    /* Read the quantized gains (table depends on mode) */
    //阅读量化收益(表取决于模式)
    index = shl(index, 2, pOverflow);

    if (mode == MR102 || mode == MR74 || mode == MR67)
    {
        p = &table_gain_highrates[index];

        *gain_pit = *p++;
        g_code = *p++;
        qua_ener_MR122 = *p++;
        qua_ener = *p;
    }
    else
    {
        if (mode == MR475)
        {
            index += (1 ^ evenSubfr) << 1; /* evenSubfr is 0 or 1 */

            if (index > (MR475_VQ_SIZE*4 - 2))
            {
                index = (MR475_VQ_SIZE * 4 - 2); /* avoid possible buffer overflow */
            }

            p = &table_gain_MR475[index];

            *gain_pit = *p++;
            g_code = *p++;

            /*---------------------------------------------------------*
             *  calculate predictor update values (not stored in 4.75  *
             *  quantizer table to save space):                        *
             *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  *
             *                                                         *
             *   qua_ener       = log2(g)                              *
             *   qua_ener_MR122 = 20*log10(g)                          *
             *---------------------------------------------------------*/
            //计算预测更新值(不存储在4.75量化表,以节省空间)

            /* Log2(x Q12) = log2(x) + 12 */
            temp1 = (Word16) L_deposit_l(g_code);
            Log2(temp1, &exp, &frac, pOverflow);
            exp = sub(exp, 12, pOverflow);

            temp1 = shr_r(frac, 5, pOverflow);
            temp2 = shl(exp, 10, pOverflow);
            qua_ener_MR122 = add(temp1, temp2, pOverflow);

            /* 24660 Q12 ~= 6.0206 = 20*log10(2) */
            L_tmp = Mpy_32_16(exp, frac, 24660, pOverflow);
            L_tmp = L_shl(L_tmp, 13, pOverflow);
            qua_ener = pv_round(L_tmp, pOverflow);
            /* Q12 * Q0 = Q13 -> Q10 */
        }
        else
        {
            p = &table_gain_lowrates[index];

            *gain_pit = *p++;
            g_code = *p++;
            qua_ener_MR122 = *p++;
            qua_ener = *p;
        }
    }

    /*-------------------------------------------------------------------*
     *  predict codebook gain                                            *
     *  ~~~~~~~~~~~~~~~~~~~~~                                            *
     *  gc0     = Pow2(int(d)+frac(d))                                   *
     *          = 2^exp + 2^frac                                         *
     *                                                                   *
     *  gcode0 (Q14) = 2^14*2^frac = gc0 * 2^(14-exp)                    *
     *-------------------------------------------------------------------*/

    gc_pred(pred_state, mode, code, &exp, &frac, NULL, NULL, pOverflow);

    gcode0 = (Word16) Pow2(14, frac, pOverflow);

    /*------------------------------------------------------------------*
     *  read quantized gains, update table of past quantized energies   *
     *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   *
     *  st->past_qua_en(Q10) = 20 * Log10(g_fac) / constant             *
     *                       = Log2(g_fac)                              *
     *                       = qua_ener                                 *
     *                                           constant = 20*Log10(2) *
     *------------------------------------------------------------------*/

    L_tmp = L_mult(g_code, gcode0, pOverflow);
    temp1 = sub(10, exp, pOverflow);
    L_tmp = L_shr(L_tmp, temp1, pOverflow);
    *gain_cod = extract_h(L_tmp);

    /* update table of past quantized energies */
    //过去的量化能量表更新

    gc_pred_update(pred_state, qua_ener_MR122, qua_ener);

    return;
}
コード例 #25
0
ファイル: postfilt.c プロジェクト: StevenLOL/g729
void agc(
  int16_t *sig_in,   /* (i)     : postfilter input signal  */
  int16_t *sig_out,  /* (i/o)   : postfilter output signal */
  int16_t l_trm      /* (i)     : subframe size            */
)
{
  static int16_t past_gain=4096;         /* past_gain = 1.0 (Q12) */
  int16_t i, exp;
  int16_t gain_in, gain_out, g0, gain;                     /* Q12 */
  int32_t s;

  int16_t signal[L_SUBFR];

  /* calculate gain_out with exponent */

  for(i=0; i<l_trm; i++)
    signal[i] = shr(sig_out[i], 2);

  s = 0;
  for(i=0; i<l_trm; i++)
    s = L_mac(s, signal[i], signal[i]);

  if (s == 0) {
    past_gain = 0;
    return;
  }
  exp = sub(norm_l(s), 1);
  gain_out = _round(L_shl(s, exp));

  /* calculate gain_in with exponent */

  for(i=0; i<l_trm; i++)
    signal[i] = shr(sig_in[i], 2);

  s = 0;
  for(i=0; i<l_trm; i++)
    s = L_mac(s, signal[i], signal[i]);

  if (s == 0) {
    g0 = 0;
  }
  else {
    i = norm_l(s);
    gain_in = _round(L_shl(s, i));
    exp = sub(exp, i);

   /*---------------------------------------------------*
    *  g0(Q12) = (1-AGC_FAC) * sqrt(gain_in/gain_out);  *
    *---------------------------------------------------*/

    s = L_deposit_l(div_s(gain_out,gain_in));   /* Q15 */
    s = L_shl(s, 7);           /* s(Q22) = gain_out / gain_in */
    s = L_shr(s, exp);         /* Q22, add exponent */

    /* i(Q12) = s(Q19) = 1 / sqrt(s(Q22)) */
    s = Inv_sqrt(s);           /* Q19 */
    i = _round(L_shl(s,9));     /* Q12 */

    /* g0(Q12) = i(Q12) * (1-AGC_FAC)(Q15) */
    g0 = mult(i, AGC_FAC1);       /* Q12 */
  }

  /* compute gain(n) = AGC_FAC gain(n-1) + (1-AGC_FAC)gain_in/gain_out */
  /* sig_out(n) = gain(n) sig_out(n)                                   */

  gain = past_gain;
  for(i=0; i<l_trm; i++) {
    gain = mult(gain, AGC_FAC);
    gain = add(gain, g0);
    sig_out[i] = extract_h(L_shl(L_mult(sig_out[i], gain), 3));
  }
  past_gain = gain;

  return;
}
コード例 #26
0
ファイル: qua_gain.c プロジェクト: 2831942318/siphon
/*---------------------------------------------------------------------------*
 * Function Gbk_presel                                                       *
 * ~~~~~~~~~~~~~~~~~~~                                                       *
 *   - presearch for gain codebook -                                         *
 *---------------------------------------------------------------------------*/
static void Gbk_presel(
   Word16 best_gain[],     /* (i) [0] Q9 : unquantized pitch gain     */
                           /* (i) [1] Q2 : unquantized code gain      */
   Word16 *cand1,          /* (o)    : index of best 1st stage vector */
   Word16 *cand2,          /* (o)    : index of best 2nd stage vector */
   Word16 gcode0           /* (i) Q4 : presearch for gain codebook    */
)
{
   Word16    acc_h;
   Word16    sft_x,sft_y;
   Word32    L_acc,L_preg,L_cfbg,L_tmp,L_tmp_x,L_tmp_y;
   Word32 L_temp;

 /*--------------------------------------------------------------------------*
   x = (best_gain[1]-(coef[0][0]*best_gain[0]+coef[1][1])*gcode0) * inv_coef;
  *--------------------------------------------------------------------------*/
   L_cfbg = L_mult( coef[0][0], best_gain[0] );        /* L_cfbg:Q20 -> !!y */
   L_acc = L_shr( L_coef[1][1], 15 );                  /* L_acc:Q20     */
   L_acc = L_add( L_cfbg , L_acc );
   acc_h = extract_h( L_acc );                         /* acc_h:Q4      */
   L_preg = L_mult( acc_h, gcode0 );                   /* L_preg:Q9     */
   L_acc = L_shl( L_deposit_l( best_gain[1] ), 7 );    /* L_acc:Q9      */
   L_acc = L_sub( L_acc, L_preg );
   acc_h = extract_h( L_shl( L_acc,2 ) );              /* L_acc_h:Q[-5] */
   L_tmp_x = L_mult( acc_h, INV_COEF );                /* L_tmp_x:Q15   */

 /*--------------------------------------------------------------------------*
   y = (coef[1][0]*(-coef[0][1]+best_gain[0]*coef[0][0])*gcode0
                                      -coef[0][0]*best_gain[1]) * inv_coef;
  *--------------------------------------------------------------------------*/
   L_acc = L_shr( L_coef[0][1], 10 );                  /* L_acc:Q20   */
   L_acc = L_sub( L_cfbg, L_acc );                     /* !!x -> L_cfbg:Q20 */
   acc_h = extract_h( L_acc );                         /* acc_h:Q4    */
   acc_h = mult( acc_h, gcode0 );                      /* acc_h:Q[-7] */
   L_tmp = L_mult( acc_h, coef[1][0] );                /* L_tmp:Q10   */

   L_preg = L_mult( coef[0][0], best_gain[1] );        /* L_preg:Q13  */
   L_acc = L_sub( L_tmp, L_shr(L_preg,3) );            /* L_acc:Q10   */

   acc_h = extract_h( L_shl( L_acc,2 ) );              /* acc_h:Q[-4] */
   L_tmp_y = L_mult( acc_h, INV_COEF );                /* L_tmp_y:Q16 */

   sft_y = (14+4+1)-16;         /* (Q[thr1]+Q[gcode0]+1)-Q[L_tmp_y] */
   sft_x = (15+4+1)-15;         /* (Q[thr2]+Q[gcode0]+1)-Q[L_tmp_x] */

   if(gcode0>0){
      /*-- pre select codebook #1 --*/
      *cand1 = 0 ;
      do{
         L_temp = L_sub( L_tmp_y, L_shr(L_mult(thr1[*cand1],gcode0),sft_y));
         if(L_temp >0L  ){
        //(*cand1) =add(*cand1,1);
           *cand1 += 1;
     }
         else               break ;
      //} while(sub((*cand1),(NCODE1-NCAN1))<0) ;
      } while ((*cand1) < (NCODE1-NCAN1));
      /*-- pre select codebook #2 --*/
      *cand2 = 0 ;
      do{
        L_temp = L_sub( L_tmp_x , L_shr(L_mult(thr2[*cand2],gcode0),sft_x));
         if( L_temp >0L) {
        //(*cand2) =add(*cand2,1);
           *cand2 += 1;
     }
         else               break ;
      //} while(sub((*cand2),(NCODE2-NCAN2))<0) ;
      } while((*cand2) < (NCODE2-NCAN2)) ;
   }
   else{
      /*-- pre select codebook #1 --*/
      *cand1 = 0 ;
      do{
        L_temp = L_sub(L_tmp_y ,L_shr(L_mult(thr1[*cand1],gcode0),sft_y));
         if( L_temp <0L){
        //(*cand1) =add(*cand1,1);
           *cand1 += 1;
     }
         else               break ;
      //} while(sub((*cand1),(NCODE1-NCAN1))) ;
      } while (*cand1 != (NCODE1-NCAN1)) ;
      /*-- pre select codebook #2 --*/
      *cand2 = 0 ;
      do{
         L_temp =L_sub(L_tmp_x ,L_shr(L_mult(thr2[*cand2],gcode0),sft_x));
         if( L_temp <0L){
        //(*cand2) =add(*cand2,1);
           *cand2 += 1;
     }
         else               break ;
      //} while(sub( (*cand2),(NCODE2-NCAN2))) ;
      } while(*cand2 != (NCODE2-NCAN2)) ;
   }

   return ;
}
コード例 #27
0
ファイル: qua_gain.c プロジェクト: 2831942318/siphon
/*---------------------------------------------------------------------------*
 * Function  Qua_gain                                                        *
 * ~~~~~~~~~~~~~~~~~~                                                        *
 * Inputs:                                                                   *
 *   code[]     :Innovative codebook.                                        *
 *   g_coeff[]  :Correlations compute for pitch.                             *
 *   L_subfr    :Subframe length.                                            *
 *                                                                           *
 * Outputs:                                                                  *
 *   gain_pit   :Quantized pitch gain.                                       *
 *   gain_cod   :Quantized code gain.                                        *
 *                                                                           *
 * Return:                                                                   *
 *   Index of quantization.                                                  *
 *                                                                           *
 *--------------------------------------------------------------------------*/
Word16 Qua_gain(
   Word16 code[],       /* (i) Q13 :Innovative vector.             */
   Word16 g_coeff[],    /* (i)     :Correlations <xn y1> -2<y1 y1> */
                        /*            <y2,y2>, -2<xn,y2>, 2<y1,y2> */
   Word16 exp_coeff[],  /* (i)     :Q-Format g_coeff[]             */
   Word16 L_subfr,      /* (i)     :Subframe length.               */
   Word16 *gain_pit,    /* (o) Q14 :Pitch gain.                    */
   Word16 *gain_cod,    /* (o) Q1  :Code gain.                     */
   Word16 tameflag      /* (i)     : set to 1 if taming is needed  */
)
{
   Word16  i, j, index1, index2;
   Word16  cand1, cand2;
   Word16  exp, gcode0, exp_gcode0, gcode0_org, e_min ;
   Word16  nume, denom, inv_denom;
   Word16  exp1,exp2,exp_nume,exp_denom,exp_inv_denom,sft,tmp;
   Word16  g_pitch, g2_pitch, g_code, g2_code, g_pit_cod;
   Word16  coeff[5], coeff_lsf[5];
   Word16  exp_min[5];
   Word32  L_gbk12;
   Word32  L_tmp, L_dist_min, L_tmp1, L_tmp2, L_acc, L_accb;
   Word16  best_gain[2];

        /* Gain predictor, Past quantized energies = -14.0 in Q10 */

 static Word16 past_qua_en[4] = { -14336, -14336, -14336, -14336 };

  /*---------------------------------------------------*
   *-  energy due to innovation                       -*
   *-  predicted energy                               -*
   *-  predicted codebook gain => gcode0[exp_gcode0]  -*
   *---------------------------------------------------*/

   Gain_predict( past_qua_en, code, L_subfr, &gcode0, &exp_gcode0 );

  /*-----------------------------------------------------------------*
   *  pre-selection                                                  *
   *-----------------------------------------------------------------*/
  /*-----------------------------------------------------------------*
   *  calculate best gain                                            *
   *                                                                 *
   *  tmp = -1./(4.*coeff[0]*coeff[2]-coeff[4]*coeff[4]) ;           *
   *  best_gain[0] = (2.*coeff[2]*coeff[1]-coeff[3]*coeff[4])*tmp ;  *
   *  best_gain[1] = (2.*coeff[0]*coeff[3]-coeff[1]*coeff[4])*tmp ;  *
   *  gbk_presel(best_gain,&cand1,&cand2,gcode0) ;                   *
   *                                                                 *
   *-----------------------------------------------------------------*/

  /*-----------------------------------------------------------------*
   *  tmp = -1./(4.*coeff[0]*coeff[2]-coeff[4]*coeff[4]) ;           *
   *-----------------------------------------------------------------*/
   L_tmp1 = L_mult( g_coeff[0], g_coeff[2] );
   exp1   = add( add( exp_coeff[0], exp_coeff[2] ), 1-2 );
   L_tmp2 = L_mult( g_coeff[4], g_coeff[4] );
   exp2   = add( add( exp_coeff[4], exp_coeff[4] ), 1 );

   //if( sub(exp1, exp2)>0 ){
   if( exp1 > exp2 ){
      L_tmp = L_sub( L_shr( L_tmp1, sub(exp1,exp2) ), L_tmp2 );
      exp = exp2;
   }
   else{
      L_tmp = L_sub( L_tmp1, L_shr( L_tmp2, sub(exp2,exp1) ) );
      exp = exp1;
   }
   sft = norm_l( L_tmp );
   denom = extract_h( L_shl(L_tmp, sft) );
   exp_denom = sub( add( exp, sft ), 16 );

   inv_denom = div_s(16384,denom);
   inv_denom = negate( inv_denom );
   exp_inv_denom = sub( 14+15, exp_denom );

  /*-----------------------------------------------------------------*
   *  best_gain[0] = (2.*coeff[2]*coeff[1]-coeff[3]*coeff[4])*tmp ;  *
   *-----------------------------------------------------------------*/
   L_tmp1 = L_mult( g_coeff[2], g_coeff[1] );
   exp1   = add( exp_coeff[2], exp_coeff[1] );
   L_tmp2 = L_mult( g_coeff[3], g_coeff[4] );
   exp2   = add( add( exp_coeff[3], exp_coeff[4] ), 1 );

   //if( sub(exp1, exp2)>0 ){
   if (exp1 > exp2){
      L_tmp = L_sub( L_shr( L_tmp1, add(sub(exp1,exp2),1 )), L_shr( L_tmp2,1 ) );
      exp = sub(exp2,1);
   }
   else{
      L_tmp = L_sub( L_shr( L_tmp1,1 ), L_shr( L_tmp2, add(sub(exp2,exp1),1 )) );
      exp = sub(exp1,1);
   }
   sft = norm_l( L_tmp );
   nume = extract_h( L_shl(L_tmp, sft) );
   exp_nume = sub( add( exp, sft ), 16 );

   sft = sub( add( exp_nume, exp_inv_denom ), (9+16-1) );
   L_acc = L_shr( L_mult( nume,inv_denom ), sft );
   best_gain[0] = extract_h( L_acc );             /*-- best_gain[0]:Q9 --*/

   if (tameflag == 1){
     //if(sub(best_gain[0], GPCLIP2) > 0) best_gain[0] = GPCLIP2;
     if(best_gain[0] > GPCLIP2) best_gain[0] = GPCLIP2;
   }

  /*-----------------------------------------------------------------*
   *  best_gain[1] = (2.*coeff[0]*coeff[3]-coeff[1]*coeff[4])*tmp ;  *
   *-----------------------------------------------------------------*/
   L_tmp1 = L_mult( g_coeff[0], g_coeff[3] );
   exp1   = add( exp_coeff[0], exp_coeff[3] ) ;
   L_tmp2 = L_mult( g_coeff[1], g_coeff[4] );
   exp2   = add( add( exp_coeff[1], exp_coeff[4] ), 1 );

   //if( sub(exp1, exp2)>0 ){
   if( exp1 > exp2 ){
      L_tmp = L_sub( L_shr( L_tmp1, add(sub(exp1,exp2),1) ), L_shr( L_tmp2,1 ) );
      exp = sub(exp2,1);
      //exp = exp2--;
   }
   else{
      L_tmp = L_sub( L_shr( L_tmp1,1 ), L_shr( L_tmp2, add(sub(exp2,exp1),1) ) );
      exp = sub(exp1,1);
      //exp = exp1--;
   }
   sft = norm_l( L_tmp );
   nume = extract_h( L_shl(L_tmp, sft) );
   exp_nume = sub( add( exp, sft ), 16 );

   sft = sub( add( exp_nume, exp_inv_denom ), (2+16-1) );
   L_acc = L_shr( L_mult( nume,inv_denom ), sft );
   best_gain[1] = extract_h( L_acc );             /*-- best_gain[1]:Q2 --*/

   /*--- Change Q-format of gcode0 ( Q[exp_gcode0] -> Q4 ) ---*/
   //if( sub(exp_gcode0,4) >= 0 ){
   if (exp_gcode0 >=4) {
      gcode0_org = shr( gcode0, sub(exp_gcode0,4) );
   }
   else{
      L_acc = L_deposit_l( gcode0 );
      L_acc = L_shl( L_acc, sub( (4+16), exp_gcode0 ) );
      gcode0_org = extract_h( L_acc );              /*-- gcode0_org:Q4 --*/
   }

  /*----------------------------------------------*
   *   - presearch for gain codebook -            *
   *----------------------------------------------*/

   Gbk_presel(best_gain, &cand1, &cand2, gcode0_org );

/*---------------------------------------------------------------------------*
 *                                                                           *
 * Find the best quantizer.                                                  *
 *                                                                           *
 *  dist_min = MAX_32;                                                       *
 *  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 * coeff[0]                                    *
 *           + g_pitch         * coeff[1]                                    *
 *           + g_code*g_code   * coeff[2]                                    *
 *           + g_code          * coeff[3]                                    *
 *           + g_pitch*g_code  * coeff[4] ;                                  *
 *                                                                           *
 *      if (dist < dist_min){                                                *
 *        dist_min = dist;                                                   *
 *        indice1 = cand1 + i ;                                              *
 *        indice2 = cand2 + j ;                                              *
 *      }                                                                    *
 *    }                                                                      *
 *  }                                                                        *
 *                                                                           *
 * g_pitch         = Q13                                                     *
 * g_pitch*g_pitch = Q11:(13+13+1-16)                                        *
 * g_code          = Q[exp_gcode0-3]:(exp_gcode0+(13-1)+1-16)                *
 * g_code*g_code   = Q[2*exp_gcode0-21]:(exp_gcode0-3+exp_gcode0-3+1-16)     *
 * g_pitch*g_code  = Q[exp_gcode0-5]:(13+exp_gcode0-3+1-16)                  *
 *                                                                           *
 * term 0: g_pitch*g_pitch*coeff[0] ;exp_min0 = 13             +exp_coeff[0] *
 * term 1: g_pitch        *coeff[1] ;exp_min1 = 14             +exp_coeff[1] *
 * term 2: g_code*g_code  *coeff[2] ;exp_min2 = 2*exp_gcode0-21+exp_coeff[2] *
 * term 3: g_code         *coeff[3] ;exp_min3 = exp_gcode0  - 3+exp_coeff[3] *
 * term 4: g_pitch*g_code *coeff[4] ;exp_min4 = exp_gcode0  - 4+exp_coeff[4] *
 *                                                                           *
 *---------------------------------------------------------------------------*/

   exp_min[0] = add( exp_coeff[0], 13 );
   exp_min[1] = add( exp_coeff[1], 14 );
   exp_min[2] = add( exp_coeff[2], sub( shl( exp_gcode0, 1 ), 21 ) );
   exp_min[3] = add( exp_coeff[3], sub( exp_gcode0, 3 ) );
   exp_min[4] = add( exp_coeff[4], sub( exp_gcode0, 4 ) );

   e_min = exp_min[0];
   for(i=1; i<5; i++){
      //if( sub(exp_min[i], e_min) < 0 ){
     if (exp_min[i] < e_min) {
         e_min = exp_min[i];
      }
   }

   /* align coeff[] and save in special 32 bit double precision */

   for(i=0; i<5; i++){
     j = sub( exp_min[i], e_min );
     L_tmp = (Word32)g_coeff[i] << 16;
     L_tmp = L_shr( L_tmp, j );          /* L_tmp:Q[exp_g_coeff[i]+16-j] */
     L_Extract( L_tmp, &coeff[i], &coeff_lsf[i] );          /* DPF */
   }

   /* Codebook search */

   L_dist_min = MAX_32;

   /* initialization used only to suppress Microsoft Visual C++  warnings */
   index1 = cand1;
   index2 = cand2;

if(tameflag == 1){
   for(i=0; i<NCAN1; i++){
      for(j=0; j<NCAN2; j++){
         g_pitch = add( gbk1[cand1+i][0], gbk2[cand2+j][0] );     /* Q14 */
         if(g_pitch < GP0999) {
         L_acc = L_deposit_l( gbk1[cand1+i][1] );
         L_accb = L_deposit_l( gbk2[cand2+j][1] );                /* Q13 */
         L_tmp = L_add( L_acc,L_accb );
         tmp = extract_l( L_shr( L_tmp,1 ) );                     /* Q12 */

         g_code   = mult( gcode0, tmp );         /*  Q[exp_gcode0+12-15] */
         g2_pitch = mult(g_pitch, g_pitch);                       /* Q13 */
         g2_code  = mult(g_code,  g_code);       /* Q[2*exp_gcode0-6-15] */
         g_pit_cod= mult(g_code,  g_pitch);      /* Q[exp_gcode0-3+14-15] */

         L_tmp = Mpy_32_16(coeff[0], coeff_lsf[0], g2_pitch);
         //L_tmp = L_add(L_tmp, Mpy_32_16(coeff[1], coeff_lsf[1], g_pitch) );
         //L_tmp = L_add(L_tmp, Mpy_32_16(coeff[2], coeff_lsf[2], g2_code) );
         //L_tmp = L_add(L_tmp, Mpy_32_16(coeff[3], coeff_lsf[3], g_code) );
         //L_tmp = L_add(L_tmp, Mpy_32_16(coeff[4], coeff_lsf[4], g_pit_cod) );
         L_tmp += Mpy_32_16(coeff[1], coeff_lsf[1], g_pitch);
         L_tmp += Mpy_32_16(coeff[2], coeff_lsf[2], g2_code);
         L_tmp += Mpy_32_16(coeff[3], coeff_lsf[3], g_code);
         L_tmp += Mpy_32_16(coeff[4], coeff_lsf[4], g_pit_cod);

         //L_temp = L_sub(L_tmp, L_dist_min);

         //if( L_temp < 0L ){
         if( L_tmp < L_dist_min ){
            L_dist_min = L_tmp;
            index1 = add(cand1,i);
            index2 = add(cand2,j);
         }
        }
      }
   }

}
else{
   for(i=0; i<NCAN1; i++){
      for(j=0; j<NCAN2; j++){
         g_pitch = add( gbk1[cand1+i][0], gbk2[cand2+j][0] );     /* Q14 */
         L_acc = L_deposit_l( gbk1[cand1+i][1] );
         L_accb = L_deposit_l( gbk2[cand2+j][1] );                /* Q13 */
         L_tmp = L_add( L_acc,L_accb );
         tmp = extract_l( L_shr( L_tmp,1 ) );                     /* Q12 */

         g_code   = mult( gcode0, tmp );         /*  Q[exp_gcode0+12-15] */
         g2_pitch = mult(g_pitch, g_pitch);                       /* Q13 */
         g2_code  = mult(g_code,  g_code);       /* Q[2*exp_gcode0-6-15] */
         g_pit_cod= mult(g_code,  g_pitch);      /* Q[exp_gcode0-3+14-15] */

         L_tmp = Mpy_32_16(coeff[0], coeff_lsf[0], g2_pitch);
         //L_tmp = L_add(L_tmp, Mpy_32_16(coeff[1], coeff_lsf[1], g_pitch) );
         //L_tmp = L_add(L_tmp, Mpy_32_16(coeff[2], coeff_lsf[2], g2_code) );
         //L_tmp = L_add(L_tmp, Mpy_32_16(coeff[3], coeff_lsf[3], g_code) );
         //L_tmp = L_add(L_tmp, Mpy_32_16(coeff[4], coeff_lsf[4], g_pit_cod) );
         L_tmp += Mpy_32_16(coeff[1], coeff_lsf[1], g_pitch);
         L_tmp += Mpy_32_16(coeff[2], coeff_lsf[2], g2_code);
         L_tmp += Mpy_32_16(coeff[3], coeff_lsf[3], g_code);
         L_tmp += Mpy_32_16(coeff[4], coeff_lsf[4], g_pit_cod);

         if( L_tmp < L_dist_min ){
            L_dist_min = L_tmp;
            index1 = add(cand1,i);
            index2 = add(cand2,j);
         }

      }
   }
}
   /* Read the quantized gain */

  /*-----------------------------------------------------------------*
   * *gain_pit = gbk1[indice1][0] + gbk2[indice2][0];                *
   *-----------------------------------------------------------------*/
   *gain_pit = add( gbk1[index1][0], gbk2[index2][0] );      /* Q14 */

  /*-----------------------------------------------------------------*
   * *gain_code = (gbk1[indice1][1]+gbk2[indice2][1]) * gcode0;      *
   *-----------------------------------------------------------------*/
   L_gbk12 = (Word32)gbk1[index1][1] + (Word32)gbk2[index2][1]; /* Q13 */
   tmp = extract_l( L_shr( L_gbk12,1 ) );                     /* Q12 */
   L_acc = L_mult(tmp, gcode0);                /* Q[exp_gcode0+12+1] */

   L_acc = L_shl(L_acc, add( negate(exp_gcode0),(-12-1+1+16) ));
   *gain_cod = extract_h( L_acc );                             /* Q1 */

  /*----------------------------------------------*
   * update table of past quantized energies      *
   *----------------------------------------------*/
   Gain_update( past_qua_en, L_gbk12 );

   return( add( map1[index1]*(Word16)NCODE2, map2[index2] ) );

}
コード例 #28
0
Word32 quant_6p_6N_2(                      /* (o) return (6*N)-2 bits         */
		Word16 pos[],                         /* (i) position of the pulse 1..6  */
		Word16 N)                             /* (i) number of bits for position */
{
	Word16 nb_pos, n_1;
	Word16 posA[6], posB[6];
	Word32 i, j, k, index;

	/* !!  N and n_1 are constants -> it doesn't need to be operated by Basic Operators */
	// N和n_1是常数-它不需要基本的运营
	n_1 = (Word16) (N - 1);
	nb_pos = (1 << n_1);                  /* nb_pos = (1<<n_1); */

	i = 0;
	j = 0;
	for (k = 0; k < 6; k++)
	{
		if ((pos[k] & nb_pos) == 0)
		{
			posA[i++] = pos[k];
		} else
		{
			posB[j++] = pos[k];
		}
	}

	switch (i)
	{
		case 0:
			index = (1 << (Word16) (6 * N - 5));        /* index = 1 << ((6*N)-5); */
			index = vo_L_add(index, (quant_5p_5N(posB, n_1) << N)); /* index += quant_5p_5N(posB, n_1) << N; */
			index = vo_L_add(index, quant_1p_N1(posB[5], n_1));        /* index += quant_1p_N1(posB[5], n_1); */
			break;
		case 1:
			index = (1L << (Word16) (6 * N - 5));        /* index = 1 << ((6*N)-5); */
			index = vo_L_add(index, (quant_5p_5N(posB, n_1) << N)); /* index += quant_5p_5N(posB, n_1) << N; */
			index = vo_L_add(index, quant_1p_N1(posA[0], n_1));        /* index += quant_1p_N1(posA[0], n_1); */
			break;
		case 2:
			index = (1L << (Word16) (6 * N - 5));        /* index = 1 << ((6*N)-5); */
			/* index += quant_4p_4N(posB, n_1) << ((2*n_1)+1); */
			index = vo_L_add(index, (quant_4p_4N(posB, n_1) << (Word16) (2 * n_1 + 1)));
			index = vo_L_add(index, quant_2p_2N1(posA[0], posA[1], n_1));      /* index += quant_2p_2N1(posA[0], posA[1], n_1); */
			break;
		case 3:
			index = (quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << (Word16) (3 * n_1 + 1));
			                                  /* index = quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << ((3*n_1)+1); */
			index =vo_L_add(index, quant_3p_3N1(posB[0], posB[1], posB[2], n_1));
			                                 /* index += quant_3p_3N1(posB[0], posB[1], posB[2], n_1); */
			break;
		case 4:
			i = 2;
			index = (quant_4p_4N(posA, n_1) << (Word16) (2 * n_1 + 1));  /* index = quant_4p_4N(posA, n_1) << ((2*n_1)+1); */
			index = vo_L_add(index, quant_2p_2N1(posB[0], posB[1], n_1));      /* index += quant_2p_2N1(posB[0], posB[1], n_1); */
			break;
		case 5:
			i = 1;
			index = (quant_5p_5N(posA, n_1) << N);       /* index = quant_5p_5N(posA, n_1) << N; */
			index = vo_L_add(index, quant_1p_N1(posB[0], n_1));        /* index += quant_1p_N1(posB[0], n_1); */
			break;
		case 6:
			i = 0;
			index = (quant_5p_5N(posA, n_1) << N);       /* index = quant_5p_5N(posA, n_1) << N; */
			index = vo_L_add(index, quant_1p_N1(posA[5], n_1));        /* index += quant_1p_N1(posA[5], n_1); */
			break;
		default:
			index = 0;
			fprintf(stderr, "Error in function quant_6p_6N_2\n");
	}
	index = vo_L_add(index, ((L_deposit_l(i) & 3L) << (Word16) (6 * N - 4)));   /* index += (i & 3) << ((6*N)-4); */

	return (index);
}
コード例 #29
0
ファイル: dec_gain.c プロジェクト: sippet/g729
/*---------------------------------------------------------------------------*
 * Function  Dec_gain                                                        *
 * ~~~~~~~~~~~~~~~~~~                                                        *
 * Decode the pitch and codebook gains                                       *
 *                                                                           *
 *---------------------------------------------------------------------------*
 * input arguments:                                                          *
 *                                                                           *
 *   index      :Quantization index                                          *
 *   code[]     :Innovative code vector                                      *
 *   L_subfr    :Subframe size                                               *
 *   bfi        :Bad frame indicator                                         *
 *                                                                           *
 * output arguments:                                                         *
 *                                                                           *
 *   gain_pit   :Quantized pitch gain                                        *
 *   gain_cod   :Quantized codebook gain                                     *
 *                                                                           *
 *---------------------------------------------------------------------------*/
void WebRtcG729fix_Dec_gain(
   Decod_ld8a_state *st,
   int16_t index,        /* (i)     :Index of quantization.         */
   int16_t code[],       /* (i) Q13 :Innovative vector.             */
   int16_t L_subfr,      /* (i)     :Subframe length.               */
   int16_t bfi,          /* (i)     :Bad frame indicator            */
   int16_t *gain_pit,    /* (o) Q14 :Pitch gain.                    */
   int16_t *gain_cod     /* (o) Q1  :Code gain.                     */
)
{
   int16_t  index1, index2, tmp;
   int16_t  gcode0, exp_gcode0;
   int32_t  L_gbk12, L_acc, L_accb;

   /*-------------- Case of erasure. ---------------*/

   if(bfi != 0){
      *gain_pit = mult( *gain_pit, 29491 );      /* *0.9 in Q15 */
      if (*gain_pit > 29491) *gain_pit = 29491;
      *gain_cod = mult( *gain_cod, 32111 );      /* *0.98 in Q15 */

     /*----------------------------------------------*
      * update table of past quantized energies      *
      *                              (frame erasure) *
      *----------------------------------------------*/
      WebRtcG729fix_Gain_update_erasure(st->past_qua_en);

      return;
   }

   /*-------------- Decode pitch gain ---------------*/

   index1 = WebRtcG729fix_imap1[ shr(index,NCODE2_B) ] ;
   index2 = WebRtcG729fix_imap2[ index & (NCODE2-1) ] ;
   *gain_pit = WebRtcSpl_AddSatW16( WebRtcG729fix_gbk1[index1][0], WebRtcG729fix_gbk2[index2][0] );

   /*-------------- Decode codebook gain ---------------*/

  /*---------------------------------------------------*
   *-  energy due to innovation                       -*
   *-  predicted energy                               -*
   *-  predicted codebook gain => gcode0[exp_gcode0]  -*
   *---------------------------------------------------*/

   WebRtcG729fix_Gain_predict(st->past_qua_en, code, L_subfr, &gcode0, &exp_gcode0 );

  /*-----------------------------------------------------------------*
   * *gain_code = (gbk1[indice1][1]+gbk2[indice2][1]) * gcode0;      *
   *-----------------------------------------------------------------*/

   L_acc = L_deposit_l( WebRtcG729fix_gbk1[index1][1] );
   L_accb = L_deposit_l( WebRtcG729fix_gbk2[index2][1] );
   L_gbk12 = WebRtcSpl_AddSatW32( L_acc, L_accb );                       /* Q13 */
   tmp = extract_l( L_shr( L_gbk12,1 ) );                  /* Q12 */
   L_acc = L_mult(tmp, gcode0);             /* Q[exp_gcode0+12+1] */

   L_acc = L_shl(L_acc, WebRtcSpl_AddSatW16( negate(exp_gcode0),(-12-1+1+16) ));
   *gain_cod = extract_h( L_acc );                          /* Q1 */

  /*----------------------------------------------*
   * update table of past quantized energies      *
   *----------------------------------------------*/
   WebRtcG729fix_Gain_update(st->past_qua_en, L_gbk12 );

   return;

}
コード例 #30
0
ファイル: encoder.c プロジェクト: avble/natClientEx
Word16 compute_region_powers(Word16  *mlt_coefs,
                             Word16  mag_shift,
                             Word16  *drp_num_bits,
                             UWord16 *drp_code_bits,
                             Word16  *absolute_region_power_index,
                             Word16  number_of_regions)
{

    Word16 *input_ptr;
    Word32 long_accumulator;
    Word16 itemp1;
    Word16 power_shift;
    Word16 region;
    Word16 j;
    Word16 differential_region_power_index[MAX_NUMBER_OF_REGIONS];
    Word16 number_of_bits;
    
    Word32 acca;
    Word16 temp;
    Word16 temp1;
    Word16 temp2;


    input_ptr = mlt_coefs;
    for (region=0; region<number_of_regions; region++)
    {
        long_accumulator = L_deposit_l(0);

        for (j=0; j<REGION_SIZE; j++)
        {
            itemp1 = *input_ptr++;
            move16();
            long_accumulator = L_mac0(long_accumulator,itemp1,itemp1);
        }

        power_shift = 0;
        move16();

        acca = (long_accumulator & 0x7fff0000L);
        logic32();

        test();
        while (acca > 0)
        {
            test();
            long_accumulator = L_shr_nocheck(long_accumulator,1);
            
            acca = (long_accumulator & 0x7fff0000L);
            logic32();

            power_shift = add(power_shift,1);
        }
        
        acca = L_sub(long_accumulator,32767);
        
        temp = add(power_shift,15);
        test();
        test();
        logic16();
        while ((acca <= 0) && (temp >= 0))
        {
            test();
            test();
            logic16();
            
            long_accumulator = L_shl_nocheck(long_accumulator,1);
            acca = L_sub(long_accumulator,32767);
            power_shift--;
            temp = add(power_shift,15);
        }
        long_accumulator = L_shr_nocheck(long_accumulator,1);
        /* 28963 corresponds to square root of 2 times REGION_SIZE(20). */
        acca = L_sub(long_accumulator,28963);
        
        test();
        if (acca >= 0)
            power_shift = add(power_shift,1);
        
        acca = L_deposit_l(mag_shift);
        acca = L_shl_nocheck(acca,1);
        acca = L_sub(power_shift,acca);
        acca = L_add(35,acca);
        acca = L_sub(acca,REGION_POWER_TABLE_NUM_NEGATIVES);
        absolute_region_power_index[region] = extract_l(acca);
    }


    /* Before we differentially encode the quantized region powers, adjust upward the
    valleys to make sure all the peaks can be accurately represented. */
    temp = sub(number_of_regions,2);

    for (region = temp; region >= 0; region--)
    {
        temp1 = sub(absolute_region_power_index[region+1],DRP_DIFF_MAX);
        temp2 = sub(absolute_region_power_index[region],temp1);
        test();
        if (temp2 < 0)
        {
            absolute_region_power_index[region] = temp1;
            move16();
        }
    }

    /* The MLT is currently scaled too low by the factor
       ENCODER_SCALE_FACTOR(=18318)/32768 * (1./sqrt(160).
       This is the ninth power of 1 over the square root of 2.
       So later we will add ESF_ADJUSTMENT_TO_RMS_INDEX (now 9)
       to drp_code_bits[0]. */

    /* drp_code_bits[0] can range from 1 to 31. 0 will be used only as an escape sequence. */
    temp1 = sub(1,ESF_ADJUSTMENT_TO_RMS_INDEX);
    temp2 = sub(absolute_region_power_index[0],temp1);
    test();
    if (temp2 < 0)
    {
        absolute_region_power_index[0] = temp1;
        move16();
    }
    
    temp1 = sub(31,ESF_ADJUSTMENT_TO_RMS_INDEX);

	/*
	 * The next line was corrected in Release 1.2 
	 */

    temp2 = sub(absolute_region_power_index[0], temp1);  
    test();
    if (temp2 > 0)
    {
        absolute_region_power_index[0] = temp1;
        move16();
    }

    differential_region_power_index[0] = absolute_region_power_index[0];
    move16();
    
    number_of_bits = 5;
    move16();
    
    drp_num_bits[0] = 5;
    move16();
    
    drp_code_bits[0] = (UWord16)add(absolute_region_power_index[0],ESF_ADJUSTMENT_TO_RMS_INDEX);
    move16();

    /* Lower limit the absolute region power indices to -8 and upper limit them to 31. Such extremes
     may be mathematically impossible anyway.*/
    for (region=1; region<number_of_regions; region++)
    {
        temp1 = sub(-8,ESF_ADJUSTMENT_TO_RMS_INDEX);
        temp2 = sub(absolute_region_power_index[region],temp1);
        test();
        if (temp2 < 0)
        {
            absolute_region_power_index[region] = temp1;
            move16();
        }

        temp1 = sub(31,ESF_ADJUSTMENT_TO_RMS_INDEX);
        temp2 = sub(absolute_region_power_index[region],temp1);
        test();
        if (temp2 > 0)
        {
            absolute_region_power_index[region] = temp1;
            move16();
        }
    }

    for (region=1; region<number_of_regions; region++)
    {
        j = sub(absolute_region_power_index[region],absolute_region_power_index[region-1]);
        temp = sub(j,DRP_DIFF_MIN);
        test();
        if (temp < 0)
        {
            j = DRP_DIFF_MIN;
        }
        j = sub(j,DRP_DIFF_MIN);
        move16();
        differential_region_power_index[region] = j;
        move16();
        
        temp = add(absolute_region_power_index[region-1],differential_region_power_index[region]);
        temp = add(temp,DRP_DIFF_MIN);
        absolute_region_power_index[region] = temp;
        move16();

        number_of_bits = add(number_of_bits,differential_region_power_bits[region][j]);
        drp_num_bits[region] = differential_region_power_bits[region][j];
        move16();
        drp_code_bits[region] = differential_region_power_codes[region][j];
        move16();
    }

    return (number_of_bits);
}