117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong/*
217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong ** Copyright 2003-2010, VisualOn, Inc.
317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong **
417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong ** Licensed under the Apache License, Version 2.0 (the "License");
517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong ** you may not use this file except in compliance with the License.
617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong ** You may obtain a copy of the License at
717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong **
817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong **     http://www.apache.org/licenses/LICENSE-2.0
917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong **
1017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong ** Unless required by applicable law or agreed to in writing, software
1117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong ** distributed under the License is distributed on an "AS IS" BASIS,
1217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong ** See the License for the specific language governing permissions and
1417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong ** limitations under the License.
1517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong */
1617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
1717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong/***********************************************************************
1817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*      File: c4t64fx.c                                                 *
1917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*                                                                      *
2017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*	   Description:Performs algebraic codebook search for higher modes *
2117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*                                                                      *
2217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong************************************************************************/
2317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
2417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong/************************************************************************
2517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* Function: ACELP_4t64_fx()                                             *
2617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*                                                                       *
2717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* 20, 36, 44, 52, 64, 72, 88 bits algebraic codebook.                   *
2817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* 4 tracks x 16 positions per track = 64 samples.                       *
2917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*                                                                       *
3017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* 20 bits --> 4 pulses in a frame of 64 samples.                        *
3117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* 36 bits --> 8 pulses in a frame of 64 samples.                        *
3217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* 44 bits --> 10 pulses in a frame of 64 samples.                       *
3317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* 52 bits --> 12 pulses in a frame of 64 samples.                       *
3417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* 64 bits --> 16 pulses in a frame of 64 samples.                       *
3517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* 72 bits --> 18 pulses in a frame of 64 samples.                       *
3617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* 88 bits --> 24 pulses in a frame of 64 samples.                       *
3717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*                                                                       *
3817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* All pulses can have two (2) possible amplitudes: +1 or -1.            *
3917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* Each pulse can have sixteen (16) possible positions.                  *
4017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*************************************************************************/
4117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
4217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#include "typedef.h"
4317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#include "basic_op.h"
4417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#include "math_op.h"
4517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#include "acelp.h"
4617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#include "cnst.h"
4717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
4817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#include "q_pulse.h"
4917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
5017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dongstatic Word16 tipos[36] = {
5117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	0, 1, 2, 3,                            /* starting point &ipos[0], 1st iter */
5217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	1, 2, 3, 0,                            /* starting point &ipos[4], 2nd iter */
5317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	2, 3, 0, 1,                            /* starting point &ipos[8], 3rd iter */
5417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	3, 0, 1, 2,                            /* starting point &ipos[12], 4th iter */
5517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	0, 1, 2, 3,
5617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	1, 2, 3, 0,
5717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	2, 3, 0, 1,
5817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	3, 0, 1, 2,
5917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	0, 1, 2, 3};                           /* end point for 24 pulses &ipos[35], 4th iter */
6017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
6117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#define NB_PULSE_MAX  24
6217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
6317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#define L_SUBFR   64
6417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#define NB_TRACK  4
6517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#define STEP      4
6617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#define NB_POS    16
6717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#define MSIZE     256
6817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#define NB_MAX    8
6917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#define NPMAXPT   ((NB_PULSE_MAX+NB_TRACK-1)/NB_TRACK)
7017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
7117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong/* Private functions */
7217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dongvoid cor_h_vec_012(
7317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 h[],                           /* (i) scaled impulse response                 */
7417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 vec[],                         /* (i) scaled vector (/8) to correlate with h[] */
7517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 track,                         /* (i) track to use                            */
7617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 sign[],                        /* (i) sign vector                             */
7717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 rrixix[][NB_POS],              /* (i) correlation of h[x] with h[x]      */
7817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 cor_1[],                       /* (o) result of correlation (NB_POS elements) */
7917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 cor_2[]                        /* (o) result of correlation (NB_POS elements) */
8017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		);
8117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
8217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dongvoid cor_h_vec_012_asm(
8317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 h[],                           /* (i) scaled impulse response                 */
8417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 vec[],                         /* (i) scaled vector (/8) to correlate with h[] */
8517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 track,                         /* (i) track to use                            */
8617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 sign[],                        /* (i) sign vector                             */
8717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 rrixix[][NB_POS],              /* (i) correlation of h[x] with h[x]      */
8817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 cor_1[],                       /* (o) result of correlation (NB_POS elements) */
8917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 cor_2[]                        /* (o) result of correlation (NB_POS elements) */
9017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		);
9117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
9217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dongvoid cor_h_vec_30(
9317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 h[],                           /* (i) scaled impulse response                 */
9417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 vec[],                         /* (i) scaled vector (/8) to correlate with h[] */
9517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 track,                         /* (i) track to use                            */
9617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 sign[],                        /* (i) sign vector                             */
9717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 rrixix[][NB_POS],              /* (i) correlation of h[x] with h[x]      */
9817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 cor_1[],                       /* (o) result of correlation (NB_POS elements) */
9917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 cor_2[]                        /* (o) result of correlation (NB_POS elements) */
10017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		);
10117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
10217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dongvoid search_ixiy(
10317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 nb_pos_ix,                     /* (i) nb of pos for pulse 1 (1..8)       */
10417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 track_x,                       /* (i) track of pulse 1                   */
10517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 track_y,                       /* (i) track of pulse 2                   */
10617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 * ps,                          /* (i/o) correlation of all fixed pulses  */
10717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 * alp,                         /* (i/o) energy of all fixed pulses       */
10817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 * ix,                          /* (o) position of pulse 1                */
10917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 * iy,                          /* (o) position of pulse 2                */
11017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 dn[],                          /* (i) corr. between target and h[]       */
11117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 dn2[],                         /* (i) vector of selected positions       */
11217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 cor_x[],                       /* (i) corr. of pulse 1 with fixed pulses */
11317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 cor_y[],                       /* (i) corr. of pulse 2 with fixed pulses */
11417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 rrixiy[][MSIZE]                /* (i) corr. of pulse 1 with pulse 2   */
11517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		);
11617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
11717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
11817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dongvoid ACELP_4t64_fx(
11917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 dn[],                          /* (i) <12b : correlation between target x[] and H[]      */
12017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 cn[],                          /* (i) <12b : residual after long term prediction         */
12117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 H[],                           /* (i) Q12: impulse response of weighted synthesis filter */
12217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 code[],                        /* (o) Q9 : algebraic (fixed) codebook excitation         */
12317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 y[],                           /* (o) Q9 : filtered fixed codebook excitation            */
12417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 nbbits,                        /* (i) : 20, 36, 44, 52, 64, 72 or 88 bits                */
12517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 ser_size,                      /* (i) : bit rate                                         */
12617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 _index[]                       /* (o) : index (20): 5+5+5+5 = 20 bits.                   */
12717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		/* (o) : index (36): 9+9+9+9 = 36 bits.                   */
12817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		/* (o) : index (44): 13+9+13+9 = 44 bits.                 */
12917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		/* (o) : index (52): 13+13+13+13 = 52 bits.               */
13017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		/* (o) : index (64): 2+2+2+2+14+14+14+14 = 64 bits.       */
13117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		/* (o) : index (72): 10+2+10+2+10+14+10+14 = 72 bits.     */
13217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		/* (o) : index (88): 11+11+11+11+11+11+11+11 = 88 bits.   */
13317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		)
13417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong{
13517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word32 i, j, k;
13617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word16 st, ix, iy, pos, index, track, nb_pulse, nbiter, j_temp;
13717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word16 psk, ps, alpk, alp, val, k_cn, k_dn, exp;
13817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word16 *p0, *p1, *p2, *p3, *psign;
13917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word16 *h, *h_inv, *ptr_h1, *ptr_h2, *ptr_hf, h_shift;
14017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word32 s, cor, L_tmp, L_index;
14117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word16 dn2[L_SUBFR], sign[L_SUBFR], vec[L_SUBFR];
14217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word16 ind[NPMAXPT * NB_TRACK];
14317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word16 codvec[NB_PULSE_MAX], nbpos[10];
14417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word16 cor_x[NB_POS], cor_y[NB_POS], pos_max[NB_TRACK];
14517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word16 h_buf[4 * L_SUBFR];
14617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word16 rrixix[NB_TRACK][NB_POS], rrixiy[NB_TRACK][MSIZE];
14717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word16 ipos[NB_PULSE_MAX];
14817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
14917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	switch (nbbits)
15017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
15117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		case 20:                               /* 20 bits, 4 pulses, 4 tracks */
15217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbiter = 4;                          /* 4x16x16=1024 loop */
15317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			alp = 8192;                          /* alp = 2.0 (Q12) */
15417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nb_pulse = 4;
15517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[0] = 4;
15617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[1] = 8;
15717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			break;
15817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		case 36:                               /* 36 bits, 8 pulses, 4 tracks */
15917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbiter = 4;                          /* 4x20x16=1280 loop */
16017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			alp = 4096;                          /* alp = 1.0 (Q12) */
16117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nb_pulse = 8;
16217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[0] = 4;
16317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[1] = 8;
16417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[2] = 8;
16517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			break;
16617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		case 44:                               /* 44 bits, 10 pulses, 4 tracks */
16717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbiter = 4;                          /* 4x26x16=1664 loop */
16817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			alp = 4096;                          /* alp = 1.0 (Q12) */
16917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nb_pulse = 10;
17017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[0] = 4;
17117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[1] = 6;
17217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[2] = 8;
17317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[3] = 8;
17417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			break;
17517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		case 52:                               /* 52 bits, 12 pulses, 4 tracks */
17617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbiter = 4;                          /* 4x26x16=1664 loop */
17717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			alp = 4096;                          /* alp = 1.0 (Q12) */
17817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nb_pulse = 12;
17917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[0] = 4;
18017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[1] = 6;
18117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[2] = 8;
18217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[3] = 8;
18317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			break;
18417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		case 64:                               /* 64 bits, 16 pulses, 4 tracks */
18517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbiter = 3;                          /* 3x36x16=1728 loop */
18617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			alp = 3277;                          /* alp = 0.8 (Q12) */
18717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nb_pulse = 16;
18817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[0] = 4;
18917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[1] = 4;
19017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[2] = 6;
19117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[3] = 6;
19217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[4] = 8;
19317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[5] = 8;
19417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			break;
19517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		case 72:                               /* 72 bits, 18 pulses, 4 tracks */
19617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbiter = 3;                          /* 3x35x16=1680 loop */
19717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			alp = 3072;                          /* alp = 0.75 (Q12) */
19817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nb_pulse = 18;
19917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[0] = 2;
20017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[1] = 3;
20117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[2] = 4;
20217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[3] = 5;
20317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[4] = 6;
20417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[5] = 7;
20517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[6] = 8;
20617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			break;
20717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		case 88:                               /* 88 bits, 24 pulses, 4 tracks */
20817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			if(ser_size > 462)
20917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				nbiter = 1;
21017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			else
21117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				nbiter = 2;                    /* 2x53x16=1696 loop */
21217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
21317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			alp = 2048;                          /* alp = 0.5 (Q12) */
21417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nb_pulse = 24;
21517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[0] = 2;
21617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[1] = 2;
21717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[2] = 3;
21817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[3] = 4;
21917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[4] = 5;
22017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[5] = 6;
22117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[6] = 7;
22217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[7] = 8;
22317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[8] = 8;
22417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbpos[9] = 8;
22517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			break;
22617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		default:
22717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nbiter = 0;
22817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			alp = 0;
22917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			nb_pulse = 0;
23017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	}
23117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
23217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	for (i = 0; i < nb_pulse; i++)
23317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
23417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		codvec[i] = i;
23517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	}
23617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
23717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	/*----------------------------------------------------------------*
23817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * Find sign for each pulse position.                             *
23917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *----------------------------------------------------------------*/
24017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	/* calculate energy for normalization of cn[] and dn[] */
24117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	/* set k_cn = 32..32767 (ener_cn = 2^30..256-0) */
24217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#ifdef ASM_OPT                  /* asm optimization branch */
24317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	s = Dot_product12_asm(cn, cn, L_SUBFR, &exp);
24417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#else
24517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	s = Dot_product12(cn, cn, L_SUBFR, &exp);
24617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#endif
24717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
24817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Isqrt_n(&s, &exp);
24917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	s = L_shl(s, (exp + 5));
25017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	k_cn = extract_h(L_add(s, 0x8000));
25117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
25217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	/* set k_dn = 32..512 (ener_dn = 2^30..2^22) */
25317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#ifdef ASM_OPT                      /* asm optimization branch */
25417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	s = Dot_product12_asm(dn, dn, L_SUBFR, &exp);
25517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#else
25617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	s = Dot_product12(dn, dn, L_SUBFR, &exp);
25717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#endif
25817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
25917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Isqrt_n(&s, &exp);
26017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	k_dn = (L_shl(s, (exp + 5 + 3)) + 0x8000) >> 16;    /* k_dn = 256..4096 */
26117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	k_dn = vo_mult_r(alp, k_dn);              /* alp in Q12 */
26217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
26317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	/* mix normalized cn[] and dn[] */
26417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	p0 = cn;
26517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	p1 = dn;
26617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	p2 = dn2;
26717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
26817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	for (i = 0; i < L_SUBFR/4; i++)
26917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
27017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		s = (k_cn* (*p0++))+(k_dn * (*p1++));
27117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		*p2++ = s >> 7;
27217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		s = (k_cn* (*p0++))+(k_dn * (*p1++));
27317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		*p2++ = s >> 7;
27417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		s = (k_cn* (*p0++))+(k_dn * (*p1++));
27517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		*p2++ = s >> 7;
27617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		s = (k_cn* (*p0++))+(k_dn * (*p1++));
27717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		*p2++ = s >> 7;
27817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	}
27917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
28017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	/* set sign according to dn2[] = k_cn*cn[] + k_dn*dn[]    */
28117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	for(i = 0; i < L_SUBFR; i++)
28217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
28317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		val = dn[i];
28417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		ps = dn2[i];
28517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		if (ps >= 0)
28617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
28717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			sign[i] = 32767;             /* sign = +1 (Q12) */
28817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			vec[i] = -32768;
28917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		} else
29017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
29117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			sign[i] = -32768;            /* sign = -1 (Q12) */
29217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			vec[i] = 32767;
29317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			dn[i] = -val;
29417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			dn2[i] = -ps;
29517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		}
29617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	}
29717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	/*----------------------------------------------------------------*
29817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * Select NB_MAX position per track according to max of dn2[].    *
29917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *----------------------------------------------------------------*/
30017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	pos = 0;
30117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	for (i = 0; i < NB_TRACK; i++)
30217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
30317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		for (k = 0; k < NB_MAX; k++)
30417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
30517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			ps = -1;
30617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			for (j = i; j < L_SUBFR; j += STEP)
30717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			{
30817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				if(dn2[j] > ps)
30917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				{
31017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong					ps = dn2[j];
31117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong					pos = j;
31217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				}
31317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			}
31417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			dn2[pos] = (k - NB_MAX);     /* dn2 < 0 when position is selected */
31517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			if (k == 0)
31617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			{
31717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				pos_max[i] = pos;
31817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			}
31917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		}
32017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	}
32117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
32217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	/*--------------------------------------------------------------*
32317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * Scale h[] to avoid overflow and to get maximum of precision  *
32417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * on correlation.                                              *
32517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *                                                              *
32617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * Maximum of h[] (h[0]) is fixed to 2048 (MAX16 / 16).         *
32717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *  ==> This allow addition of 16 pulses without saturation.    *
32817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *                                                              *
32917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * Energy worst case (on resonant impulse response),            *
33017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * - energy of h[] is approximately MAX/16.                     *
33117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * - During search, the energy is divided by 8 to avoid         *
33217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *   overflow on "alp". (energy of h[] = MAX/128).              *
33317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *  ==> "alp" worst case detected is 22854 on sinusoidal wave.  *
33417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *--------------------------------------------------------------*/
33517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
33617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	/* impulse response buffer for fast computation */
33717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
33817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	h = h_buf;
33917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	h_inv = h_buf + (2 * L_SUBFR);
34017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	L_tmp = 0;
34117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	for (i = 0; i < L_SUBFR; i++)
34217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
34317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		*h++ = 0;
34417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		*h_inv++ = 0;
34517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		L_tmp += (H[i] * H[i]) << 1;
34617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	}
34717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	/* scale h[] down (/2) when energy of h[] is high with many pulses used */
34817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	val = extract_h(L_tmp);
34917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	h_shift = 0;
35017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
35117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	if ((nb_pulse >= 12) && (val > 1024))
35217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
35317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		h_shift = 1;
35417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	}
35517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	p0 = H;
35617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	p1 = h;
35717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	p2 = h_inv;
35817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
35917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	for (i = 0; i < L_SUBFR/4; i++)
36017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
36117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		*p1 = *p0++ >> h_shift;
36217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		*p2++ = -(*p1++);
36317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		*p1 = *p0++ >> h_shift;
36417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		*p2++ = -(*p1++);
36517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		*p1 = *p0++ >> h_shift;
36617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		*p2++ = -(*p1++);
36717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		*p1 = *p0++ >> h_shift;
36817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		*p2++ = -(*p1++);
36917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	}
37017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
37117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	/*------------------------------------------------------------*
37217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * Compute rrixix[][] needed for the codebook search.         *
37317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * This algorithm compute impulse response energy of all      *
37417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * positions (16) in each track (4).       Total = 4x16 = 64. *
37517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *------------------------------------------------------------*/
37617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
37717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	/* storage order --> i3i3, i2i2, i1i1, i0i0 */
37817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
37917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	/* Init pointers to last position of rrixix[] */
38017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	p0 = &rrixix[0][NB_POS - 1];
38117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	p1 = &rrixix[1][NB_POS - 1];
38217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	p2 = &rrixix[2][NB_POS - 1];
38317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	p3 = &rrixix[3][NB_POS - 1];
38417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
38517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	ptr_h1 = h;
38617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	cor = 0x00008000L;                             /* for rounding */
38717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	for (i = 0; i < NB_POS; i++)
38817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
38917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		cor += vo_L_mult((*ptr_h1), (*ptr_h1));
39017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		ptr_h1++;
39117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		*p3-- = extract_h(cor);
39217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		cor += vo_L_mult((*ptr_h1), (*ptr_h1));
39317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		ptr_h1++;
39417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		*p2-- = extract_h(cor);
39517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		cor += vo_L_mult((*ptr_h1), (*ptr_h1));
39617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		ptr_h1++;
39717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		*p1-- = extract_h(cor);
39817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		cor += vo_L_mult((*ptr_h1), (*ptr_h1));
39917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		ptr_h1++;
40017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		*p0-- = extract_h(cor);
40117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	}
40217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
40317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	/*------------------------------------------------------------*
40417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * Compute rrixiy[][] needed for the codebook search.         *
40517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * This algorithm compute correlation between 2 pulses        *
40617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * (2 impulses responses) in 4 possible adjacents tracks.     *
40717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * (track 0-1, 1-2, 2-3 and 3-0).     Total = 4x16x16 = 1024. *
40817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *------------------------------------------------------------*/
40917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
41017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	/* storage order --> i2i3, i1i2, i0i1, i3i0 */
41117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
41217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	pos = MSIZE - 1;
41317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	ptr_hf = h + 1;
41417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
41517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	for (k = 0; k < NB_POS; k++)
41617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
41717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		p3 = &rrixiy[2][pos];
41817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		p2 = &rrixiy[1][pos];
41917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		p1 = &rrixiy[0][pos];
42017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		p0 = &rrixiy[3][pos - NB_POS];
42117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
42217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		cor = 0x00008000L;                   /* for rounding */
42317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		ptr_h1 = h;
42417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		ptr_h2 = ptr_hf;
42517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
42617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		for (i = k + 1; i < NB_POS; i++)
42717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
42817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			cor += vo_L_mult((*ptr_h1), (*ptr_h2));
42917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			ptr_h1++;
43017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			ptr_h2++;
43117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			*p3 = extract_h(cor);
43217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			cor += vo_L_mult((*ptr_h1), (*ptr_h2));
43317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			ptr_h1++;
43417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			ptr_h2++;
43517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			*p2 = extract_h(cor);
43617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			cor += vo_L_mult((*ptr_h1), (*ptr_h2));
43717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			ptr_h1++;
43817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			ptr_h2++;
43917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			*p1 = extract_h(cor);
44017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			cor += vo_L_mult((*ptr_h1), (*ptr_h2));
44117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			ptr_h1++;
44217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			ptr_h2++;
44317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			*p0 = extract_h(cor);
44417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
44517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			p3 -= (NB_POS + 1);
44617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			p2 -= (NB_POS + 1);
44717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			p1 -= (NB_POS + 1);
44817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			p0 -= (NB_POS + 1);
44917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		}
45017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		cor += vo_L_mult((*ptr_h1), (*ptr_h2));
45117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		ptr_h1++;
45217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		ptr_h2++;
45317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		*p3 = extract_h(cor);
45417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		cor += vo_L_mult((*ptr_h1), (*ptr_h2));
45517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		ptr_h1++;
45617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		ptr_h2++;
45717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		*p2 = extract_h(cor);
45817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		cor += vo_L_mult((*ptr_h1), (*ptr_h2));
45917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		ptr_h1++;
46017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		ptr_h2++;
46117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		*p1 = extract_h(cor);
46217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
46317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		pos -= NB_POS;
46417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		ptr_hf += STEP;
46517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	}
46617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
46717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	/* storage order --> i3i0, i2i3, i1i2, i0i1 */
46817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
46917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	pos = MSIZE - 1;
47017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	ptr_hf = h + 3;
47117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
47217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	for (k = 0; k < NB_POS; k++)
47317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
47417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		p3 = &rrixiy[3][pos];
47517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		p2 = &rrixiy[2][pos - 1];
47617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		p1 = &rrixiy[1][pos - 1];
47717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		p0 = &rrixiy[0][pos - 1];
47817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
47917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		cor = 0x00008000L;								/* for rounding */
48017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		ptr_h1 = h;
48117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		ptr_h2 = ptr_hf;
48217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
48317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		for (i = k + 1; i < NB_POS; i++)
48417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
48517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			cor += vo_L_mult((*ptr_h1), (*ptr_h2));
48617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			ptr_h1++;
48717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			ptr_h2++;
48817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			*p3 = extract_h(cor);
48917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			cor += vo_L_mult((*ptr_h1), (*ptr_h2));
49017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			ptr_h1++;
49117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			ptr_h2++;
49217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			*p2 = extract_h(cor);
49317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			cor += vo_L_mult((*ptr_h1), (*ptr_h2));
49417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			ptr_h1++;
49517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			ptr_h2++;
49617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			*p1 = extract_h(cor);
49717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			cor += vo_L_mult((*ptr_h1), (*ptr_h2));
49817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			ptr_h1++;
49917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			ptr_h2++;
50017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			*p0 = extract_h(cor);
50117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
50217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			p3 -= (NB_POS + 1);
50317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			p2 -= (NB_POS + 1);
50417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			p1 -= (NB_POS + 1);
50517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			p0 -= (NB_POS + 1);
50617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		}
50717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		cor += vo_L_mult((*ptr_h1), (*ptr_h2));
50817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		ptr_h1++;
50917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		ptr_h2++;
51017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		*p3 = extract_h(cor);
51117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
51217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		pos--;
51317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		ptr_hf += STEP;
51417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	}
51517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
51617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	/*------------------------------------------------------------*
51717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * Modification of rrixiy[][] to take signs into account.     *
51817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *------------------------------------------------------------*/
51917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
52017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	p0 = &rrixiy[0][0];
52117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
52217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	for (k = 0; k < NB_TRACK; k++)
52317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
52417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		j_temp = (k + 1)&0x03;
52517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		for (i = k; i < L_SUBFR; i += STEP)
52617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
52717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			psign = sign;
52817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			if (psign[i] < 0)
52917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			{
53017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				psign = vec;
53117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			}
53217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			j = j_temp;
53317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			for (; j < L_SUBFR; j += STEP)
53417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			{
53517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				*p0 = vo_mult(*p0, psign[j]);
53617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				p0++;
53717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			}
53817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		}
53917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	}
54017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
54117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	/*-------------------------------------------------------------------*
54217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *                       Deep first search                           *
54317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *-------------------------------------------------------------------*/
54417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
54517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	psk = -1;
54617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	alpk = 1;
54717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
54817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	for (k = 0; k < nbiter; k++)
54917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
55017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		j_temp = k<<2;
55117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		for (i = 0; i < nb_pulse; i++)
55217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			ipos[i] = tipos[j_temp + i];
55317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
55417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		if(nbbits == 20)
55517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
55617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			pos = 0;
55717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			ps = 0;
55817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			alp = 0;
55917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			for (i = 0; i < L_SUBFR; i++)
56017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			{
56117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				vec[i] = 0;
56217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			}
56317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		} else if ((nbbits == 36) || (nbbits == 44))
56417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
56517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			/* first stage: fix 2 pulses */
56617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			pos = 2;
56717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
56817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			ix = ind[0] = pos_max[ipos[0]];
56917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			iy = ind[1] = pos_max[ipos[1]];
57017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			ps = dn[ix] + dn[iy];
57117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			i = ix >> 2;                /* ix / STEP */
57217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			j = iy >> 2;                /* iy / STEP */
57317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			s = rrixix[ipos[0]][i] << 13;
57417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			s += rrixix[ipos[1]][j] << 13;
57517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			i = (i << 4) + j;         /* (ix/STEP)*NB_POS + (iy/STEP) */
57617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			s += rrixiy[ipos[0]][i] << 14;
57717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			alp = (s + 0x8000) >> 16;
57817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			if (sign[ix] < 0)
57917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				p0 = h_inv - ix;
58017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			else
58117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				p0 = h - ix;
58217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			if (sign[iy] < 0)
58317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				p1 = h_inv - iy;
58417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			else
58517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				p1 = h - iy;
58617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
58717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			for (i = 0; i < L_SUBFR; i++)
58817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			{
58917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				vec[i] = (*p0++) + (*p1++);
59017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			}
59117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
59217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			if(nbbits == 44)
59317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			{
59417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				ipos[8] = 0;
59517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				ipos[9] = 1;
59617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			}
59717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		} else
59817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
59917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			/* first stage: fix 4 pulses */
60017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			pos = 4;
60117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
60217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			ix = ind[0] = pos_max[ipos[0]];
60317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			iy = ind[1] = pos_max[ipos[1]];
60417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			i = ind[2] = pos_max[ipos[2]];
60517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			j = ind[3] = pos_max[ipos[3]];
60617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			ps = add1(add1(add1(dn[ix], dn[iy]), dn[i]), dn[j]);
60717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
60817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			if (sign[ix] < 0)
60917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				p0 = h_inv - ix;
61017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			else
61117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				p0 = h - ix;
61217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
61317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			if (sign[iy] < 0)
61417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				p1 = h_inv - iy;
61517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			else
61617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				p1 = h - iy;
61717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
61817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			if (sign[i] < 0)
61917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				p2 = h_inv - i;
62017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			else
62117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				p2 = h - i;
62217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
62317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			if (sign[j] < 0)
62417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				p3 = h_inv - j;
62517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			else
62617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				p3 = h - j;
62717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
62817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			L_tmp = 0L;
62917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			for(i = 0; i < L_SUBFR; i++)
63017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			{
63117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				vec[i]  = add1(add1(add1(*p0++, *p1++), *p2++), *p3++);
63217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				L_tmp  += (vec[i] * vec[i]) << 1;
63317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			}
63417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
63517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			alp = ((L_tmp >> 3) + 0x8000) >> 16;
63617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
63717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			if(nbbits == 72)
63817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			{
63917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				ipos[16] = 0;
64017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				ipos[17] = 1;
64117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			}
64217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		}
64317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
64417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		/* other stages of 2 pulses */
64517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
64617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		for (j = pos, st = 0; j < nb_pulse; j += 2, st++)
64717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
64817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			/*--------------------------------------------------*
64917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			 * Calculate correlation of all possible positions  *
65017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			 * of the next 2 pulses with previous fixed pulses. *
65117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			 * Each pulse can have 16 possible positions.       *
65217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			 *--------------------------------------------------*/
65317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			if(ipos[j] == 3)
65417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			{
65517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				cor_h_vec_30(h, vec, ipos[j], sign, rrixix, cor_x, cor_y);
65617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			}
65717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			else
65817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			{
65917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#ifdef ASM_OPT                 /* asm optimization branch */
66017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				cor_h_vec_012_asm(h, vec, ipos[j], sign, rrixix, cor_x, cor_y);
66117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#else
66217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				cor_h_vec_012(h, vec, ipos[j], sign, rrixix, cor_x, cor_y);
66317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#endif
66417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			}
66517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			/*--------------------------------------------------*
66617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			 * Find best positions of 2 pulses.                 *
66717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			 *--------------------------------------------------*/
66817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			search_ixiy(nbpos[st], ipos[j], ipos[j + 1], &ps, &alp,
66917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong					&ix, &iy, dn, dn2, cor_x, cor_y, rrixiy);
67017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
67117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			ind[j] = ix;
67217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			ind[j + 1] = iy;
67317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
67417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			if (sign[ix] < 0)
67517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				p0 = h_inv - ix;
67617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			else
67717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				p0 = h - ix;
67817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			if (sign[iy] < 0)
67917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				p1 = h_inv - iy;
68017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			else
68117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				p1 = h - iy;
68217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
68317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			for (i = 0; i < L_SUBFR; i+=4)
68417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			{
68517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				vec[i]   += add1((*p0++), (*p1++));
68617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				vec[i+1] += add1((*p0++), (*p1++));
68717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				vec[i+2] += add1((*p0++), (*p1++));
68817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				vec[i+3] += add1((*p0++), (*p1++));
68917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			}
69017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		}
69117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		/* memorise the best codevector */
69217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		ps = vo_mult(ps, ps);
69317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		s = vo_L_msu(vo_L_mult(alpk, ps), psk, alp);
69417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		if (s > 0)
69517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
69617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			psk = ps;
69717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			alpk = alp;
69817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			for (i = 0; i < nb_pulse; i++)
69917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			{
70017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				codvec[i] = ind[i];
70117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			}
70217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			for (i = 0; i < L_SUBFR; i++)
70317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			{
70417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				y[i] = vec[i];
70517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			}
70617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		}
70717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	}
70817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	/*-------------------------------------------------------------------*
70917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 * Build the codeword, the filtered codeword and index of codevector.*
71017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	 *-------------------------------------------------------------------*/
71117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	for (i = 0; i < NPMAXPT * NB_TRACK; i++)
71217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
71317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		ind[i] = -1;
71417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	}
71517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	for (i = 0; i < L_SUBFR; i++)
71617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
71717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		code[i] = 0;
71817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		y[i] = vo_shr_r(y[i], 3);               /* Q12 to Q9 */
71917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	}
72017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	val = (512 >> h_shift);               /* codeword in Q9 format */
72117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	for (k = 0; k < nb_pulse; k++)
72217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
72317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		i = codvec[k];                       /* read pulse position */
72417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		j = sign[i];                         /* read sign           */
72517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		index = i >> 2;                 /* index = pos of pulse (0..15) */
72617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		track = (Word16) (i & 0x03);         /* track = i % NB_TRACK (0..3)  */
72717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
72817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		if (j > 0)
72917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
73017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			code[i] += val;
73117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			codvec[k] += 128;
73217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		} else
73317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
73417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			code[i] -= val;
73517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			index += NB_POS;
73617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		}
73717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
73817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		i = (Word16)((vo_L_mult(track, NPMAXPT) >> 1));
73917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
74017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		while (ind[i] >= 0)
74117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
74217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			i += 1;
74317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		}
74417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		ind[i] = index;
74517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	}
74617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
74717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	k = 0;
74817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	/* Build index of codevector */
74917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	if(nbbits == 20)
75017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
75117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		for (track = 0; track < NB_TRACK; track++)
75217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
75317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			_index[track] = (Word16)(quant_1p_N1(ind[k], 4));
75417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			k += NPMAXPT;
75517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		}
75617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	} else if(nbbits == 36)
75717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
75817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		for (track = 0; track < NB_TRACK; track++)
75917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
76017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			_index[track] = (Word16)(quant_2p_2N1(ind[k], ind[k + 1], 4));
76117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			k += NPMAXPT;
76217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		}
76317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	} else if(nbbits == 44)
76417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
76517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		for (track = 0; track < NB_TRACK - 2; track++)
76617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
76717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			_index[track] = (Word16)(quant_3p_3N1(ind[k], ind[k + 1], ind[k + 2], 4));
76817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			k += NPMAXPT;
76917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		}
77017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		for (track = 2; track < NB_TRACK; track++)
77117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
77217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			_index[track] = (Word16)(quant_2p_2N1(ind[k], ind[k + 1], 4));
77317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			k += NPMAXPT;
77417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		}
77517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	} else if(nbbits == 52)
77617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
77717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		for (track = 0; track < NB_TRACK; track++)
77817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
77917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			_index[track] = (Word16)(quant_3p_3N1(ind[k], ind[k + 1], ind[k + 2], 4));
78017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			k += NPMAXPT;
78117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		}
78217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	} else if(nbbits == 64)
78317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
78417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		for (track = 0; track < NB_TRACK; track++)
78517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
78617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			L_index = quant_4p_4N(&ind[k], 4);
78717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			_index[track] = (Word16)((L_index >> 14) & 3);
78817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			_index[track + NB_TRACK] = (Word16)(L_index & 0x3FFF);
78917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			k += NPMAXPT;
79017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		}
79117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	} else if(nbbits == 72)
79217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
79317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		for (track = 0; track < NB_TRACK - 2; track++)
79417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
79517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			L_index = quant_5p_5N(&ind[k], 4);
79617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			_index[track] = (Word16)((L_index >> 10) & 0x03FF);
79717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			_index[track + NB_TRACK] = (Word16)(L_index & 0x03FF);
79817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			k += NPMAXPT;
79917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		}
80017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		for (track = 2; track < NB_TRACK; track++)
80117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
80217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			L_index = quant_4p_4N(&ind[k], 4);
80317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			_index[track] = (Word16)((L_index >> 14) & 3);
80417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			_index[track + NB_TRACK] = (Word16)(L_index & 0x3FFF);
80517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			k += NPMAXPT;
80617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		}
80717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	} else if(nbbits == 88)
80817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
80917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		for (track = 0; track < NB_TRACK; track++)
81017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
81117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			L_index = quant_6p_6N_2(&ind[k], 4);
81217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			_index[track] = (Word16)((L_index >> 11) & 0x07FF);
81317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			_index[track + NB_TRACK] = (Word16)(L_index & 0x07FF);
81417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			k += NPMAXPT;
81517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		}
81617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	}
81717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	return;
81817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong}
81917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
82017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
82117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong/*-------------------------------------------------------------------*
82217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong * Function  cor_h_vec()                                             *
82317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong * ~~~~~~~~~~~~~~~~~~~~~                                             *
82417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong * Compute correlations of h[] with vec[] for the specified track.   *
82517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *-------------------------------------------------------------------*/
82617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dongvoid cor_h_vec_30(
82717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 h[],                           /* (i) scaled impulse response                 */
82817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 vec[],                         /* (i) scaled vector (/8) to correlate with h[] */
82917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 track,                         /* (i) track to use                            */
83017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 sign[],                        /* (i) sign vector                             */
83117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 rrixix[][NB_POS],              /* (i) correlation of h[x] with h[x]      */
83217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 cor_1[],                       /* (o) result of correlation (NB_POS elements) */
83317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 cor_2[]                        /* (o) result of correlation (NB_POS elements) */
83417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		)
83517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong{
83617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word32 i, j, pos, corr;
83717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word16 *p0, *p1, *p2,*p3,*cor_x,*cor_y;
83817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word32 L_sum1,L_sum2;
83917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	cor_x = cor_1;
84017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	cor_y = cor_2;
84117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	p0 = rrixix[track];
84217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	p3 = rrixix[0];
84317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	pos = track;
84417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
84517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	for (i = 0; i < NB_POS; i+=2)
84617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
84717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		L_sum1 = L_sum2 = 0L;
84817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		p1 = h;
84917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		p2 = &vec[pos];
85017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		for (j=pos;j < L_SUBFR; j++)
85117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
85217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			L_sum1 += *p1 * *p2;
85317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			p2-=3;
85417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			L_sum2 += *p1++ * *p2;
85517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			p2+=4;
85617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		}
85717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		p2-=3;
85817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		L_sum2 += *p1++ * *p2++;
85917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		L_sum2 += *p1++ * *p2++;
86017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		L_sum2 += *p1++ * *p2++;
86117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
86217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		L_sum1 = (L_sum1 << 2);
86317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		L_sum2 = (L_sum2 << 2);
86417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
86517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		corr = vo_round(L_sum1);
86617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		*cor_x++ = vo_mult(corr, sign[pos]) + (*p0++);
86717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		corr = vo_round(L_sum2);
86817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		*cor_y++ = vo_mult(corr, sign[pos-3]) + (*p3++);
86917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		pos += STEP;
87017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
87117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		L_sum1 = L_sum2 = 0L;
87217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		p1 = h;
87317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		p2 = &vec[pos];
87417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		for (j=pos;j < L_SUBFR; j++)
87517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
87617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			L_sum1 += *p1 * *p2;
87717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			p2-=3;
87817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			L_sum2 += *p1++ * *p2;
87917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			p2+=4;
88017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		}
88117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		p2-=3;
88217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		L_sum2 += *p1++ * *p2++;
88317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		L_sum2 += *p1++ * *p2++;
88417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		L_sum2 += *p1++ * *p2++;
88517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
88617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		L_sum1 = (L_sum1 << 2);
88717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		L_sum2 = (L_sum2 << 2);
88817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
88917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		corr = vo_round(L_sum1);
89017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		*cor_x++ = vo_mult(corr, sign[pos]) + (*p0++);
89117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		corr = vo_round(L_sum2);
89217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		*cor_y++ = vo_mult(corr, sign[pos-3]) + (*p3++);
89317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		pos += STEP;
89417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	}
89517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	return;
89617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong}
89717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
89817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dongvoid cor_h_vec_012(
89917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 h[],                           /* (i) scaled impulse response                 */
90017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 vec[],                         /* (i) scaled vector (/8) to correlate with h[] */
90117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 track,                         /* (i) track to use                            */
90217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 sign[],                        /* (i) sign vector                             */
90317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 rrixix[][NB_POS],              /* (i) correlation of h[x] with h[x]      */
90417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 cor_1[],                       /* (o) result of correlation (NB_POS elements) */
90517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 cor_2[]                        /* (o) result of correlation (NB_POS elements) */
90617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		)
90717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong{
90817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word32 i, j, pos, corr;
90917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word16 *p0, *p1, *p2,*p3,*cor_x,*cor_y;
91017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word32 L_sum1,L_sum2;
91117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	cor_x = cor_1;
91217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	cor_y = cor_2;
91317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	p0 = rrixix[track];
91417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	p3 = rrixix[track+1];
91517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	pos = track;
91617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
91717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	for (i = 0; i < NB_POS; i+=2)
91817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
91917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		L_sum1 = L_sum2 = 0L;
92017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		p1 = h;
92117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		p2 = &vec[pos];
92217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		for (j=62-pos ;j >= 0; j--)
92317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
92417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			L_sum1 += *p1 * *p2++;
92517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			L_sum2 += *p1++ * *p2;
92617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		}
92717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		L_sum1 += *p1 * *p2;
92817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		L_sum1 = (L_sum1 << 2);
92917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		L_sum2 = (L_sum2 << 2);
93017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
93117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		corr = (L_sum1 + 0x8000) >> 16;
93217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		cor_x[i] = vo_mult(corr, sign[pos]) + (*p0++);
93317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		corr = (L_sum2 + 0x8000) >> 16;
93417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		cor_y[i] = vo_mult(corr, sign[pos + 1]) + (*p3++);
93517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		pos += STEP;
93617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
93717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		L_sum1 = L_sum2 = 0L;
93817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		p1 = h;
93917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		p2 = &vec[pos];
94017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		for (j= 62-pos;j >= 0; j--)
94117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
94217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			L_sum1 += *p1 * *p2++;
94317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			L_sum2 += *p1++ * *p2;
94417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		}
94517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		L_sum1 += *p1 * *p2;
94617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		L_sum1 = (L_sum1 << 2);
94717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		L_sum2 = (L_sum2 << 2);
94817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
94917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		corr = (L_sum1 + 0x8000) >> 16;
95017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		cor_x[i+1] = vo_mult(corr, sign[pos]) + (*p0++);
95117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		corr = (L_sum2 + 0x8000) >> 16;
95217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		cor_y[i+1] = vo_mult(corr, sign[pos + 1]) + (*p3++);
95317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		pos += STEP;
95417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	}
95517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	return;
95617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong}
95717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
95817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong/*-------------------------------------------------------------------*
95917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong * Function  search_ixiy()                                           *
96017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong * ~~~~~~~~~~~~~~~~~~~~~~~                                           *
96117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong * Find the best positions of 2 pulses in a subframe.                *
96217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong *-------------------------------------------------------------------*/
96317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
96417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dongvoid search_ixiy(
96517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 nb_pos_ix,                     /* (i) nb of pos for pulse 1 (1..8)       */
96617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 track_x,                       /* (i) track of pulse 1                   */
96717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 track_y,                       /* (i) track of pulse 2                   */
96817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 * ps,                          /* (i/o) correlation of all fixed pulses  */
96917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 * alp,                         /* (i/o) energy of all fixed pulses       */
97017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 * ix,                          /* (o) position of pulse 1                */
97117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 * iy,                          /* (o) position of pulse 2                */
97217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 dn[],                          /* (i) corr. between target and h[]       */
97317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 dn2[],                         /* (i) vector of selected positions       */
97417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 cor_x[],                       /* (i) corr. of pulse 1 with fixed pulses */
97517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 cor_y[],                       /* (i) corr. of pulse 2 with fixed pulses */
97617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		Word16 rrixiy[][MSIZE]                /* (i) corr. of pulse 1 with pulse 2   */
97717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		)
97817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong{
97917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word32 x, y, pos, thres_ix;
98017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word16 ps1, ps2, sq, sqk;
98117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word16 alp_16, alpk;
98217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word16 *p0, *p1, *p2;
98317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	Word32 s, alp0, alp1, alp2;
98417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
98517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	p0 = cor_x;
98617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	p1 = cor_y;
98717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	p2 = rrixiy[track_x];
98817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
98917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	thres_ix = nb_pos_ix - NB_MAX;
99017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
99117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	alp0 = L_deposit_h(*alp);
99217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	alp0 = (alp0 + 0x00008000L);       /* for rounding */
99317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
99417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	sqk = -1;
99517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	alpk = 1;
99617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
99717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	for (x = track_x; x < L_SUBFR; x += STEP)
99817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	{
99917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		ps1 = *ps + dn[x];
100017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		alp1 = alp0 + ((*p0++)<<13);
100117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
100217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		if (dn2[x] < thres_ix)
100317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
100417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			pos = -1;
100517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			for (y = track_y; y < L_SUBFR; y += STEP)
100617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			{
100717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				ps2 = add1(ps1, dn[y]);
100817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
100917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				alp2 = alp1 + ((*p1++)<<13);
101017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				alp2 = alp2 + ((*p2++)<<14);
101117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				alp_16 = extract_h(alp2);
101217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				sq = vo_mult(ps2, ps2);
101317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				s = vo_L_mult(alpk, sq) - ((sqk * alp_16)<<1);
101417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
101517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				if (s > 0)
101617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				{
101717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong					sqk = sq;
101817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong					alpk = alp_16;
101917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong					pos = y;
102017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				}
102117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			}
102217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			p1 -= NB_POS;
102317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
102417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			if (pos >= 0)
102517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			{
102617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				*ix = x;
102717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong				*iy = pos;
102817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			}
102917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		} else
103017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		{
103117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong			p2 += NB_POS;
103217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		}
103317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	}
103417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
103517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	*ps = add1(*ps, add1(dn[*ix], dn[*iy]));
103617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	*alp = alpk;
103717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
103817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	return;
103917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong}
104017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
104117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
104217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
104317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
1044