1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
22 ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23 Available from http://www.3gpp.org
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 ****************************************************************************************/
30 Filename: syn_filt.cpp
32 ------------------------------------------------------------------------------
35 /*----------------------------------------------------------------------------
37 ----------------------------------------------------------------------------*/
45 /*----------------------------------------------------------------------------
47 ; Define module specific macros here
48 ----------------------------------------------------------------------------*/
51 /*----------------------------------------------------------------------------
53 ; Include all pre-processor statements here. Include conditional
54 ; compile variables also.
55 ----------------------------------------------------------------------------*/
57 /*----------------------------------------------------------------------------
58 ; LOCAL FUNCTION DEFINITIONS
59 ; Function Prototype declaration
60 ----------------------------------------------------------------------------*/
62 /*----------------------------------------------------------------------------
63 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
64 ; Variable declaration - defined here and used outside this module
65 ----------------------------------------------------------------------------*/
69 ------------------------------------------------------------------------------
70 FUNCTION NAME: Syn_filt
71 ------------------------------------------------------------------------------
72 INPUT AND OUTPUT DEFINITIONS
75 a = buffer containing the prediction coefficients (Word16) max 2^12
76 x = input signal buffer (Word16) max 2^15
77 y = output signal buffer (Word16)
78 lg = size of filtering (Word16)
79 mem = memory buffer associated with this filtering (Word16)
80 update = flag to indicate memory update; 0=no update, 1=update memory
84 mem buffer is changed to be the last M data points of the output signal
85 if update was set to 1
86 y buffer contains the newly calculated filter output
91 Global Variables Used:
94 Local Variables Needed:
97 ------------------------------------------------------------------------------
100 Perform synthesis filtering through 1/A(z)
102 ------------------------------------------------------------------------------
107 ------------------------------------------------------------------------------
110 syn_filt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
112 ------------------------------------------------------------------------------
116 Word16 a[], // (i) : a[M+1] prediction coefficients (M=10)
117 Word16 x[], // (i) : input signal
118 Word16 y[], // (o) : output signal
119 Word16 lg, // (i) : size of filtering
120 Word16 mem[], // (i/o) : memory associated with this filtering.
121 Word16 update // (i) : 0=no update, 1=update of memory.
126 Word16 tmp[80]; // This is usually done by memory allocation (lg+M)
129 // Copy mem[] to yy[]
133 for (i = 0; i < M; i++)
140 for (i = 0; i < lg; i++)
142 s = L_mult (x[i], a[0]);
143 for (j = 1; j <= M; j++)
145 s = L_msu (s, a[j], yy[-j]);
148 *yy++ = pv_round (s);
151 for (i = 0; i < lg; i++)
156 // Update of memory if update==1
160 for (i = 0; i < M; i++)
162 mem[i] = y[lg - M + i];
168 ------------------------------------------------------------------------------
170 [State any special notes, constraints or cautions for users of this function]
172 ------------------------------------------------------------------------------
175 OSCL_EXPORT_REF void Syn_filt(
176 Word16 a[], /* (i) : a[M+1] prediction coefficients (M=10) */
177 Word16 x[], /* (i) : input signal */
178 Word16 y[], /* (o) : output signal */
179 Word16 lg, /* (i) : size of filtering (40) */
180 Word16 mem[], /* (i/o) : memory associated with this filtering. */
181 Word16 update /* (i) : 0=no update, 1=update of memory. */
187 Word16 tmp[2*M]; /* This is usually done by memory allocation (lg+M) */
195 /* Copy mem[] to yy[] */
199 oscl_memcpy(yy, mem, M*sizeof(Word16));
203 /* Do the filtering. */
209 for (i = M >> 1; i != 0; i--)
213 s1 = amrnb_fxp_mac_16_by_16bb((Word32) * (p_x++), (Word32) * (p_a), 0x00000800L);
214 s2 = amrnb_fxp_mac_16_by_16bb((Word32) * (p_x++), (Word32) * (p_a++), 0x00000800L);
215 s1 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a++), (Word32) * (p_yy1), s1);
217 for (j = (M >> 1) - 2; j != 0; j--)
219 s2 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a), (Word32) * (p_yy1--), s2);
220 s1 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a++), (Word32) * (p_yy1), s1);
221 s2 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a), (Word32) * (p_yy1--), s2);
222 s1 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a++), (Word32) * (p_yy1), s1);
223 s2 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a), (Word32) * (p_yy1--), s2);
224 s1 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a++), (Word32) * (p_yy1), s1);
227 /* check for overflow on s1 */
228 if ((UWord32)(s1 + 134217728) < 0x0fffffffL)
230 temp = (Word16)(s1 >> 12);
232 else if (s1 > 0x07ffffffL)
241 s2 = amrnb_fxp_msu_16_by_16bb((Word32)a[1], (Word32)temp, s2);
248 /* check for overflow on s2 */
249 if ((UWord32)(s2 + 134217728) < 0x0fffffffL)
251 temp = (Word16)(s2 >> 12);
253 else if (s2 > 0x07ffffffL)
268 for (i = (lg - M) >> 1; i != 0; i--)
272 s1 = amrnb_fxp_mac_16_by_16bb((Word32) * (p_x++), (Word32) * (p_a), 0x00000800L);
273 s2 = amrnb_fxp_mac_16_by_16bb((Word32) * (p_x++), (Word32) * (p_a++), 0x00000800L);
274 s1 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a++), (Word32) * (p_yy1), s1);
276 for (j = (M >> 1) - 2; j != 0; j--)
278 s2 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a), (Word32) * (p_yy1--), s2);
279 s1 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a++), (Word32) * (p_yy1), s1);
280 s2 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a), (Word32) * (p_yy1--), s2);
281 s1 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a++), (Word32) * (p_yy1), s1);
282 s2 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a), (Word32) * (p_yy1--), s2);
283 s1 = amrnb_fxp_msu_16_by_16bb((Word32) * (p_a++), (Word32) * (p_yy1), s1);
286 if ((UWord32)(s1 + 134217728) < 0x0fffffffL)
288 temp = (Word16)(s1 >> 12);
290 else if (s1 > 0x07ffffffL)
299 s2 = amrnb_fxp_msu_16_by_16bb((Word32)a[1], (Word32)temp, s2);
304 if ((UWord32)(s2 + 134217728) < 0x0fffffffL)
306 *(p_y++) = (Word16)(s2 >> 12);
308 else if (s2 > 0x07ffffffL)
318 /* Update of memory if update==1 */
321 oscl_memcpy(mem, &y[lg-M], M*sizeof(Word16));