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: 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----------------------------------------------------------------------------*/
103const 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
129void 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
142void 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