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------------------------------------------------------------------------------
31
32
33
34 Pathname: ./audio/gsm-amr/c/src/dec_lag6.c
35 Functions: Dec_lag6
36
37     Date: 01/31/2002
38
39------------------------------------------------------------------------------
40 REVISION HISTORY
41
42 Description:
43 (1) Updated to accept new parameter, Flag *pOverflow.
44 (2) Placed file in the proper PV Software template.
45
46 Description:
47 (1) Removed "count.h" and "basic_op.h" and replaced with individual include
48     files (add.h, sub.h, etc.)
49
50 Description:
51 (1) Removed optimization -- mult(i, 3, pOverflow) is NOT the same as adding
52     i to itself 3 times.  The reason is because the mult function does a
53     right shift by 15, which will obliterate smaller numbers.
54
55 Description:  Replaced "int" and/or "char" with OSCL defined types.
56
57 Description:
58
59 ------------------------------------------------------------------------------
60 INPUT AND OUTPUT DEFINITIONS
61
62 Inputs:
63    index   -- Word16 -- received pitch index
64    pit_min  -- Word16 -- minimum pitch lag
65    pit_max  -- Word16 -- maximum pitch lag
66    i_subfr -- Word16 -- subframe flag
67    T0 -- Pointer to type Word16 -- integer part of pitch lag
68
69 Outputs:
70
71    T0 -- Pointer to type Word16 -- integer part of pitch lag
72    T0_frac -- Pointer to type Word16 -- fractional part of pitch lag
73    pOverflow -- Pointer to type Flag -- Flag set when overflow occurs
74
75 Returns:
76    None.
77
78 Global Variables Used:
79    None
80
81 Local Variables Needed:
82    None
83
84------------------------------------------------------------------------------
85 FUNCTION DESCRIPTION
86
87 PURPOSE:  Decoding of fractional pitch lag with 1/6 resolution.
88           Extract the integer and fraction parts of the pitch lag from
89           the received adaptive codebook index.
90
91  See "Enc_lag6.c" for more details about the encoding procedure.
92
93  The fractional lag in 1st and 3rd subframes is encoded with 9 bits
94  while that in 2nd and 4th subframes is relatively encoded with 6 bits.
95  Note that in relative encoding only 61 values are used. If the
96  decoder receives 61, 62, or 63 as the relative pitch index, it means
97  that a transmission error occurred. In this case, the pitch lag from
98  previous subframe (actually from previous frame) is used.
99
100------------------------------------------------------------------------------
101 REQUIREMENTS
102
103
104
105------------------------------------------------------------------------------
106 REFERENCES
107
108 dec_lag6.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
109
110------------------------------------------------------------------------------
111 PSEUDO-CODE
112
113
114
115------------------------------------------------------------------------------
116 RESOURCES USED
117   When the code is written for a specific target processor the
118     the resources used should be documented below.
119
120 STACK USAGE: [stack count for this module] + [variable to represent
121          stack usage for each subroutine called]
122
123     where: [stack usage variable] = stack usage for [subroutine
124         name] (see [filename].ext)
125
126 DATA MEMORY USED: x words
127
128 PROGRAM MEMORY USED: x words
129
130 CLOCK CYCLES: [cycle count equation for this module] + [variable
131           used to represent cycle count for each subroutine
132           called]
133
134     where: [cycle count variable] = cycle count for [subroutine
135        name] (see [filename].ext)
136
137------------------------------------------------------------------------------
138*/
139
140
141/*----------------------------------------------------------------------------
142; INCLUDES
143----------------------------------------------------------------------------*/
144#include "dec_lag6.h"
145#include "typedef.h"
146#include "basic_op.h"
147
148/*----------------------------------------------------------------------------
149; MACROS
150; Define module specific macros here
151----------------------------------------------------------------------------*/
152
153
154/*----------------------------------------------------------------------------
155; DEFINES
156; Include all pre-processor statements here. Include conditional
157; compile variables also.
158----------------------------------------------------------------------------*/
159
160/*----------------------------------------------------------------------------
161; LOCAL FUNCTION DEFINITIONS
162; Function Prototype declaration
163----------------------------------------------------------------------------*/
164
165
166/*----------------------------------------------------------------------------
167; LOCAL STORE/BUFFER/POINTER DEFINITIONS
168; Variable declaration - defined here and used outside this module
169----------------------------------------------------------------------------*/
170
171/*----------------------------------------------------------------------------
172; EXTERNAL FUNCTION REFERENCES
173; Declare functions defined elsewhere and referenced in this module
174----------------------------------------------------------------------------*/
175
176/*----------------------------------------------------------------------------
177; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
178; Declare variables used in this module but defined elsewhere
179----------------------------------------------------------------------------*/
180
181/*----------------------------------------------------------------------------
182; FUNCTION CODE
183----------------------------------------------------------------------------*/
184
185void Dec_lag6(
186    Word16 index,      /* input : received pitch index           */
187    Word16 pit_min,    /* input : minimum pitch lag              */
188    Word16 pit_max,    /* input : maximum pitch lag              */
189    Word16 i_subfr,    /* input : subframe flag                  */
190    Word16 *T0,        /* in/out: integer part of pitch lag      */
191    Word16 *T0_frac,   /* output: fractional part of pitch lag   */
192    Flag   *pOverflow  /* o : Flag set when overflow occurs      */
193)
194{
195    Word16 i;
196    Word16 T0_min;
197    Word16 T0_max;
198    Word16 k;
199    Word16 w;
200
201    if (i_subfr == 0)          /* if 1st or 3rd subframe */
202    {
203        if (index < 463)
204        {
205            /* T0 = (index+5)/6 + 17 */
206            i = index + 5;
207            i =
208                mult(
209                    i,
210                    5462,
211                    pOverflow);
212
213            i =
214                add(
215                    i,
216                    17,
217                    pOverflow);
218
219            *T0 = i;
220
221            /* i = 3* (*T0) */
222
223            i = add(i, i, pOverflow);
224            i = add(i, *T0, pOverflow);
225
226            /* *T0_frac = index - T0*6 + 105 */
227
228            i =
229                add(
230                    i,
231                    i,
232                    pOverflow);
233
234            i =
235                sub(
236                    index,
237                    i,
238                    pOverflow);
239
240            *T0_frac =
241                add(
242                    i,
243                    105,
244                    pOverflow);
245        }
246        else
247        {
248            *T0 =
249                sub(
250                    index,
251                    368,
252                    pOverflow);
253
254            *T0_frac = 0;
255        }
256    }
257    else       /* second or fourth subframe */
258    {
259        /* find T0_min and T0_max for 2nd (or 4th) subframe */
260
261        T0_min =
262            sub(
263                *T0,
264                5,
265                pOverflow);
266
267        if (T0_min < pit_min)
268        {
269            T0_min = pit_min;
270        }
271
272        T0_max =
273            add(
274                T0_min,
275                9,
276                pOverflow);
277
278        if (T0_max > pit_max)
279        {
280            T0_max = pit_max;
281
282            T0_min =
283                sub(
284                    T0_max,
285                    9,
286                    pOverflow);
287        }
288
289        /* i = (index+5)/6 - 1 */
290        i =
291            add(
292                index,
293                5,
294                pOverflow);
295
296        i =
297            mult(
298                i,
299                5462,
300                pOverflow);
301
302        i =
303            sub(
304                i,
305                1,
306                pOverflow);
307
308        *T0 =
309            add(
310                i,
311                T0_min,
312                pOverflow);
313
314        /* i = 3* (*T0) */
315
316        w = add(i, i, pOverflow);
317        i = add(i, w, pOverflow);
318
319        i =
320            add(
321                i,
322                i,
323                pOverflow);
324
325        k =
326            sub(
327                index,
328                3,
329                pOverflow);
330
331        *T0_frac =
332            sub(
333                k,
334                i,
335                pOverflow);
336    }
337}
338