d_plsf_5.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------------------------------------------------------------------------------
31
32
33
34 Pathname: ./audio/gsm-amr/c/src/d_plsf_5.c
35
36     Date: 04/24/2000
37
38------------------------------------------------------------------------------
39 REVISION HISTORY
40
41 Description: Made changes based on review meeting.
42
43 Description: Synchronized file with UMTS version 3.2.0. Updated coding
44              template. Removed unnecessary include files.
45
46 Description: Updated to accept new parameter, Flag *pOverflow.
47
48 Description:
49 (1) Removed "count.h" and "basic_op.h" and replaced with individual include
50     files (add.h, sub.h, etc.)
51
52 Description:  Replaced "int" and/or "char" with OSCL defined types.
53
54 Description: Added #ifdef __cplusplus around extern'ed table.
55
56 Description:
57
58------------------------------------------------------------------------------
59*/
60
61/*----------------------------------------------------------------------------
62; INCLUDES
63----------------------------------------------------------------------------*/
64#include "d_plsf.h"
65#include "typedef.h"
66#include "basic_op.h"
67#include "lsp_lsf.h"
68#include "reorder.h"
69#include "cnst.h"
70#include "copy.h"
71
72/*--------------------------------------------------------------------------*/
73#ifdef __cplusplus
74extern "C"
75{
76#endif
77
78    /*----------------------------------------------------------------------------
79    ; MACROS
80    ; Define module specific macros here
81    ----------------------------------------------------------------------------*/
82
83
84    /*----------------------------------------------------------------------------
85    ; DEFINES
86    ; Include all pre-processor statements here. Include conditional
87    ; compile variables also.
88    ----------------------------------------------------------------------------*/
89    /* ALPHA    ->  0.95       */
90    /* ONE_ALPHA-> (1.0-ALPHA) */
91#define ALPHA     31128
92#define ONE_ALPHA 1639
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
104    /* These tables are defined in q_plsf_5_tbl.c */
105    extern const Word16 mean_lsf_5[];
106    extern const Word16 dico1_lsf_5[];
107    extern const Word16 dico2_lsf_5[];
108    extern const Word16 dico3_lsf_5[];
109    extern const Word16 dico4_lsf_5[];
110    extern const Word16 dico5_lsf_5[];
111
112    /*--------------------------------------------------------------------------*/
113#ifdef __cplusplus
114}
115#endif
116
117/*
118------------------------------------------------------------------------------
119 FUNCTION NAME: D_plsf_5
120------------------------------------------------------------------------------
121 INPUT AND OUTPUT DEFINITIONS
122
123 Inputs:
124    st = pointer to a structure of type D_plsfState
125    bfi = bad frame indicator; set to 1 if a bad frame is received (Word16)
126    indice = pointer to quantization indices of 5 submatrices (Word16)
127    lsp1_q = pointer to the quantized 1st LSP vector (Word16)
128    lsp2_q = pointer to the quantized 2nd LSP vector (Word16)
129
130 Outputs:
131    lsp1_q points to the updated quantized 1st LSP vector
132    lsp2_q points to the updated quantized 2nd LSP vector
133    Flag  *pOverflow  -- Flag set when overflow occurs.
134
135 Returns:
136    return_value = 0 (int)
137
138 Global Variables Used:
139    None.
140
141 Local Variables Needed:
142    None.
143
144------------------------------------------------------------------------------
145 FUNCTION DESCRIPTION
146
147 This function decodes the 2 sets of LSP parameters in a frame using the
148 received quantization indices.
149
150------------------------------------------------------------------------------
151 REQUIREMENTS
152
153 None.
154
155------------------------------------------------------------------------------
156 REFERENCES
157
158 d_plsf_5.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
159
160------------------------------------------------------------------------------
161 PSEUDO-CODE
162
163int D_plsf_5 (
164    D_plsfState *st,    // i/o: State variables
165    Word16 bfi,         // i  : bad frame indicator (set to 1 if a bad
166                                frame is received)
167    Word16 *indice,     // i  : quantization indices of 5 submatrices, Q0
168    Word16 *lsp1_q,     // o  : quantized 1st LSP vector (M),          Q15
169    Word16 *lsp2_q      // o  : quantized 2nd LSP vector (M),          Q15
170)
171{
172    Word16 i;
173    const Word16 *p_dico;
174    Word16 temp, sign;
175    Word16 lsf1_r[M], lsf2_r[M];
176    Word16 lsf1_q[M], lsf2_q[M];
177
178    if (bfi != 0)                               // if bad frame
179    {
180        // use the past LSFs slightly shifted towards their mean
181
182        for (i = 0; i < M; i++)
183        {
184            // lsfi_q[i] = ALPHA*st->past_lsf_q[i] + ONE_ALPHA*mean_lsf[i];
185
186            lsf1_q[i] = add (mult (st->past_lsf_q[i], ALPHA),
187                             mult (mean_lsf[i], ONE_ALPHA));
188
189            lsf2_q[i] = lsf1_q[i];
190        }
191
192        // estimate past quantized residual to be used in next frame
193
194        for (i = 0; i < M; i++)
195        {
196            // temp  = mean_lsf[i] +  st->past_r_q[i] * LSP_PRED_FAC_MR122;
197
198            temp = add (mean_lsf[i], mult (st->past_r_q[i],
199                                           LSP_PRED_FAC_MR122));
200
201            st->past_r_q[i] = sub (lsf2_q[i], temp);
202        }
203    }
204    else
205        // if good LSFs received
206    {
207        // decode prediction residuals from 5 received indices
208
209        p_dico = &dico1_lsf[shl (indice[0], 2)];
210        lsf1_r[0] = *p_dico++;
211        lsf1_r[1] = *p_dico++;
212        lsf2_r[0] = *p_dico++;
213        lsf2_r[1] = *p_dico++;
214
215        p_dico = &dico2_lsf[shl (indice[1], 2)];
216        lsf1_r[2] = *p_dico++;
217        lsf1_r[3] = *p_dico++;
218        lsf2_r[2] = *p_dico++;
219        lsf2_r[3] = *p_dico++;
220
221        sign = indice[2] & 1;
222        i = shr (indice[2], 1);
223        p_dico = &dico3_lsf[shl (i, 2)];
224
225        if (sign == 0)
226        {
227            lsf1_r[4] = *p_dico++;
228            lsf1_r[5] = *p_dico++;
229            lsf2_r[4] = *p_dico++;
230            lsf2_r[5] = *p_dico++;
231        }
232        else
233        {
234            lsf1_r[4] = negate (*p_dico++);
235            lsf1_r[5] = negate (*p_dico++);
236            lsf2_r[4] = negate (*p_dico++);
237            lsf2_r[5] = negate (*p_dico++);
238        }
239
240        p_dico = &dico4_lsf[shl (indice[3], 2)];
241        lsf1_r[6] = *p_dico++;
242        lsf1_r[7] = *p_dico++;
243        lsf2_r[6] = *p_dico++;
244        lsf2_r[7] = *p_dico++;
245
246        p_dico = &dico5_lsf[shl (indice[4], 2)];
247        lsf1_r[8] = *p_dico++;
248        lsf1_r[9] = *p_dico++;
249        lsf2_r[8] = *p_dico++;
250        lsf2_r[9] = *p_dico++;
251
252        // Compute quantized LSFs and update the past quantized residual
253        for (i = 0; i < M; i++)
254        {
255            temp = add (mean_lsf[i], mult (st->past_r_q[i],
256                                           LSP_PRED_FAC_MR122));
257            lsf1_q[i] = add (lsf1_r[i], temp);
258            lsf2_q[i] = add (lsf2_r[i], temp);
259            st->past_r_q[i] = lsf2_r[i];
260        }
261    }
262
263    // verification that LSFs have minimum distance of LSF_GAP Hz
264
265    Reorder_lsf (lsf1_q, LSF_GAP, M);
266    Reorder_lsf (lsf2_q, LSF_GAP, M);
267
268    Copy (lsf2_q, st->past_lsf_q, M);
269
270    //  convert LSFs to the cosine domain
271
272    Lsf_lsp (lsf1_q, lsp1_q, M);
273    Lsf_lsp (lsf2_q, lsp2_q, M);
274
275    return 0;
276}
277
278------------------------------------------------------------------------------
279 RESOURCES USED [optional]
280
281 When the code is written for a specific target processor the
282 the resources used should be documented below.
283
284 HEAP MEMORY USED: x bytes
285
286 STACK MEMORY USED: x bytes
287
288 CLOCK CYCLES: (cycle count equation for this function) + (variable
289                used to represent cycle count for each subroutine
290                called)
291     where: (cycle count variable) = cycle count for [subroutine
292                                     name]
293
294------------------------------------------------------------------------------
295 CAUTION [optional]
296 [State any special notes, constraints or cautions for users of this function]
297
298------------------------------------------------------------------------------
299*/
300
301void D_plsf_5(
302    D_plsfState *st,    /* i/o: State variables                             */
303    Word16 bfi,         /* i  : bad frame indicator (set to 1 if a bad
304                                frame is received)                          */
305    Word16 *indice,     /* i  : quantization indices of 5 submatrices, Q0   */
306    Word16 *lsp1_q,     /* o  : quantized 1st LSP vector (M),          Q15  */
307    Word16 *lsp2_q,     /* o  : quantized 2nd LSP vector (M),          Q15  */
308    Flag  *pOverflow    /* o : Flag set when overflow occurs                */
309)
310{
311    register Word16 i;
312    Word16 temp;
313    Word16 sign;
314
315    const Word16 *p_dico;
316
317    Word16 lsf1_r[M];
318    Word16 lsf2_r[M];
319    Word16 lsf1_q[M];
320    Word16 lsf2_q[M];
321
322    if (bfi != 0)                               /* if bad frame */
323    {
324        /* use the past LSFs slightly shifted towards their mean */
325
326        for (i = 0; i < M; i++)
327        {
328            /*
329             *  lsfi_q[i] = ALPHA*st->past_lsf_q[i] +
330             *  ONE_ALPHA*mean_lsf[i];
331             */
332
333            temp =
334                mult(
335                    st->past_lsf_q[i],
336                    ALPHA,
337                    pOverflow);
338
339            sign =
340                mult(
341                    *(mean_lsf_5 + i),
342                    ONE_ALPHA,
343                    pOverflow);
344
345            *(lsf1_q + i) =
346                add(
347                    sign,
348                    temp,
349                    pOverflow);
350
351            *(lsf2_q + i) = *(lsf1_q + i);
352
353            /*
354             * estimate past quantized residual to be used in
355             * next frame
356             */
357
358            /*
359             * temp  = mean_lsf[i] +
360             * st->past_r_q[i] * LSP_PRED_FAC_MR122;
361             */
362
363            temp =
364                mult(
365                    st->past_r_q[i],
366                    LSP_PRED_FAC_MR122,
367                    pOverflow);
368
369            temp =
370                add(
371                    *(mean_lsf_5 + i),
372                    temp,
373                    pOverflow);
374
375            st->past_r_q[i] =
376                sub(
377                    *(lsf2_q + i),
378                    temp,
379                    pOverflow);
380        }
381    }
382    else
383        /* if good LSFs received */
384    {
385        /* decode prediction residuals from 5 received indices */
386
387        temp =
388            shl(
389                *(indice),
390                2,
391                pOverflow);
392
393        p_dico = &dico1_lsf_5[temp];
394
395        *(lsf1_r + 0) = *p_dico++;
396        *(lsf1_r + 1) = *p_dico++;
397        *(lsf2_r + 0) = *p_dico++;
398        *(lsf2_r + 1) = *p_dico++;
399
400        temp =
401            shl(
402                *(indice + 1),
403                2,
404                pOverflow);
405
406        p_dico = &dico2_lsf_5[temp];
407
408        *(lsf1_r + 2) = *p_dico++;
409        *(lsf1_r + 3) = *p_dico++;
410        *(lsf2_r + 2) = *p_dico++;
411        *(lsf2_r + 3) = *p_dico++;
412
413        sign = *(indice + 2) & 1;
414
415        if (*(indice + 2) < 0)
416        {
417            i = ~(~(*(indice + 2)) >> 1);
418        }
419        else
420        {
421            i = *(indice + 2) >> 1;
422        }
423
424        temp =
425            shl(
426                i,
427                2,
428                pOverflow);
429
430        p_dico = &dico3_lsf_5[temp];
431
432        if (sign == 0)
433        {
434            *(lsf1_r + 4) = *p_dico++;
435            *(lsf1_r + 5) = *p_dico++;
436            *(lsf2_r + 4) = *p_dico++;
437            *(lsf2_r + 5) = *p_dico++;
438        }
439        else
440        {
441            *(lsf1_r + 4) = negate(*p_dico++);
442            *(lsf1_r + 5) = negate(*p_dico++);
443            *(lsf2_r + 4) = negate(*p_dico++);
444            *(lsf2_r + 5) = negate(*p_dico++);
445        }
446
447        temp =
448            shl(
449                *(indice + 3),
450                2,
451                pOverflow);
452
453        p_dico = &dico4_lsf_5[temp];
454
455        *(lsf1_r + 6) = *p_dico++;
456        *(lsf1_r + 7) = *p_dico++;
457        *(lsf2_r + 6) = *p_dico++;
458        *(lsf2_r + 7) = *p_dico++;
459
460        temp =
461            shl(
462                *(indice + 4),
463                2,
464                pOverflow);
465
466        p_dico = &dico5_lsf_5[temp];
467
468        *(lsf1_r + 8) = *p_dico++;
469        *(lsf1_r + 9) = *p_dico++;
470        *(lsf2_r + 8) = *p_dico++;
471        *(lsf2_r + 9) = *p_dico++;
472
473        /* Compute quantized LSFs and update the past quantized
474        residual */
475        for (i = 0; i < M; i++)
476        {
477            temp =
478                mult(
479                    st->past_r_q[i],
480                    LSP_PRED_FAC_MR122,
481                    pOverflow);
482
483            temp =
484                add(
485                    *(mean_lsf_5 + i),
486                    temp,
487                    pOverflow);
488
489            *(lsf1_q + i) =
490                add(
491                    *(lsf1_r + i),
492                    temp,
493                    pOverflow);
494
495            *(lsf2_q + i) =
496                add(
497                    *(lsf2_r + i),
498                    temp,
499                    pOverflow);
500
501            st->past_r_q[i] = *(lsf2_r + i);
502        }
503    }
504
505    /* verification that LSFs have minimum distance of LSF_GAP Hz */
506
507    Reorder_lsf(
508        lsf1_q,
509        LSF_GAP,
510        M,
511        pOverflow);
512
513    Reorder_lsf(
514        lsf2_q,
515        LSF_GAP,
516        M,
517        pOverflow);
518
519    Copy(
520        lsf2_q,
521        st->past_lsf_q,
522        M);
523
524    /*  convert LSFs to the cosine domain */
525
526    Lsf_lsp(
527        lsf1_q,
528        lsp1_q,
529        M,
530        pOverflow);
531
532    Lsf_lsp(
533        lsf2_q,
534        lsp2_q,
535        M,
536        pOverflow);
537
538    return;
539}
540