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