Home | History | Annotate | Download | only in src
      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 
    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     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 
    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 
    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     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 
    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 
   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     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