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