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: oversamp_12k8_to_16k.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 Oversamp_16k : oversampling from 12.8kHz to 16kHz.
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_acelp.h"
79#include "pvamrwbdecoder_cnst.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
93#define FAC4   4
94#define FAC5   5
95#define INV_FAC5   6554                    /* 1/5 in Q15 */
96#define DOWN_FAC  26215                    /* 4/5 in Q15 */
97#define UP_FAC    20480                    /* 5/4 in Q14 */
98#define NB_COEF_DOWN  15
99#define NB_COEF_UP    12
100#define N_LOOP_COEF_UP    4
101
102/*----------------------------------------------------------------------------
103; LOCAL FUNCTION DEFINITIONS
104; Function Prototype declaration
105----------------------------------------------------------------------------*/
106
107#ifdef __cplusplus
108extern "C"
109{
110#endif
111
112
113    /* Local functions */
114
115    void AmrWbUp_samp(
116        int16 * sig_d,                       /* input:  signal to oversampling  */
117        int16 * sig_u,                       /* output: oversampled signal      */
118        int16 L_frame                        /* input:  length of output        */
119    );
120
121
122    int16 AmrWbInterpol(                      /* return result of interpolation */
123        int16 * x,                           /* input vector                   */
124        const int16 * fir,                   /* filter coefficient             */
125        int16 nb_coef                        /* number of coefficients         */
126    );
127
128
129#ifdef __cplusplus
130}
131#endif
132
133/*----------------------------------------------------------------------------
134; LOCAL STORE/BUFFER/POINTER DEFINITIONS
135; Variable declaration - defined here and used outside this module
136----------------------------------------------------------------------------*/
137
138
139/* 1/5 resolution interpolation filter  (in Q14)  */
140/* -1.5dB @ 6kHz,    -6dB @ 6.4kHz, -10dB @ 6.6kHz,
141    -20dB @ 6.9kHz, -25dB @ 7kHz,   -55dB @ 8kHz  */
142
143
144const int16 fir_up[4][24] =
145{
146
147    {
148        -1,        12,       -33,       68,       -119,       191,
149        -291,       430,      -634,       963,     -1616,      3792,
150        15317,     -2496,      1288,      -809,       542,      -369,
151        247,      -160,        96,       -52,        23,        -6,
152    },
153    {
154        -4,        24,       -62,       124,      -213,       338,
155        -510,       752,     -1111,      1708,     -2974,      8219,
156        12368,     -3432,      1881,     -1204,       812,      -552,
157        368,      -235,       139,       -73,        30,        -7,
158    },
159    {
160        -7,        30,       -73,       139,      -235,       368,
161        -552,       812,     -1204,      1881,     -3432,     12368,
162        8219,     -2974,      1708,     -1111,       752,      -510,
163        338,      -213,       124,       -62,        24,        -4,
164    },
165    {
166        -6,        23,       -52,        96,      -160,       247,
167        -369,       542,      -809,      1288,     -2496,     15317,
168        3792,     -1616,       963,      -634,       430,      -291,
169        191,      -119,        68,       -33,        12,        -1,
170    }
171};
172
173/*----------------------------------------------------------------------------
174; EXTERNAL FUNCTION REFERENCES
175; Declare functions defined elsewhere and referenced in this module
176----------------------------------------------------------------------------*/
177
178/*----------------------------------------------------------------------------
179; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
180; Declare variables used in this module but defined elsewhere
181----------------------------------------------------------------------------*/
182
183/*----------------------------------------------------------------------------
184; FUNCTION CODE
185----------------------------------------------------------------------------*/
186
187
188/* output: memory (2*NB_COEF_UP) set to zeros  */
189void oversamp_12k8_to_16k_init(int16 mem[])
190{
191    pv_memset((void *)mem, 0, (2*NB_COEF_UP)*sizeof(*mem));
192
193}
194
195/*----------------------------------------------------------------------------
196; FUNCTION CODE
197----------------------------------------------------------------------------*/
198
199void oversamp_12k8_to_16k(
200    int16 sig12k8[],                     /* input:  signal to oversampling  */
201    int16 lg,                            /* input:  length of input         */
202    int16 sig16k[],                      /* output: oversampled signal      */
203    int16 mem[],                         /* in/out: memory (2*NB_COEF_UP)   */
204    int16 signal[]
205)
206{
207    int16 lg_up;
208
209    pv_memcpy((void *)signal,
210              (void *)mem,
211              (2*NB_COEF_UP)*sizeof(*mem));
212
213    pv_memcpy((void *)(signal + (2*NB_COEF_UP)),
214              (void *)sig12k8,
215              lg*sizeof(*sig12k8));
216
217    lg_up = lg + (lg >> 2); /* 5/4 of lg */
218
219    AmrWbUp_samp(signal + NB_COEF_UP, sig16k, lg_up);
220
221    pv_memcpy((void *)mem,
222              (void *)(signal + lg),
223              (2*NB_COEF_UP)*sizeof(*signal));
224
225    return;
226}
227
228
229
230/*----------------------------------------------------------------------------
231; FUNCTION CODE
232----------------------------------------------------------------------------*/
233
234
235void AmrWbUp_samp(
236    int16 * sig_d,                       /* input:  signal to oversampling  */
237    int16 * sig_u,                       /* output: oversampled signal      */
238    int16 L_frame                        /* input:  length of output        */
239)
240{
241
242    int32 i;
243    int16 frac, j;
244    int16 * pt_sig_u = sig_u;
245
246    frac = 1;
247    for (j = 0; j < L_frame; j++)
248    {
249        i = ((int32)j * INV_FAC5) >> 13;       /* integer part = pos * 1/5 */
250
251        frac--;
252        if (frac)
253        {
254            *(pt_sig_u++) = AmrWbInterpol(&sig_d[i],
255                                          fir_up[(FAC5-1) - frac],
256                                          N_LOOP_COEF_UP);
257        }
258        else
259        {
260            *(pt_sig_u++) = sig_d[i+12 - NB_COEF_UP ];
261            frac = FAC5;
262        }
263    }
264
265}
266
267/*----------------------------------------------------------------------------
268; FUNCTION CODE
269----------------------------------------------------------------------------*/
270
271
272/* Fractional interpolation of signal at position (frac/resol) */
273
274
275int16 AmrWbInterpol(                      /* return result of interpolation */
276    int16 * x,                           /* input vector                   */
277    const int16 *fir,                    /* filter coefficient             */
278    int16 nb_coef                        /* number of coefficients         */
279)
280{
281    int32 L_sum;
282    const int16 *pt_fir = fir;
283
284    int16 tmp1, tmp2, tmp3, tmp4;
285    int16 *pt_x = x - nb_coef - (nb_coef << 1) + 1;
286
287
288    tmp1 = *(pt_x++);
289    tmp2 = *(pt_x++);
290    tmp3 = *(pt_x++);
291    tmp4 = *(pt_x++);
292    L_sum = fxp_mac_16by16(tmp1, *(pt_fir++), 0x00002000L);
293    L_sum = fxp_mac_16by16(tmp2, *(pt_fir++), L_sum);
294    L_sum = fxp_mac_16by16(tmp3, *(pt_fir++), L_sum);
295    L_sum = fxp_mac_16by16(tmp4, *(pt_fir++), L_sum);
296    tmp1 = *(pt_x++);
297    tmp2 = *(pt_x++);
298    tmp3 = *(pt_x++);
299    tmp4 = *(pt_x++);
300    L_sum = fxp_mac_16by16(tmp1, *(pt_fir++), L_sum);
301    L_sum = fxp_mac_16by16(tmp2, *(pt_fir++), L_sum);
302    L_sum = fxp_mac_16by16(tmp3, *(pt_fir++), L_sum);
303    L_sum = fxp_mac_16by16(tmp4, *(pt_fir++), L_sum);
304    tmp1 = *(pt_x++);
305    tmp2 = *(pt_x++);
306    tmp3 = *(pt_x++);
307    tmp4 = *(pt_x++);
308    L_sum = fxp_mac_16by16(tmp1, *(pt_fir++), L_sum);
309    L_sum = fxp_mac_16by16(tmp2, *(pt_fir++), L_sum);
310    L_sum = fxp_mac_16by16(tmp3, *(pt_fir++), L_sum);
311    L_sum = fxp_mac_16by16(tmp4, *(pt_fir++), L_sum);
312    tmp1 = *(pt_x++);
313    tmp2 = *(pt_x++);
314    tmp3 = *(pt_x++);
315    tmp4 = *(pt_x++);
316    L_sum = fxp_mac_16by16(tmp1, *(pt_fir++), L_sum);
317    L_sum = fxp_mac_16by16(tmp2, *(pt_fir++), L_sum);
318    L_sum = fxp_mac_16by16(tmp3, *(pt_fir++), L_sum);
319    L_sum = fxp_mac_16by16(tmp4, *(pt_fir++), L_sum);
320    tmp1 = *(pt_x++);
321    tmp2 = *(pt_x++);
322    tmp3 = *(pt_x++);
323    tmp4 = *(pt_x++);
324    L_sum = fxp_mac_16by16(tmp1, *(pt_fir++), L_sum);
325    L_sum = fxp_mac_16by16(tmp2, *(pt_fir++), L_sum);
326    L_sum = fxp_mac_16by16(tmp3, *(pt_fir++), L_sum);
327    L_sum = fxp_mac_16by16(tmp4, *(pt_fir++), L_sum);
328    tmp1 = *(pt_x++);
329    tmp2 = *(pt_x++);
330    tmp3 = *(pt_x++);
331    tmp4 = *(pt_x++);
332    L_sum = fxp_mac_16by16(tmp1, *(pt_fir++), L_sum);
333    L_sum = fxp_mac_16by16(tmp2, *(pt_fir++), L_sum);
334    L_sum = fxp_mac_16by16(tmp3, *(pt_fir++), L_sum);
335    L_sum = fxp_mac_16by16(tmp4, *(pt_fir++), L_sum);
336
337
338    L_sum = shl_int32(L_sum, 2);               /* saturation can occur here */
339
340    return ((int16)(L_sum >> 16));
341}
342
343