Git init
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_wb / dec / src / wb_syn_filt.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.173
22     ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec
23     Available from http://www.3gpp.org
24
25 (C) 2007, 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: wb_syn_filt.cpp
35
36 ------------------------------------------------------------------------------
37  INPUT AND OUTPUT DEFINITIONS
38
39 wb_syn_filt
40
41      int16 a[],               (i) Q12 : a[m+1] prediction coefficients
42      int16 m,                 (i)     : order of LP filter
43      int16 x[],               (i)     : input signal
44      int16 y[],               (o)     : output signal
45      int16 lg,                (i)     : size of filtering
46      int16 mem[],             (i/o)   : memory associated with this filtering.
47      int16 update,            (i)     : 0=no update, 1=update of memory.
48      int16 y_buf[]
49
50 Syn_filt_32
51
52      int16 a[],              (i) Q12 : a[m+1] prediction coefficients
53      int16 m,                (i)     : order of LP filter
54      int16 exc[],            (i) Qnew: excitation (exc[i] >> Qnew)
55      int16 Qnew,             (i)     : exc scaling = 0(min) to 8(max)
56      int16 sig_hi[],         (o) /16 : synthesis high
57      int16 sig_lo[],         (o) /16 : synthesis low
58      int16 lg                (i)     : size of filtering
59
60 ------------------------------------------------------------------------------
61  FUNCTION DESCRIPTION
62
63     Do the synthesis filtering 1/A(z)  16 and 32-bits version
64
65 ------------------------------------------------------------------------------
66  REQUIREMENTS
67
68
69 ------------------------------------------------------------------------------
70  REFERENCES
71
72 ------------------------------------------------------------------------------
73  PSEUDO-CODE
74
75 ------------------------------------------------------------------------------
76 */
77
78
79 /*----------------------------------------------------------------------------
80 ; INCLUDES
81 ----------------------------------------------------------------------------*/
82
83
84 #include "pv_amr_wb_type_defs.h"
85 #include "pvamrwbdecoder_mem_funcs.h"
86 #include "pvamrwbdecoder_basic_op.h"
87 #include "pvamrwb_math_op.h"
88 #include "pvamrwbdecoder_cnst.h"
89 #include "pvamrwbdecoder_acelp.h"
90
91 /*----------------------------------------------------------------------------
92 ; MACROS
93 ; Define module specific macros here
94 ----------------------------------------------------------------------------*/
95
96
97 /*----------------------------------------------------------------------------
98 ; DEFINES
99 ; Include all pre-processor statements here. Include conditional
100 ; compile variables also.
101 ----------------------------------------------------------------------------*/
102
103 /*----------------------------------------------------------------------------
104 ; EXTERNAL FUNCTION REFERENCES
105 ; Declare functions defined elsewhere and referenced in this module
106 ----------------------------------------------------------------------------*/
107
108 /*----------------------------------------------------------------------------
109 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
110 ; Declare variables used in this module but defined elsewhere
111 ----------------------------------------------------------------------------*/
112
113 /*----------------------------------------------------------------------------
114 ; FUNCTION CODE
115 ----------------------------------------------------------------------------*/
116
117 void wb_syn_filt(
118     int16 a[],       /* (i) Q12 : a[m+1] prediction coefficients           */
119     int16 m,         /* (i)     : order of LP filter                       */
120     int16 x[],       /* (i)     : input signal                             */
121     int16 y[],       /* (o)     : output signal                            */
122     int16 lg,        /* (i)     : size of filtering                        */
123     int16 mem[],     /* (i/o)   : memory associated with this filtering.   */
124     int16 update,    /* (i)     : 0=no update, 1=update of memory.         */
125     int16 y_buf[]
126 )
127 {
128
129     int16 i, j;
130     int32 L_tmp1;
131     int32 L_tmp2;
132     int32 L_tmp3;
133     int32 L_tmp4;
134     int16 *yy;
135
136     /* copy initial filter states into synthesis buffer */
137     pv_memcpy(y_buf, mem, m*sizeof(*yy));
138
139     yy = &y_buf[m];
140
141     /* Do the filtering. */
142
143     for (i = 0; i < lg >> 2; i++)
144     {
145         L_tmp1 = -((int32)x[(i<<2)] << 11);
146         L_tmp2 = -((int32)x[(i<<2)+1] << 11);
147         L_tmp3 = -((int32)x[(i<<2)+2] << 11);
148         L_tmp4 = -((int32)x[(i<<2)+3] << 11);
149
150         /* a[] uses Q12 and abs(a) =< 1 */
151
152         L_tmp1  = fxp_mac_16by16(yy[(i<<2) -3], a[3], L_tmp1);
153         L_tmp2  = fxp_mac_16by16(yy[(i<<2) -2], a[3], L_tmp2);
154         L_tmp1  = fxp_mac_16by16(yy[(i<<2) -2], a[2], L_tmp1);
155         L_tmp2  = fxp_mac_16by16(yy[(i<<2) -1], a[2], L_tmp2);
156         L_tmp1  = fxp_mac_16by16(yy[(i<<2) -1], a[1], L_tmp1);
157
158         for (j = 4; j < m; j += 2)
159         {
160             L_tmp1  = fxp_mac_16by16(yy[(i<<2)-1  - j], a[j+1], L_tmp1);
161             L_tmp2  = fxp_mac_16by16(yy[(i<<2)    - j], a[j+1], L_tmp2);
162             L_tmp1  = fxp_mac_16by16(yy[(i<<2)    - j], a[j  ], L_tmp1);
163             L_tmp2  = fxp_mac_16by16(yy[(i<<2)+1  - j], a[j  ], L_tmp2);
164             L_tmp3  = fxp_mac_16by16(yy[(i<<2)+1  - j], a[j+1], L_tmp3);
165             L_tmp4  = fxp_mac_16by16(yy[(i<<2)+2  - j], a[j+1], L_tmp4);
166             L_tmp3  = fxp_mac_16by16(yy[(i<<2)+2  - j], a[j  ], L_tmp3);
167             L_tmp4  = fxp_mac_16by16(yy[(i<<2)+3  - j], a[j  ], L_tmp4);
168         }
169
170         L_tmp1  = fxp_mac_16by16(yy[(i<<2)    - j], a[j], L_tmp1);
171         L_tmp2  = fxp_mac_16by16(yy[(i<<2)+1  - j], a[j], L_tmp2);
172         L_tmp3  = fxp_mac_16by16(yy[(i<<2)+2  - j], a[j], L_tmp3);
173         L_tmp4  = fxp_mac_16by16(yy[(i<<2)+3  - j], a[j], L_tmp4);
174
175         L_tmp1 = shl_int32(L_tmp1, 4);
176
177         y[(i<<2)] = yy[(i<<2)] = amr_wb_round(-L_tmp1);
178
179         L_tmp2  = fxp_mac_16by16(yy[(i<<2)], a[1], L_tmp2);
180
181         L_tmp2 = shl_int32(L_tmp2, 4);
182
183         y[(i<<2)+1] = yy[(i<<2)+1] = amr_wb_round(-L_tmp2);
184
185         L_tmp3  = fxp_mac_16by16(yy[(i<<2) - 1], a[3], L_tmp3);
186         L_tmp4  = fxp_mac_16by16(yy[(i<<2)], a[3], L_tmp4);
187         L_tmp3  = fxp_mac_16by16(yy[(i<<2)], a[2], L_tmp3);
188         L_tmp4  = fxp_mac_16by16(yy[(i<<2) + 1], a[2], L_tmp4);
189         L_tmp3  = fxp_mac_16by16(yy[(i<<2) + 1], a[1], L_tmp3);
190
191         L_tmp3 = shl_int32(L_tmp3, 4);
192
193         y[(i<<2)+2] = yy[(i<<2)+2] = amr_wb_round(-L_tmp3);
194
195         L_tmp4  = fxp_mac_16by16(yy[(i<<2)+2], a[1], L_tmp4);
196
197         L_tmp4 = shl_int32(L_tmp4, 4);
198
199         y[(i<<2)+3] = yy[(i<<2)+3] = amr_wb_round(-L_tmp4);
200     }
201
202
203     /* Update memory if required */
204
205     if (update)
206     {
207         pv_memcpy(mem, &y[lg - m], m*sizeof(*y));
208     }
209
210     return;
211 }
212
213 /*----------------------------------------------------------------------------
214 ; FUNCTION CODE
215 ----------------------------------------------------------------------------*/
216
217 void Syn_filt_32(
218     int16 a[],              /* (i) Q12 : a[m+1] prediction coefficients */
219     int16 m,                /* (i)     : order of LP filter             */
220     int16 exc[],            /* (i) Qnew: excitation (exc[i] >> Qnew)    */
221     int16 Qnew,             /* (i)     : exc scaling = 0(min) to 8(max) */
222     int16 sig_hi[],         /* (o) /16 : synthesis high                 */
223     int16 sig_lo[],         /* (o) /16 : synthesis low                  */
224     int16 lg                /* (i)     : size of filtering              */
225 )
226 {
227     int16 i, k, a0;
228     int32 L_tmp1;
229     int32 L_tmp2;
230     int32 L_tmp3;
231     int32 L_tmp4;
232
233     a0 = 9 - Qnew;        /* input / 16 and >>Qnew */
234
235     /* Do the filtering. */
236
237     for (i = 0; i < lg >> 1; i++)
238     {
239
240         L_tmp3 = 0;
241         L_tmp4 = 0;
242
243         L_tmp1 = fxp_mul_16by16(sig_lo[(i<<1) - 1], a[1]);
244         L_tmp2 = fxp_mul_16by16(sig_hi[(i<<1) - 1], a[1]);
245
246         for (k = 2; k < m; k += 2)
247         {
248
249             L_tmp1 = fxp_mac_16by16(sig_lo[(i<<1)-1 - k], a[k+1], L_tmp1);
250             L_tmp2 = fxp_mac_16by16(sig_hi[(i<<1)-1 - k], a[k+1], L_tmp2);
251             L_tmp1 = fxp_mac_16by16(sig_lo[(i<<1)   - k], a[k  ], L_tmp1);
252             L_tmp2 = fxp_mac_16by16(sig_hi[(i<<1)   - k], a[k  ], L_tmp2);
253             L_tmp3 = fxp_mac_16by16(sig_lo[(i<<1)   - k], a[k+1], L_tmp3);
254             L_tmp4 = fxp_mac_16by16(sig_hi[(i<<1)   - k], a[k+1], L_tmp4);
255             L_tmp3 = fxp_mac_16by16(sig_lo[(i<<1)+1 - k], a[k  ], L_tmp3);
256             L_tmp4 = fxp_mac_16by16(sig_hi[(i<<1)+1 - k], a[k  ], L_tmp4);
257         }
258
259         L_tmp1 = -fxp_mac_16by16(sig_lo[(i<<1)   - k], a[k], L_tmp1);
260         L_tmp3 =  fxp_mac_16by16(sig_lo[(i<<1)+1 - k], a[k], L_tmp3);
261         L_tmp2 =  fxp_mac_16by16(sig_hi[(i<<1)   - k], a[k], L_tmp2);
262         L_tmp4 =  fxp_mac_16by16(sig_hi[(i<<1)+1 - k], a[k], L_tmp4);
263
264
265
266         L_tmp1 >>= 11;      /* -4 : sig_lo[i] << 4 */
267
268         L_tmp1 += (int32)exc[(i<<1)] << a0;
269
270         L_tmp1 -= (L_tmp2 << 1);
271         /* sig_hi = bit16 to bit31 of synthesis */
272         L_tmp1 = shl_int32(L_tmp1, 3);           /* ai in Q12 */
273
274         sig_hi[(i<<1)] = (int16)(L_tmp1 >> 16);
275
276         L_tmp4 = fxp_mac_16by16((int16)(L_tmp1 >> 16), a[1], L_tmp4);
277
278         /* sig_lo = bit4 to bit15 of synthesis */
279         /* L_tmp1 >>= 4 : sig_lo[i] >> 4 */
280         sig_lo[(i<<1)] = (int16)((L_tmp1 >> 4) - ((L_tmp1 >> 16) << 12));
281
282         L_tmp3 = fxp_mac_16by16(sig_lo[(i<<1)], a[1], L_tmp3);
283         L_tmp3 = -L_tmp3 >> 11;
284
285         L_tmp3 += (int32)exc[(i<<1)+1] << a0;
286
287         L_tmp3 -= (L_tmp4 << 1);
288         /* sig_hi = bit16 to bit31 of synthesis */
289         L_tmp3 = shl_int32(L_tmp3, 3);           /* ai in Q12 */
290         sig_hi[(i<<1)+1] = (int16)(L_tmp3 >> 16);
291
292         /* sig_lo = bit4 to bit15 of synthesis */
293         /* L_tmp1 >>= 4 : sig_lo[i] >> 4 */
294         sig_lo[(i<<1)+1] = (int16)((L_tmp3 >> 4) - (sig_hi[(i<<1)+1] << 12));
295     }
296
297 }
298
299