Git init
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / enc / src / cor_h_x2.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_x2.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 "cor_h_x2.h" // BX
46 #include "basic_op.h"
47 #include "l_abs.h"
48
49 /*----------------------------------------------------------------------------
50 ; MACROS
51 ; Define module specific macros here
52 ----------------------------------------------------------------------------*/
53
54
55 /*----------------------------------------------------------------------------
56 ; DEFINES
57 ; Include all pre-processor statements here. Include conditional
58 ; compile variables also.
59 ----------------------------------------------------------------------------*/
60 #define LOG2_OF_32  5
61
62 /*----------------------------------------------------------------------------
63 ; LOCAL FUNCTION DEFINITIONS
64 ; Function Prototype declaration
65 ----------------------------------------------------------------------------*/
66
67 /*----------------------------------------------------------------------------
68 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
69 ; Variable declaration - defined here and used outside this module
70 ----------------------------------------------------------------------------*/
71
72
73 /*
74 ------------------------------------------------------------------------------
75  FUNCTION NAME: cor_h_x2
76 ------------------------------------------------------------------------------
77  INPUT AND OUTPUT DEFINITIONS
78
79  Inputs:
80     h = vector containing the impulse response of the weighted synthesis
81         filter; vector contents are of type Word16; vector length is
82         2 * L_SUBFR
83     x = target signal vector; vector contents are of type Word16; vector
84         length is L_SUBFR
85     dn = vector containing the correlation between the target and the
86          impulse response; vector contents are of type Word16; vector
87          length is L_CODE
88     sf = scaling factor of type Word16 ; 2 when mode is MR122, 1 for all
89          other modes
90     nb_track = number of ACB tracks (Word16)
91     step = step size between pulses in one track (Word16)
92     pOverflow = pointer to overflow (Flag)
93
94  Outputs:
95     dn contents are the newly calculated correlation values
96     pOverflow = 1 if the math functions called by cor_h_x2 result in overflow
97     else zero.
98
99  Returns:
100     None
101
102  Global Variables Used:
103     None
104
105  Local Variables Needed:
106     None
107
108 ------------------------------------------------------------------------------
109  FUNCTION DESCRIPTION
110
111  This function computes the correlation between the target signal (x) and the
112  impulse response (h).
113
114  The correlation is given by: d[n] = sum_{i=n}^{L-1} x[i] h[i-n],
115  where: n=0,...,L-1
116
117  d[n] is normalized such that the sum of 5 maxima of d[n] corresponding to
118  each position track does not saturate.
119
120 ------------------------------------------------------------------------------
121  REQUIREMENTS
122
123  None
124
125 ------------------------------------------------------------------------------
126  REFERENCES
127
128  cor_h.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
129
130 ------------------------------------------------------------------------------
131  PSEUDO-CODE
132
133 The original etsi reference code uses a global flag Overflow. However, in the
134 actual implementation a pointer to a the overflow flag is passed in.
135
136 void cor_h_x2 (
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     Word16 nb_track,// (i): the number of ACB tracks
142     Word16 step    // (i): step size from one pulse position to the next
143                            in one track
144 )
145 {
146     Word16 i, j, k;
147     Word32 s, y32[L_CODE], max, tot;
148
149     // first keep the result on 32 bits and find absolute maximum
150
151     tot = 5;
152
153     for (k = 0; k < nb_track; k++)
154     {
155         max = 0;
156         for (i = k; i < L_CODE; i += step)
157         {
158             s = 0;
159             for (j = i; j < L_CODE; j++)
160                 s = L_mac (s, x[j], h[j - i]);
161
162             y32[i] = s;
163
164             s = L_abs (s);
165             if (L_sub (s, max) > (Word32) 0L)
166                 max = s;
167         }
168         tot = L_add (tot, L_shr (max, 1));
169     }
170
171     j = sub (norm_l (tot), sf);
172
173     for (i = 0; i < L_CODE; i++)
174     {
175         dn[i] = pv_round (L_shl (y32[i], j));
176     }
177 }
178
179 ------------------------------------------------------------------------------
180  CAUTION [optional]
181  [State any special notes, constraints or cautions for users of this function]
182
183 ------------------------------------------------------------------------------
184 */
185
186 void cor_h_x2(
187     Word16 h[],    /* (i): impulse response of weighted synthesis filter */
188     Word16 x[],    /* (i): target                                        */
189     Word16 dn[],   /* (o): correlation between target and h[]            */
190     Word16 sf,     /* (i): scaling factor: 2 for 12.2, 1 for others      */
191     Word16 nb_track,/* (i): the number of ACB tracks                     */
192     Word16 step,   /* (i): step size from one pulse position to the next
193                            in one track                                  */
194     Flag *pOverflow
195 )
196 {
197     register Word16 i;
198     register Word16 j;
199     register Word16 k;
200     Word32 s;
201     Word32 y32[L_CODE];
202     Word32 max;
203     Word32 tot;
204
205
206     /* first keep the result on 32 bits and find absolute maximum */
207     tot = LOG2_OF_32;
208     for (k = 0; k < nb_track; k++)
209     {
210         max = 0;
211         for (i = k; i < L_CODE; i += step)
212         {
213             s = 0;
214
215             for (j = i; j < L_CODE; j++)
216             {
217                 s = amrnb_fxp_mac_16_by_16bb((Word32)x[j], (Word32)h[j-i], s);
218             }
219
220             s = s << 1;
221             y32[i] = s;
222             s = L_abs(s);
223
224             if (s > max)
225             {
226                 max = s;
227             }
228         }
229         tot = (tot + (max >> 1));
230     }
231
232     j = norm_l(tot) - sf;
233
234     for (i = 0; i < L_CODE; i++)
235     {
236         dn[i] = pv_round(L_shl(y32[i], j, pOverflow), pOverflow);
237     }
238
239     return;
240 }