1e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*
2e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Copyright 2003-2010, VisualOn, Inc.
3e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
4e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Licensed under the Apache License, Version 2.0 (the "License");
5e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** you may not use this file except in compliance with the License.
6e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** You may obtain a copy of the License at
7e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
8e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **     http://www.apache.org/licenses/LICENSE-2.0
9e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
10e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Unless required by applicable law or agreed to in writing, software
11e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** distributed under the License is distributed on an "AS IS" BASIS,
12e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** See the License for the specific language governing permissions and
14e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** limitations under the License.
15e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard */
16e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
17e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/***********************************************************************
18e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*      File: c4t64fx.c                                                 *
19e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                                      *
20e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*	   Description:Performs algebraic codebook search for higher modes *
21e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                                      *
22e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard************************************************************************/
23e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
24e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/************************************************************************
25e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function: ACELP_4t64_fx()                                             *
26e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                                       *
27e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 20, 36, 44, 52, 64, 72, 88 bits algebraic codebook.                   *
28e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 4 tracks x 16 positions per track = 64 samples.                       *
29e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                                       *
30e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 20 bits --> 4 pulses in a frame of 64 samples.                        *
31e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 36 bits --> 8 pulses in a frame of 64 samples.                        *
32e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 44 bits --> 10 pulses in a frame of 64 samples.                       *
33e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 52 bits --> 12 pulses in a frame of 64 samples.                       *
34e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 64 bits --> 16 pulses in a frame of 64 samples.                       *
35e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 72 bits --> 18 pulses in a frame of 64 samples.                       *
36e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 88 bits --> 24 pulses in a frame of 64 samples.                       *
37e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                                       *
38e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* All pulses can have two (2) possible amplitudes: +1 or -1.            *
39e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Each pulse can have sixteen (16) possible positions.                  *
40e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*************************************************************************/
41e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
42e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "typedef.h"
43e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "basic_op.h"
44e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "math_op.h"
45e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "acelp.h"
46e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "cnst.h"
47e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
48e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "q_pulse.h"
49e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
50e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic Word16 tipos[36] = {
51e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	0, 1, 2, 3,                            /* starting point &ipos[0], 1st iter */
52e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	1, 2, 3, 0,                            /* starting point &ipos[4], 2nd iter */
53e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	2, 3, 0, 1,                            /* starting point &ipos[8], 3rd iter */
54e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	3, 0, 1, 2,                            /* starting point &ipos[12], 4th iter */
55e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	0, 1, 2, 3,
56e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	1, 2, 3, 0,
57e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	2, 3, 0, 1,
58e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	3, 0, 1, 2,
59e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	0, 1, 2, 3};                           /* end point for 24 pulses &ipos[35], 4th iter */
60e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
61e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define NB_PULSE_MAX  24
62e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
63e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define L_SUBFR   64
64e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define NB_TRACK  4
65e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define STEP      4
66e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define NB_POS    16
67e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define MSIZE     256
68e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define NB_MAX    8
69e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define NPMAXPT   ((NB_PULSE_MAX+NB_TRACK-1)/NB_TRACK)
70e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
71e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/* Private functions */
72e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardvoid cor_h_vec_012(
73e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 h[],                           /* (i) scaled impulse response                 */
74e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 vec[],                         /* (i) scaled vector (/8) to correlate with h[] */
75e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 track,                         /* (i) track to use                            */
76e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 sign[],                        /* (i) sign vector                             */
77e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 rrixix[][NB_POS],              /* (i) correlation of h[x] with h[x]      */
78e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 cor_1[],                       /* (o) result of correlation (NB_POS elements) */
79e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 cor_2[]                        /* (o) result of correlation (NB_POS elements) */
80e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		);
81e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
82e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardvoid cor_h_vec_012_asm(
83e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 h[],                           /* (i) scaled impulse response                 */
84e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 vec[],                         /* (i) scaled vector (/8) to correlate with h[] */
85e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 track,                         /* (i) track to use                            */
86e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 sign[],                        /* (i) sign vector                             */
87e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 rrixix[][NB_POS],              /* (i) correlation of h[x] with h[x]      */
88e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 cor_1[],                       /* (o) result of correlation (NB_POS elements) */
89e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 cor_2[]                        /* (o) result of correlation (NB_POS elements) */
90e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		);
91e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
92e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardvoid cor_h_vec_30(
93e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 h[],                           /* (i) scaled impulse response                 */
94e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 vec[],                         /* (i) scaled vector (/8) to correlate with h[] */
95e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 track,                         /* (i) track to use                            */
96e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 sign[],                        /* (i) sign vector                             */
97e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 rrixix[][NB_POS],              /* (i) correlation of h[x] with h[x]      */
98e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 cor_1[],                       /* (o) result of correlation (NB_POS elements) */
99e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 cor_2[]                        /* (o) result of correlation (NB_POS elements) */
100e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		);
101e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
102e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardvoid search_ixiy(
103e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 nb_pos_ix,                     /* (i) nb of pos for pulse 1 (1..8)       */
104e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 track_x,                       /* (i) track of pulse 1                   */
105e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 track_y,                       /* (i) track of pulse 2                   */
106e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 * ps,                          /* (i/o) correlation of all fixed pulses  */
107e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 * alp,                         /* (i/o) energy of all fixed pulses       */
108e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 * ix,                          /* (o) position of pulse 1                */
109e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 * iy,                          /* (o) position of pulse 2                */
110e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 dn[],                          /* (i) corr. between target and h[]       */
111e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 dn2[],                         /* (i) vector of selected positions       */
112e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 cor_x[],                       /* (i) corr. of pulse 1 with fixed pulses */
113e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 cor_y[],                       /* (i) corr. of pulse 2 with fixed pulses */
114e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 rrixiy[][MSIZE]                /* (i) corr. of pulse 1 with pulse 2   */
115e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		);
116e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
117e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
118e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardvoid ACELP_4t64_fx(
119e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 dn[],                          /* (i) <12b : correlation between target x[] and H[]      */
120e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 cn[],                          /* (i) <12b : residual after long term prediction         */
121e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 H[],                           /* (i) Q12: impulse response of weighted synthesis filter */
122e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 code[],                        /* (o) Q9 : algebraic (fixed) codebook excitation         */
123e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 y[],                           /* (o) Q9 : filtered fixed codebook excitation            */
124e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 nbbits,                        /* (i) : 20, 36, 44, 52, 64, 72 or 88 bits                */
125e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 ser_size,                      /* (i) : bit rate                                         */
126e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 _index[]                       /* (o) : index (20): 5+5+5+5 = 20 bits.                   */
127e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		/* (o) : index (36): 9+9+9+9 = 36 bits.                   */
128e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		/* (o) : index (44): 13+9+13+9 = 44 bits.                 */
129e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		/* (o) : index (52): 13+13+13+13 = 52 bits.               */
130e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		/* (o) : index (64): 2+2+2+2+14+14+14+14 = 64 bits.       */
131e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		/* (o) : index (72): 10+2+10+2+10+14+10+14 = 72 bits.     */
132e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		/* (o) : index (88): 11+11+11+11+11+11+11+11 = 88 bits.   */
133e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		)
134e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
135e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 i, j, k;
136e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 st, ix, iy, pos, index, track, nb_pulse, nbiter, j_temp;
137e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 psk, ps, alpk, alp, val, k_cn, k_dn, exp;
138e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 *p0, *p1, *p2, *p3, *psign;
139e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 *h, *h_inv, *ptr_h1, *ptr_h2, *ptr_hf, h_shift;
140e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 s, cor, L_tmp, L_index;
141e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 dn2[L_SUBFR], sign[L_SUBFR], vec[L_SUBFR];
142e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 ind[NPMAXPT * NB_TRACK];
143e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 codvec[NB_PULSE_MAX], nbpos[10];
144e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 cor_x[NB_POS], cor_y[NB_POS], pos_max[NB_TRACK];
145e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 h_buf[4 * L_SUBFR];
146e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 rrixix[NB_TRACK][NB_POS], rrixiy[NB_TRACK][MSIZE];
147e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 ipos[NB_PULSE_MAX];
148e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
149e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	switch (nbbits)
150e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
151e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		case 20:                               /* 20 bits, 4 pulses, 4 tracks */
152e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			nbiter = 4;                          /* 4x16x16=1024 loop */
153e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			alp = 8192;                          /* alp = 2.0 (Q12) */
154b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nb_pulse = 4;
155b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[0] = 4;
156b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[1] = 8;
157e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			break;
158e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		case 36:                               /* 36 bits, 8 pulses, 4 tracks */
159e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			nbiter = 4;                          /* 4x20x16=1280 loop */
160e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			alp = 4096;                          /* alp = 1.0 (Q12) */
161b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nb_pulse = 8;
162b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[0] = 4;
163b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[1] = 8;
164b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[2] = 8;
165e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			break;
166e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		case 44:                               /* 44 bits, 10 pulses, 4 tracks */
167e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			nbiter = 4;                          /* 4x26x16=1664 loop */
168e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			alp = 4096;                          /* alp = 1.0 (Q12) */
169b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nb_pulse = 10;
170b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[0] = 4;
171b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[1] = 6;
172b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[2] = 8;
173b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[3] = 8;
174e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			break;
175e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		case 52:                               /* 52 bits, 12 pulses, 4 tracks */
176e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			nbiter = 4;                          /* 4x26x16=1664 loop */
177e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			alp = 4096;                          /* alp = 1.0 (Q12) */
178b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nb_pulse = 12;
179b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[0] = 4;
180b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[1] = 6;
181b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[2] = 8;
182b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[3] = 8;
183e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			break;
184e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		case 64:                               /* 64 bits, 16 pulses, 4 tracks */
185e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			nbiter = 3;                          /* 3x36x16=1728 loop */
186e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			alp = 3277;                          /* alp = 0.8 (Q12) */
187b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nb_pulse = 16;
188b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[0] = 4;
189b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[1] = 4;
190b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[2] = 6;
191b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[3] = 6;
192b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[4] = 8;
193b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[5] = 8;
194e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			break;
195e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		case 72:                               /* 72 bits, 18 pulses, 4 tracks */
196e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			nbiter = 3;                          /* 3x35x16=1680 loop */
197e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			alp = 3072;                          /* alp = 0.75 (Q12) */
198b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nb_pulse = 18;
199b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[0] = 2;
200b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[1] = 3;
201b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[2] = 4;
202b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[3] = 5;
203b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[4] = 6;
204b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[5] = 7;
205b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[6] = 8;
206e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			break;
207e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		case 88:                               /* 88 bits, 24 pulses, 4 tracks */
208e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			if(ser_size > 462)
209e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				nbiter = 1;
210e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			else
211e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				nbiter = 2;                    /* 2x53x16=1696 loop */
212e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
213e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			alp = 2048;                          /* alp = 0.5 (Q12) */
214b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nb_pulse = 24;
215b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[0] = 2;
216b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[1] = 2;
217b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[2] = 3;
218b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[3] = 4;
219b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[4] = 5;
220b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[5] = 6;
221b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[6] = 7;
222b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[7] = 8;
223b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[8] = 8;
224b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			nbpos[9] = 8;
225e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			break;
226e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		default:
227e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			nbiter = 0;
228e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			alp = 0;
229e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			nb_pulse = 0;
230e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
231e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
232e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 0; i < nb_pulse; i++)
233e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
234b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		codvec[i] = i;
235e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
236e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
237e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/*----------------------------------------------------------------*
238e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * Find sign for each pulse position.                             *
239e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *----------------------------------------------------------------*/
240e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* calculate energy for normalization of cn[] and dn[] */
241e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* set k_cn = 32..32767 (ener_cn = 2^30..256-0) */
242e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT                  /* asm optimization branch */
243e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	s = Dot_product12_asm(cn, cn, L_SUBFR, &exp);
244e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else
245e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	s = Dot_product12(cn, cn, L_SUBFR, &exp);
246e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
247e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
248e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Isqrt_n(&s, &exp);
249b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	s = L_shl(s, (exp + 5));
250e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	k_cn = extract_h(L_add(s, 0x8000));
251e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
252e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* set k_dn = 32..512 (ener_dn = 2^30..2^22) */
253e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT                      /* asm optimization branch */
254e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	s = Dot_product12_asm(dn, dn, L_SUBFR, &exp);
255e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else
256e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	s = Dot_product12(dn, dn, L_SUBFR, &exp);
257e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
258e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
259e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Isqrt_n(&s, &exp);
260e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	k_dn = (L_shl(s, (exp + 5 + 3)) + 0x8000) >> 16;    /* k_dn = 256..4096 */
261e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	k_dn = vo_mult_r(alp, k_dn);              /* alp in Q12 */
262e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
263e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* mix normalized cn[] and dn[] */
264e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	p0 = cn;
265e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	p1 = dn;
266e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	p2 = dn2;
267e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
268e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 0; i < L_SUBFR/4; i++)
269e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
270e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		s = (k_cn* (*p0++))+(k_dn * (*p1++));
271e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		*p2++ = s >> 7;
272e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		s = (k_cn* (*p0++))+(k_dn * (*p1++));
273e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		*p2++ = s >> 7;
274e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		s = (k_cn* (*p0++))+(k_dn * (*p1++));
275e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		*p2++ = s >> 7;
276e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		s = (k_cn* (*p0++))+(k_dn * (*p1++));
277b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		*p2++ = s >> 7;
278e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
279e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
280e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* set sign according to dn2[] = k_cn*cn[] + k_dn*dn[]    */
281e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for(i = 0; i < L_SUBFR; i++)
282e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
283b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		val = dn[i];
284b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		ps = dn2[i];
285e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		if (ps >= 0)
286e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
287e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			sign[i] = 32767;             /* sign = +1 (Q12) */
288b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			vec[i] = -32768;
289e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		} else
290e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
291e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			sign[i] = -32768;            /* sign = -1 (Q12) */
292b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			vec[i] = 32767;
293e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			dn[i] = -val;
294e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			dn2[i] = -ps;
295e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
296e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
297e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/*----------------------------------------------------------------*
298e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * Select NB_MAX position per track according to max of dn2[].    *
299e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *----------------------------------------------------------------*/
300e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	pos = 0;
301e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 0; i < NB_TRACK; i++)
302e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
303e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		for (k = 0; k < NB_MAX; k++)
304e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
305b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			ps = -1;
306e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			for (j = i; j < L_SUBFR; j += STEP)
307e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			{
308e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				if(dn2[j] > ps)
309e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				{
310b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard					ps = dn2[j];
311b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard					pos = j;
312e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				}
313e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			}
314e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			dn2[pos] = (k - NB_MAX);     /* dn2 < 0 when position is selected */
315e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			if (k == 0)
316e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			{
317b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				pos_max[i] = pos;
318e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			}
319e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
320e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
321e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
322e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/*--------------------------------------------------------------*
323e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * Scale h[] to avoid overflow and to get maximum of precision  *
324e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * on correlation.                                              *
325e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *                                                              *
326e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * Maximum of h[] (h[0]) is fixed to 2048 (MAX16 / 16).         *
327e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *  ==> This allow addition of 16 pulses without saturation.    *
328e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *                                                              *
329e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * Energy worst case (on resonant impulse response),            *
330e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * - energy of h[] is approximately MAX/16.                     *
331e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * - During search, the energy is divided by 8 to avoid         *
332e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *   overflow on "alp". (energy of h[] = MAX/128).              *
333e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *  ==> "alp" worst case detected is 22854 on sinusoidal wave.  *
334e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *--------------------------------------------------------------*/
335e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
336e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* impulse response buffer for fast computation */
337e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
338b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	h = h_buf;
339b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	h_inv = h_buf + (2 * L_SUBFR);
340e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	L_tmp = 0;
341e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 0; i < L_SUBFR; i++)
342e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
343b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		*h++ = 0;
344b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		*h_inv++ = 0;
345e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_tmp += (H[i] * H[i]) << 1;
346e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
347e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* scale h[] down (/2) when energy of h[] is high with many pulses used */
348e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	val = extract_h(L_tmp);
349b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	h_shift = 0;
350e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
351e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	if ((nb_pulse >= 12) && (val > 1024))
352e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
353b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		h_shift = 1;
354e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
355e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	p0 = H;
356e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	p1 = h;
357e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	p2 = h_inv;
358e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
359e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 0; i < L_SUBFR/4; i++)
360e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
361b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		*p1 = *p0++ >> h_shift;
362b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		*p2++ = -(*p1++);
363b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		*p1 = *p0++ >> h_shift;
364b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		*p2++ = -(*p1++);
365b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		*p1 = *p0++ >> h_shift;
366b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		*p2++ = -(*p1++);
367b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		*p1 = *p0++ >> h_shift;
368b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		*p2++ = -(*p1++);
369e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
370e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
371e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/*------------------------------------------------------------*
372e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * Compute rrixix[][] needed for the codebook search.         *
373e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * This algorithm compute impulse response energy of all      *
374e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * positions (16) in each track (4).       Total = 4x16 = 64. *
375e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *------------------------------------------------------------*/
376e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
377e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* storage order --> i3i3, i2i2, i1i1, i0i0 */
378e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
379e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Init pointers to last position of rrixix[] */
380b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	p0 = &rrixix[0][NB_POS - 1];
381b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	p1 = &rrixix[1][NB_POS - 1];
382b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	p2 = &rrixix[2][NB_POS - 1];
383b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	p3 = &rrixix[3][NB_POS - 1];
384e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
385b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	ptr_h1 = h;
386e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	cor = 0x00008000L;                             /* for rounding */
387e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 0; i < NB_POS; i++)
388e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
389e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		cor += vo_L_mult((*ptr_h1), (*ptr_h1));
390e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		ptr_h1++;
391b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		*p3-- = extract_h(cor);
392e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		cor += vo_L_mult((*ptr_h1), (*ptr_h1));
393e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		ptr_h1++;
394b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		*p2-- = extract_h(cor);
395e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		cor += vo_L_mult((*ptr_h1), (*ptr_h1));
396e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		ptr_h1++;
397b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		*p1-- = extract_h(cor);
398e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		cor += vo_L_mult((*ptr_h1), (*ptr_h1));
399e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		ptr_h1++;
400b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		*p0-- = extract_h(cor);
401e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
402e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
403e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/*------------------------------------------------------------*
404e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * Compute rrixiy[][] needed for the codebook search.         *
405e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * This algorithm compute correlation between 2 pulses        *
406e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * (2 impulses responses) in 4 possible adjacents tracks.     *
407e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * (track 0-1, 1-2, 2-3 and 3-0).     Total = 4x16x16 = 1024. *
408e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *------------------------------------------------------------*/
409e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
410e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* storage order --> i2i3, i1i2, i0i1, i3i0 */
411e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
412b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	pos = MSIZE - 1;
413b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	ptr_hf = h + 1;
414e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
415e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (k = 0; k < NB_POS; k++)
416e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
417b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		p3 = &rrixiy[2][pos];
418b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		p2 = &rrixiy[1][pos];
419b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		p1 = &rrixiy[0][pos];
420b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		p0 = &rrixiy[3][pos - NB_POS];
421e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
422e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		cor = 0x00008000L;                   /* for rounding */
423b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		ptr_h1 = h;
424b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		ptr_h2 = ptr_hf;
425e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
426e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		for (i = k + 1; i < NB_POS; i++)
427e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
428e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			cor += vo_L_mult((*ptr_h1), (*ptr_h2));
429e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			ptr_h1++;
430e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			ptr_h2++;
431b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			*p3 = extract_h(cor);
432e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			cor += vo_L_mult((*ptr_h1), (*ptr_h2));
433e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			ptr_h1++;
434e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			ptr_h2++;
435b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			*p2 = extract_h(cor);
436e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			cor += vo_L_mult((*ptr_h1), (*ptr_h2));
437e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			ptr_h1++;
438e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			ptr_h2++;
439b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			*p1 = extract_h(cor);
440e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			cor += vo_L_mult((*ptr_h1), (*ptr_h2));
441e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			ptr_h1++;
442e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			ptr_h2++;
443b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			*p0 = extract_h(cor);
444e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
445e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			p3 -= (NB_POS + 1);
446e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			p2 -= (NB_POS + 1);
447e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			p1 -= (NB_POS + 1);
448e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			p0 -= (NB_POS + 1);
449e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
450e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		cor += vo_L_mult((*ptr_h1), (*ptr_h2));
451e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		ptr_h1++;
452e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		ptr_h2++;
453b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		*p3 = extract_h(cor);
454e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		cor += vo_L_mult((*ptr_h1), (*ptr_h2));
455e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		ptr_h1++;
456e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		ptr_h2++;
457b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		*p2 = extract_h(cor);
458e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		cor += vo_L_mult((*ptr_h1), (*ptr_h2));
459e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		ptr_h1++;
460e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		ptr_h2++;
461b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		*p1 = extract_h(cor);
462e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
463e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		pos -= NB_POS;
464e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		ptr_hf += STEP;
465e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
466e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
467e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* storage order --> i3i0, i2i3, i1i2, i0i1 */
468e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
469b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	pos = MSIZE - 1;
470b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	ptr_hf = h + 3;
471e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
472e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (k = 0; k < NB_POS; k++)
473e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
474b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		p3 = &rrixiy[3][pos];
475b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		p2 = &rrixiy[2][pos - 1];
476b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		p1 = &rrixiy[1][pos - 1];
477b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		p0 = &rrixiy[0][pos - 1];
478e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
479e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		cor = 0x00008000L;								/* for rounding */
480b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		ptr_h1 = h;
481b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		ptr_h2 = ptr_hf;
482e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
483e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		for (i = k + 1; i < NB_POS; i++)
484e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
485e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			cor += vo_L_mult((*ptr_h1), (*ptr_h2));
486e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			ptr_h1++;
487e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			ptr_h2++;
488b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			*p3 = extract_h(cor);
489e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			cor += vo_L_mult((*ptr_h1), (*ptr_h2));
490e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			ptr_h1++;
491e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			ptr_h2++;
492b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			*p2 = extract_h(cor);
493e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			cor += vo_L_mult((*ptr_h1), (*ptr_h2));
494e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			ptr_h1++;
495e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			ptr_h2++;
496b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			*p1 = extract_h(cor);
497e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			cor += vo_L_mult((*ptr_h1), (*ptr_h2));
498e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			ptr_h1++;
499e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			ptr_h2++;
500b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			*p0 = extract_h(cor);
501e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
502e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			p3 -= (NB_POS + 1);
503e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			p2 -= (NB_POS + 1);
504e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			p1 -= (NB_POS + 1);
505e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			p0 -= (NB_POS + 1);
506e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
507e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		cor += vo_L_mult((*ptr_h1), (*ptr_h2));
508e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		ptr_h1++;
509e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		ptr_h2++;
510b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		*p3 = extract_h(cor);
511e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
512e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		pos--;
513e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		ptr_hf += STEP;
514e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
515e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
516e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/*------------------------------------------------------------*
517e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * Modification of rrixiy[][] to take signs into account.     *
518e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *------------------------------------------------------------*/
519e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
520b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	p0 = &rrixiy[0][0];
521e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
522e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (k = 0; k < NB_TRACK; k++)
523e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
524e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		j_temp = (k + 1)&0x03;
525e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		for (i = k; i < L_SUBFR; i += STEP)
526e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
527b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			psign = sign;
528e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			if (psign[i] < 0)
529e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			{
530b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				psign = vec;
531e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			}
532e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			j = j_temp;
533e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			for (; j < L_SUBFR; j += STEP)
534e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			{
535b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				*p0 = vo_mult(*p0, psign[j]);
536e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				p0++;
537e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			}
538e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
539e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
540e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
541e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/*-------------------------------------------------------------------*
542e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *                       Deep first search                           *
543e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *-------------------------------------------------------------------*/
544e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
545b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	psk = -1;
546b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	alpk = 1;
547e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
548e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (k = 0; k < nbiter; k++)
549e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
550e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		j_temp = k<<2;
551e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		for (i = 0; i < nb_pulse; i++)
552e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			ipos[i] = tipos[j_temp + i];
553e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
554e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		if(nbbits == 20)
555e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
556b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			pos = 0;
557b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			ps = 0;
558b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			alp = 0;
559e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			for (i = 0; i < L_SUBFR; i++)
560e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			{
561b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				vec[i] = 0;
562e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			}
563e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		} else if ((nbbits == 36) || (nbbits == 44))
564e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
565e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			/* first stage: fix 2 pulses */
566e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			pos = 2;
567e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
568e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			ix = ind[0] = pos_max[ipos[0]];
569e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			iy = ind[1] = pos_max[ipos[1]];
570e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			ps = dn[ix] + dn[iy];
571e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			i = ix >> 2;                /* ix / STEP */
572e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			j = iy >> 2;                /* iy / STEP */
573e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			s = rrixix[ipos[0]][i] << 13;
574e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			s += rrixix[ipos[1]][j] << 13;
575e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			i = (i << 4) + j;         /* (ix/STEP)*NB_POS + (iy/STEP) */
576e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			s += rrixiy[ipos[0]][i] << 14;
577e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			alp = (s + 0x8000) >> 16;
578e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			if (sign[ix] < 0)
579e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				p0 = h_inv - ix;
580e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			else
581e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				p0 = h - ix;
582e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			if (sign[iy] < 0)
583e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				p1 = h_inv - iy;
584e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			else
585e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				p1 = h - iy;
586e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
587e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			for (i = 0; i < L_SUBFR; i++)
588e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			{
589e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				vec[i] = (*p0++) + (*p1++);
590e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			}
591e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
592e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			if(nbbits == 44)
593e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			{
594b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				ipos[8] = 0;
595b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				ipos[9] = 1;
596e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			}
597e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		} else
598e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
599e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			/* first stage: fix 4 pulses */
600e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			pos = 4;
601e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
602b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			ix = ind[0] = pos_max[ipos[0]];
603b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			iy = ind[1] = pos_max[ipos[1]];
604b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			i = ind[2] = pos_max[ipos[2]];
605b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			j = ind[3] = pos_max[ipos[3]];
606e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			ps = add1(add1(add1(dn[ix], dn[iy]), dn[i]), dn[j]);
607e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
608e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			if (sign[ix] < 0)
609e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				p0 = h_inv - ix;
610e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			else
611e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				p0 = h - ix;
612e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
613e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			if (sign[iy] < 0)
614e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				p1 = h_inv - iy;
615e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			else
616e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				p1 = h - iy;
617e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
618e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			if (sign[i] < 0)
619e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				p2 = h_inv - i;
620e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			else
621e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				p2 = h - i;
622e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
623e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			if (sign[j] < 0)
624e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				p3 = h_inv - j;
625e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			else
626e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				p3 = h - j;
627e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
628e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			L_tmp = 0L;
629e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			for(i = 0; i < L_SUBFR; i++)
630e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			{
631e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				vec[i]  = add1(add1(add1(*p0++, *p1++), *p2++), *p3++);
632e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				L_tmp  += (vec[i] * vec[i]) << 1;
633e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			}
634e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
635e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			alp = ((L_tmp >> 3) + 0x8000) >> 16;
636e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
637e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			if(nbbits == 72)
638e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			{
639b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				ipos[16] = 0;
640b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				ipos[17] = 1;
641e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			}
642e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
643e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
644e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		/* other stages of 2 pulses */
645e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
646e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		for (j = pos, st = 0; j < nb_pulse; j += 2, st++)
647e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
648e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			/*--------------------------------------------------*
649e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			 * Calculate correlation of all possible positions  *
650e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			 * of the next 2 pulses with previous fixed pulses. *
651e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			 * Each pulse can have 16 possible positions.       *
652e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			 *--------------------------------------------------*/
653e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			if(ipos[j] == 3)
654e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			{
655e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				cor_h_vec_30(h, vec, ipos[j], sign, rrixix, cor_x, cor_y);
656e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			}
657e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			else
658e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			{
659e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT                 /* asm optimization branch */
660e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				cor_h_vec_012_asm(h, vec, ipos[j], sign, rrixix, cor_x, cor_y);
661e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else
662e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				cor_h_vec_012(h, vec, ipos[j], sign, rrixix, cor_x, cor_y);
663e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif
664e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			}
665e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			/*--------------------------------------------------*
666e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			 * Find best positions of 2 pulses.                 *
667e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			 *--------------------------------------------------*/
668e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			search_ixiy(nbpos[st], ipos[j], ipos[j + 1], &ps, &alp,
669e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard					&ix, &iy, dn, dn2, cor_x, cor_y, rrixiy);
670e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
671b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			ind[j] = ix;
672b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			ind[j + 1] = iy;
673e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
674e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			if (sign[ix] < 0)
675e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				p0 = h_inv - ix;
676e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			else
677e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				p0 = h - ix;
678e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			if (sign[iy] < 0)
679e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				p1 = h_inv - iy;
680e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			else
681e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				p1 = h - iy;
682e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
683e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			for (i = 0; i < L_SUBFR; i+=4)
684e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			{
685b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				vec[i]   += add1((*p0++), (*p1++));
686b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				vec[i+1] += add1((*p0++), (*p1++));
687b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				vec[i+2] += add1((*p0++), (*p1++));
688b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				vec[i+3] += add1((*p0++), (*p1++));
689e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			}
690e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
691e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		/* memorise the best codevector */
692e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		ps = vo_mult(ps, ps);
693e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		s = vo_L_msu(vo_L_mult(alpk, ps), psk, alp);
694e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		if (s > 0)
695e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
696b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			psk = ps;
697b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			alpk = alp;
698e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			for (i = 0; i < nb_pulse; i++)
699e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			{
700b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				codvec[i] = ind[i];
701e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			}
702e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			for (i = 0; i < L_SUBFR; i++)
703e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			{
704b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				y[i] = vec[i];
705e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			}
706e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
707e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
708e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/*-------------------------------------------------------------------*
709e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * Build the codeword, the filtered codeword and index of codevector.*
710e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 *-------------------------------------------------------------------*/
711e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 0; i < NPMAXPT * NB_TRACK; i++)
712e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
713b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		ind[i] = -1;
714e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
715e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 0; i < L_SUBFR; i++)
716e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
717b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		code[i] = 0;
718e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		y[i] = vo_shr_r(y[i], 3);               /* Q12 to Q9 */
719e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
720e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	val = (512 >> h_shift);               /* codeword in Q9 format */
721e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (k = 0; k < nb_pulse; k++)
722e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
723e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		i = codvec[k];                       /* read pulse position */
724e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		j = sign[i];                         /* read sign           */
725e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		index = i >> 2;                 /* index = pos of pulse (0..15) */
726e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		track = (Word16) (i & 0x03);         /* track = i % NB_TRACK (0..3)  */
727e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
728e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		if (j > 0)
729e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
730b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			code[i] += val;
731b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			codvec[k] += 128;
732e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		} else
733e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
734b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			code[i] -= val;
735b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			index += NB_POS;
736e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
737e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
738e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		i = (Word16)((vo_L_mult(track, NPMAXPT) >> 1));
739e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
740e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		while (ind[i] >= 0)
741e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
742e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			i += 1;
743e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
744b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		ind[i] = index;
745e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
746e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
747b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	k = 0;
748e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Build index of codevector */
749e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	if(nbbits == 20)
750e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
751e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		for (track = 0; track < NB_TRACK; track++)
752e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
753e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			_index[track] = (Word16)(quant_1p_N1(ind[k], 4));
754e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			k += NPMAXPT;
755e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
756e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	} else if(nbbits == 36)
757e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
758e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		for (track = 0; track < NB_TRACK; track++)
759e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
760e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			_index[track] = (Word16)(quant_2p_2N1(ind[k], ind[k + 1], 4));
761e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			k += NPMAXPT;
762e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
763e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	} else if(nbbits == 44)
764e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
765e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		for (track = 0; track < NB_TRACK - 2; track++)
766e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
767e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			_index[track] = (Word16)(quant_3p_3N1(ind[k], ind[k + 1], ind[k + 2], 4));
768e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			k += NPMAXPT;
769e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
770e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		for (track = 2; track < NB_TRACK; track++)
771e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
772e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			_index[track] = (Word16)(quant_2p_2N1(ind[k], ind[k + 1], 4));
773e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			k += NPMAXPT;
774e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
775e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	} else if(nbbits == 52)
776e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
777e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		for (track = 0; track < NB_TRACK; track++)
778e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
779e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			_index[track] = (Word16)(quant_3p_3N1(ind[k], ind[k + 1], ind[k + 2], 4));
780e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			k += NPMAXPT;
781e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
782e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	} else if(nbbits == 64)
783e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
784e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		for (track = 0; track < NB_TRACK; track++)
785e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
786e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			L_index = quant_4p_4N(&ind[k], 4);
787e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			_index[track] = (Word16)((L_index >> 14) & 3);
788e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			_index[track + NB_TRACK] = (Word16)(L_index & 0x3FFF);
789e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			k += NPMAXPT;
790e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
791e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	} else if(nbbits == 72)
792e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
793e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		for (track = 0; track < NB_TRACK - 2; track++)
794e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
795e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			L_index = quant_5p_5N(&ind[k], 4);
796e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			_index[track] = (Word16)((L_index >> 10) & 0x03FF);
797e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			_index[track + NB_TRACK] = (Word16)(L_index & 0x03FF);
798e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			k += NPMAXPT;
799e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
800e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		for (track = 2; track < NB_TRACK; track++)
801e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
802e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			L_index = quant_4p_4N(&ind[k], 4);
803e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			_index[track] = (Word16)((L_index >> 14) & 3);
804e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			_index[track + NB_TRACK] = (Word16)(L_index & 0x3FFF);
805e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			k += NPMAXPT;
806e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
807e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	} else if(nbbits == 88)
808e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
809e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		for (track = 0; track < NB_TRACK; track++)
810e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
811e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			L_index = quant_6p_6N_2(&ind[k], 4);
812e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			_index[track] = (Word16)((L_index >> 11) & 0x07FF);
813e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			_index[track + NB_TRACK] = (Word16)(L_index & 0x07FF);
814e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			k += NPMAXPT;
815e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
816e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
817e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	return;
818e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
819e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
820e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
821e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*-------------------------------------------------------------------*
822e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * Function  cor_h_vec()                                             *
823e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * ~~~~~~~~~~~~~~~~~~~~~                                             *
824e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * Compute correlations of h[] with vec[] for the specified track.   *
825e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *-------------------------------------------------------------------*/
826e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardvoid cor_h_vec_30(
827e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 h[],                           /* (i) scaled impulse response                 */
828e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 vec[],                         /* (i) scaled vector (/8) to correlate with h[] */
829e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 track,                         /* (i) track to use                            */
830e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 sign[],                        /* (i) sign vector                             */
831e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 rrixix[][NB_POS],              /* (i) correlation of h[x] with h[x]      */
832e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 cor_1[],                       /* (o) result of correlation (NB_POS elements) */
833e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 cor_2[]                        /* (o) result of correlation (NB_POS elements) */
834e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		)
835e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
836e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 i, j, pos, corr;
837e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 *p0, *p1, *p2,*p3,*cor_x,*cor_y;
838e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 L_sum1,L_sum2;
839e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	cor_x = cor_1;
840e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	cor_y = cor_2;
841e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	p0 = rrixix[track];
842e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	p3 = rrixix[0];
843e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	pos = track;
844e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
845e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 0; i < NB_POS; i+=2)
846e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
847e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_sum1 = L_sum2 = 0L;
848e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		p1 = h;
849e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		p2 = &vec[pos];
850e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		for (j=pos;j < L_SUBFR; j++)
851e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
852b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			L_sum1 += *p1 * *p2;
853e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			p2-=3;
854b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			L_sum2 += *p1++ * *p2;
855e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			p2+=4;
856e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
857e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		p2-=3;
858b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		L_sum2 += *p1++ * *p2++;
859b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		L_sum2 += *p1++ * *p2++;
860b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		L_sum2 += *p1++ * *p2++;
861e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
862e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_sum1 = (L_sum1 << 2);
863e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_sum2 = (L_sum2 << 2);
864e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
865b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		corr = vo_round(L_sum1);
866e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		*cor_x++ = vo_mult(corr, sign[pos]) + (*p0++);
867e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		corr = vo_round(L_sum2);
868e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		*cor_y++ = vo_mult(corr, sign[pos-3]) + (*p3++);
869e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		pos += STEP;
870e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
871e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_sum1 = L_sum2 = 0L;
872e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		p1 = h;
873e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		p2 = &vec[pos];
874e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		for (j=pos;j < L_SUBFR; j++)
875e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
876b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			L_sum1 += *p1 * *p2;
877e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			p2-=3;
878b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			L_sum2 += *p1++ * *p2;
879e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			p2+=4;
880e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
881e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		p2-=3;
882b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		L_sum2 += *p1++ * *p2++;
883b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		L_sum2 += *p1++ * *p2++;
884b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		L_sum2 += *p1++ * *p2++;
885e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
886e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_sum1 = (L_sum1 << 2);
887e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_sum2 = (L_sum2 << 2);
888e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
889b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		corr = vo_round(L_sum1);
890e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		*cor_x++ = vo_mult(corr, sign[pos]) + (*p0++);
891e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		corr = vo_round(L_sum2);
892e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		*cor_y++ = vo_mult(corr, sign[pos-3]) + (*p3++);
893e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		pos += STEP;
894e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
895e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	return;
896e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
897e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
898e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardvoid cor_h_vec_012(
899e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 h[],                           /* (i) scaled impulse response                 */
900e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 vec[],                         /* (i) scaled vector (/8) to correlate with h[] */
901e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 track,                         /* (i) track to use                            */
902e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 sign[],                        /* (i) sign vector                             */
903e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 rrixix[][NB_POS],              /* (i) correlation of h[x] with h[x]      */
904e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 cor_1[],                       /* (o) result of correlation (NB_POS elements) */
905e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 cor_2[]                        /* (o) result of correlation (NB_POS elements) */
906e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		)
907e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
908e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 i, j, pos, corr;
909e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 *p0, *p1, *p2,*p3,*cor_x,*cor_y;
910e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 L_sum1,L_sum2;
911e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	cor_x = cor_1;
912e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	cor_y = cor_2;
913e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	p0 = rrixix[track];
914e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	p3 = rrixix[track+1];
915e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	pos = track;
916e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
917e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 0; i < NB_POS; i+=2)
918e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
919e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_sum1 = L_sum2 = 0L;
920e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		p1 = h;
921e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		p2 = &vec[pos];
922e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		for (j=62-pos ;j >= 0; j--)
923e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
924e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			L_sum1 += *p1 * *p2++;
925e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			L_sum2 += *p1++ * *p2;
926e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
927e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_sum1 += *p1 * *p2;
928e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_sum1 = (L_sum1 << 2);
929e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_sum2 = (L_sum2 << 2);
930e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
931e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		corr = (L_sum1 + 0x8000) >> 16;
932e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		cor_x[i] = vo_mult(corr, sign[pos]) + (*p0++);
933e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		corr = (L_sum2 + 0x8000) >> 16;
934e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		cor_y[i] = vo_mult(corr, sign[pos + 1]) + (*p3++);
935e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		pos += STEP;
936e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
937e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_sum1 = L_sum2 = 0L;
938e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		p1 = h;
939e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		p2 = &vec[pos];
940e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		for (j= 62-pos;j >= 0; j--)
941e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
942e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			L_sum1 += *p1 * *p2++;
943e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			L_sum2 += *p1++ * *p2;
944e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
945e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_sum1 += *p1 * *p2;
946e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_sum1 = (L_sum1 << 2);
947e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_sum2 = (L_sum2 << 2);
948e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
949e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		corr = (L_sum1 + 0x8000) >> 16;
950e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		cor_x[i+1] = vo_mult(corr, sign[pos]) + (*p0++);
951e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		corr = (L_sum2 + 0x8000) >> 16;
952e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		cor_y[i+1] = vo_mult(corr, sign[pos + 1]) + (*p3++);
953e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		pos += STEP;
954e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
955e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	return;
956e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
957e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
958e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*-------------------------------------------------------------------*
959e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * Function  search_ixiy()                                           *
960e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * ~~~~~~~~~~~~~~~~~~~~~~~                                           *
961e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * Find the best positions of 2 pulses in a subframe.                *
962e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *-------------------------------------------------------------------*/
963e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
964e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardvoid search_ixiy(
965e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 nb_pos_ix,                     /* (i) nb of pos for pulse 1 (1..8)       */
966e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 track_x,                       /* (i) track of pulse 1                   */
967e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 track_y,                       /* (i) track of pulse 2                   */
968e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 * ps,                          /* (i/o) correlation of all fixed pulses  */
969e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 * alp,                         /* (i/o) energy of all fixed pulses       */
970e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 * ix,                          /* (o) position of pulse 1                */
971e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 * iy,                          /* (o) position of pulse 2                */
972e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 dn[],                          /* (i) corr. between target and h[]       */
973e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 dn2[],                         /* (i) vector of selected positions       */
974e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 cor_x[],                       /* (i) corr. of pulse 1 with fixed pulses */
975e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 cor_y[],                       /* (i) corr. of pulse 2 with fixed pulses */
976e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 rrixiy[][MSIZE]                /* (i) corr. of pulse 1 with pulse 2   */
977e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		)
978e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
979e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 x, y, pos, thres_ix;
980e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 ps1, ps2, sq, sqk;
981e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 alp_16, alpk;
982e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 *p0, *p1, *p2;
983e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 s, alp0, alp1, alp2;
984e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
985b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	p0 = cor_x;
986b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	p1 = cor_y;
987b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	p2 = rrixiy[track_x];
988e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
989e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	thres_ix = nb_pos_ix - NB_MAX;
990e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
991e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	alp0 = L_deposit_h(*alp);
992e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	alp0 = (alp0 + 0x00008000L);       /* for rounding */
993e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
994b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	sqk = -1;
995b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	alpk = 1;
996e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
997e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (x = track_x; x < L_SUBFR; x += STEP)
998e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
999e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		ps1 = *ps + dn[x];
1000e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		alp1 = alp0 + ((*p0++)<<13);
1001e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1002e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		if (dn2[x] < thres_ix)
1003e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
1004e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			pos = -1;
1005e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			for (y = track_y; y < L_SUBFR; y += STEP)
1006e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			{
1007e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				ps2 = add1(ps1, dn[y]);
1008e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1009e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				alp2 = alp1 + ((*p1++)<<13);
1010e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				alp2 = alp2 + ((*p2++)<<14);
1011e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				alp_16 = extract_h(alp2);
1012e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				sq = vo_mult(ps2, ps2);
1013e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				s = vo_L_mult(alpk, sq) - ((sqk * alp_16)<<1);
1014e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1015e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				if (s > 0)
1016e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				{
1017b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard					sqk = sq;
1018b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard					alpk = alp_16;
1019b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard					pos = y;
1020e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				}
1021e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			}
1022e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			p1 -= NB_POS;
1023e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1024e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			if (pos >= 0)
1025e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			{
1026b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				*ix = x;
1027b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				*iy = pos;
1028e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			}
1029e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		} else
1030e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
1031e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			p2 += NB_POS;
1032e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
1033e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
1034e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1035b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	*ps = add1(*ps, add1(dn[*ix], dn[*iy]));
1036b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	*alp = alpk;
1037e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1038e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	return;
1039e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
1040e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1041e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1042e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1043e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
1044