pred_lt.cpp revision 4f1efc098cb5791c3e9f483f2af84aef70d2d0a0
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.073
22    ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23    Available from http://www.3gpp.org
24
25(C) 2004, 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 Pathname: ./audio/gsm-amr/c/src/pred_lt.c
31
32------------------------------------------------------------------------------
33 REVISION HISTORY
34
35 Description: Updated template used to PV coding template. First attempt at
36          optimizing C code.
37
38 Description: Deleted variables listed in the Local Stores Needed/Modified
39          sections.
40
41 Description: Updated file per comments from Phase 2/3 review.
42
43 Description: Synchronized file with UMTS version 3.2.0. Updated coding
44              template. Removed unnecessary include files.
45
46 Description: Fixed typecasting issue with TI C compiler. Updated copyright
47              year.
48
49 Description:
50 (1) Removed instance of static in the const table "inter_6"
51 (2) Changed Overflow from a global to a parameter passed via a pointer.
52 (3) Made numerous small changes to bring code more in line with PV standards.
53
54 Description:  For pred_ltp()
55              1. Eliminated unused include files.
56              2. Replaced array addressing by pointers
57              3. Eliminated math operations that unnecessary checked for
58                 saturation
59              4. Unrolled loops to speed up processing, use decrement loops,
60                 loaded into memory filter coefficient in linear order for
61                 faster execution in main loop.
62              5. Eliminated call to round by proper initialization
63
64 Description:  Replaced "int" and/or "char" with defined types.
65               Added proper casting (Word32) to some left shifting operations
66
67
68 Description: Changed round function name to pv_round to avoid conflict with
69              round function in C standard library.
70
71 Who:                           Date:
72 Description:
73
74------------------------------------------------------------------------------
75*/
76
77/*----------------------------------------------------------------------------
78; INCLUDES
79----------------------------------------------------------------------------*/
80#include "pred_lt.h"
81#include "cnst.h"
82
83/*----------------------------------------------------------------------------
84; MACROS
85; Define module specific macros here
86----------------------------------------------------------------------------*/
87
88/*----------------------------------------------------------------------------
89; DEFINES
90; Include all pre-processor statements here. Include conditional
91; compile variables also.
92----------------------------------------------------------------------------*/
93#define UP_SAMP_MAX  6
94#define L_INTER10    (L_INTERPOL-1)
95#define FIR_SIZE     (UP_SAMP_MAX*L_INTER10+1)
96
97/*----------------------------------------------------------------------------
98; LOCAL FUNCTION DEFINITIONS
99; Function Prototype declaration
100----------------------------------------------------------------------------*/
101
102/*----------------------------------------------------------------------------
103; LOCAL STORE/BUFFER/POINTER DEFINITIONS
104; Variable declaration - defined here and used outside this module
105----------------------------------------------------------------------------*/
106
107/* 1/6 resolution interpolation filter  (-3 dB at 3600 Hz) */
108/* Note: the 1/3 resolution filter is simply a subsampled
109 *       version of the 1/6 resolution filter, i.e. it uses
110 *       every second coefficient:
111 *
112 *          inter_3l[k] = inter_6[2*k], 0 <= k <= 3*L_INTER10
113 */
114
115const Word16 inter_6_pred_lt[FIR_SIZE] =
116{
117    29443,
118    28346, 25207, 20449, 14701,  8693,  3143,
119    -1352, -4402, -5865, -5850, -4673, -2783,
120    -672,  1211,  2536,  3130,  2991,  2259,
121    1170,     0, -1001, -1652, -1868, -1666,
122    -1147,  -464,   218,   756,  1060,  1099,
123    904,   550,   135,  -245,  -514,  -634,
124    -602,  -451,  -231,     0,   191,   308,
125    340,   296,   198,    78,   -36,  -120,
126    -163,  -165,  -132,   -79,   -19,    34,
127    73,    91,    89,    70,    38,     0
128};
129
130
131/*
132------------------------------------------------------------------------------
133 FUNCTION NAME: Pred_lt_3or6
134------------------------------------------------------------------------------
135 INPUT AND OUTPUT DEFINITIONS
136
137 Inputs:
138    exc = buffer containing the excitation (Word16)
139    T0 = integer pitch lag (Word16)
140    frac = fraction of lag (Word16)
141    L_subfr = number of samples per subframe (Word16)
142    flag3 = flag to indicate the upsampling rate; if set, upsampling
143            rate is 3, otherwise, upsampling rate is 6 (Word16)
144
145    pOverflow = pointer to overflow (Flag)
146
147 Returns:
148    None
149
150 Outputs:
151    exc buffer contains the newly formed adaptive codebook excitation
152    pOverflow -> 1 if the add operation resulted in overflow
153
154 Global Variables Used:
155    inter_6_pred_lt = (1/6) resolution interpolation filter table (Word16)
156
157 Local Variables Needed:
158    None
159
160------------------------------------------------------------------------------
161 FUNCTION DESCRIPTION
162
163 This function computes the result of long term prediction with fractional
164 interpolation of resolution 1/3 or 1/6. (Interpolated past excitation).
165
166 The past excitation signal at the given delay is interpolated at
167 the given fraction to build the adaptive codebook excitation.
168 On return exc[0..L_subfr-1] contains the interpolated signal
169 (adaptive codebook excitation).
170
171------------------------------------------------------------------------------
172 REQUIREMENTS
173
174 None
175
176------------------------------------------------------------------------------
177 REFERENCES
178
179 pred_lt.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
180
181------------------------------------------------------------------------------
182 PSEUDO-CODE
183
184void Pred_lt_3or6 (
185    Word16 exc[],     // in/out: excitation buffer
186    Word16 T0,        // input : integer pitch lag
187    Word16 frac,      // input : fraction of lag
188    Word16 L_subfr,   // input : subframe size
189    Word16 flag3      // input : if set, upsampling rate = 3 (6 otherwise)
190)
191{
192    Word16 i, j, k;
193    Word16 *pX0, *pX1, *pX2;
194    const Word16 *pC1, *pC2;
195    Word32 s;
196
197    pX0 = &exc[-T0];
198
199    frac = negate (frac);
200    if (flag3 != 0)
201    {
202      frac = shl (frac, 1);   // inter_3l[k] = inter_6[2*k] -> k' = 2*k
203    }
204
205    if (frac < 0)
206    {
207        frac = add (frac, UP_SAMP_MAX);
208        pX0--;
209    }
210
211    for (j = 0; j < L_subfr; j++)
212    {
213        pX1 = pX0++;
214        pX2 = pX0;
215        pC1 = &inter_6[frac];
216        pC2 = &inter_6[sub (UP_SAMP_MAX, frac)];
217
218        s = 0;
219        for (i = 0, k = 0; i < L_INTER10; i++, k += UP_SAMP_MAX)
220        {
221            s = L_mac (s, pX1[-i], pC1[k]);
222            s = L_mac (s, pX2[i], pC2[k]);
223        }
224
225        exc[j] = pv_round (s);
226    }
227
228    return;
229}
230
231------------------------------------------------------------------------------
232 RESOURCES USED [optional]
233
234 When the code is written for a specific target processor the
235 the resources used should be documented below.
236
237 HEAP MEMORY USED: x bytes
238
239 STACK MEMORY USED: x bytes
240
241 CLOCK CYCLES: (cycle count equation for this function) + (variable
242                used to represent cycle count for each subroutine
243                called)
244     where: (cycle count variable) = cycle count for [subroutine
245                                     name]
246
247------------------------------------------------------------------------------
248 CAUTION [optional]
249 [State any special notes, constraints or cautions for users of this function]
250
251------------------------------------------------------------------------------
252*/
253
254void Pred_lt_3or6(
255    Word16 exc[],     /* in/out: excitation buffer                          */
256    Word16 T0,        /* input : integer pitch lag                          */
257    Word16 frac,      /* input : fraction of lag                            */
258    Word16 L_subfr,   /* input : subframe size                              */
259    Word16 flag3,     /* input : if set, upsampling rate = 3 (6 otherwise)  */
260    Flag  *pOverflow  /* output: if set, overflow occurred in this function */
261)
262{
263    register Word16 i;
264    register Word16 j;
265    register Word16 k;
266
267    Word16 *pX0;
268    Word16 *pX2;
269    Word16 *pX3;
270    Word16 *p_exc;
271    Word16 *pC1;
272    const Word16 *pC1_ref;
273    const Word16 *pC2_ref;
274
275    Word16 Coeff_1[(L_INTER10<<1)];
276
277    Word32 s1;
278    Word32 s2;
279    OSCL_UNUSED_ARG(pOverflow);
280
281    pX0 = &(exc[-T0]);
282
283    /* frac goes between -3 and 3 */
284
285    frac = -frac;
286
287    if (flag3 != 0)
288    {
289        frac <<= 1;   /* inter_3l[k] = inter_6[2*k] -> k' = 2*k */
290    }
291
292    if (frac < 0)
293    {
294        frac += UP_SAMP_MAX;
295        pX0--;
296    }
297
298    pC1_ref = &inter_6_pred_lt[frac];
299    pC2_ref = &inter_6_pred_lt[UP_SAMP_MAX-frac];
300
301
302    pC1 = Coeff_1;
303
304    k = 0;
305
306    for (i = L_INTER10 >> 1; i > 0; i--)
307    {
308        *(pC1++) = pC1_ref[k];
309        *(pC1++) = pC2_ref[k];
310        k += UP_SAMP_MAX;
311        *(pC1++) = pC1_ref[k];
312        *(pC1++) = pC2_ref[k];
313        k += UP_SAMP_MAX;
314
315    }
316
317    p_exc = exc;
318
319    for (j = (L_subfr >> 1); j != 0 ; j--)
320    {
321        pX0++;
322        pX2 = pX0;
323        pX3 = pX0++;
324
325        pC1 = Coeff_1;
326
327        s1  = 0x00004000L;
328        s2  = 0x00004000L;
329
330        for (i = L_INTER10 >> 1; i > 0; i--)
331        {
332            s2 += ((Word32) * (pX3--)) * *(pC1);
333            s1 += ((Word32) * (pX3)) * *(pC1++);
334            s1 += ((Word32) * (pX2++)) * *(pC1);
335            s2 += ((Word32) * (pX2)) * *(pC1++);
336            s2 += ((Word32) * (pX3--)) * *(pC1);
337            s1 += ((Word32) * (pX3)) * *(pC1++);
338            s1 += ((Word32) * (pX2++)) * *(pC1);
339            s2 += ((Word32) * (pX2)) * *(pC1++);
340
341        } /* for (i = L_INTER10>>1; i > 0; i--) */
342
343        *(p_exc++) = (Word16)(s1 >> 15);
344        *(p_exc++) = (Word16)(s2 >> 15);
345
346    } /* for (j = (L_subfr>>1); j != 0 ; j--) */
347
348    return;
349}
350