Initialize Tizen 2.3
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / common / src / q_plsf_5.cpp
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
20
21     3GPP TS 26.073
22     ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23     Available from http://www.3gpp.org
24
25 (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26 Permission to distribute, modify and use this file under the standard license
27 terms listed above has been obtained from the copyright holder.
28 ****************************************************************************************/
29 /*
30  Filename: q_plsf_5.cpp
31
32 ------------------------------------------------------------------------------
33  MODULE DESCRIPTION
34
35
36 ------------------------------------------------------------------------------
37 */
38
39 /*----------------------------------------------------------------------------
40 ; INCLUDES
41 ----------------------------------------------------------------------------*/
42 #include "q_plsf.h"
43 #include "typedef.h"
44 #include "basic_op.h"
45 #include "lsp_lsf.h"
46 #include "reorder.h"
47 #include "lsfwt.h"
48
49 /*--------------------------------------------------------------------------*/
50 #ifdef __cplusplus
51 extern "C"
52 {
53 #endif
54
55     /*----------------------------------------------------------------------------
56     ; MACROS
57     ; Define module specific macros here
58     ----------------------------------------------------------------------------*/
59
60     /*----------------------------------------------------------------------------
61     ; DEFINES
62     ; Include all pre-processor statements here. Include conditional
63     ; compile variables also.
64     ----------------------------------------------------------------------------*/
65
66     /*----------------------------------------------------------------------------
67     ; LOCAL FUNCTION DEFINITIONS
68     ; Function Prototype declaration
69     ----------------------------------------------------------------------------*/
70
71     /*----------------------------------------------------------------------------
72     ; LOCAL VARIABLE DEFINITIONS
73     ; Variable declaration - defined here and used outside this module
74     ----------------------------------------------------------------------------*/
75
76     /*----------------------------------------------------------------------------
77     ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
78     ; Declare variables used in this module but defined elsewhere
79     ----------------------------------------------------------------------------*/
80     /* Codebooks of LSF prediction residual */
81     extern const Word16 mean_lsf_5[];
82
83     extern const Word16 dico1_lsf_5[];
84     extern const Word16 dico2_lsf_5[];
85     extern const Word16 dico3_lsf_5[];
86     extern const Word16 dico4_lsf_5[];
87     extern const Word16 dico5_lsf_5[];
88
89     /*--------------------------------------------------------------------------*/
90 #ifdef __cplusplus
91 }
92 #endif
93
94 /*
95 ------------------------------------------------------------------------------
96  FUNCTION NAME: Vq_subvec
97 ------------------------------------------------------------------------------
98  INPUT AND OUTPUT DEFINITIONS
99
100  Inputs:
101     lsf_r1 -- array of type Word16 -- 1st LSF residual vector,  Q15
102     lsf_r2 -- array of type Word16 -- 2nd LSF residual vector,  Q15
103     dico -- pointer to const Word16 -- quantization codebook,   Q15
104     wf1 -- array of type Word16 -- 1st LSF weighting factors,   Q13
105     wf2 -- array of type Word16 -- 2nd LSF weighting factors,   Q13
106     dico_size -- Word16 -- size of quantization codebook,       Q0
107  Outputs:
108     pOverflow -- pointer to type Flag -- overflow indicator
109
110  Returns:
111     Word16 -- quantization index, Q0
112
113  Global Variables Used:
114     None
115
116  Local Variables Needed:
117     None
118
119 ------------------------------------------------------------------------------
120  FUNCTION DESCRIPTION
121
122  This function performs the quantization of a 4-dimensional subvector.
123
124 ------------------------------------------------------------------------------
125  REQUIREMENTS
126
127  None
128
129 ------------------------------------------------------------------------------
130  REFERENCES
131
132  q_plsf_5.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
133
134 ------------------------------------------------------------------------------
135  PSEUDO-CODE
136
137
138 ------------------------------------------------------------------------------
139  CAUTION [optional]
140  [State any special notes, constraints or cautions for users of this function]
141
142 ------------------------------------------------------------------------------
143 */
144 /* Quantization of a 4 dimensional subvector */
145
146 static Word16 Vq_subvec( /* o : quantization index,            Q0  */
147     Word16 *lsf_r1,      /* i : 1st LSF residual vector,       Q15 */
148     Word16 *lsf_r2,      /* i : 2nd LSF residual vector,       Q15 */
149     const Word16 *dico,  /* i : quantization codebook,         Q15 */
150     Word16 *wf1,         /* i : 1st LSF weighting factors      Q13 */
151     Word16 *wf2,         /* i : 2nd LSF weighting factors      Q13 */
152     Word16 dico_size,    /* i : size of quantization codebook, Q0  */
153     Flag   *pOverflow    /* o : overflow indicator                 */
154 )
155 {
156     Word16 index = 0; /* initialization only needed to keep gcc silent */
157     Word16 i;
158     Word16 temp;
159     const Word16 *p_dico;
160     Word32 dist_min;
161     Word32 dist;
162     Word16 wf1_0;
163     Word16 wf1_1;
164     Word16 wf2_0;
165     Word16 wf2_1;
166     Word32 aux1;
167     Word32 aux2;
168     Word32 aux3;
169     Word32 aux4;
170
171     OSCL_UNUSED_ARG(pOverflow);
172
173     dist_min = MAX_32;
174     p_dico = dico;
175
176     wf1_0 = wf1[0];
177     wf1_1 = wf1[1];
178     wf2_0 = wf2[0];
179     wf2_1 = wf2[1];
180
181     aux1 = ((Word32) lsf_r1[0] * wf1_0);
182     aux2 = ((Word32) lsf_r1[1] * wf1_1);
183     aux3 = ((Word32) lsf_r2[0] * wf2_0);
184     aux4 = ((Word32) lsf_r2[1] * wf2_1);
185
186     for (i = 0; i < dico_size; i++)
187     {
188         temp  = (aux1 - ((Word32)wf1_0 * *(p_dico++))) >> 15;
189         dist  = ((Word32)temp * temp);
190
191         if (dist >= dist_min)
192         {
193             p_dico += 3;
194             continue;
195         }
196
197         temp  = (aux2 - ((Word32)wf1_1 * *(p_dico++))) >> 15;
198         dist += ((Word32)temp * temp);
199
200         if (dist >= dist_min)
201         {
202             p_dico += 2;
203             continue;
204         }
205
206         temp  = (aux3 - ((Word32)wf2_0 * *(p_dico++))) >> 15;
207         dist += ((Word32)temp * temp);
208
209         if (dist >= dist_min)
210         {
211             p_dico += 1;
212             continue;
213         }
214
215         temp  = (aux4 - ((Word32)wf2_1 * *(p_dico++))) >> 15;
216         dist += ((Word32)temp * temp);
217
218
219         if (dist < dist_min)
220         {
221             dist_min = dist;
222             index = i;
223         }
224     }
225
226
227
228     /* Reading the selected vector */
229
230     p_dico = &dico[ index<<2];
231     lsf_r1[0] = *p_dico++;
232     lsf_r1[1] = *p_dico++;
233     lsf_r2[0] = *p_dico++;
234     lsf_r2[1] = *p_dico;
235
236     return index;
237
238 }
239
240
241 /*
242 ------------------------------------------------------------------------------
243  FUNCTION NAME: Vq_subvec_s
244 ------------------------------------------------------------------------------
245  INPUT AND OUTPUT DEFINITIONS
246
247  Inputs:
248     lsf_r1 -- array of type Word16 -- 1st LSF residual vector,  Q15
249     lsf_r2 -- array of type Word16 -- 2nd LSF residual vector,  Q15
250     dico -- pointer to const Word16 -- quantization codebook,   Q15
251     wf1 -- array of type Word16 -- 1st LSF weighting factors,   Q13
252     wf2 -- array of type Word16 -- 2nd LSF weighting factors,   Q13
253     dico_size -- Word16 -- size of quantization codebook,       Q0
254
255  Outputs:
256     pOverflow -- pointer to type Flag -- overflow indicator
257
258  Returns:
259     Word16 -- quantization index, Q0
260
261  Global Variables Used:
262     None
263
264  Local Variables Needed:
265     None
266
267 ------------------------------------------------------------------------------
268  FUNCTION DESCRIPTION
269
270  This function performs the quantization of a 4-dimensional subvector.
271
272 ------------------------------------------------------------------------------
273  REQUIREMENTS
274
275  None
276
277 ------------------------------------------------------------------------------
278  REFERENCES
279
280  q_plsf_5.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
281
282 ------------------------------------------------------------------------------
283  PSEUDO-CODE
284
285
286 ------------------------------------------------------------------------------
287  CAUTION [optional]
288  [State any special notes, constraints or cautions for users of this function]
289
290 ------------------------------------------------------------------------------
291 */
292
293
294 /* Quantization of a 4 dimensional subvector with a signed codebook */
295
296 static Word16 Vq_subvec_s(  /* o : quantization index            Q0  */
297     Word16 *lsf_r1,         /* i : 1st LSF residual vector       Q15 */
298     Word16 *lsf_r2,         /* i : and LSF residual vector       Q15 */
299     const Word16 *dico,     /* i : quantization codebook         Q15 */
300     Word16 *wf1,            /* i : 1st LSF weighting factors     Q13 */
301     Word16 *wf2,            /* i : 2nd LSF weighting factors     Q13 */
302     Word16 dico_size,       /* i : size of quantization codebook Q0  */
303     Flag   *pOverflow)      /* o : overflow indicator                */
304 {
305     Word16 index = 0;  /* initialization only needed to keep gcc silent */
306     Word16 sign = 0;   /* initialization only needed to keep gcc silent */
307     Word16 i;
308     Word16 temp;
309     Word16 temp1;
310     Word16 temp2;
311     const Word16 *p_dico;
312     Word32 dist_min;
313     Word32 dist1;
314     Word32 dist2;
315
316     Word16 lsf_r1_0;
317     Word16 lsf_r1_1;
318     Word16 lsf_r2_0;
319     Word16 lsf_r2_1;
320
321     Word16 wf1_0;
322     Word16 wf1_1;
323     Word16 wf2_0;
324     Word16 wf2_1;
325
326     OSCL_UNUSED_ARG(pOverflow);
327
328     dist_min = MAX_32;
329     p_dico = dico;
330
331
332     lsf_r1_0 = lsf_r1[0];
333     lsf_r1_1 = lsf_r1[1];
334     lsf_r2_0 = lsf_r2[0];
335     lsf_r2_1 = lsf_r2[1];
336
337     wf1_0 = wf1[0];
338     wf1_1 = wf1[1];
339     wf2_0 = wf2[0];
340     wf2_1 = wf2[1];
341
342     for (i = 0; i < dico_size; i++)
343     {
344         /* test positive */
345         temp = *p_dico++;
346         temp1 = lsf_r1_0 - temp;
347         temp2 = lsf_r1_0 + temp;
348         temp1 = ((Word32)wf1_0 * temp1) >> 15;
349         temp2 = ((Word32)wf1_0 * temp2) >> 15;
350         dist1 = ((Word32)temp1 * temp1);
351         dist2 = ((Word32)temp2 * temp2);
352
353         temp = *p_dico++;
354         temp1 = lsf_r1_1 - temp;
355         temp2 = lsf_r1_1 + temp;
356         temp1 = ((Word32)wf1_1 * temp1) >> 15;
357         temp2 = ((Word32)wf1_1 * temp2) >> 15;
358         dist1 += ((Word32)temp1 * temp1);
359         dist2 += ((Word32)temp2 * temp2);
360
361         if ((dist1 >= dist_min) && (dist2 >= dist_min))
362         {
363             p_dico += 2;
364             continue;
365         }
366
367         temp = *p_dico++;
368         temp1 = lsf_r2_0 - temp;
369         temp2 = lsf_r2_0 + temp;
370         temp1 = ((Word32)wf2_0 * temp1) >> 15;
371         temp2 = ((Word32)wf2_0 * temp2) >> 15;
372         dist1 += ((Word32)temp1 * temp1);
373         dist2 += ((Word32)temp2 * temp2);
374
375         temp = *p_dico++;
376         temp1 = lsf_r2_1 - temp;
377         temp2 = lsf_r2_1 + temp;
378         temp1 = ((Word32)wf2_1 * temp1) >> 15;
379         temp2 = ((Word32)wf2_1 * temp2) >> 15;
380         dist1 += ((Word32)temp1 * temp1);
381         dist2 += ((Word32)temp2 * temp2);
382
383         if (dist1 < dist_min)
384         {
385             dist_min = dist1;
386             index = i;
387             sign = 0;
388         }
389
390         /* test negative */
391
392         if (dist2 < dist_min)
393         {
394             dist_min = dist2;
395             index = i;
396             sign = 1;
397         }
398     }
399
400     /* Reading the selected vector */
401
402     p_dico = &dico[index<<2];
403     index <<= 1;
404     if (sign)
405     {
406         lsf_r1[0] = - (*p_dico++);
407         lsf_r1[1] = - (*p_dico++);
408         lsf_r2[0] = - (*p_dico++);
409         lsf_r2[1] = - (*p_dico);
410         index +=  1;
411     }
412     else
413     {
414         lsf_r1[0] = *p_dico++;
415         lsf_r1[1] = *p_dico++;
416         lsf_r2[0] = *p_dico++;
417         lsf_r2[1] = *p_dico;
418     }
419
420     return index;
421
422 }
423
424 /*
425 ------------------------------------------------------------------------------
426  FUNCTION NAME: Q_plsf_5
427 ------------------------------------------------------------------------------
428  INPUT AND OUTPUT DEFINITIONS
429
430
431  Inputs:
432     st   -- pointer to Q_plsfState -- state information
433     lsp1 -- array of type Word16 -- 1st LSP vector,  Q15
434     lsp2 -- array of type Word16 -- 2nd LSP vector,  Q15
435
436  Outputs:
437     lps1_q -- array of type Word16 -- quantized 1st LSP vector,   Q15
438     lps2_q -- array of type Word16 -- quantized 2nd LSP vector,   Q15
439     indices -- array of type Word16 -- quantization indices of 5 matrics, Q0
440     pOverflow -- pointer to type Flag -- overflow indicator
441
442  Returns:
443     None
444
445  Global Variables Used:
446     mean_lsf_5[];
447
448     dico1_lsf_5[];
449     dico2_lsf_5[];
450     dico3_lsf_5[];
451     dico4_lsf_5[];
452     dico5_lsf_5[];
453
454  Local Variables Needed:
455     None
456
457 ------------------------------------------------------------------------------
458  FUNCTION DESCRIPTION
459
460  PURPOSE:  Quantization of 2 sets of LSF parameters using 1st order MA
461            prediction and split by 5 matrix quantization (split-MQ)
462
463  DESCRIPTION:
464
465       p[i] = pred_factor*past_rq[i];   i=0,...,m-1
466       r1[i]= lsf1[i] - p[i];           i=0,...,m-1
467       r2[i]= lsf2[i] - p[i];           i=0,...,m-1
468  where:
469       lsf1[i]           1st mean-removed LSF vector.
470       lsf2[i]           2nd mean-removed LSF vector.
471       r1[i]             1st residual prediction vector.
472       r2[i]             2nd residual prediction vector.
473       past_r2q[i]       Past quantized residual (2nd vector).
474
475  The residual vectors r1[i] and r2[i] are jointly quantized using
476  split-MQ with 5 codebooks. Each 4th dimension submatrix contains 2
477  elements from each residual vector. The 5 submatrices are as follows:
478    {r1[0], r1[1], r2[0], r2[1]};  {r1[2], r1[3], r2[2], r2[3]};
479    {r1[4], r1[5], r2[4], r2[5]};  {r1[6], r1[7], r2[6], r2[7]};
480                   {r1[8], r1[9], r2[8], r2[9]}
481
482 ------------------------------------------------------------------------------
483  REQUIREMENTS
484
485  None
486
487 ------------------------------------------------------------------------------
488  REFERENCES
489
490  q_plsf_5.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
491
492 ------------------------------------------------------------------------------
493  PSEUDO-CODE
494
495
496 ------------------------------------------------------------------------------
497  CAUTION [optional]
498  [State any special notes, constraints or cautions for users of this function]
499
500 ------------------------------------------------------------------------------
501 */
502
503 OSCL_EXPORT_REF void Q_plsf_5(
504     Q_plsfState *st,
505     Word16 *lsp1,      /* i : 1st LSP vector,                     Q15 */
506     Word16 *lsp2,      /* i : 2nd LSP vector,                     Q15 */
507     Word16 *lsp1_q,    /* o : quantized 1st LSP vector,           Q15 */
508     Word16 *lsp2_q,    /* o : quantized 2nd LSP vector,           Q15 */
509     Word16 *indice,    /* o : quantization indices of 5 matrices, Q0  */
510     Flag   *pOverflow  /* o : overflow indicator                      */
511 )
512 {
513     Word16 i;
514     Word16 lsf1[M];
515     Word16 lsf2[M];
516     Word16 wf1[M];
517     Word16 wf2[M];
518     Word16 lsf_p[M];
519     Word16 lsf_r1[M];
520     Word16 lsf_r2[M];
521     Word16 lsf1_q[M];
522     Word16 lsf2_q[M];
523
524     Word16 *p_lsf_p;
525     Word16 *p_lsf1;
526     Word16 *p_lsf2;
527     Word16 *p_lsf_r1;
528     Word16 *p_lsf_r2;
529
530     /* convert LSFs to normalize frequency domain 0..16384  */
531
532     Lsp_lsf(lsp1, lsf1, M, pOverflow);
533     Lsp_lsf(lsp2, lsf2, M, pOverflow);
534
535     /* Compute LSF weighting factors (Q13) */
536
537     Lsf_wt(lsf1, wf1, pOverflow);
538     Lsf_wt(lsf2, wf2, pOverflow);
539
540     /* Compute predicted LSF and prediction error */
541
542     p_lsf_p  = &lsf_p[0];
543     p_lsf1   = &lsf1[0];
544     p_lsf2   = &lsf2[0];
545     p_lsf_r1 = &lsf_r1[0];
546     p_lsf_r2 = &lsf_r2[0];
547
548     for (i = 0; i < M; i++)
549     {
550         *(p_lsf_p) = mean_lsf_5[i] +
551                      (((Word32)st->past_rq[i] * LSP_PRED_FAC_MR122) >> 15);
552
553         *(p_lsf_r1++) = *(p_lsf1++) - *(p_lsf_p);
554         *(p_lsf_r2++) = *(p_lsf2++) - *(p_lsf_p++);
555     }
556
557     /*---- Split-MQ of prediction error ----*/
558
559     indice[0] = Vq_subvec(&lsf_r1[0], &lsf_r2[0], dico1_lsf_5,
560                           &wf1[0], &wf2[0], DICO1_5_SIZE, pOverflow);
561
562     indice[1] = Vq_subvec(&lsf_r1[2], &lsf_r2[2], dico2_lsf_5,
563                           &wf1[2], &wf2[2], DICO2_5_SIZE, pOverflow);
564
565     indice[2] = Vq_subvec_s(&lsf_r1[4], &lsf_r2[4], dico3_lsf_5,
566                             &wf1[4], &wf2[4], DICO3_5_SIZE, pOverflow);
567
568     indice[3] = Vq_subvec(&lsf_r1[6], &lsf_r2[6], dico4_lsf_5,
569                           &wf1[6], &wf2[6], DICO4_5_SIZE, pOverflow);
570
571     indice[4] = Vq_subvec(&lsf_r1[8], &lsf_r2[8], dico5_lsf_5,
572                           &wf1[8], &wf2[8], DICO5_5_SIZE, pOverflow);
573
574     /* Compute quantized LSFs and update the past quantized residual */
575
576     p_lsf_r1 = &lsf_r1[0];
577     p_lsf_r2 = &lsf_r2[0];
578     p_lsf_p  = &lsf_p[0];
579     p_lsf1   = &lsf1_q[0];
580     p_lsf2   = &lsf2_q[0];
581
582
583     for (i = 0; i < M; i++)
584     {
585         *(p_lsf1++) = *(p_lsf_r1++) + *(p_lsf_p);
586         *(p_lsf2++) = *(p_lsf_r2) + *(p_lsf_p++);
587         st->past_rq[i] = *(p_lsf_r2++);
588     }
589
590     /* verification that LSFs has minimum distance of LSF_GAP */
591
592     Reorder_lsf(lsf1_q, LSF_GAP, M, pOverflow);
593     Reorder_lsf(lsf2_q, LSF_GAP, M, pOverflow);
594
595     /*  convert LSFs to the cosine domain */
596
597     Lsf_lsp(lsf1_q, lsp1_q, M, pOverflow);
598     Lsf_lsp(lsf2_q, lsp2_q, M, pOverflow);
599 }
600