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