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 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
74 extern "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
163 int 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
D_plsf_5(D_plsfState * st,Word16 bfi,Word16 * indice,Word16 * lsp1_q,Word16 * lsp2_q,Flag * pOverflow)301 void 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 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