Git init
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / dec / src / d_plsf_5.cpp
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 /****************************************************************************************
19 Portions 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)
26 Permission to distribute, modify and use this file under the standard license
27 terms listed above has been obtained from the copyright holder.
28 ****************************************************************************************/
29 /*
30 ------------------------------------------------------------------------------
31
32
33
34  Filename: d_plsf_5.cpp
35
36 ------------------------------------------------------------------------------
37 */
38
39 /*----------------------------------------------------------------------------
40 ; INCLUDES
41 ----------------------------------------------------------------------------*/
42 #include "d_plsf.h"
43 #include "typedef.h"
44 #include "basic_op.h"
45 #include "lsp_lsf.h"
46 #include "reorder.h"
47 #include "cnst.h"
48 #include "oscl_mem.h"
49
50 /*--------------------------------------------------------------------------*/
51 #ifdef __cplusplus
52 extern "C"
53 {
54 #endif
55
56     /*----------------------------------------------------------------------------
57     ; MACROS
58     ; Define module specific macros here
59     ----------------------------------------------------------------------------*/
60
61
62     /*----------------------------------------------------------------------------
63     ; DEFINES
64     ; Include all pre-processor statements here. Include conditional
65     ; compile variables also.
66     ----------------------------------------------------------------------------*/
67     /* ALPHA    ->  0.95       */
68     /* ONE_ALPHA-> (1.0-ALPHA) */
69 #define ALPHA     31128
70 #define ONE_ALPHA 1639
71
72     /*----------------------------------------------------------------------------
73     ; LOCAL FUNCTION DEFINITIONS
74     ; Function Prototype declaration
75     ----------------------------------------------------------------------------*/
76
77     /*----------------------------------------------------------------------------
78     ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
79     ; Variable declaration - defined here and used outside this module
80     ----------------------------------------------------------------------------*/
81
82     /*--------------------------------------------------------------------------*/
83 #ifdef __cplusplus
84 }
85 #endif
86
87 /*
88 ------------------------------------------------------------------------------
89  FUNCTION NAME: D_plsf_5
90 ------------------------------------------------------------------------------
91  INPUT AND OUTPUT DEFINITIONS
92
93  Inputs:
94     st = pointer to a structure of type D_plsfState
95     bfi = bad frame indicator; set to 1 if a bad frame is received (Word16)
96     indice = pointer to quantization indices of 5 submatrices (Word16)
97     lsp1_q = pointer to the quantized 1st LSP vector (Word16)
98     lsp2_q = pointer to the quantized 2nd LSP vector (Word16)
99
100  Outputs:
101     lsp1_q points to the updated quantized 1st LSP vector
102     lsp2_q points to the updated quantized 2nd LSP vector
103     Flag  *pOverflow  -- Flag set when overflow occurs.
104
105  Returns:
106     return_value = 0 (int)
107
108  Global Variables Used:
109     None.
110
111  Local Variables Needed:
112     None.
113
114 ------------------------------------------------------------------------------
115  FUNCTION DESCRIPTION
116
117  This function decodes the 2 sets of LSP parameters in a frame using the
118  received quantization indices.
119
120 ------------------------------------------------------------------------------
121  REQUIREMENTS
122
123  None.
124
125 ------------------------------------------------------------------------------
126  REFERENCES
127
128  d_plsf_5.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
129
130 ------------------------------------------------------------------------------
131  PSEUDO-CODE
132
133 int D_plsf_5 (
134     D_plsfState *st,    // i/o: State variables
135     Word16 bfi,         // i  : bad frame indicator (set to 1 if a bad
136                                 frame is received)
137     Word16 *indice,     // i  : quantization indices of 5 submatrices, Q0
138     Word16 *lsp1_q,     // o  : quantized 1st LSP vector (M),          Q15
139     Word16 *lsp2_q      // o  : quantized 2nd LSP vector (M),          Q15
140 )
141 {
142     Word16 i;
143     const Word16 *p_dico;
144     Word16 temp, sign;
145     Word16 lsf1_r[M], lsf2_r[M];
146     Word16 lsf1_q[M], lsf2_q[M];
147
148     if (bfi != 0)                               // if bad frame
149     {
150         // use the past LSFs slightly shifted towards their mean
151
152         for (i = 0; i < M; i++)
153         {
154             // lsfi_q[i] = ALPHA*st->past_lsf_q[i] + ONE_ALPHA*mean_lsf[i];
155
156             lsf1_q[i] = add (mult (st->past_lsf_q[i], ALPHA),
157                              mult (mean_lsf[i], ONE_ALPHA));
158
159             lsf2_q[i] = lsf1_q[i];
160         }
161
162         // estimate past quantized residual to be used in next frame
163
164         for (i = 0; i < M; i++)
165         {
166             // temp  = mean_lsf[i] +  st->past_r_q[i] * LSP_PRED_FAC_MR122;
167
168             temp = add (mean_lsf[i], mult (st->past_r_q[i],
169                                            LSP_PRED_FAC_MR122));
170
171             st->past_r_q[i] = sub (lsf2_q[i], temp);
172         }
173     }
174     else
175         // if good LSFs received
176     {
177         // decode prediction residuals from 5 received indices
178
179         p_dico = &dico1_lsf[shl (indice[0], 2)];
180         lsf1_r[0] = *p_dico++;
181         lsf1_r[1] = *p_dico++;
182         lsf2_r[0] = *p_dico++;
183         lsf2_r[1] = *p_dico++;
184
185         p_dico = &dico2_lsf[shl (indice[1], 2)];
186         lsf1_r[2] = *p_dico++;
187         lsf1_r[3] = *p_dico++;
188         lsf2_r[2] = *p_dico++;
189         lsf2_r[3] = *p_dico++;
190
191         sign = indice[2] & 1;
192         i = shr (indice[2], 1);
193         p_dico = &dico3_lsf[shl (i, 2)];
194
195         if (sign == 0)
196         {
197             lsf1_r[4] = *p_dico++;
198             lsf1_r[5] = *p_dico++;
199             lsf2_r[4] = *p_dico++;
200             lsf2_r[5] = *p_dico++;
201         }
202         else
203         {
204             lsf1_r[4] = negate (*p_dico++);
205             lsf1_r[5] = negate (*p_dico++);
206             lsf2_r[4] = negate (*p_dico++);
207             lsf2_r[5] = negate (*p_dico++);
208         }
209
210         p_dico = &dico4_lsf[shl (indice[3], 2)];
211         lsf1_r[6] = *p_dico++;
212         lsf1_r[7] = *p_dico++;
213         lsf2_r[6] = *p_dico++;
214         lsf2_r[7] = *p_dico++;
215
216         p_dico = &dico5_lsf[shl (indice[4], 2)];
217         lsf1_r[8] = *p_dico++;
218         lsf1_r[9] = *p_dico++;
219         lsf2_r[8] = *p_dico++;
220         lsf2_r[9] = *p_dico++;
221
222         // Compute quantized LSFs and update the past quantized residual
223         for (i = 0; i < M; i++)
224         {
225             temp = add (mean_lsf[i], mult (st->past_r_q[i],
226                                            LSP_PRED_FAC_MR122));
227             lsf1_q[i] = add (lsf1_r[i], temp);
228             lsf2_q[i] = add (lsf2_r[i], temp);
229             st->past_r_q[i] = lsf2_r[i];
230         }
231     }
232
233     // verification that LSFs have minimum distance of LSF_GAP Hz
234
235     Reorder_lsf (lsf1_q, LSF_GAP, M);
236     Reorder_lsf (lsf2_q, LSF_GAP, M);
237
238     Copy (lsf2_q, st->past_lsf_q, M);
239
240     //  convert LSFs to the cosine domain
241
242     Lsf_lsp (lsf1_q, lsp1_q, M);
243     Lsf_lsp (lsf2_q, lsp2_q, M);
244
245     return 0;
246 }
247
248 ------------------------------------------------------------------------------
249  CAUTION [optional]
250  [State any special notes, constraints or cautions for users of this function]
251
252 ------------------------------------------------------------------------------
253 */
254
255 void D_plsf_5(
256     D_plsfState *st,    /* i/o: State variables                             */
257     Word16 bfi,         /* i  : bad frame indicator (set to 1 if a bad
258                                 frame is received)                          */
259     Word16 *indice,     /* i  : quantization indices of 5 submatrices, Q0   */
260     CommonAmrTbls* common_amr_tbls, /* i : structure containing ptrs to read-only tables */
261     Word16 *lsp1_q,     /* o  : quantized 1st LSP vector (M),          Q15  */
262     Word16 *lsp2_q,     /* o  : quantized 2nd LSP vector (M),          Q15  */
263     Flag  *pOverflow    /* o : Flag set when overflow occurs                */
264 )
265 {
266     register Word16 i;
267     Word16 temp;
268     Word16 sign;
269
270     const Word16 *p_dico;
271
272     Word16 lsf1_r[M];
273     Word16 lsf2_r[M];
274     Word16 lsf1_q[M];
275     Word16 lsf2_q[M];
276
277     /* These tables are defined in q_plsf_5_tbl.c */
278     const Word16* mean_lsf_5_ptr = common_amr_tbls->mean_lsf_5_ptr;
279     const Word16* dico1_lsf_5_ptr = common_amr_tbls->dico1_lsf_5_ptr;
280     const Word16* dico2_lsf_5_ptr = common_amr_tbls->dico2_lsf_5_ptr;
281     const Word16* dico3_lsf_5_ptr = common_amr_tbls->dico3_lsf_5_ptr;
282     const Word16* dico4_lsf_5_ptr = common_amr_tbls->dico4_lsf_5_ptr;
283     const Word16* dico5_lsf_5_ptr = common_amr_tbls->dico5_lsf_5_ptr;
284
285     if (bfi != 0)                               /* if bad frame */
286     {
287         /* use the past LSFs slightly shifted towards their mean */
288
289         for (i = 0; i < M; i++)
290         {
291             /*
292              *  lsfi_q[i] = ALPHA*st->past_lsf_q[i] +
293              *  ONE_ALPHA*mean_lsf[i];
294              */
295
296             temp = (Word16)(((Word32)  st->past_lsf_q[i] * ALPHA) >> 15);
297
298             sign = (Word16)(((Word32)  * (mean_lsf_5_ptr + i) * ONE_ALPHA) >> 15);
299
300             *(lsf1_q + i) = add_16(sign, temp,  pOverflow);
301
302             *(lsf2_q + i) = *(lsf1_q + i);
303
304             /*
305              * estimate past quantized residual to be used in
306              * next frame
307              */
308
309             /*
310              * temp  = mean_lsf[i] +
311              * st->past_r_q[i] * LSP_PRED_FAC_MR122;
312              */
313
314             temp = (Word16)(((Word32)  st->past_r_q[i] * LSP_PRED_FAC_MR122) >> 15);
315
316             temp = add_16(*(mean_lsf_5_ptr + i), temp, pOverflow);
317
318             st->past_r_q[i] = sub(*(lsf2_q + i), temp, pOverflow);
319         }
320     }
321     else
322         /* if good LSFs received */
323     {
324         /* decode prediction residuals from 5 received indices */
325
326         temp =
327             shl(
328                 *(indice),
329                 2,
330                 pOverflow);
331
332         p_dico = &dico1_lsf_5_ptr[temp];
333
334         *(lsf1_r + 0) = *p_dico++;
335         *(lsf1_r + 1) = *p_dico++;
336         *(lsf2_r + 0) = *p_dico++;
337         *(lsf2_r + 1) = *p_dico++;
338
339         temp = shl(*(indice + 1), 2, pOverflow);
340
341         p_dico = &dico2_lsf_5_ptr[temp];
342
343         *(lsf1_r + 2) = *p_dico++;
344         *(lsf1_r + 3) = *p_dico++;
345         *(lsf2_r + 2) = *p_dico++;
346         *(lsf2_r + 3) = *p_dico++;
347
348         sign = *(indice + 2) & 1;
349
350         if (*(indice + 2) < 0)
351         {
352             i = ~(~(*(indice + 2)) >> 1);
353         }
354         else
355         {
356             i = *(indice + 2) >> 1;
357         }
358
359         temp = shl(i, 2, pOverflow);
360
361         p_dico = &dico3_lsf_5_ptr[temp];
362
363         if (sign == 0)
364         {
365             *(lsf1_r + 4) = *p_dico++;
366             *(lsf1_r + 5) = *p_dico++;
367             *(lsf2_r + 4) = *p_dico++;
368             *(lsf2_r + 5) = *p_dico++;
369         }
370         else
371         {
372             *(lsf1_r + 4) = negate(*p_dico++);
373             *(lsf1_r + 5) = negate(*p_dico++);
374             *(lsf2_r + 4) = negate(*p_dico++);
375             *(lsf2_r + 5) = negate(*p_dico++);
376         }
377
378         temp = shl(*(indice + 3), 2, pOverflow);
379
380         p_dico = &dico4_lsf_5_ptr[temp];
381
382         *(lsf1_r + 6) = *p_dico++;
383         *(lsf1_r + 7) = *p_dico++;
384         *(lsf2_r + 6) = *p_dico++;
385         *(lsf2_r + 7) = *p_dico++;
386
387         temp = shl(*(indice + 4), 2, pOverflow);
388
389         p_dico = &dico5_lsf_5_ptr[temp];
390
391         *(lsf1_r + 8) = *p_dico++;
392         *(lsf1_r + 9) = *p_dico++;
393         *(lsf2_r + 8) = *p_dico++;
394         *(lsf2_r + 9) = *p_dico++;
395
396         /* Compute quantized LSFs and update the past quantized
397         residual */
398         for (i = 0; i < M; i++)
399         {
400             temp =
401                 mult(
402                     st->past_r_q[i],
403                     LSP_PRED_FAC_MR122,
404                     pOverflow);
405
406             temp =
407                 add_16(
408                     *(mean_lsf_5_ptr + i),
409                     temp,
410                     pOverflow);
411
412             *(lsf1_q + i) =
413                 add_16(
414                     *(lsf1_r + i),
415                     temp,
416                     pOverflow);
417
418             *(lsf2_q + i) =
419                 add_16(
420                     *(lsf2_r + i),
421                     temp,
422                     pOverflow);
423
424             st->past_r_q[i] = *(lsf2_r + i);
425         }
426     }
427
428     /* verification that LSFs have minimum distance of LSF_GAP Hz */
429
430     Reorder_lsf(
431         lsf1_q,
432         LSF_GAP,
433         M,
434         pOverflow);
435
436     Reorder_lsf(
437         lsf2_q,
438         LSF_GAP,
439         M,
440         pOverflow);
441
442     oscl_memmove((void *)st->past_lsf_q, lsf2_q, M*sizeof(*lsf2_q));
443
444     /*  convert LSFs to the cosine domain */
445
446     Lsf_lsp(
447         lsf1_q,
448         lsp1_q,
449         M,
450         pOverflow);
451
452     Lsf_lsp(
453         lsf2_q,
454         lsp2_q,
455         M,
456         pOverflow);
457
458     return;
459 }