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: low_pass_filt_7k.cpp
35 
36      Date: 05/08/2004
37 
38 ------------------------------------------------------------------------------
39  REVISION HISTORY
40 
41 
42  Description:
43 
44 ------------------------------------------------------------------------------
45  INPUT AND OUTPUT DEFINITIONS
46 
47      int16 signal[],             input signal / output is divided by 16
48      int16 lg,                   lenght of signal
49      int16 mem[]                 in/out: memory (size=30)
50      int16 x[]                   scratch mem ( size= 60)
51 
52 ------------------------------------------------------------------------------
53  FUNCTION DESCRIPTION
54 
55         15th order high pass 7kHz FIR filter
56 
57 
58 ------------------------------------------------------------------------------
59  REQUIREMENTS
60 
61 
62 ------------------------------------------------------------------------------
63  REFERENCES
64 
65 ------------------------------------------------------------------------------
66  PSEUDO-CODE
67 
68 ------------------------------------------------------------------------------
69 */
70 
71 
72 /*----------------------------------------------------------------------------
73 ; INCLUDES
74 ----------------------------------------------------------------------------*/
75 
76 #include "pv_amr_wb_type_defs.h"
77 #include "pvamrwbdecoder_basic_op.h"
78 #include "pvamrwbdecoder_cnst.h"
79 #include "pvamrwbdecoder_acelp.h"
80 
81 /*----------------------------------------------------------------------------
82 ; MACROS
83 ; Define module specific macros here
84 ----------------------------------------------------------------------------*/
85 
86 
87 /*----------------------------------------------------------------------------
88 ; DEFINES
89 ; Include all pre-processor statements here. Include conditional
90 ; compile variables also.
91 ----------------------------------------------------------------------------*/
92 #define L_FIR 30
93 
94 /*----------------------------------------------------------------------------
95 ; LOCAL FUNCTION DEFINITIONS
96 ; Function Prototype declaration
97 ----------------------------------------------------------------------------*/
98 
99 /*----------------------------------------------------------------------------
100 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
101 ; Variable declaration - defined here and used outside this module
102 ----------------------------------------------------------------------------*/
103 const int16 fir_7k[L_FIR+1] =
104 {
105     -21, 47, -89, 146, -203,
106     229, -177, 0, 335, -839,
107     1485, -2211, 2931, -3542, 3953,
108     28682, 3953, -3542, 2931, -2211,
109     1485, -839, 335, 0, -177,
110     229, -203, 146, -89, 47,
111     -21
112 };
113 
114 /*----------------------------------------------------------------------------
115 ; EXTERNAL FUNCTION REFERENCES
116 ; Declare functions defined elsewhere and referenced in this module
117 ----------------------------------------------------------------------------*/
118 
119 /*----------------------------------------------------------------------------
120 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
121 ; Declare variables used in this module but defined elsewhere
122 ----------------------------------------------------------------------------*/
123 
124 /*----------------------------------------------------------------------------
125 ; FUNCTION CODE
126 ----------------------------------------------------------------------------*/
127 
128 
low_pass_filt_7k_init(int16 mem[])129 void low_pass_filt_7k_init(int16 mem[])            /* mem[30] */
130 {
131     pv_memset((void *)mem, 0, (L_FIR)*sizeof(*mem));
132 
133     return;
134 }
135 
136 
137 /*----------------------------------------------------------------------------
138 ; FUNCTION CODE
139 ----------------------------------------------------------------------------*/
140 
141 
low_pass_filt_7k(int16 signal[],int16 lg,int16 mem[],int16 x[])142 void low_pass_filt_7k(
143     int16 signal[],                      /* input:  signal                  */
144     int16 lg,                            /* input:  length of input         */
145     int16 mem[],                         /* in/out: memory (size=30)        */
146     int16 x[]
147 )
148 {
149     int16 i, j;
150     int32 L_tmp1;
151     int32 L_tmp2;
152     int32 L_tmp3;
153     int32 L_tmp4;
154 
155     pv_memcpy((void *)x, (void *)mem, (L_FIR)*sizeof(*x));
156 
157     for (i = 0; i < lg >> 2; i++)
158     {
159         x[(i<<2) + L_FIR    ] = signal[(i<<2)];
160         x[(i<<2) + L_FIR + 1] = signal[(i<<2)+1];
161         x[(i<<2) + L_FIR + 2] = signal[(i<<2)+2];
162         x[(i<<2) + L_FIR + 3] = signal[(i<<2)+3];
163 
164         L_tmp1 = fxp_mac_16by16(x[(i<<2)] + signal[(i<<2)], fir_7k[0], 0x00004000);
165         L_tmp2 = fxp_mac_16by16(x[(i<<2)+1] + signal[(i<<2)+1], fir_7k[0], 0x00004000);
166         L_tmp3 = fxp_mac_16by16(x[(i<<2)+2] + signal[(i<<2)+2], fir_7k[0], 0x00004000);
167         L_tmp4 = fxp_mac_16by16(x[(i<<2)+3] + signal[(i<<2)+3], fir_7k[0], 0x00004000);
168 
169         for (j = 1; j < L_FIR - 1; j += 4)
170         {
171 
172 
173             int16 tmp1 = x[(i<<2)+j  ];
174             int16 tmp2 = x[(i<<2)+j+1];
175             int16 tmp3 = x[(i<<2)+j+2];
176 
177             L_tmp1 = fxp_mac_16by16(tmp1, fir_7k[j  ], L_tmp1);
178             L_tmp2 = fxp_mac_16by16(tmp2, fir_7k[j  ], L_tmp2);
179             L_tmp1 = fxp_mac_16by16(tmp2, fir_7k[j+1], L_tmp1);
180             L_tmp2 = fxp_mac_16by16(tmp3, fir_7k[j+1], L_tmp2);
181             L_tmp3 = fxp_mac_16by16(tmp3, fir_7k[j  ], L_tmp3);
182             L_tmp1 = fxp_mac_16by16(tmp3, fir_7k[j+2], L_tmp1);
183 
184             tmp1 = x[(i<<2)+j+3];
185             tmp2 = x[(i<<2)+j+4];
186 
187             L_tmp2 = fxp_mac_16by16(tmp1, fir_7k[j+2], L_tmp2);
188             L_tmp4 = fxp_mac_16by16(tmp1, fir_7k[j  ], L_tmp4);
189             L_tmp3 = fxp_mac_16by16(tmp1, fir_7k[j+1], L_tmp3);
190             L_tmp1 = fxp_mac_16by16(tmp1, fir_7k[j+3], L_tmp1);
191             L_tmp2 = fxp_mac_16by16(tmp2, fir_7k[j+3], L_tmp2);
192             L_tmp4 = fxp_mac_16by16(tmp2, fir_7k[j+1], L_tmp4);
193             L_tmp3 = fxp_mac_16by16(tmp2, fir_7k[j+2], L_tmp3);
194 
195             tmp1 = x[(i<<2)+j+5];
196             tmp2 = x[(i<<2)+j+6];
197 
198             L_tmp4 = fxp_mac_16by16(tmp1, fir_7k[j+2], L_tmp4);
199             L_tmp3 = fxp_mac_16by16(tmp1, fir_7k[j+3], L_tmp3);
200             L_tmp4 = fxp_mac_16by16(tmp2, fir_7k[j+3], L_tmp4);
201 
202         }
203 
204         L_tmp1 = fxp_mac_16by16(x[(i<<2)+j  ], fir_7k[j  ], L_tmp1);
205         L_tmp2 = fxp_mac_16by16(x[(i<<2)+j+1], fir_7k[j  ], L_tmp2);
206         L_tmp3 = fxp_mac_16by16(x[(i<<2)+j+2], fir_7k[j  ], L_tmp3);
207         L_tmp4 = fxp_mac_16by16(x[(i<<2)+j+3], fir_7k[j  ], L_tmp4);
208 
209         signal[(i<<2)] = (int16)(L_tmp1 >> 15);
210         signal[(i<<2)+1] = (int16)(L_tmp2 >> 15);
211         signal[(i<<2)+2] = (int16)(L_tmp3 >> 15);
212         signal[(i<<2)+3] = (int16)(L_tmp4 >> 15);
213 
214     }
215 
216     pv_memcpy((void *)mem, (void *)(x + lg), (L_FIR)*sizeof(*mem));
217 
218     return;
219 }
220 
221