Ejemplo n.º 1
0
Word16 G_pitch(          /* (o) Q14 : Gain of pitch lag saturated to 1.2   */
     Word16 xn[],        /* (i)     : Pitch target.                        */
     Word16 y1[],        /* (i)     : filtered adaptive codebook.          */
     Word16 g_coeff[],   /* : Correlations need for gain quantization.     */
     Word16 L_subfr      /* : Length of subframe.                          */
)
{
    Word16 i;
    Word16 xy, yy, exp_xy, exp_yy, gain;
    Word32 L_tmp;

    /* Compute scalar product <y1[],y1[]> */

    L_tmp = Dot_product12(y1, y1, L_subfr, &exp_yy);
    yy = (Word16)(L_tmp >> 16);

    /* Compute scalar product <xn[],y1[]> */

    L_tmp = Dot_product12(xn, y1, L_subfr, &exp_xy);
    xy = (Word16)(L_tmp >> 16);
    
    g_coeff[0] = yy;
    g_coeff[1] = exp_yy;
    g_coeff[2] = xy;
    g_coeff[3] = exp_xy;

    xy = xy >> 1;                       /* Be sure xy < yy */
    /* If (xy < 0) gain = 0 */
    if (xy <= 0)
        return ((Word16) 0);

    /* compute gain = xy/yy */

    gain = div_s(xy, yy);

    i = add(exp_xy, 1 - 1);                /* -1 -> gain in Q14 */
    i = sub(i, exp_yy);

    gain = shl(gain, i);                   /* saturation can occur here */

    /* if (gain > 1.2) gain = 1.2  in Q14 */
    if (gain > 19661)
    {
        gain = 19661;
    }
    return (gain);
}
Word16 voice_factor(                                  /* (o) Q15   : factor (-1=unvoiced to 1=voiced) */
        Word16 exc[],                         /* (i) Q_exc : pitch excitation                 */
        Word16 Q_exc,                         /* (i)       : exc format                       */
        Word16 gain_pit,                      /* (i) Q14   : gain of pitch                    */
        Word16 code[],                        /* (i) Q9    : Fixed codebook excitation        */
        Word16 gain_code,                     /* (i) Q0    : gain of code                     */
        Word16 L_subfr                        /* (i)       : subframe length                  */
        )
{
    Word16 tmp, exp, ener1, exp1, ener2, exp2;
    Word32 i, L_tmp;

#ifdef ASM_OPT               /* asm optimization branch */
    ener1 = extract_h(Dot_product12_asm(exc, exc, L_subfr, &exp1));
#else
    ener1 = extract_h(Dot_product12(exc, exc, L_subfr, &exp1));
#endif
    exp1 = exp1 - (Q_exc + Q_exc);
    L_tmp = vo_L_mult(gain_pit, gain_pit);
    exp = norm_l(L_tmp);
    tmp = extract_h(L_tmp << exp);
    ener1 = vo_mult(ener1, tmp);
    exp1 = exp1 - exp - 10;        /* 10 -> gain_pit Q14 to Q9 */

#ifdef ASM_OPT                /* asm optimization branch */
    ener2 = extract_h(Dot_product12_asm(code, code, L_subfr, &exp2));
#else
    ener2 = extract_h(Dot_product12(code, code, L_subfr, &exp2));
#endif

    exp = norm_s(gain_code);
    tmp = gain_code << exp;
    tmp = vo_mult(tmp, tmp);
    ener2 = vo_mult(ener2, tmp);
    exp2 = exp2 - (exp + exp);

    i = exp1 - exp2;

    if (i >= 0)
    {
        ener1 = ener1 >> 1;
        ener2 = ener2 >> (i + 1);
    } else
//============================================================================
//函数功能:找到语音因子
//函数参数:"exc[]"表示因子,作为输入参数;"Q_exc"表示激励,表示输入参数;"gain_pit"
//         表示增益音高,作为输入参数;"code[]"表示固定码本激励,作为输入参数;
//         "gain_code"表示编码增益,作为输入参数;"L_subfr"表示子帧长度
//============================================================================
int16 voice_factor(    /* (o) Q15   : factor (-1=unvoiced to 1=voiced) */
    int16 exc[],      /* (i) Q_exc : pitch excitation                 */
    int16 Q_exc,      /* (i)       : exc format                       */
    int16 gain_pit,   /* (i) Q14   : gain of pitch                    */
    int16 code[],     /* (i) Q9    : Fixed codebook excitation        */
    int16 gain_code,  /* (i) Q0    : gain of code                     */
    int16 L_subfr     /* (i)       : subframe length                  */
)
{
    int16 i, tmp, exp, ener1, exp1, ener2, exp2;
    int32 L_tmp;

    ener1 = extract_h(Dot_product12(exc, exc, L_subfr, &exp1));
    exp1 = sub_int16(exp1, Q_exc << 1);
    L_tmp = mul_16by16_to_int32(gain_pit, gain_pit);
    exp = normalize_amr_wb(L_tmp);

    tmp = (int16)((L_tmp << exp) >> 16);
    ener1 = mult_int16(ener1, tmp);
    exp1 -= (exp + 10);        /* 10 -> gain_pit Q14 to Q9 */

    ener2 = extract_h(Dot_product12(code, code, L_subfr, &exp2));

    exp = norm_s(gain_code);
    tmp = shl_int16(gain_code, exp);
    tmp = mult_int16(tmp, tmp);
    ener2 = mult_int16(ener2, tmp);
    exp2 -= (exp << 1);

    i = exp1 - exp2;


    if (i >= 0)
    {
        ener1 >>=  1;
        ener2 >>= (i + 1);
    }
//============================================================================
//函数功能:设置存储器
//函数参数:"index"表示指标量化,作为输入参数;"nbits"表示位数,作为输入参数;"
//         code[]"表示创新载体,作为输入参数;"L_subfr"表示子帧长度,作为输入参
//         数;"gain_pit"表示基音增益,作为输出参数;"gain_cod"表示编码增益,作
//         为输出参数;"bfi"表示坏帧指示,作为输入参数;"prev_bfi"表示先前BF指
//         示器,作为输入参数;"state"表示BFH的状态,作为输入参数;"unusable_frame"
//         表示UF指示器,作为输入参数;"vad_hist"表示非语音帧的数目,作为输入参
//         数;"mem"表示静态存储器,既作为输入参数又作为输出参数
//============================================================================
void dec_gain2_amr_wb(
    int16 index,               /* (i)     : index of quantization.      */
    int16 nbits,               /* (i)     : number of bits (6 or 7)     */
    int16 code[],              /* (i) Q9  : Innovative vector.          */
    int16 L_subfr,             /* (i)     : Subframe lenght.            */
    int16 * gain_pit,          /* (o) Q14 : Pitch gain.                 */
    int32 * gain_cod,          /* (o) Q16 : Code gain.                  */
    int16 bfi,                 /* (i)     : bad frame indicator         */
    int16 prev_bfi,            /* (i)     : Previous BF indicator       */
    int16 state,               /* (i)     : State of BFH                */
    int16 unusable_frame,      /* (i)     : UF indicator                */
    int16 vad_hist,            /* (i)     : number of non-speech frames */
    int16 * mem                /* (i/o)   : static memory (4 words)     */
)
{
    const int16 *p;
    int16 *past_gain_pit, *past_gain_code, *past_qua_en, *gbuf, *pbuf, *prev_gc;
    int16 *pbuf2;
    int16 i, tmp, exp, frac, gcode0, exp_gcode0, qua_ener, gcode_inov;
    int16 tmp1, g_code;
    int16 tmp2;
    int32 L_tmp;

    past_qua_en = mem;
    past_gain_pit = mem + 4;
    past_gain_code = mem + 5;
    prev_gc = mem + 6;
    pbuf = mem + 7;
    gbuf = mem + 12;
    pbuf2 = mem + 17;

    /*
     *  Find energy of code and compute:
     *
     *    L_tmp = 1.0 / sqrt(energy of code/ L_subfr)
     */

    L_tmp = Dot_product12(code, code, L_subfr, &exp);
    exp -= 24;                /* exp: -18 (code in Q9), -6 (/L_subfr) */

    one_ov_sqrt_norm(&L_tmp, &exp);

    gcode_inov = extract_h(shl_int32(L_tmp, exp - 3));  /* g_code_inov in Q12 */

    /*
     * Case of erasure.
     */

    if (bfi != 0)
    {
        tmp = median5(&pbuf[2]);
        *past_gain_pit = tmp;

        if (*past_gain_pit > 15565)
        {
            *past_gain_pit = 15565;        /* 0.95 in Q14 */

        }

        if (unusable_frame != 0)
        {
            *gain_pit = mult_int16(pdown_unusable[state], *past_gain_pit);
        }
        else
        {
            *gain_pit = mult_int16(pdown_usable[state], *past_gain_pit);
        }
        tmp = median5(&gbuf[2]);

        if (vad_hist > 2)
        {
            *past_gain_code = tmp;
        }
        else
        {

            if (unusable_frame != 0)
            {
                *past_gain_code = mult_int16(cdown_unusable[state], tmp);
            }
            else
            {
                *past_gain_code = mult_int16(cdown_usable[state], tmp);
            }
        }

        /* update table of past quantized energies */

        //更新过去的量子化的能量表
        tmp  = past_qua_en[3];
        tmp1 = past_qua_en[2];
        L_tmp  = tmp;
        L_tmp += tmp1;
        past_qua_en[3] = tmp;
        tmp  = past_qua_en[1];
        tmp1 = past_qua_en[0];
        L_tmp += tmp;
        L_tmp += tmp1;
        past_qua_en[2] = tmp;
        qua_ener = (int16)(L_tmp >> 3);
        past_qua_en[1] = tmp1;


        qua_ener -= 3072;    /* -3 in Q10 */

        if (qua_ener < -14336)
        {
            qua_ener = -14336;                /* -14 in Q10 */
        }

        past_qua_en[0] = qua_ener;


        for (i = 1; i < 5; i++)
        {
            gbuf[i - 1] = gbuf[i];
            pbuf[i - 1] = pbuf[i];
        }
        gbuf[4] = *past_gain_code;
        pbuf[4] = *past_gain_pit;


        /* adjust gain according to energy of code */
        /* past_gain_code(Q3) * gcode_inov(Q12) => Q16 */
	 //调整增益根据能量代码
        *gain_cod = mul_16by16_to_int32(*past_gain_code, gcode_inov);

        return;
    }
Ejemplo n.º 5
0
void ACELP_4t64_fx(
		Word16 dn[],                          /* (i) <12b : correlation between target x[] and H[]      */
		Word16 cn[],                          /* (i) <12b : residual after long term prediction         */
		Word16 H[],                           /* (i) Q12: impulse response of weighted synthesis filter */
		Word16 code[],                        /* (o) Q9 : algebraic (fixed) codebook excitation         */
		Word16 y[],                           /* (o) Q9 : filtered fixed codebook excitation            */
		Word16 nbbits,                        /* (i) : 20, 36, 44, 52, 64, 72 or 88 bits                */
		Word16 ser_size,                      /* (i) : bit rate                                         */
		Word16 _index[]                       /* (o) : index (20): 5+5+5+5 = 20 bits.                   */
		/* (o) : index (36): 9+9+9+9 = 36 bits.                   */
		/* (o) : index (44): 13+9+13+9 = 44 bits.                 */
		/* (o) : index (52): 13+13+13+13 = 52 bits.               */
		/* (o) : index (64): 2+2+2+2+14+14+14+14 = 64 bits.       */
		/* (o) : index (72): 10+2+10+2+10+14+10+14 = 72 bits.     */
		/* (o) : index (88): 11+11+11+11+11+11+11+11 = 88 bits.   */
		)
{
	Word32 i, j, k;
	Word16 st, ix, iy, pos, index, track, nb_pulse, nbiter, j_temp;
	Word16 psk, ps, alpk, alp, val, k_cn, k_dn, exp;
	Word16 *p0, *p1, *p2, *p3, *psign;
	Word16 *h, *h_inv, *ptr_h1, *ptr_h2, *ptr_hf, h_shift;
	Word32 s, cor, L_tmp, L_index;
	Word16 dn2[L_SUBFR], sign[L_SUBFR], vec[L_SUBFR];
	Word16 ind[NPMAXPT * NB_TRACK];
	Word16 codvec[NB_PULSE_MAX], nbpos[10];
	Word16 cor_x[NB_POS], cor_y[NB_POS], pos_max[NB_TRACK];
	Word16 h_buf[4 * L_SUBFR];
	Word16 rrixix[NB_TRACK][NB_POS], rrixiy[NB_TRACK][MSIZE];
	Word16 ipos[NB_PULSE_MAX];

	switch (nbbits)
	{
		case 20:                               /* 20 bits, 4 pulses, 4 tracks */
			nbiter = 4;                          /* 4x16x16=1024 loop */
			alp = 8192;                          /* alp = 2.0 (Q12) */
			nb_pulse = 4;                      
			nbpos[0] = 4;                      
			nbpos[1] = 8;                      
			break;
		case 36:                               /* 36 bits, 8 pulses, 4 tracks */
			nbiter = 4;                          /* 4x20x16=1280 loop */
			alp = 4096;                          /* alp = 1.0 (Q12) */
			nb_pulse = 8;                      
			nbpos[0] = 4;                      
			nbpos[1] = 8;                      
			nbpos[2] = 8;                      
			break;
		case 44:                               /* 44 bits, 10 pulses, 4 tracks */
			nbiter = 4;                          /* 4x26x16=1664 loop */
			alp = 4096;                          /* alp = 1.0 (Q12) */
			nb_pulse = 10;                     
			nbpos[0] = 4;                      
			nbpos[1] = 6;                      
			nbpos[2] = 8;                      
			nbpos[3] = 8;                      
			break;
		case 52:                               /* 52 bits, 12 pulses, 4 tracks */
			nbiter = 4;                          /* 4x26x16=1664 loop */
			alp = 4096;                          /* alp = 1.0 (Q12) */
			nb_pulse = 12;                     
			nbpos[0] = 4;                      
			nbpos[1] = 6;                      
			nbpos[2] = 8;                      
			nbpos[3] = 8;                      
			break;
		case 64:                               /* 64 bits, 16 pulses, 4 tracks */
			nbiter = 3;                          /* 3x36x16=1728 loop */
			alp = 3277;                          /* alp = 0.8 (Q12) */
			nb_pulse = 16;                     
			nbpos[0] = 4;                      
			nbpos[1] = 4;                      
			nbpos[2] = 6;                      
			nbpos[3] = 6;                      
			nbpos[4] = 8;                      
			nbpos[5] = 8;                      
			break;
		case 72:                               /* 72 bits, 18 pulses, 4 tracks */
			nbiter = 3;                          /* 3x35x16=1680 loop */
			alp = 3072;                          /* alp = 0.75 (Q12) */
			nb_pulse = 18;                     
			nbpos[0] = 2;                      
			nbpos[1] = 3;                      
			nbpos[2] = 4;                      
			nbpos[3] = 5;                      
			nbpos[4] = 6;                      
			nbpos[5] = 7;                      
			nbpos[6] = 8;                      
			break;
		case 88:                               /* 88 bits, 24 pulses, 4 tracks */
			if(ser_size > 462)
				nbiter = 1;
			else
				nbiter = 2;                    /* 2x53x16=1696 loop */

			alp = 2048;                          /* alp = 0.5 (Q12) */
			nb_pulse = 24;                     
			nbpos[0] = 2;                      
			nbpos[1] = 2;                      
			nbpos[2] = 3;                      
			nbpos[3] = 4;                      
			nbpos[4] = 5;                      
			nbpos[5] = 6;                      
			nbpos[6] = 7;                      
			nbpos[7] = 8;                      
			nbpos[8] = 8;                      
			nbpos[9] = 8;                      
			break;
		default:
			nbiter = 0;
			alp = 0;
			nb_pulse = 0;
	}

	for (i = 0; i < nb_pulse; i++)
	{
		codvec[i] = i;                     
	}

	/*----------------------------------------------------------------*
	 * Find sign for each pulse position.                             *
	 *----------------------------------------------------------------*/
	/* calculate energy for normalization of cn[] and dn[] */
	/* set k_cn = 32..32767 (ener_cn = 2^30..256-0) */
#ifdef ASM_OPT                  /* asm optimization branch */
	s = Dot_product12_asm(cn, cn, L_SUBFR, &exp);
#else
	s = Dot_product12(cn, cn, L_SUBFR, &exp);
#endif

	Isqrt_n(&s, &exp);
	s = L_shl(s, (exp + 5)); 
	k_cn = extract_h(L_add(s, 0x8000));

	/* set k_dn = 32..512 (ener_dn = 2^30..2^22) */
#ifdef ASM_OPT                      /* asm optimization branch */
	s = Dot_product12_asm(dn, dn, L_SUBFR, &exp);
#else
	s = Dot_product12(dn, dn, L_SUBFR, &exp);
#endif

	Isqrt_n(&s, &exp);
	k_dn = (L_shl(s, (exp + 5 + 3)) + 0x8000) >> 16;    /* k_dn = 256..4096 */
	k_dn = vo_mult_r(alp, k_dn);              /* alp in Q12 */

	/* mix normalized cn[] and dn[] */
	p0 = cn;
	p1 = dn;
	p2 = dn2;

	for (i = 0; i < L_SUBFR/4; i++)
	{
		s = (k_cn* (*p0++))+(k_dn * (*p1++));
		*p2++ = s >> 7;
		s = (k_cn* (*p0++))+(k_dn * (*p1++));
		*p2++ = s >> 7;
		s = (k_cn* (*p0++))+(k_dn * (*p1++));
		*p2++ = s >> 7;
		s = (k_cn* (*p0++))+(k_dn * (*p1++));
		*p2++ = s >> 7; 
	}

	/* set sign according to dn2[] = k_cn*cn[] + k_dn*dn[]    */
	for(i = 0; i < L_SUBFR; i++)
	{
		val = dn[i];                   
		ps = dn2[i];                   
		if (ps >= 0)
		{
			sign[i] = 32767;             /* sign = +1 (Q12) */
			vec[i] = -32768;           
		} else
		{
			sign[i] = -32768;            /* sign = -1 (Q12) */
			vec[i] = 32767;            
			dn[i] = -val;
			dn2[i] = -ps;
		}
	}
	/*----------------------------------------------------------------*
	 * Select NB_MAX position per track according to max of dn2[].    *
	 *----------------------------------------------------------------*/
	pos = 0;
	for (i = 0; i < NB_TRACK; i++)
	{
		for (k = 0; k < NB_MAX; k++)
		{
			ps = -1;                       
			for (j = i; j < L_SUBFR; j += STEP)
			{
				if(dn2[j] > ps)
				{
					ps = dn2[j];          
					pos = j;               
				}
			}
			dn2[pos] = (k - NB_MAX);     /* dn2 < 0 when position is selected */
			if (k == 0)
			{
				pos_max[i] = pos;          
			}
		}
	}

	/*--------------------------------------------------------------*
	 * Scale h[] to avoid overflow and to get maximum of precision  *
	 * on correlation.                                              *
	 *                                                              *
	 * Maximum of h[] (h[0]) is fixed to 2048 (MAX16 / 16).         *
	 *  ==> This allow addition of 16 pulses without saturation.    *
	 *                                                              *
	 * Energy worst case (on resonant impulse response),            *
	 * - energy of h[] is approximately MAX/16.                     *
	 * - During search, the energy is divided by 8 to avoid         *
	 *   overflow on "alp". (energy of h[] = MAX/128).              *
	 *  ==> "alp" worst case detected is 22854 on sinusoidal wave.  *
	 *--------------------------------------------------------------*/

	/* impulse response buffer for fast computation */

	h = h_buf;                             
	h_inv = h_buf + (2 * L_SUBFR);   
	L_tmp = 0;
	for (i = 0; i < L_SUBFR; i++)
	{
		*h++ = 0;                          
		*h_inv++ = 0;   
		L_tmp += (H[i] * H[i]) << 1;
	}
	/* scale h[] down (/2) when energy of h[] is high with many pulses used */
	val = extract_h(L_tmp);
	h_shift = 0;                           

	if ((nb_pulse >= 12) && (val > 1024))
	{
		h_shift = 1;                       
	}
	p0 = H;
	p1 = h;
	p2 = h_inv;

	for (i = 0; i < L_SUBFR/4; i++)
	{
		*p1 = *p0++ >> h_shift;         
		*p2++ = -(*p1++);  
		*p1 = *p0++ >> h_shift;         
		*p2++ = -(*p1++); 
		*p1 = *p0++ >> h_shift;         
		*p2++ = -(*p1++); 
		*p1 = *p0++ >> h_shift;         
		*p2++ = -(*p1++); 
	}

	/*------------------------------------------------------------*
	 * Compute rrixix[][] needed for the codebook search.         *
	 * This algorithm compute impulse response energy of all      *
	 * positions (16) in each track (4).       Total = 4x16 = 64. *
	 *------------------------------------------------------------*/

	/* storage order --> i3i3, i2i2, i1i1, i0i0 */

	/* Init pointers to last position of rrixix[] */
	p0 = &rrixix[0][NB_POS - 1];           
	p1 = &rrixix[1][NB_POS - 1];           
	p2 = &rrixix[2][NB_POS - 1];           
	p3 = &rrixix[3][NB_POS - 1];           

	ptr_h1 = h;                            
	cor = 0x00008000L;                             /* for rounding */
	for (i = 0; i < NB_POS; i++)
	{
		cor += vo_L_mult((*ptr_h1), (*ptr_h1));
		ptr_h1++;
		*p3-- = extract_h(cor);            
		cor += vo_L_mult((*ptr_h1), (*ptr_h1));
		ptr_h1++;
		*p2-- = extract_h(cor);            
		cor += vo_L_mult((*ptr_h1), (*ptr_h1));
		ptr_h1++;
		*p1-- = extract_h(cor);            
		cor += vo_L_mult((*ptr_h1), (*ptr_h1));
		ptr_h1++;
		*p0-- = extract_h(cor);            
	}

	/*------------------------------------------------------------*
	 * Compute rrixiy[][] needed for the codebook search.         *
	 * This algorithm compute correlation between 2 pulses        *
	 * (2 impulses responses) in 4 possible adjacents tracks.     *
	 * (track 0-1, 1-2, 2-3 and 3-0).     Total = 4x16x16 = 1024. *
	 *------------------------------------------------------------*/

	/* storage order --> i2i3, i1i2, i0i1, i3i0 */

	pos = MSIZE - 1;                       
	ptr_hf = h + 1;                        

	for (k = 0; k < NB_POS; k++)
	{
		p3 = &rrixiy[2][pos];              
		p2 = &rrixiy[1][pos];              
		p1 = &rrixiy[0][pos];              
		p0 = &rrixiy[3][pos - NB_POS];     

		cor = 0x00008000L;                   /* for rounding */
		ptr_h1 = h;                        
		ptr_h2 = ptr_hf;                   

		for (i = k + 1; i < NB_POS; i++)
		{
			cor += vo_L_mult((*ptr_h1), (*ptr_h2));
			ptr_h1++;
			ptr_h2++;
			*p3 = extract_h(cor);          
			cor += vo_L_mult((*ptr_h1), (*ptr_h2));
			ptr_h1++;
			ptr_h2++;
			*p2 = extract_h(cor);          
			cor += vo_L_mult((*ptr_h1), (*ptr_h2));
			ptr_h1++;
			ptr_h2++;
			*p1 = extract_h(cor);          
			cor += vo_L_mult((*ptr_h1), (*ptr_h2));
			ptr_h1++;
			ptr_h2++;
			*p0 = extract_h(cor);         

			p3 -= (NB_POS + 1);
			p2 -= (NB_POS + 1);
			p1 -= (NB_POS + 1);
			p0 -= (NB_POS + 1);
		}
		cor += vo_L_mult((*ptr_h1), (*ptr_h2));
		ptr_h1++;
		ptr_h2++;
		*p3 = extract_h(cor);              
		cor += vo_L_mult((*ptr_h1), (*ptr_h2));
		ptr_h1++;
		ptr_h2++;
		*p2 = extract_h(cor);              
		cor += vo_L_mult((*ptr_h1), (*ptr_h2));
		ptr_h1++;
		ptr_h2++;
		*p1 = extract_h(cor);              

		pos -= NB_POS;
		ptr_hf += STEP;
	}

	/* storage order --> i3i0, i2i3, i1i2, i0i1 */

	pos = MSIZE - 1;                       
	ptr_hf = h + 3;                        

	for (k = 0; k < NB_POS; k++)
	{
		p3 = &rrixiy[3][pos];              
		p2 = &rrixiy[2][pos - 1];          
		p1 = &rrixiy[1][pos - 1];          
		p0 = &rrixiy[0][pos - 1];          

		cor = 0x00008000L;								/* for rounding */
		ptr_h1 = h;                        
		ptr_h2 = ptr_hf;                   

		for (i = k + 1; i < NB_POS; i++)
		{
			cor += vo_L_mult((*ptr_h1), (*ptr_h2));
			ptr_h1++;
			ptr_h2++;
			*p3 = extract_h(cor);          
			cor += vo_L_mult((*ptr_h1), (*ptr_h2));
			ptr_h1++;
			ptr_h2++;
			*p2 = extract_h(cor);          
			cor += vo_L_mult((*ptr_h1), (*ptr_h2));
			ptr_h1++;
			ptr_h2++;
			*p1 = extract_h(cor);          
			cor += vo_L_mult((*ptr_h1), (*ptr_h2));
			ptr_h1++;
			ptr_h2++;
			*p0 = extract_h(cor);          

			p3 -= (NB_POS + 1);
			p2 -= (NB_POS + 1);
			p1 -= (NB_POS + 1);
			p0 -= (NB_POS + 1);
		}
		cor += vo_L_mult((*ptr_h1), (*ptr_h2));
		ptr_h1++;
		ptr_h2++;
		*p3 = extract_h(cor);              

		pos--;
		ptr_hf += STEP;
	}

	/*------------------------------------------------------------*
	 * Modification of rrixiy[][] to take signs into account.     *
	 *------------------------------------------------------------*/

	p0 = &rrixiy[0][0];                    

	for (k = 0; k < NB_TRACK; k++)
	{
		j_temp = (k + 1)&0x03;
		for (i = k; i < L_SUBFR; i += STEP)
		{
			psign = sign;                  
			if (psign[i] < 0)
			{
				psign = vec;               
			}
			j = j_temp;
			for (; j < L_SUBFR; j += STEP)
			{
				*p0 = vo_mult(*p0, psign[j]);    
				p0++;
			}
		}
	}

	/*-------------------------------------------------------------------*
	 *                       Deep first search                           *
	 *-------------------------------------------------------------------*/

	psk = -1;                              
	alpk = 1;                              

	for (k = 0; k < nbiter; k++)
	{
		j_temp = k<<2;
		for (i = 0; i < nb_pulse; i++)
			ipos[i] = tipos[j_temp + i];

		if(nbbits == 20)
		{
			pos = 0;                       
			ps = 0;                        
			alp = 0;                       
			for (i = 0; i < L_SUBFR; i++)
			{
				vec[i] = 0;                
			}
		} else if ((nbbits == 36) || (nbbits == 44))
		{
			/* first stage: fix 2 pulses */
			pos = 2;

			ix = ind[0] = pos_max[ipos[0]];
			iy = ind[1] = pos_max[ipos[1]];
			ps = dn[ix] + dn[iy];
			i = ix >> 2;                /* ix / STEP */
			j = iy >> 2;                /* iy / STEP */
			s = rrixix[ipos[0]][i] << 13;
			s += rrixix[ipos[1]][j] << 13;
			i = (i << 4) + j;         /* (ix/STEP)*NB_POS + (iy/STEP) */
			s += rrixiy[ipos[0]][i] << 14;
			alp = (s + 0x8000) >> 16;
			if (sign[ix] < 0)
				p0 = h_inv - ix;
			else
				p0 = h - ix;
			if (sign[iy] < 0)
				p1 = h_inv - iy;
			else
				p1 = h - iy;

			for (i = 0; i < L_SUBFR; i++)
			{
				vec[i] = (*p0++) + (*p1++);
			}

			if(nbbits == 44)
			{
				ipos[8] = 0;               
				ipos[9] = 1;               
			}
		} else
		{