Git init
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / enc / src / cor_h_x.cpp
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
20
21     3GPP TS 26.073
22     ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23     Available from http://www.3gpp.org
24
25 (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26 Permission to distribute, modify and use this file under the standard license
27 terms listed above has been obtained from the copyright holder.
28 ****************************************************************************************/
29 /*
30 ------------------------------------------------------------------------------
31
32
33
34  Filename: cor_h_x.cpp
35
36 ------------------------------------------------------------------------------
37 */
38
39 /*----------------------------------------------------------------------------
40 ; INCLUDES
41 ----------------------------------------------------------------------------*/
42 #include "typedef.h"
43 #include "cnst.h"
44 #include "cor_h_x.h"
45 #include "basic_op.h"
46
47 /*----------------------------------------------------------------------------
48 ; MACROS
49 ; Define module specific macros here
50 ----------------------------------------------------------------------------*/
51
52
53 /*----------------------------------------------------------------------------
54 ; DEFINES
55 ; Include all pre-processor statements here. Include conditional
56 ; compile variables also.
57 ----------------------------------------------------------------------------*/
58
59 /*----------------------------------------------------------------------------
60 ; LOCAL FUNCTION DEFINITIONS
61 ; Function Prototype declaration
62 ----------------------------------------------------------------------------*/
63
64 /*----------------------------------------------------------------------------
65 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
66 ; Variable declaration - defined here and used outside this module
67 ----------------------------------------------------------------------------*/
68
69 /*----------------------------------------------------------------------------
70 ; EXTERNAL FUNCTION REFERENCES
71 ; Declare functions defined elsewhere and referenced in this module
72 ----------------------------------------------------------------------------*/
73
74 /*----------------------------------------------------------------------------
75 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
76 ; Declare variables used in this module but defined elsewhere
77 ----------------------------------------------------------------------------*/
78
79 /*
80 ------------------------------------------------------------------------------
81  FUNCTION NAME: cor_h_x
82 ------------------------------------------------------------------------------
83  INPUT AND OUTPUT DEFINITIONS
84
85  Inputs:
86     h = vector containing the impulse response of the weighted synthesis
87         filter; vector contents are of type Word16; vector length is
88         2 * L_SUBFR
89     x = target signal vector; vector contents are of type Word16; vector
90         length is L_SUBFR
91     dn = vector containing the correlation between the target and the
92          impulse response; vector contents are of type Word16; vector
93          length is L_CODE
94     sf = scaling factor of type Word16 ; 2 when mode is MR122, 1 for all
95          other modes
96
97  Outputs:
98     dn contents are the newly calculated correlation values
99
100     pOverflow = pointer of type Flag * to overflow indicator.
101
102  Returns:
103     None
104
105  Global Variables Used:
106     None
107
108  Local Variables Needed:
109     None
110
111 ------------------------------------------------------------------------------
112  FUNCTION DESCRIPTION
113
114  This function computes the correlation between the target signal (x) and the
115  impulse response (h).
116
117  The correlation is given by: d[n] = sum_{i=n}^{L-1} x[i] h[i-n],
118  where: n=0,...,L-1
119
120  d[n] is normalized such that the sum of 5 maxima of d[n] corresponding to
121  each position track does not saturate.
122
123 ------------------------------------------------------------------------------
124  REQUIREMENTS
125
126  None
127
128 ------------------------------------------------------------------------------
129  REFERENCES
130
131  cor_h.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
132
133 ------------------------------------------------------------------------------
134  PSEUDO-CODE
135
136 void cor_h_x (
137     Word16 h[],    // (i): impulse response of weighted synthesis filter
138     Word16 x[],    // (i): target
139     Word16 dn[],   // (o): correlation between target and h[]
140     Word16 sf      // (i): scaling factor: 2 for 12.2, 1 for others
141 )
142 {
143     cor_h_x2(h, x, dn, sf, NB_TRACK, STEP);
144 }
145
146
147 void cor_h_x2 (
148     Word16 h[],    // (i): impulse response of weighted synthesis filter
149     Word16 x[],    // (i): target
150     Word16 dn[],   // (o): correlation between target and h[]
151     Word16 sf,     // (i): scaling factor: 2 for 12.2, 1 for others
152     Word16 nb_track,// (i): the number of ACB tracks
153     Word16 step    // (i): step size from one pulse position to the next
154                            in one track
155 )
156 {
157     Word16 i, j, k;
158     Word32 s, y32[L_CODE], max, tot;
159
160     // first keep the result on 32 bits and find absolute maximum
161
162     tot = 5;
163
164     for (k = 0; k < nb_track; k++)
165     {
166         max = 0;
167         for (i = k; i < L_CODE; i += step)
168         {
169             s = 0;
170             for (j = i; j < L_CODE; j++)
171                 s = L_mac (s, x[j], h[j - i]);
172
173             y32[i] = s;
174
175             s = L_abs (s);
176             if (L_sub (s, max) > (Word32) 0L)
177                 max = s;
178         }
179         tot = L_add (tot, L_shr (max, 1));
180     }
181
182     j = sub (norm_l (tot), sf);
183
184     for (i = 0; i < L_CODE; i++)
185     {
186         dn[i] = pv_round (L_shl (y32[i], j));
187     }
188 }
189
190 ------------------------------------------------------------------------------
191  CAUTION [optional]
192  [State any special notes, constraints or cautions for users of this function]
193
194 ------------------------------------------------------------------------------
195 */
196
197 void cor_h_x(
198     Word16 h[],       /* (i): impulse response of weighted synthesis filter */
199     Word16 x[],       /* (i): target                                        */
200     Word16 dn[],      /* (o): correlation between target and h[]            */
201     Word16 sf,        /* (i): scaling factor: 2 for 12.2, 1 for others      */
202     Flag   *pOverflow /* (o): pointer to overflow flag                      */
203 )
204 {
205     register Word16 i;
206     register Word16 j;
207     register Word16 k;
208
209     Word32 s;
210     Word32 y32[L_CODE];
211     Word32 max;
212     Word32 tot;
213
214     Word16 *p_x;
215     Word16 *p_ptr;
216     Word32 *p_y32;
217
218
219     tot = 5;
220     for (k = 0; k < NB_TRACK; k++)              /* NB_TRACK = 5 */
221     {
222         max = 0;
223         for (i = k; i < L_CODE; i += STEP)      /* L_CODE = 40; STEP = 5 */
224         {
225             s = 0;
226             p_x = &x[i];
227             p_ptr = h;
228
229             for (j = (L_CODE - i - 1) >> 1; j != 0; j--)
230             {
231                 s += ((Word32) * (p_x++) * *(p_ptr++)) << 1;
232                 s += ((Word32) * (p_x++) * *(p_ptr++)) << 1;
233             }
234
235             s += ((Word32) * (p_x++) * *(p_ptr++)) << 1;
236
237             if (!((L_CODE - i) & 1))    /* if even number of iterations */
238             {
239                 s += ((Word32) * (p_x++) * *(p_ptr++)) << 1;
240             }
241
242             y32[i] = s;
243
244             if (s < 0)
245             {
246                 s = -s;
247             }
248
249             if (s > max)
250             {
251                 max = s;
252             }
253         }
254
255         tot += (max >> 1);
256     }
257
258
259     j = norm_l(tot) - sf;
260
261     p_ptr = dn;
262     p_y32 = y32;;
263
264     for (i = L_CODE >> 1; i != 0; i--)
265     {
266         s = L_shl(*(p_y32++), j, pOverflow);
267         *(p_ptr++) = (s + 0x00008000) >> 16;
268         s = L_shl(*(p_y32++), j, pOverflow);
269         *(p_ptr++) = (s + 0x00008000) >> 16;
270     }
271
272     return;
273 }