1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
22 ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23 Available from http://www.3gpp.org
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 ****************************************************************************************/
31 Filename: q_plsf_3.cpp
38 ------------------------------------------------------------------------------
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).
45 ------------------------------------------------------------------------------
48 /*----------------------------------------------------------------------------
50 ----------------------------------------------------------------------------*/
58 /*--------------------------------------------------------------------------*/
64 /*----------------------------------------------------------------------------
66 ; Define module specific macros here
67 ----------------------------------------------------------------------------*/
69 /*----------------------------------------------------------------------------
71 ; Include all pre-processor statements here. Include conditional
72 ; compile variables also.
73 ----------------------------------------------------------------------------*/
74 #define PAST_RQ_INIT_SIZE 8
76 /*----------------------------------------------------------------------------
77 ; LOCAL FUNCTION DEFINITIONS
78 ; Function Prototype declaration
79 ----------------------------------------------------------------------------*/
81 /*----------------------------------------------------------------------------
82 ; LOCAL VARIABLE DEFINITIONS
83 ; Variable declaration - defined here and used outside this module
84 ----------------------------------------------------------------------------*/
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[];
93 extern const Word16 pred_fac_3[];
95 extern const Word16 dico1_lsf_3[];
96 extern const Word16 dico2_lsf_3[];
97 extern const Word16 dico3_lsf_3[];
99 extern const Word16 mr515_3_lsf[];
100 extern const Word16 mr795_1_lsf[];
102 extern const Word16 past_rq_init[];
104 /*--------------------------------------------------------------------------*/
110 ------------------------------------------------------------------------------
111 FUNCTION NAME: Vq_subvec4
112 ------------------------------------------------------------------------------
113 INPUT AND OUTPUT DEFINITIONS
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)
122 buffer pointed to by lsf_r1 contains the selected vector
123 pOverflow -- pointer to Flag -- Flag set when overflow occurs
126 index = quantization index (Q0) (Word16)
128 Global Variables Used:
131 Local Variables Needed:
134 ------------------------------------------------------------------------------
137 This function performs the quantization of a 4-dimensional subvector.
139 ------------------------------------------------------------------------------
144 ------------------------------------------------------------------------------
147 q_plsf_3.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
149 ------------------------------------------------------------------------------
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
160 Word16 *p_dico, temp;
161 Word32 dist_min, dist;
166 for (i = 0; i < dico_size; i++)
168 temp = sub (lsf_r1[0], *p_dico++);
169 temp = mult (wf1[0], temp);
170 dist = L_mult (temp, temp);
172 temp = sub (lsf_r1[1], *p_dico++);
173 temp = mult (wf1[1], temp);
174 dist = L_mac (dist, temp, temp);
176 temp = sub (lsf_r1[2], *p_dico++);
177 temp = mult (wf1[2], temp);
178 dist = L_mac (dist, temp, temp);
180 temp = sub (lsf_r1[3], *p_dico++);
181 temp = mult (wf1[3], temp);
182 dist = L_mac (dist, temp, temp);
185 if (L_sub (dist, dist_min) < (Word32) 0)
192 // Reading the selected vector
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++;
204 ------------------------------------------------------------------------------
206 [State any special notes, constraints or cautions for users of this function]
208 ------------------------------------------------------------------------------
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 */
221 const Word16 *p_dico;
236 OSCL_UNUSED_ARG(pOverflow);
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];
251 for (i = 0; i < dico_size; i++)
253 temp = lsf_r1_0 - (*p_dico++);
254 temp = (Word16)((((Word32) wf1_0) * temp) >> 15);
255 dist = ((Word32) temp) * temp;
257 temp = lsf_r1_1 - (*p_dico++);
258 temp = (Word16)((((Word32) wf1_1) * temp) >> 15);
259 dist += ((Word32) temp) * temp;
261 temp = lsf_r1_2 - (*p_dico++);
262 temp = (Word16)((((Word32) wf1_2) * temp) >> 15);
263 dist += ((Word32) temp) * temp;
265 temp = lsf_r1_3 - (*p_dico++);
266 temp = (Word16)((((Word32) wf1_3) * temp) >> 15);
267 dist += ((Word32) temp) * temp;
276 /* Reading the selected vector */
278 p_dico = dico + (index << 2);
279 *lsf_r1++ = *p_dico++;
280 *lsf_r1++ = *p_dico++;
281 *lsf_r1++ = *p_dico++;
288 /****************************************************************************/
292 ------------------------------------------------------------------------------
293 FUNCTION NAME: Test_Vq_subvec4
294 ------------------------------------------------------------------------------
295 INPUT AND OUTPUT DEFINITIONS
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)
304 buffer pointed to by lsf_r1 contains the selected vector
305 pOverflow -- pointer to Flag -- Flag set when overflow occurs
308 index = quantization index (Q0) (Word16)
310 Global Variables Used:
313 Local Variables Needed:
316 ------------------------------------------------------------------------------
319 This function calls the static function Vq_subvec4. It is used for testing
322 ------------------------------------------------------------------------------
327 ------------------------------------------------------------------------------
332 ------------------------------------------------------------------------------
336 CALL Vq_subvec4(lsf_r1 = lsf_r1
339 dico_size = dico_size)
341 RETURNING(index = tst_index4)
343 ------------------------------------------------------------------------------
345 [State any special notes, constraints or cautions for users of this function]
347 ------------------------------------------------------------------------------
350 Word16 Test_Vq_subvec4(
357 Word16 tst_index4 = 0;
359 /*------------------------------------------------------------------------
360 CALL Vq_subvec4(lsf_r1 = lsf_r1
363 dico_size = dico_size)
365 RETURNING(index = index)
366 ------------------------------------------------------------------------*/
379 /****************************************************************************/
382 ------------------------------------------------------------------------------
383 FUNCTION NAME: Vq_subvec3
384 ------------------------------------------------------------------------------
385 INPUT AND OUTPUT DEFINITIONS
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
396 buffer pointed to by lsf_r1 contains the selected vector
397 pOverflow -- pointer to Flag -- Flag set when overflow occurs
400 index = quantization index (Q0) (Word16)
402 Global Variables Used:
405 Local Variables Needed:
408 ------------------------------------------------------------------------------
411 This function performs the quantization of a 3 dimensional subvector.
413 ------------------------------------------------------------------------------
418 ------------------------------------------------------------------------------
421 q_plsf_3.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
423 ------------------------------------------------------------------------------
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
435 Word16 *p_dico, temp;
436 Word32 dist_min, dist;
442 for (i = 0; i < dico_size; i++)
444 temp = sub(lsf_r1[0], *p_dico++);
445 temp = mult(wf1[0], temp);
446 dist = L_mult(temp, temp);
448 temp = sub(lsf_r1[1], *p_dico++);
449 temp = mult(wf1[1], temp);
450 dist = L_mac(dist, temp, temp);
452 temp = sub(lsf_r1[2], *p_dico++);
453 temp = mult(wf1[2], temp);
454 dist = L_mac(dist, temp, temp);
456 if (L_sub(dist, dist_min) < (Word32) 0) {
461 p_dico = &dico[add(index, add(index, index))];
465 for (i = 0; i < dico_size; i++)
467 temp = sub(lsf_r1[0], *p_dico++);
468 temp = mult(wf1[0], temp);
469 dist = L_mult(temp, temp);
471 temp = sub(lsf_r1[1], *p_dico++);
472 temp = mult(wf1[1], temp);
473 dist = L_mac(dist, temp, temp);
475 temp = sub(lsf_r1[2], *p_dico++);
476 temp = mult(wf1[2], temp);
477 dist = L_mac(dist, temp, temp);
479 if (L_sub(dist, dist_min) < (Word32) 0)
484 p_dico = p_dico + 3; add(0,0);
486 p_dico = &dico[shl(add(index, add(index, index)),1)];
490 // Reading the selected vector
491 lsf_r1[0] = *p_dico++;
492 lsf_r1[1] = *p_dico++;
493 lsf_r1[2] = *p_dico++;
498 ------------------------------------------------------------------------------
500 [State any special notes, constraints or cautions for users of this function]
502 ------------------------------------------------------------------------------
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 */
516 const Word16 *p_dico;
518 Word16 p_dico_index = 0;
532 OSCL_UNUSED_ARG(pOverflow);
537 lsf_r1_0 = lsf_r1[0];
538 lsf_r1_1 = lsf_r1[1];
539 lsf_r1_2 = lsf_r1[2];
550 for (i = 0; i < dico_size; i++)
552 temp = lsf_r1_0 - (*p_dico++);
553 temp = (Word16)((((Word32) wf1_0) * temp) >> 15);
554 dist = ((Word32) temp) * temp;
556 temp = lsf_r1_1 - (*p_dico++);
557 temp = (Word16)((((Word32) wf1_1) * temp) >> 15);
558 dist += ((Word32) temp) * temp;
560 temp = lsf_r1_2 - (*p_dico++);
561 temp = (Word16)((((Word32) wf1_2) * temp) >> 15);
562 dist += ((Word32) temp) * temp;
570 p_dico = p_dico + p_dico_index;
573 p_dico = dico + (3 * index);
577 p_dico += (3 * index);
580 /* Reading the selected vector */
581 *lsf_r1++ = *p_dico++;
582 *lsf_r1++ = *p_dico++;
588 /****************************************************************************/
592 ------------------------------------------------------------------------------
593 FUNCTION NAME: Test_Vq_subvec3
594 ------------------------------------------------------------------------------
595 INPUT AND OUTPUT DEFINITIONS
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
606 buffer pointed to by lsf_r1 contains the selected vector
607 pOverflow -- pointer to Flag -- Flag set when overflow occurs
610 index = quantization index (Q0) (Word16)
612 Global Variables Used:
615 Local Variables Needed:
618 ------------------------------------------------------------------------------
621 This function calls the static function Vq_subvec3. It is used for testing
624 ------------------------------------------------------------------------------
629 ------------------------------------------------------------------------------
634 ------------------------------------------------------------------------------
637 CALL Vq_subvec3(lsf_r1 = lsf_r1
640 dico_size = dico_size
643 RETURNING(index = tst_index3)
645 ------------------------------------------------------------------------------
647 [State any special notes, constraints or cautions for users of this function]
649 ------------------------------------------------------------------------------
652 Word16 Test_Vq_subvec3(
660 Word16 tst_index3 = 0;
662 /*------------------------------------------------------------------------
663 CALL Vq_subvec3(lsf_r1 = lsf_r1
666 dico_size = dico_size
669 RETURNING(index = index)
670 ------------------------------------------------------------------------*/
684 /****************************************************************************/
688 ------------------------------------------------------------------------------
689 FUNCTION NAME: Q_plsf_3
690 ------------------------------------------------------------------------------
691 INPUT AND OUTPUT DEFINITIONS
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)
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
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
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
729 Local Variables Needed:
732 ------------------------------------------------------------------------------
735 This function performs quantization of LSF parameters with 1st order MA
736 prediction and split by 3 vector quantization (split-VQ)
738 ------------------------------------------------------------------------------
743 ------------------------------------------------------------------------------
746 q_plsf_3.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
748 ------------------------------------------------------------------------------
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
761 Word16 lsf1[M], wf1[M], lsf_p[M], lsf_r1[M];
764 Word32 L_pred_init_err;
765 Word32 L_min_pred_init_err;
769 // convert LSFs to normalize frequency domain 0..16384
771 Lsp_lsf(lsp1, lsf1, M);
773 // compute LSF weighting factors (Q13)
777 // Compute predicted LSF and prediction error
778 if (test(), sub(mode, MRDTX) != 0)
780 for (i = 0; i < M; i++)
782 lsf_p[i] = add(mean_lsf[i],
785 lsf_r1[i] = sub(lsf1[i], lsf_p[i]);
790 // DTX mode, search the init vector that yields
791 // lowest prediction resuidual energy
793 L_min_pred_init_err = 0x7fffffff; // 2^31 - 1
794 for (j = 0; j < PAST_RQ_INIT_SIZE; j++)
797 for (i = 0; i < M; i++)
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]);
805 if (L_sub(L_pred_init_err, L_min_pred_init_err) < (Word32) 0)
807 L_min_pred_init_err = L_pred_init_err;
808 Copy(temp_r1, lsf_r1, M);
809 Copy(temp_p, lsf_p, M);
811 Copy(&past_rq_init[j*M], st->past_rq, M);
817 //---- Split-VQ of prediction error ----
818 if (sub (mode, MR475) == 0 || sub (mode, MR515) == 0)
822 indice[0] = Vq_subvec3(&lsf_r1[0], dico1_lsf, &wf1[0], DICO1_SIZE, 0);
824 indice[1] = Vq_subvec3(&lsf_r1[3], dico2_lsf, &wf1[3], DICO2_SIZE/2, 1);
826 indice[2] = Vq_subvec4(&lsf_r1[6], mr515_3_lsf, &wf1[6], MR515_3_SIZE);
829 else if (sub (mode, MR795) == 0)
833 indice[0] = Vq_subvec3(&lsf_r1[0], mr795_1_lsf, &wf1[0], MR795_1_SIZE, 0);
835 indice[1] = Vq_subvec3(&lsf_r1[3], dico2_lsf, &wf1[3], DICO2_SIZE, 0);
837 indice[2] = Vq_subvec4(&lsf_r1[6], dico3_lsf, &wf1[6], DICO3_SIZE);
841 { // MR59, MR67, MR74, MR102 , MRDTX
844 indice[0] = Vq_subvec3(&lsf_r1[0], dico1_lsf, &wf1[0], DICO1_SIZE, 0);
846 indice[1] = Vq_subvec3(&lsf_r1[3], dico2_lsf, &wf1[3], DICO2_SIZE, 0);
848 indice[2] = Vq_subvec4(&lsf_r1[6], dico3_lsf, &wf1[6], DICO3_SIZE);
853 // Compute quantized LSFs and update the past quantized residual
855 for (i = 0; i < M; i++)
857 lsf1_q[i] = add(lsf_r1[i], lsf_p[i]);
858 st->past_rq[i] = lsf_r1[i];
861 // verification that LSFs has mimimum distance of LSF_GAP Hz
863 Reorder_lsf(lsf1_q, LSF_GAP, M);
865 // convert LSFs to the cosine domain
867 Lsf_lsp(lsf1_q, lsp1_q, M);
870 ------------------------------------------------------------------------------
872 [State any special notes, constraints or cautions for users of this function]
874 ------------------------------------------------------------------------------
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 */
887 register Word16 i, j;
894 Word32 L_pred_init_err;
895 Word32 L_min_pred_init_err;
901 /* convert LSFs to normalize frequency domain 0..16384 */
909 /* compute LSF weighting factors (Q13) */
916 /* Compute predicted LSF and prediction error */
919 for (i = 0; i < M; i++)
921 temp = (Word16)((((Word32) st->past_rq[i]) *
922 (*(pred_fac_3 + i))) >> 15);
924 *(lsf_p + i) = *(mean_lsf_3 + i) + temp;
926 *(lsf_r1 + i) = *(lsf1 + i) - *(lsf_p + i);
931 /* DTX mode, search the init vector that yields */
932 /* lowest prediction resuidual energy */
934 L_min_pred_init_err = 0x7fffffff; /* 2^31 - 1 */
936 for (j = 0; j < PAST_RQ_INIT_SIZE; j++)
939 for (i = 0; i < M; i++)
941 *(temp_p + i) = *(mean_lsf_3 + i) + *(past_rq_init + j * M + i);
943 *(temp_r1 + i) = *(lsf1 + i) - *(temp_p + i);
945 L_temp = ((Word32) * (temp_r1 + i)) * *(temp_r1 + i);
947 L_pred_init_err = L_pred_init_err + (L_temp << 1);
952 if (L_pred_init_err < L_min_pred_init_err)
954 L_min_pred_init_err = L_pred_init_err;
978 /*---- Split-VQ of prediction error ----*/
979 if ((mode == MR475) || (mode == MR515))
1009 else if (mode == MR795)
1040 { /* MR59, MR67, MR74, MR102 , MRDTX */
1071 /* Compute quantized LSFs and update the past quantized residual */
1073 for (i = 0; i < M; i++)
1075 *(lsf1_q + i) = *(lsf_r1 + i) + *(lsf_p + i);
1076 st->past_rq[i] = *(lsf_r1 + i);
1079 /* verification that LSFs has mimimum distance of LSF_GAP Hz */
1087 /* convert LSFs to the cosine domain */