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 Pathname: ./audio/gsm-amr/c/src/q_plsf_3.c
32 Funtions: Vq_subvec4
33 Test_Vq_subvec4
34 Vq_subvec3
35 Test_Vq_subvec3
36 Q_plsf_3
37
38 ------------------------------------------------------------------------------
39 REVISION HISTORY
40
41 Description: Updated template used to PV coding template. First attempt at
42 optimizing C code.
43
44 Description: Updated modules per Phase 2/3 review comments. Updated
45 Vq_subvec3 pseudo-code to reflect the new restructured code.
46
47 Description: Added setting of Overflow flag in inlined code.
48
49 Description: Synchronized file with UMTS version 3.2.0. Updated coding
50 template. Removed unnecessary include files.
51
52 Description: Replaced basic_op.h with the header file of the math functions
53 used in the file.
54
55 Description: Made the following changes per comments from Phase 2/3 review:
56 1. Fixed typecasting issue with TI C compiler.
57 2. Optimized IF stament in Vq_subvec3() function.
58 3. Updated copyright year.
59
60 Description: Removed redundancy in the Vq_subvec4 function.
61
62 Description: Updated to accept new parameter, Flag *pOverflow.
63
64 Description: Per review comments, added pOverflow flag description
65 to the input/outputs section.
66
67 Description: Corrected missed Overflow global variables -- changed to
68 proper pOverflow.
69
70 Description: Optimized all functions to further reduce clock cycle usage.
71 Updated copyright year.
72
73 Description: Added left shift by 1 in line 1050 of Q_plsf_3().
74
75 Description: Replaced OSCL mem type functions and eliminated include
76 files that now are chosen by OSCL definitions
77
78 Description: Replaced "int" and/or "char" with OSCL defined types.
79
80 Description: Added #ifdef __cplusplus around extern'ed table.
81
82 Who: Date:
83 Description:
84
85 ------------------------------------------------------------------------------
86 MODULE DESCRIPTION
87
88 This file contains the functions that perform the quantization of LSF
89 parameters with first order MA prediction and split by 3 vector
90 quantization (split-VQ).
91
92 ------------------------------------------------------------------------------
93 */
94
95 /*----------------------------------------------------------------------------
96 ; INCLUDES
97 ----------------------------------------------------------------------------*/
98
99 #include <string.h>
100
101 #include "q_plsf.h"
102 #include "typedef.h"
103 #include "lsp_lsf.h"
104 #include "reorder.h"
105 #include "lsfwt.h"
106
107 /*--------------------------------------------------------------------------*/
108 #ifdef __cplusplus
109 extern "C"
110 {
111 #endif
112
113 /*----------------------------------------------------------------------------
114 ; MACROS
115 ; Define module specific macros here
116 ----------------------------------------------------------------------------*/
117
118 /*----------------------------------------------------------------------------
119 ; DEFINES
120 ; Include all pre-processor statements here. Include conditional
121 ; compile variables also.
122 ----------------------------------------------------------------------------*/
123 #define PAST_RQ_INIT_SIZE 8
124
125 /*----------------------------------------------------------------------------
126 ; LOCAL FUNCTION DEFINITIONS
127 ; Function Prototype declaration
128 ----------------------------------------------------------------------------*/
129
130 /*----------------------------------------------------------------------------
131 ; LOCAL VARIABLE DEFINITIONS
132 ; Variable declaration - defined here and used outside this module
133 ----------------------------------------------------------------------------*/
134
135 /*----------------------------------------------------------------------------
136 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
137 ; Declare variables used in this module but defined elsewhere
138 ----------------------------------------------------------------------------*/
139 /* Codebooks of LSF prediction residual */
140 extern const Word16 mean_lsf_3[];
141
142 extern const Word16 pred_fac_3[];
143
144 extern const Word16 dico1_lsf_3[];
145 extern const Word16 dico2_lsf_3[];
146 extern const Word16 dico3_lsf_3[];
147
148 extern const Word16 mr515_3_lsf[];
149 extern const Word16 mr795_1_lsf[];
150
151 extern const Word16 past_rq_init[];
152
153 /*--------------------------------------------------------------------------*/
154 #ifdef __cplusplus
155 }
156 #endif
157
158 /*
159 ------------------------------------------------------------------------------
160 FUNCTION NAME: Vq_subvec4
161 ------------------------------------------------------------------------------
162 INPUT AND OUTPUT DEFINITIONS
163
164 Inputs:
165 lsf_r1 = pointer to the first LSF residual vector (Q15) (Word16)
166 dico = pointer to the quantization codebook (Q15) (const Word16)
167 wf1 = pointer to the first LSF weighting factor (Q13) (Word16)
168 dico_size = size of quantization codebook (Q0) (Word16)
169
170 Outputs:
171 buffer pointed to by lsf_r1 contains the selected vector
172 pOverflow -- pointer to Flag -- Flag set when overflow occurs
173
174 Returns:
175 index = quantization index (Q0) (Word16)
176
177 Global Variables Used:
178 None
179
180 Local Variables Needed:
181 None
182
183 ------------------------------------------------------------------------------
184 FUNCTION DESCRIPTION
185
186 This function performs the quantization of a 4-dimensional subvector.
187
188 ------------------------------------------------------------------------------
189 REQUIREMENTS
190
191 None
192
193 ------------------------------------------------------------------------------
194 REFERENCES
195
196 q_plsf_3.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
197
198 ------------------------------------------------------------------------------
199 PSEUDO-CODE
200
201 static Word16
202 Vq_subvec4( // o: quantization index, Q0
203 Word16 * lsf_r1, // i: 1st LSF residual vector, Q15
204 Word16 * dico, // i: quantization codebook, Q15
205 Word16 * wf1, // i: 1st LSF weighting factors, Q13
206 Word16 dico_size) // i: size of quantization codebook, Q0
207 {
208 Word16 i, index = 0;
209 Word16 *p_dico, temp;
210 Word32 dist_min, dist;
211
212 dist_min = MAX_32;
213 p_dico = dico;
214
215 for (i = 0; i < dico_size; i++)
216 {
217 temp = sub (lsf_r1[0], *p_dico++);
218 temp = mult (wf1[0], temp);
219 dist = L_mult (temp, temp);
220
221 temp = sub (lsf_r1[1], *p_dico++);
222 temp = mult (wf1[1], temp);
223 dist = L_mac (dist, temp, temp);
224
225 temp = sub (lsf_r1[2], *p_dico++);
226 temp = mult (wf1[2], temp);
227 dist = L_mac (dist, temp, temp);
228
229 temp = sub (lsf_r1[3], *p_dico++);
230 temp = mult (wf1[3], temp);
231 dist = L_mac (dist, temp, temp);
232
233
234 if (L_sub (dist, dist_min) < (Word32) 0)
235 {
236 dist_min = dist;
237 index = i;
238 }
239 }
240
241 // Reading the selected vector
242
243 p_dico = &dico[shl (index, 2)];
244 lsf_r1[0] = *p_dico++;
245 lsf_r1[1] = *p_dico++;
246 lsf_r1[2] = *p_dico++;
247 lsf_r1[3] = *p_dico;
248
249 return index;
250
251 }
252
253 ------------------------------------------------------------------------------
254 RESOURCES USED [optional]
255
256 When the code is written for a specific target processor the
257 the resources used should be documented below.
258
259 HEAP MEMORY USED: x bytes
260
261 STACK MEMORY USED: x bytes
262
263 CLOCK CYCLES: (cycle count equation for this function) + (variable
264 used to represent cycle count for each subroutine
265 called)
266 where: (cycle count variable) = cycle count for [subroutine
267 name]
268
269 ------------------------------------------------------------------------------
270 CAUTION [optional]
271 [State any special notes, constraints or cautions for users of this function]
272
273 ------------------------------------------------------------------------------
274 */
275
Vq_subvec4(Word16 * lsf_r1,const Word16 * dico,Word16 * wf1,Word16 dico_size,Flag * pOverflow)276 static Word16 Vq_subvec4( /* o: quantization index, Q0 */
277 Word16 * lsf_r1, /* i: 1st LSF residual vector, Q15 */
278 const Word16 * dico, /* i: quantization codebook, Q15 */
279 Word16 * wf1, /* i: 1st LSF weighting factors, Q13 */
280 Word16 dico_size, /* i: size of quantization codebook, Q0 */
281 Flag *pOverflow /* o : Flag set when overflow occurs */
282 )
283 {
284 register Word16 i;
285 Word16 temp;
286 const Word16 *p_dico;
287 Word16 index = 0;
288 Word32 dist_min;
289 Word32 dist;
290
291 Word16 lsf_r1_0;
292 Word16 lsf_r1_1;
293 Word16 lsf_r1_2;
294 Word16 lsf_r1_3;
295
296 Word16 wf1_0;
297 Word16 wf1_1;
298 Word16 wf1_2;
299 Word16 wf1_3;
300
301 OSCL_UNUSED_ARG(pOverflow);
302
303 dist_min = MAX_32;
304 p_dico = dico;
305
306 lsf_r1_0 = lsf_r1[0];
307 lsf_r1_1 = lsf_r1[1];
308 lsf_r1_2 = lsf_r1[2];
309 lsf_r1_3 = lsf_r1[3];
310
311 wf1_0 = wf1[0];
312 wf1_1 = wf1[1];
313 wf1_2 = wf1[2];
314 wf1_3 = wf1[3];
315
316 for (i = 0; i < dico_size; i++)
317 {
318 temp = lsf_r1_0 - (*p_dico++);
319 temp = (Word16)((((Word32) wf1_0) * temp) >> 15);
320 dist = ((Word32) temp) * temp;
321
322 temp = lsf_r1_1 - (*p_dico++);
323 temp = (Word16)((((Word32) wf1_1) * temp) >> 15);
324 dist += ((Word32) temp) * temp;
325
326 temp = lsf_r1_2 - (*p_dico++);
327 temp = (Word16)((((Word32) wf1_2) * temp) >> 15);
328 dist += ((Word32) temp) * temp;
329
330 temp = lsf_r1_3 - (*p_dico++);
331 temp = (Word16)((((Word32) wf1_3) * temp) >> 15);
332 dist += ((Word32) temp) * temp;
333
334 if (dist < dist_min)
335 {
336 dist_min = dist;
337 index = i;
338 }
339 }
340
341 /* Reading the selected vector */
342
343 p_dico = dico + (index << 2);
344 *lsf_r1++ = *p_dico++;
345 *lsf_r1++ = *p_dico++;
346 *lsf_r1++ = *p_dico++;
347 *lsf_r1 = *p_dico;
348
349 return(index);
350
351 }
352
353 /****************************************************************************/
354
355
356 /*
357 ------------------------------------------------------------------------------
358 FUNCTION NAME: Test_Vq_subvec4
359 ------------------------------------------------------------------------------
360 INPUT AND OUTPUT DEFINITIONS
361
362 Inputs:
363 lsf_r1 = pointer to the first LSF residual vector (Q15) (Word16)
364 dico = pointer to the quantization codebook (Q15) (const Word16)
365 wf1 = pointer to the first LSF weighting factor (Q13) (Word16)
366 dico_size = size of quantization codebook (Q0) (Word16)
367
368 Outputs:
369 buffer pointed to by lsf_r1 contains the selected vector
370 pOverflow -- pointer to Flag -- Flag set when overflow occurs
371
372 Returns:
373 index = quantization index (Q0) (Word16)
374
375 Global Variables Used:
376 None
377
378 Local Variables Needed:
379 None
380
381 ------------------------------------------------------------------------------
382 FUNCTION DESCRIPTION
383
384 This function calls the static function Vq_subvec4. It is used for testing
385 purposes only
386
387 ------------------------------------------------------------------------------
388 REQUIREMENTS
389
390 None
391
392 ------------------------------------------------------------------------------
393 REFERENCES
394
395 None
396
397 ------------------------------------------------------------------------------
398 PSEUDO-CODE
399
400
401 CALL Vq_subvec4(lsf_r1 = lsf_r1
402 dico = dico
403 wf1 = wf1
404 dico_size = dico_size)
405 MODIFYING(nothing)
406 RETURNING(index = tst_index4)
407
408 ------------------------------------------------------------------------------
409 RESOURCES USED [optional]
410
411 When the code is written for a specific target processor the
412 the resources used should be documented below.
413
414 HEAP MEMORY USED: x bytes
415
416 STACK MEMORY USED: x bytes
417
418 CLOCK CYCLES: (cycle count equation for this function) + (variable
419 used to represent cycle count for each subroutine
420 called)
421 where: (cycle count variable) = cycle count for [subroutine
422 name]
423
424 ------------------------------------------------------------------------------
425 CAUTION [optional]
426 [State any special notes, constraints or cautions for users of this function]
427
428 ------------------------------------------------------------------------------
429 */
430
Test_Vq_subvec4(Word16 * lsf_r1,const Word16 * dico,Word16 * wf1,Word16 dico_size,Flag * pOverflow)431 Word16 Test_Vq_subvec4(
432 Word16 * lsf_r1,
433 const Word16 * dico,
434 Word16 * wf1,
435 Word16 dico_size,
436 Flag *pOverflow)
437 {
438 Word16 tst_index4 = 0;
439
440 /*------------------------------------------------------------------------
441 CALL Vq_subvec4(lsf_r1 = lsf_r1
442 dico = dico
443 wf1 = wf1
444 dico_size = dico_size)
445 MODIFYING(nothing)
446 RETURNING(index = index)
447 ------------------------------------------------------------------------*/
448 tst_index4 =
449 Vq_subvec4(
450 lsf_r1,
451 dico,
452 wf1,
453 dico_size,
454 pOverflow);
455
456 return(tst_index4);
457
458 }
459
460 /****************************************************************************/
461
462 /*
463 ------------------------------------------------------------------------------
464 FUNCTION NAME: Vq_subvec3
465 ------------------------------------------------------------------------------
466 INPUT AND OUTPUT DEFINITIONS
467
468 Inputs:
469 lsf_r1 = pointer to the first LSF residual vector (Q15) (Word16)
470 dico = pointer to the quantization codebook (Q15) (const Word16)
471 wf1 = pointer to the first LSF weighting factor (Q13) (Word16)
472 dico_size = size of quantization codebook (Q0) (Word16)
473 use_half = flag to indicate use of every second entry in the
474 codebook (Flag)
475
476 Outputs:
477 buffer pointed to by lsf_r1 contains the selected vector
478 pOverflow -- pointer to Flag -- Flag set when overflow occurs
479
480 Returns:
481 index = quantization index (Q0) (Word16)
482
483 Global Variables Used:
484 None
485
486 Local Variables Needed:
487 None
488
489 ------------------------------------------------------------------------------
490 FUNCTION DESCRIPTION
491
492 This function performs the quantization of a 3 dimensional subvector.
493
494 ------------------------------------------------------------------------------
495 REQUIREMENTS
496
497 None
498
499 ------------------------------------------------------------------------------
500 REFERENCES
501
502 q_plsf_3.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
503
504 ------------------------------------------------------------------------------
505 PSEUDO-CODE
506
507 static Word16
508 Vq_subvec3( // o: quantization index, Q0
509 Word16 * lsf_r1, // i: 1st LSF residual vector, Q15
510 Word16 * dico, // i: quantization codebook, Q15
511 Word16 * wf1, // i: 1st LSF weighting factors, Q13
512 Word16 dico_size, // i: size of quantization codebook, Q0
513 Flag use_half) // i: use every second entry in codebook
514 {
515 Word16 i, index = 0;
516 Word16 *p_dico, temp;
517 Word32 dist_min, dist;
518
519 dist_min = MAX_32;
520 p_dico = dico;
521
522 if (use_half == 0) {
523 for (i = 0; i < dico_size; i++)
524 {
525 temp = sub(lsf_r1[0], *p_dico++);
526 temp = mult(wf1[0], temp);
527 dist = L_mult(temp, temp);
528
529 temp = sub(lsf_r1[1], *p_dico++);
530 temp = mult(wf1[1], temp);
531 dist = L_mac(dist, temp, temp);
532
533 temp = sub(lsf_r1[2], *p_dico++);
534 temp = mult(wf1[2], temp);
535 dist = L_mac(dist, temp, temp);
536
537 if (L_sub(dist, dist_min) < (Word32) 0) {
538 dist_min = dist;
539 index = i;
540 }
541 }
542 p_dico = &dico[add(index, add(index, index))];
543 }
544 else
545 {
546 for (i = 0; i < dico_size; i++)
547 {
548 temp = sub(lsf_r1[0], *p_dico++);
549 temp = mult(wf1[0], temp);
550 dist = L_mult(temp, temp);
551
552 temp = sub(lsf_r1[1], *p_dico++);
553 temp = mult(wf1[1], temp);
554 dist = L_mac(dist, temp, temp);
555
556 temp = sub(lsf_r1[2], *p_dico++);
557 temp = mult(wf1[2], temp);
558 dist = L_mac(dist, temp, temp);
559
560 if (L_sub(dist, dist_min) < (Word32) 0)
561 {
562 dist_min = dist;
563 index = i;
564 }
565 p_dico = p_dico + 3; add(0,0);
566 }
567 p_dico = &dico[shl(add(index, add(index, index)),1)];
568 }
569
570
571 // Reading the selected vector
572 lsf_r1[0] = *p_dico++;
573 lsf_r1[1] = *p_dico++;
574 lsf_r1[2] = *p_dico++;
575
576 return index;
577 }
578
579 ------------------------------------------------------------------------------
580 RESOURCES USED [optional]
581
582 When the code is written for a specific target processor the
583 the resources used should be documented below.
584
585 HEAP MEMORY USED: x bytes
586
587 STACK MEMORY USED: x bytes
588
589 CLOCK CYCLES: (cycle count equation for this function) + (variable
590 used to represent cycle count for each subroutine
591 called)
592 where: (cycle count variable) = cycle count for [subroutine
593 name]
594
595 ------------------------------------------------------------------------------
596 CAUTION [optional]
597 [State any special notes, constraints or cautions for users of this function]
598
599 ------------------------------------------------------------------------------
600 */
601
Vq_subvec3(Word16 * lsf_r1,const Word16 * dico,Word16 * wf1,Word16 dico_size,Flag use_half,Flag * pOverflow)602 static Word16 Vq_subvec3( /* o: quantization index, Q0 */
603 Word16 * lsf_r1, /* i: 1st LSF residual vector, Q15 */
604 const Word16 * dico, /* i: quantization codebook, Q15 */
605 Word16 * wf1, /* i: 1st LSF weighting factors, Q13 */
606 Word16 dico_size, /* i: size of quantization codebook, Q0 */
607 Flag use_half, /* i: use every second entry in codebook */
608 Flag *pOverflow) /* o : Flag set when overflow occurs */
609 {
610 register Word16 i;
611 Word16 temp;
612
613 const Word16 *p_dico;
614
615 Word16 p_dico_index = 0;
616 Word16 index = 0;
617
618 Word32 dist_min;
619 Word32 dist;
620
621 Word16 lsf_r1_0;
622 Word16 lsf_r1_1;
623 Word16 lsf_r1_2;
624
625 Word16 wf1_0;
626 Word16 wf1_1;
627 Word16 wf1_2;
628
629 OSCL_UNUSED_ARG(pOverflow);
630
631 dist_min = MAX_32;
632 p_dico = dico;
633
634 lsf_r1_0 = lsf_r1[0];
635 lsf_r1_1 = lsf_r1[1];
636 lsf_r1_2 = lsf_r1[2];
637
638 wf1_0 = wf1[0];
639 wf1_1 = wf1[1];
640 wf1_2 = wf1[2];
641
642 if (use_half != 0)
643 {
644 p_dico_index = 3;
645 }
646
647 for (i = 0; i < dico_size; i++)
648 {
649 temp = lsf_r1_0 - (*p_dico++);
650 temp = (Word16)((((Word32) wf1_0) * temp) >> 15);
651 dist = ((Word32) temp) * temp;
652
653 temp = lsf_r1_1 - (*p_dico++);
654 temp = (Word16)((((Word32) wf1_1) * temp) >> 15);
655 dist += ((Word32) temp) * temp;
656
657 temp = lsf_r1_2 - (*p_dico++);
658 temp = (Word16)((((Word32) wf1_2) * temp) >> 15);
659 dist += ((Word32) temp) * temp;
660
661 if (dist < dist_min)
662 {
663 dist_min = dist;
664 index = i;
665 }
666
667 p_dico = p_dico + p_dico_index;
668 }
669
670 p_dico = dico + (3 * index);
671
672 if (use_half != 0)
673 {
674 p_dico += (3 * index);
675 }
676
677 /* Reading the selected vector */
678 *lsf_r1++ = *p_dico++;
679 *lsf_r1++ = *p_dico++;
680 *lsf_r1 = *p_dico;
681
682 return(index);
683 }
684
685 /****************************************************************************/
686
687
688 /*
689 ------------------------------------------------------------------------------
690 FUNCTION NAME: Test_Vq_subvec3
691 ------------------------------------------------------------------------------
692 INPUT AND OUTPUT DEFINITIONS
693
694 Inputs:
695 lsf_r1 = pointer to the first LSF residual vector (Q15) (Word16)
696 dico = pointer to the quantization codebook (Q15) (const Word16)
697 wf1 = pointer to the first LSF weighting factor (Q13) (Word16)
698 dico_size = size of quantization codebook (Q0) (Word16)
699 use_half = flag to indicate use of every second entry in the
700 codebook (Flag)
701
702 Outputs:
703 buffer pointed to by lsf_r1 contains the selected vector
704 pOverflow -- pointer to Flag -- Flag set when overflow occurs
705
706 Returns:
707 index = quantization index (Q0) (Word16)
708
709 Global Variables Used:
710 None
711
712 Local Variables Needed:
713 None
714
715 ------------------------------------------------------------------------------
716 FUNCTION DESCRIPTION
717
718 This function calls the static function Vq_subvec3. It is used for testing
719 purposes only
720
721 ------------------------------------------------------------------------------
722 REQUIREMENTS
723
724 None
725
726 ------------------------------------------------------------------------------
727 REFERENCES
728
729 None
730
731 ------------------------------------------------------------------------------
732 PSEUDO-CODE
733
734 CALL Vq_subvec3(lsf_r1 = lsf_r1
735 dico = dico
736 wf1 = wf1
737 dico_size = dico_size
738 use_half = use_half)
739 MODIFYING(nothing)
740 RETURNING(index = tst_index3)
741
742 ------------------------------------------------------------------------------
743 RESOURCES USED [optional]
744
745 When the code is written for a specific target processor the
746 the resources used should be documented below.
747
748 HEAP MEMORY USED: x bytes
749
750 STACK MEMORY USED: x bytes
751
752 CLOCK CYCLES: (cycle count equation for this function) + (variable
753 used to represent cycle count for each subroutine
754 called)
755 where: (cycle count variable) = cycle count for [subroutine
756 name]
757
758 ------------------------------------------------------------------------------
759 CAUTION [optional]
760 [State any special notes, constraints or cautions for users of this function]
761
762 ------------------------------------------------------------------------------
763 */
764
Test_Vq_subvec3(Word16 * lsf_r1,const Word16 * dico,Word16 * wf1,Word16 dico_size,Flag use_half,Flag * pOverflow)765 Word16 Test_Vq_subvec3(
766 Word16 * lsf_r1,
767 const Word16 * dico,
768 Word16 * wf1,
769 Word16 dico_size,
770 Flag use_half,
771 Flag *pOverflow)
772 {
773 Word16 tst_index3 = 0;
774
775 /*------------------------------------------------------------------------
776 CALL Vq_subvec3(lsf_r1 = lsf_r1
777 dico = dico
778 wf1 = wf1
779 dico_size = dico_size
780 use_half = use_half)
781 MODIFYING(nothing)
782 RETURNING(index = index)
783 ------------------------------------------------------------------------*/
784 tst_index3 =
785 Vq_subvec3(
786 lsf_r1,
787 dico,
788 wf1,
789 dico_size,
790 use_half,
791 pOverflow);
792
793 return(tst_index3);
794
795 }
796
797 /****************************************************************************/
798
799
800 /*
801 ------------------------------------------------------------------------------
802 FUNCTION NAME: Q_plsf_3
803 ------------------------------------------------------------------------------
804 INPUT AND OUTPUT DEFINITIONS
805
806 Inputs:
807 st = pointer to structures of type Q_plsfState (Q_plsfState)
808 mode = coder mode (enum)
809 lsp1 = pointer to the first LSP vector (Word16)
810 lsp1_q = pointer to the quantized first LSP vector (Word16)
811 indice = pointer to the quantization indices of 3 vectors (Word16)
812 pred_init_i = pointer to the index of the initial value for
813 MA prediction in DTX mode (Word16)
814
815 Outputs:
816 lsp1_q points to a vector containing the new quantized LSPs
817 indice points to the new quantization indices of 3 vectors
818 pred_init_i points to the new initial index for MA prediction
819 in DTX mode
820 past_rq field of structure pointed to by st contains the current
821 quantized LSF parameters
822 pOverflow -- pointer to Flag -- Flag set when overflow occurs
823
824 Returns:
825 None
826
827 Global Variables Used:
828 pred_fac = table containing prediction factors (const Word16)
829 dico1_lsf = quantization table for split_MQ of 2 sets of LSFs
830 in a 20 ms frame (const Word16)
831 dico2_lsf = quantization table for split_MQ of 2 sets of LSFs
832 in a 20 ms frame (const Word16)
833 dico3_lsf = quantization table for split_MQ of 2 sets of LSFs
834 in a 20 ms frame (const Word16)
835 mr515_3_lsf = third codebook for MR475 and MR515 modes (const Word16)
836 mr795_1_lsf = first codebook for MR795 mode (const Word16)
837 mean_lsf = table of mean LSFs (const Word16)
838 past_rq_init = initalization table for MA predictor in DTX mode
839 (const Word16)
840
841
842 Local Variables Needed:
843 None
844
845 ------------------------------------------------------------------------------
846 FUNCTION DESCRIPTION
847
848 This function performs quantization of LSF parameters with 1st order MA
849 prediction and split by 3 vector quantization (split-VQ)
850
851 ------------------------------------------------------------------------------
852 REQUIREMENTS
853
854 None
855
856 ------------------------------------------------------------------------------
857 REFERENCES
858
859 q_plsf_3.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
860
861 ------------------------------------------------------------------------------
862 PSEUDO-CODE
863
864 void Q_plsf_3(
865 Q_plsfState *st, // i/o: state struct
866 enum Mode mode, // i : coder mode
867 Word16 *lsp1, // i : 1st LSP vector Q15
868 Word16 *lsp1_q, // o : quantized 1st LSP vector Q15
869 Word16 *indice, // o : quantization indices of 3 vectors Q0
870 Word16 *pred_init_i // o : init index for MA prediction in DTX mode
871 )
872 {
873 Word16 i, j;
874 Word16 lsf1[M], wf1[M], lsf_p[M], lsf_r1[M];
875 Word16 lsf1_q[M];
876
877 Word32 L_pred_init_err;
878 Word32 L_min_pred_init_err;
879 Word16 temp_r1[M];
880 Word16 temp_p[M];
881
882 // convert LSFs to normalize frequency domain 0..16384
883
884 Lsp_lsf(lsp1, lsf1, M);
885
886 // compute LSF weighting factors (Q13)
887
888 Lsf_wt(lsf1, wf1);
889
890 // Compute predicted LSF and prediction error
891 if (test(), sub(mode, MRDTX) != 0)
892 {
893 for (i = 0; i < M; i++)
894 {
895 lsf_p[i] = add(mean_lsf[i],
896 mult(st->past_rq[i],
897 pred_fac[i]));
898 lsf_r1[i] = sub(lsf1[i], lsf_p[i]);
899 }
900 }
901 else
902 {
903 // DTX mode, search the init vector that yields
904 // lowest prediction resuidual energy
905 *pred_init_i = 0;
906 L_min_pred_init_err = 0x7fffffff; // 2^31 - 1
907 for (j = 0; j < PAST_RQ_INIT_SIZE; j++)
908 {
909 L_pred_init_err = 0;
910 for (i = 0; i < M; i++)
911 {
912 temp_p[i] = add(mean_lsf[i], past_rq_init[j*M+i]);
913 temp_r1[i] = sub(lsf1[i],temp_p[i]);
914 L_pred_init_err = L_mac(L_pred_init_err, temp_r1[i], temp_r1[i]);
915 } // next i
916
917
918 if (L_sub(L_pred_init_err, L_min_pred_init_err) < (Word32) 0)
919 {
920 L_min_pred_init_err = L_pred_init_err;
921 Copy(temp_r1, lsf_r1, M);
922 Copy(temp_p, lsf_p, M);
923 // Set zerom
924 Copy(&past_rq_init[j*M], st->past_rq, M);
925 *pred_init_i = j;
926 } // endif
927 } // next j
928 } // endif MRDTX
929
930 //---- Split-VQ of prediction error ----
931 if (sub (mode, MR475) == 0 || sub (mode, MR515) == 0)
932 { // MR475, MR515
933
934
935 indice[0] = Vq_subvec3(&lsf_r1[0], dico1_lsf, &wf1[0], DICO1_SIZE, 0);
936
937 indice[1] = Vq_subvec3(&lsf_r1[3], dico2_lsf, &wf1[3], DICO2_SIZE/2, 1);
938
939 indice[2] = Vq_subvec4(&lsf_r1[6], mr515_3_lsf, &wf1[6], MR515_3_SIZE);
940
941 }
942 else if (sub (mode, MR795) == 0)
943 { // MR795
944
945
946 indice[0] = Vq_subvec3(&lsf_r1[0], mr795_1_lsf, &wf1[0], MR795_1_SIZE, 0);
947
948 indice[1] = Vq_subvec3(&lsf_r1[3], dico2_lsf, &wf1[3], DICO2_SIZE, 0);
949
950 indice[2] = Vq_subvec4(&lsf_r1[6], dico3_lsf, &wf1[6], DICO3_SIZE);
951
952 }
953 else
954 { // MR59, MR67, MR74, MR102 , MRDTX
955
956
957 indice[0] = Vq_subvec3(&lsf_r1[0], dico1_lsf, &wf1[0], DICO1_SIZE, 0);
958
959 indice[1] = Vq_subvec3(&lsf_r1[3], dico2_lsf, &wf1[3], DICO2_SIZE, 0);
960
961 indice[2] = Vq_subvec4(&lsf_r1[6], dico3_lsf, &wf1[6], DICO3_SIZE);
962
963 }
964
965
966 // Compute quantized LSFs and update the past quantized residual
967
968 for (i = 0; i < M; i++)
969 {
970 lsf1_q[i] = add(lsf_r1[i], lsf_p[i]);
971 st->past_rq[i] = lsf_r1[i];
972 }
973
974 // verification that LSFs has mimimum distance of LSF_GAP Hz
975
976 Reorder_lsf(lsf1_q, LSF_GAP, M);
977
978 // convert LSFs to the cosine domain
979
980 Lsf_lsp(lsf1_q, lsp1_q, M);
981 }
982
983 ------------------------------------------------------------------------------
984 RESOURCES USED [optional]
985
986 When the code is written for a specific target processor the
987 the resources used should be documented below.
988
989 HEAP MEMORY USED: x bytes
990
991 STACK MEMORY USED: x bytes
992
993 CLOCK CYCLES: (cycle count equation for this function) + (variable
994 used to represent cycle count for each subroutine
995 called)
996 where: (cycle count variable) = cycle count for [subroutine
997 name]
998
999 ------------------------------------------------------------------------------
1000 CAUTION [optional]
1001 [State any special notes, constraints or cautions for users of this function]
1002
1003 ------------------------------------------------------------------------------
1004 */
1005
Q_plsf_3(Q_plsfState * st,enum Mode mode,Word16 * lsp1,Word16 * lsp1_q,Word16 * indice,Word16 * pred_init_i,Flag * pOverflow)1006 void Q_plsf_3(
1007 Q_plsfState *st, /* i/o: state struct */
1008 enum Mode mode, /* i : coder mode */
1009 Word16 *lsp1, /* i : 1st LSP vector Q15 */
1010 Word16 *lsp1_q, /* o : quantized 1st LSP vector Q15 */
1011 Word16 *indice, /* o : quantization indices of 3 vectors Q0 */
1012 Word16 *pred_init_i,/* o : init index for MA prediction in DTX mode */
1013 Flag *pOverflow /* o : Flag set when overflow occurs */
1014 )
1015 {
1016 register Word16 i, j;
1017 Word16 lsf1[M];
1018 Word16 wf1[M];
1019 Word16 lsf_p[M];
1020 Word16 lsf_r1[M];
1021 Word16 lsf1_q[M];
1022
1023 Word32 L_pred_init_err;
1024 Word32 L_min_pred_init_err;
1025 Word32 L_temp;
1026 Word16 temp_r1[M];
1027 Word16 temp_p[M];
1028 Word16 temp;
1029
1030 /* convert LSFs to normalize frequency domain 0..16384 */
1031
1032 Lsp_lsf(
1033 lsp1,
1034 lsf1,
1035 M,
1036 pOverflow);
1037
1038 /* compute LSF weighting factors (Q13) */
1039
1040 Lsf_wt(
1041 lsf1,
1042 wf1,
1043 pOverflow);
1044
1045 /* Compute predicted LSF and prediction error */
1046 if (mode != MRDTX)
1047 {
1048 for (i = 0; i < M; i++)
1049 {
1050 temp = (Word16)((((Word32) st->past_rq[i]) *
1051 (*(pred_fac_3 + i))) >> 15);
1052
1053 *(lsf_p + i) = *(mean_lsf_3 + i) + temp;
1054
1055 *(lsf_r1 + i) = *(lsf1 + i) - *(lsf_p + i);
1056 }
1057 }
1058 else
1059 {
1060 /* DTX mode, search the init vector that yields */
1061 /* lowest prediction resuidual energy */
1062 *pred_init_i = 0;
1063 L_min_pred_init_err = 0x7fffffff; /* 2^31 - 1 */
1064
1065 for (j = 0; j < PAST_RQ_INIT_SIZE; j++)
1066 {
1067 L_pred_init_err = 0;
1068 for (i = 0; i < M; i++)
1069 {
1070 *(temp_p + i) = *(mean_lsf_3 + i) + *(past_rq_init + j * M + i);
1071
1072 *(temp_r1 + i) = *(lsf1 + i) - *(temp_p + i);
1073
1074 L_temp = ((Word32) * (temp_r1 + i)) * *(temp_r1 + i);
1075
1076 L_pred_init_err = L_pred_init_err + (L_temp << 1);
1077
1078 } /* next i */
1079
1080
1081 if (L_pred_init_err < L_min_pred_init_err)
1082 {
1083 L_min_pred_init_err = L_pred_init_err;
1084
1085 memcpy(
1086 lsf_r1,
1087 temp_r1,
1088 M*sizeof(Word16));
1089
1090 memcpy(
1091 lsf_p,
1092 temp_p,
1093 M*sizeof(Word16));
1094
1095 /* Set zerom */
1096 memcpy(
1097 st->past_rq,
1098 &past_rq_init[j*M],
1099 M*sizeof(Word16));
1100
1101 *pred_init_i = j;
1102
1103 } /* endif */
1104 } /* next j */
1105 } /* endif MRDTX */
1106
1107 /*---- Split-VQ of prediction error ----*/
1108 if ((mode == MR475) || (mode == MR515))
1109 { /* MR475, MR515 */
1110
1111 *indice =
1112 Vq_subvec3(
1113 lsf_r1,
1114 dico1_lsf_3,
1115 wf1,
1116 DICO1_SIZE,
1117 0,
1118 pOverflow);
1119
1120 *(indice + 1) =
1121 Vq_subvec3(
1122 lsf_r1 + 3,
1123 dico2_lsf_3,
1124 wf1 + 3,
1125 DICO2_SIZE / 2,
1126 1,
1127 pOverflow);
1128
1129 *(indice + 2) =
1130 Vq_subvec4(
1131 lsf_r1 + 6,
1132 mr515_3_lsf,
1133 wf1 + 6,
1134 MR515_3_SIZE,
1135 pOverflow);
1136
1137 }
1138 else if (mode == MR795)
1139 { /* MR795 */
1140
1141 *indice =
1142 Vq_subvec3(
1143 lsf_r1,
1144 mr795_1_lsf,
1145 wf1,
1146 MR795_1_SIZE,
1147 0,
1148 pOverflow);
1149
1150 *(indice + 1) =
1151 Vq_subvec3(
1152 lsf_r1 + 3,
1153 dico2_lsf_3,
1154 wf1 + 3,
1155 DICO2_SIZE,
1156 0,
1157 pOverflow);
1158
1159 *(indice + 2) =
1160 Vq_subvec4(
1161 lsf_r1 + 6,
1162 dico3_lsf_3,
1163 wf1 + 6,
1164 DICO3_SIZE,
1165 pOverflow);
1166
1167 }
1168 else
1169 { /* MR59, MR67, MR74, MR102 , MRDTX */
1170
1171 *indice =
1172 Vq_subvec3(
1173 lsf_r1,
1174 dico1_lsf_3,
1175 wf1,
1176 DICO1_SIZE,
1177 0,
1178 pOverflow);
1179
1180 *(indice + 1) =
1181 Vq_subvec3(
1182 lsf_r1 + 3,
1183 dico2_lsf_3,
1184 wf1 + 3,
1185 DICO2_SIZE,
1186 0,
1187 pOverflow);
1188
1189 *(indice + 2) =
1190 Vq_subvec4(
1191 lsf_r1 + 6,
1192 dico3_lsf_3,
1193 wf1 + 6,
1194 DICO3_SIZE,
1195 pOverflow);
1196
1197 }
1198
1199
1200 /* Compute quantized LSFs and update the past quantized residual */
1201
1202 for (i = 0; i < M; i++)
1203 {
1204 *(lsf1_q + i) = *(lsf_r1 + i) + *(lsf_p + i);
1205 st->past_rq[i] = *(lsf_r1 + i);
1206 }
1207
1208 /* verification that LSFs has mimimum distance of LSF_GAP Hz */
1209
1210 Reorder_lsf(
1211 lsf1_q,
1212 LSF_GAP,
1213 M,
1214 pOverflow);
1215
1216 /* convert LSFs to the cosine domain */
1217
1218 Lsf_lsp(
1219 lsf1_q,
1220 lsp1_q,
1221 M,
1222 pOverflow);
1223
1224 return;
1225
1226 }
1227