Initialize Tizen 2.3
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / enc / src / autocorr.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: autocorr.cpp
35
36 ----------------------------------------------------------------------------*/
37
38 /*----------------------------------------------------------------------------
39 ; INCLUDES
40 ----------------------------------------------------------------------------*/
41 #include "autocorr.h"
42 #include "typedef.h"
43 #include "basic_op.h"
44 #include "oper_32b.h"
45 #include "cnst.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 /*----------------------------------------------------------------------------
61 ; LOCAL FUNCTION DEFINITIONS
62 ; Function Prototype declaration
63 ----------------------------------------------------------------------------*/
64
65 /*----------------------------------------------------------------------------
66 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
67 ; Variable declaration - defined here and used outside this module
68 ----------------------------------------------------------------------------*/
69
70 /*----------------------------------------------------------------------------
71 ; EXTERNAL FUNCTION REFERENCES
72 ; Declare functions defined elsewhere and referenced in this module
73 ----------------------------------------------------------------------------*/
74
75
76 /*----------------------------------------------------------------------------
77 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
78 ; Declare variables used in this module but defined elsewhere
79 ----------------------------------------------------------------------------*/
80
81 /*
82 ------------------------------------------------------------------------------
83  FUNCTION NAME: Autocorr
84 ----------------------------------------------------------------------------
85  INPUT AND OUTPUT DEFINITIONS
86
87  Inputs:
88     x = buffer of input signals of type Word16
89     m = LPC order of type Word16
90     wind = buffer of window signals of type Word16
91     r_h = buffer containing the high word of the autocorrelation values
92           of type Word16
93     r_l = buffer containing the low word of the autocorrelation values
94           of type Word16
95
96     pOverflow = pointer to variable of type Flag *, which indicates if
97                 overflow occurs.
98
99  Outputs:
100     r_h buffer contains the high word of the new autocorrelation values
101     r_l buffer contains the low word of the new autocorrelation values
102     pOverflow -> 1 if overflow occurs.
103
104  Returns:
105     norm = normalized autocorrelation at lag zero of type Word16
106
107  Global Variables Used:
108     None
109
110  Local Variables Needed:
111     None
112
113 ------------------------------------------------------------------------------
114  FUNCTION DESCRIPTION
115
116  This function windows the input signal with the provided window
117  then calculates the autocorrelation values for lags of 0,1,...m,
118  where m is the passed in LPC order.
119
120 ------------------------------------------------------------------------------
121  REQUIREMENTS
122
123  None.
124
125 ------------------------------------------------------------------------------
126  REFERENCES
127
128  autocorr.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
129
130 ------------------------------------------------------------------------------
131  PSEUDO-CODE
132
133 Word16 Autocorr (
134     Word16 x[],            // (i)    : Input signal (L_WINDOW)
135     Word16 m,              // (i)    : LPC order
136     Word16 r_h[],          // (o)    : Autocorrelations  (msb)
137     Word16 r_l[],          // (o)    : Autocorrelations  (lsb)
138     const Word16 wind[]    // (i)    : window for LPC analysis (L_WINDOW)
139 )
140 {
141     Word16 i, j, norm;
142     Word16 y[L_WINDOW];
143     Word32 sum;
144     Word16 overfl, overfl_shft;
145
146     // Windowing of signal
147
148     for (i = 0; i < L_WINDOW; i++)
149     {
150         y[i] = mult_r (x[i], wind[i]);
151     }
152
153     // Compute r[0] and test for overflow
154
155     overfl_shft = 0;
156
157     do
158     {
159         overfl = 0;
160         sum = 0L;
161
162         for (i = 0; i < L_WINDOW; i++)
163         {
164             sum = L_mac (sum, y[i], y[i]);
165         }
166
167         // If overflow divide y[] by 4
168
169         if (L_sub (sum, MAX_32) == 0L)
170         {
171             overfl_shft = add (overfl_shft, 4);
172             overfl = 1; // Set the overflow flag
173
174             for (i = 0; i < L_WINDOW; i++)
175             {
176                 y[i] = shr (y[i], 2);
177             }
178         }
179     }
180     while (overfl != 0);
181
182     sum = L_add (sum, 1L);             // Avoid the case of all zeros
183
184     // Normalization of r[0]
185
186     norm = norm_l (sum);
187     sum = L_shl (sum, norm);
188     L_Extract (sum, &r_h[0], &r_l[0]); // Put in DPF format (see oper_32b)
189
190     // r[1] to r[m]
191
192     for (i = 1; i <= m; i++)
193     {
194         sum = 0;
195
196         for (j = 0; j < L_WINDOW - i; j++)
197         {
198             sum = L_mac (sum, y[j], y[j + i]);
199         }
200
201         sum = L_shl (sum, norm);
202         L_Extract (sum, &r_h[i], &r_l[i]);
203     }
204
205     norm = sub (norm, overfl_shft);
206
207     return norm;
208 }
209
210
211 ------------------------------------------------------------------------------
212  CAUTION [optional]
213  [State any special notes, constraints or cautions for users of this function]
214
215 ------------------------------------------------------------------------------
216 */
217
218 Word16 Autocorr(
219     Word16 x[],            /* (i)    : Input signal (L_WINDOW)            */
220     Word16 m,              /* (i)    : LPC order                          */
221     Word16 r_h[],          /* (o)    : Autocorrelations  (msb)            */
222     Word16 r_l[],          /* (o)    : Autocorrelations  (lsb)            */
223     const Word16 wind[],   /* (i)    : window for LPC analysis (L_WINDOW) */
224     Flag  *pOverflow       /* (o)    : indicates overflow                 */
225 )
226 {
227     register Word16 i;
228     register Word16 j;
229     register Word16 norm;
230
231     Word16 y[L_WINDOW];
232     Word32 sum;
233     Word16 overfl_shft;
234
235
236     /* Added for optimization  */
237
238
239     Word16 temp;
240     Word16 *p_x;
241     Word16 *p_y;
242     Word16 *p_y_1;
243     Word16 *p_y_ref;
244     Word16 *p_rh;
245     Word16 *p_rl;
246     const Word16 *p_wind;
247     p_y = y;
248     p_x = x;
249     p_wind = wind;
250     /*
251      *  Windowing of the signal
252      */
253
254     OSCL_UNUSED_ARG(pOverflow);
255
256     sum = 0L;
257     j = 0;
258
259     for (i = L_WINDOW; i != 0; i--)
260     {
261         temp = (Word16)((amrnb_fxp_mac_16_by_16bb((Word32) * (p_x++), (Word32) * (p_wind++), 0x04000)) >> 15);
262         *(p_y++) = temp;
263
264         sum += ((Word32)temp * temp) << 1;
265         if (sum < 0)
266         {
267             /*
268              * if oveflow exist, then stop accumulation
269              */
270             j = 1;
271             break;
272         }
273
274     }
275     /*
276      * if oveflow existed, complete  windowing operation
277      * without computing energy
278      */
279
280     if (j)
281     {
282         p_y = &y[L_WINDOW-i];
283         p_x = &x[L_WINDOW-i];
284         p_wind = &wind[L_WINDOW-i];
285
286         for (; i != 0; i--)
287         {
288             temp = (Word16)((amrnb_fxp_mac_16_by_16bb((Word32) * (p_x++), (Word32) * (p_wind++), 0x04000)) >> 15);
289             *(p_y++) = temp;
290         }
291     }
292
293
294     /*
295      *  Compute r[0] and test for overflow
296      */
297
298     overfl_shft = 0;
299
300     /*
301      * scale down by 1/4 only when needed
302      */
303     while (j == 1)
304     {
305         /* If overflow divide y[] by 4          */
306         /* FYI: For better resolution, we could */
307         /*      divide y[] by 2                 */
308         overfl_shft += 4;
309         p_y   = &y[0];
310         sum = 0L;
311
312         for (i = (L_WINDOW >> 1); i != 0 ; i--)
313         {
314             temp = *p_y >> 2;
315             *(p_y++) = temp;
316             sum += ((Word32)temp * temp) << 1;
317             temp = *p_y >> 2;
318             *(p_y++) = temp;
319             sum += ((Word32)temp * temp) << 1;
320         }
321         if (sum > 0)
322         {
323             j = 0;
324         }
325
326     }
327
328     sum += 1L;              /* Avoid the case of all zeros */
329
330     /* Normalization of r[0] */
331
332     norm = norm_l(sum);
333
334     sum <<= norm;
335
336     /* Put in DPF format (see oper_32b) */
337     r_h[0] = (Word16)(sum >> 16);
338     r_l[0] = (Word16)((sum >> 1) - ((Word32)(r_h[0]) << 15));
339
340     /* r[1] to r[m] */
341
342     p_y_ref = &y[L_WINDOW - 1 ];
343     p_rh = &r_h[m];
344     p_rl = &r_l[m];
345
346     for (i = m; i > 0; i--)
347     {
348         sum  = 0;
349
350         p_y   = &y[L_WINDOW - i - 1];
351         p_y_1 = p_y_ref;
352
353         for (j = (L_WINDOW - i - 1) >> 1; j != 0; j--)
354         {
355             sum = amrnb_fxp_mac_16_by_16bb((Word32) * (p_y--), (Word32) * (p_y_1--), sum);
356             sum = amrnb_fxp_mac_16_by_16bb((Word32) * (p_y--), (Word32) * (p_y_1--), sum);
357         }
358
359         sum = amrnb_fxp_mac_16_by_16bb((Word32) * (p_y--), (Word32) * (p_y_1--), sum);
360
361         if (((L_WINDOW - i - 1) & 1))
362         {
363             sum = amrnb_fxp_mac_16_by_16bb((Word32) * (p_y--), (Word32) * (p_y_1--), sum);
364         }
365
366         sum  <<= (norm + 1);
367
368         *(p_rh)   = (Word16)(sum >> 16);
369         *(p_rl--) = (Word16)((sum >> 1) - ((Word32) * (p_rh--) << 15));
370
371     }
372
373     norm -= overfl_shft;
374
375     return (norm);
376
377 } /* Autocorr */