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 
     32 
     33 
     34  Pathname: ./audio/gsm-amr/c/src/c1035pf.c
     35  Functions: q_p
     36             build_code
     37             code_10i40_35bits
     38 
     39 
     40      Date: 09/28/2000
     41 
     42 ------------------------------------------------------------------------------
     43  REVISION HISTORY
     44 
     45  Description: Updated template. Cleaned up code. Passing in a pointer to
     46               overflow flag for build_code() and code_10i40_35bits() functions.
     47               Removed unnecessary header files.
     48 
     49  Description:
     50               1. Eliminated unused include files.
     51               2. Replaced array addressing by pointers
     52               3. Eliminated math operations that unnecessary checked for
     53                  saturation
     54               4. Replaced for-loops with memset()
     55 
     56  Description: Changed function name to pv_round to avoid conflict with
     57               round function in C standard library.
     58 
     59  Description:  Replaced OSCL mem type functions and eliminated include
     60                files that now are chosen by OSCL definitions
     61 
     62  Description:  Replaced "int" and/or "char" with OSCL defined types.
     63 
     64  Description:
     65 
     66 ------------------------------------------------------------------------------
     67  MODULE DESCRIPTION
     68 
     69  This file contains the function that searches a 35 bit algebraic codebook
     70  containing 10 pulses in a frame of 40 samples.
     71 
     72 ------------------------------------------------------------------------------
     73 */
     74 
     75 /*----------------------------------------------------------------------------
     76 ; INCLUDES
     77 ----------------------------------------------------------------------------*/
     78 #include <string.h>
     79 
     80 #include "c1035pf.h"
     81 #include "cnst.h"
     82 #include "basic_op.h"
     83 #include "inv_sqrt.h"
     84 #include "set_sign.h"
     85 #include "cor_h.h"
     86 #include "cor_h_x.h"
     87 #include "s10_8pf.h"
     88 
     89 /*----------------------------------------------------------------------------
     90 ; MACROS
     91 ; [Define module specific macros here]
     92 ----------------------------------------------------------------------------*/
     93 
     94 
     95 /*----------------------------------------------------------------------------
     96 ; DEFINES
     97 ; [Include all pre-processor statements here. Include conditional
     98 ; compile variables also.]
     99 ----------------------------------------------------------------------------*/
    100 #define NB_PULSE  10
    101 
    102 /*----------------------------------------------------------------------------
    103 ; LOCAL FUNCTION DEFINITIONS
    104 ; [List function prototypes here]
    105 ----------------------------------------------------------------------------*/
    106 
    107 /*----------------------------------------------------------------------------
    108 ; LOCAL VARIABLE DEFINITIONS
    109 ; [Variable declaration - defined here and used outside this module]
    110 ----------------------------------------------------------------------------*/
    111 
    112 /*
    113 ------------------------------------------------------------------------------
    114  FUNCTION NAME: q_p
    115 ------------------------------------------------------------------------------
    116  INPUT AND OUTPUT DEFINITIONS
    117 
    118  Inputs:
    119     pShift_reg = pointer to Old CN generator shift register state (Word32)
    120     no_bits = Number of bits (Word16)
    121 
    122  Outputs:
    123     pShift_reg -> Updated CN generator shift register state
    124 
    125  Returns:
    126     noise_bits = Generated random integer value (Word16)
    127 
    128  Global Variables Used:
    129     None
    130 
    131  Local Variables Needed:
    132     None
    133 
    134 ------------------------------------------------------------------------------
    135  FUNCTION DESCRIPTION
    136 
    137  This is a local function that determnes the index of the pulses by looking up
    138  the gray encoder table
    139 
    140 ------------------------------------------------------------------------------
    141  REQUIREMENTS
    142 
    143  None
    144 
    145 ------------------------------------------------------------------------------
    146  REFERENCES
    147 
    148  c1035pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    149 
    150 ------------------------------------------------------------------------------
    151  PSEUDO-CODE
    152 
    153 void q_p (
    154     Word16 *ind,        // Pulse position
    155     Word16 n            // Pulse number
    156 )
    157 {
    158     Word16 tmp;
    159 
    160     tmp = *ind;
    161 
    162     if (sub (n, 5) < 0)
    163     {
    164         *ind = (tmp & 0x8) | gray[tmp & 0x7];
    165     }
    166     else
    167     {
    168         *ind = gray[tmp & 0x7];
    169     }
    170 }
    171 
    172 ------------------------------------------------------------------------------
    173  RESOURCES USED [optional]
    174 
    175  When the code is written for a specific target processor the
    176  the resources used should be documented below.
    177 
    178  HEAP MEMORY USED: x bytes
    179 
    180  STACK MEMORY USED: x bytes
    181 
    182  CLOCK CYCLES: (cycle count equation for this function) + (variable
    183                 used to represent cycle count for each subroutine
    184                 called)
    185      where: (cycle count variable) = cycle count for [subroutine
    186                                      name]
    187 
    188 ------------------------------------------------------------------------------
    189  CAUTION [optional]
    190  [State any special notes, constraints or cautions for users of this function]
    191 
    192 ------------------------------------------------------------------------------
    193 */
    194 
    195 /*----------------------------------------------------------------------------
    196 ; FUNCTION CODE
    197 ----------------------------------------------------------------------------*/
    198 
    199 void q_p(
    200     Word16 *pInd,       /* Pulse position */
    201     Word16 n            /* Pulse number   */
    202 )
    203 {
    204     Word16 tmp;
    205 
    206     tmp = *pInd;
    207 
    208     if (n < 5)
    209     {
    210         *pInd = (tmp & 0x8) | gray[tmp & 0x7];
    211     }
    212     else
    213     {
    214         *pInd = gray[tmp & 0x7];
    215     }
    216 }
    217 
    218 /*
    219 ------------------------------------------------------------------------------
    220  FUNCTION NAME: build_code
    221 ------------------------------------------------------------------------------
    222  INPUT AND OUTPUT DEFINITIONS
    223 
    224  Inputs:
    225     pSeed = pointer to the Old CN generator shift register state (Word32)
    226     n_param = Number of parameters to randomize (Word16)
    227     param_size_table = table holding paameter sizes (Word16)
    228     param[] = array to hold CN generated paramters (Word16)
    229     pOverflow = pointer to overflow flag (Flag)
    230 
    231  Outputs:
    232     param[] = CN generated parameters (Word16)
    233     pSeed = Updated CN generator shift register state (Word16)
    234     pOverflow -> 1 if overflow occured
    235 
    236  Returns:
    237     None
    238 
    239  Global Variables Used:
    240     None
    241 
    242  Local Variables Needed:
    243     None
    244 
    245 ------------------------------------------------------------------------------
    246  FUNCTION DESCRIPTION
    247 
    248  This function builds the codeword, the filtered codeword and index of the
    249  codevector, based on the signs and positions of 10 pulses.
    250 ------------------------------------------------------------------------------
    251  REQUIREMENTS
    252 
    253  None
    254 
    255 ------------------------------------------------------------------------------
    256  REFERENCES
    257 
    258  c1035pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    259 
    260 ------------------------------------------------------------------------------
    261  PSEUDO-CODE
    262 static void build_code (
    263     Word16 codvec[],    // (i)  : position of pulses
    264     Word16 sign[],      // (i)  : sign of d[n]
    265     Word16 cod[],       // (o)  : innovative code vector
    266     Word16 h[],         // (i)  : impulse response of weighted synthesis filter
    267     Word16 y[],         // (o)  : filtered innovative code
    268     Word16 indx[]       // (o)  : index of 10 pulses (sign+position)
    269 )
    270 {
    271     Word16 i, j, k, track, index, _sign[NB_PULSE];
    272     Word16 *p0, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9;
    273     Word32 s;
    274 
    275     for (i = 0; i < L_CODE; i++)
    276     {
    277         cod[i] = 0;
    278     }
    279     for (i = 0; i < NB_TRACK; i++)
    280     {
    281         indx[i] = -1;
    282     }
    283 
    284     for (k = 0; k < NB_PULSE; k++)
    285     {
    286         // read pulse position
    287         i = codvec[k];
    288         // read sign
    289         j = sign[i];
    290 
    291         index = mult (i, 6554);                  // index = pos/5
    292         // track = pos%5
    293         track = sub (i, extract_l (L_shr (L_mult (index, 5), 1)));
    294 
    295         if (j > 0)
    296         {
    297             cod[i] = add (cod[i], 4096);
    298             _sign[k] = 8192;
    299 
    300         }
    301         else
    302         {
    303             cod[i] = sub (cod[i], 4096);
    304             _sign[k] = -8192;
    305             index = add (index, 8);
    306         }
    307 
    308         if (indx[track] < 0)
    309         {
    310             indx[track] = index;
    311         }
    312         else
    313         {
    314             if (((index ^ indx[track]) & 8) == 0)
    315             {
    316                 // sign of 1st pulse == sign of 2nd pulse
    317 
    318                 if (sub (indx[track], index) <= 0)
    319                 {
    320                     indx[track + 5] = index;
    321                 }
    322                 else
    323                 {
    324                     indx[track + 5] = indx[track];
    325                     indx[track] = index;
    326                 }
    327             }
    328             else
    329             {
    330                 // sign of 1st pulse != sign of 2nd pulse
    331 
    332                 if (sub ((Word16)(indx[track] & 7), (Word16)(index & 7)) <= 0)
    333                 {
    334                     indx[track + 5] = indx[track];
    335                     indx[track] = index;
    336                 }
    337                 else
    338                 {
    339                     indx[track + 5] = index;
    340                 }
    341             }
    342         }
    343     }
    344 
    345     p0 = h - codvec[0];
    346     p1 = h - codvec[1];
    347     p2 = h - codvec[2];
    348     p3 = h - codvec[3];
    349     p4 = h - codvec[4];
    350     p5 = h - codvec[5];
    351     p6 = h - codvec[6];
    352     p7 = h - codvec[7];
    353     p8 = h - codvec[8];
    354     p9 = h - codvec[9];
    355 
    356     for (i = 0; i < L_CODE; i++)
    357     {
    358         s = 0;
    359         s = L_mac (s, *p0++, _sign[0]);
    360         s = L_mac (s, *p1++, _sign[1]);
    361         s = L_mac (s, *p2++, _sign[2]);
    362         s = L_mac (s, *p3++, _sign[3]);
    363         s = L_mac (s, *p4++, _sign[4]);
    364         s = L_mac (s, *p5++, _sign[5]);
    365         s = L_mac (s, *p6++, _sign[6]);
    366         s = L_mac (s, *p7++, _sign[7]);
    367         s = L_mac (s, *p8++, _sign[8]);
    368         s = L_mac (s, *p9++, _sign[9]);
    369         y[i] = pv_round (s);
    370     }
    371 }
    372 
    373 ------------------------------------------------------------------------------
    374  RESOURCES USED [optional]
    375 
    376  When the code is written for a specific target processor the
    377  the resources used should be documented below.
    378 
    379  HEAP MEMORY USED: x bytes
    380 
    381  STACK MEMORY USED: x bytes
    382 
    383  CLOCK CYCLES: (cycle count equation for this function) + (variable
    384                 used to represent cycle count for each subroutine
    385                 called)
    386      where: (cycle count variable) = cycle count for [subroutine
    387                                      name]
    388 
    389 ------------------------------------------------------------------------------
    390  CAUTION [optional]
    391  [State any special notes, constraints or cautions for users of this function]
    392 
    393 ------------------------------------------------------------------------------
    394 */
    395 
    396 /*----------------------------------------------------------------------------
    397 ; FUNCTION CODE
    398 ----------------------------------------------------------------------------*/
    399 static void build_code(
    400     Word16 codvec[],    /* (i)  : position of pulses                        */
    401     Word16 sign[],      /* (i)  : sign of d[n]                              */
    402     Word16 cod[],       /* (o)  : innovative code vector                    */
    403     Word16 h[],         /* (i)  : impulse response of weighted synthesis filter*/
    404     Word16 y[],         /* (o)  : filtered innovative code                  */
    405     Word16 indx[],      /* (o)  : index of 10 pulses (sign+position)        */
    406     Flag   *pOverflow   /* i/o  : overflow Flag                             */
    407 )
    408 {
    409     Word16 i, k, track, index, _sign[NB_PULSE];
    410     Word16 *p0, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9;
    411     Word32 s;
    412     Word16 temp;
    413     Word16 *p__sign;
    414     Word16 *p_y;
    415     Word16 *p_codvec;
    416 
    417     OSCL_UNUSED_ARG(pOverflow);
    418 
    419     memset(cod, 0, L_CODE*sizeof(*cod));
    420     memset(indx, 0xFF, NB_TRACK*sizeof(*indx));
    421 
    422     p__sign = _sign;
    423 
    424     p0 = &codvec[0];
    425 
    426     for (k = 0; k < NB_PULSE; k++)
    427     {
    428         /* read pulse position */
    429         i = *(p0++);
    430         /* read sign           */
    431 
    432         index = ((Word32)i * 6554) >> 15;       /* index = pos/5    */
    433 
    434         /* track = pos%5 */
    435         /* track = sub (i, extract_l (L_shr (L_mult (index, 5), 1))); */
    436         track = i - (index * 5);
    437 
    438         if (sign[i] > 0)
    439         {
    440             cod[i] +=  4096;
    441             *(p__sign++) = 8192;
    442 
    443         }
    444         else
    445         {
    446             cod[i] -=  4096;
    447             *(p__sign++) = -8192;
    448             /* index = add (index, 8); */
    449             index += 8;
    450         }
    451 
    452         p1 = &indx[track];
    453 
    454         temp = *p1;
    455 
    456         if (temp < 0)
    457         {
    458             *p1 = index;
    459         }
    460         else
    461         {
    462             if (((index ^ temp) & 8) == 0)
    463             {
    464                 /* sign of 1st pulse == sign of 2nd pulse */
    465 
    466                 /* if (sub (indx[track], index) <= 0) */
    467                 if (temp <= index)
    468                 {
    469                     *(p1 + 5) = index;
    470                 }
    471                 else
    472                 {
    473                     *(p1 + 5) = temp;
    474                     *p1 = index;
    475                 }
    476             }
    477             else
    478             {
    479                 /* sign of 1st pulse != sign of 2nd pulse */
    480 
    481                 /* if (sub ((Word16)(indx[track] & 7), (Word16)(index & 7)) <= 0) */
    482                 if ((temp & 7) <= (index & 7))
    483                 {
    484                     *(p1 + 5) = temp;
    485                     *p1 = index;
    486                 }
    487                 else
    488                 {
    489                     *(p1 + 5) = index;
    490                 }
    491             }
    492         }
    493     }
    494 
    495     p_codvec = &codvec[0];
    496 
    497     p0 = h - *(p_codvec++);
    498     p1 = h - *(p_codvec++);
    499     p2 = h - *(p_codvec++);
    500     p3 = h - *(p_codvec++);
    501     p4 = h - *(p_codvec++);
    502     p5 = h - *(p_codvec++);
    503     p6 = h - *(p_codvec++);
    504     p7 = h - *(p_codvec++);
    505     p8 = h - *(p_codvec++);
    506     p9 = h - *(p_codvec++);
    507 
    508     p_y = y;
    509 
    510     for (i = L_CODE; i != 0; i--)
    511     {
    512         p__sign = _sign;
    513 
    514         s  = (*p0++ * *(p__sign++)) >> 7;
    515         s += (*p1++ * *(p__sign++)) >> 7;
    516         s += (*p2++ * *(p__sign++)) >> 7;
    517         s += (*p3++ * *(p__sign++)) >> 7;
    518         s += (*p4++ * *(p__sign++)) >> 7;
    519         s += (*p5++ * *(p__sign++)) >> 7;
    520         s += (*p6++ * *(p__sign++)) >> 7;
    521         s += (*p7++ * *(p__sign++)) >> 7;
    522         s += (*p8++ * *(p__sign++)) >> 7;
    523         s += (*p9++ * *(p__sign++)) >> 7;
    524 
    525         *(p_y++) = (s + 0x080) >> 8;
    526     }
    527 
    528 }
    529 
    530 /*
    531 ------------------------------------------------------------------------------
    532  FUNCTION NAME: code_10i40_35bits
    533 ------------------------------------------------------------------------------
    534  INPUT AND OUTPUT DEFINITIONS
    535 
    536  Inputs:
    537     pSeed = pointer to the Old CN generator shift register state (Word32)
    538     n_param = Number of parameters to randomize (Word16)
    539     param_size_table = table holding paameter sizes (Word16)
    540     param[] = array to hold CN generated paramters (Word16)
    541     pOverflow = pointer to overflow flag (Flag)
    542 
    543  Outputs:
    544     param[] = CN generated parameters (Word16)
    545     pSeed = Updated CN generator shift register state (Word16)
    546     pOverflow -> 1 if overflow occured
    547 
    548  Returns:
    549     None
    550 
    551  Global Variables Used:
    552     None
    553 
    554  Local Variables Needed:
    555     None
    556 
    557 ------------------------------------------------------------------------------
    558  FUNCTION DESCRIPTION
    559 
    560  This function searches a 35 bit algebraic codebook containing 10 pulses in a
    561  frame of 40 samples.
    562 
    563  The code contains 10 nonzero pulses: i0...i9.
    564  All pulses can have two possible amplitudes: +1 or -1.
    565  The 40 positions in a subframe are divided into 5 tracks of
    566  interleaved positions. Each track contains two pulses.
    567  The pulses can have the following possible positions:
    568 
    569     i0, i5 :  0, 5, 10, 15, 20, 25, 30, 35.
    570     i1, i6 :  1, 6, 11, 16, 21, 26, 31, 36.
    571     i2, i7 :  2, 7, 12, 17, 22, 27, 32, 37.
    572     i3, i8 :  3, 8, 13, 18, 23, 28, 33, 38.
    573     i4, i9 :  4, 9, 14, 19, 24, 29, 34, 39.
    574 
    575  Each pair of pulses require 1 bit for their signs and 6 bits for their
    576  positions (3 bits + 3 bits). This results in a 35 bit codebook.
    577  The function determines the optimal pulse signs and positions, builds
    578  the codevector, and computes the filtered codevector.
    579 
    580 ------------------------------------------------------------------------------
    581  REQUIREMENTS
    582 
    583  None
    584 
    585 ------------------------------------------------------------------------------
    586  REFERENCES
    587 
    588  c1035pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    589 
    590 ------------------------------------------------------------------------------
    591  PSEUDO-CODE
    592 void code_10i40_35bits (
    593     Word16 x[],   // (i)   : target vector
    594     Word16 cn[],  // (i)   : residual after long term prediction
    595     Word16 h[],   // (i)   : impulse response of weighted synthesis filter
    596                            // h[-L_subfr..-1] must be set to zero
    597     Word16 cod[], // (o)   : algebraic (fixed) codebook excitation
    598     Word16 y[],   // (o)   : filtered fixed codebook excitation
    599     Word16 indx[] // (o)   : index of 10 pulses (sign + position)
    600 )
    601 {
    602     Word16 ipos[NB_PULSE], pos_max[NB_TRACK], codvec[NB_PULSE];
    603     Word16 dn[L_CODE], sign[L_CODE];
    604     Word16 rr[L_CODE][L_CODE], i;
    605 
    606     cor_h_x (h, x, dn, 2);
    607     set_sign12k2 (dn, cn, sign, pos_max, NB_TRACK, ipos, STEP);
    608     cor_h (h, sign, rr);
    609 
    610     search_10and8i40 (NB_PULSE, STEP, NB_TRACK,
    611                       dn, rr, ipos, pos_max, codvec);
    612 
    613     build_code (codvec, sign, cod, h, y, indx);
    614     for (i = 0; i < 10; i++)
    615     {
    616         q_p (&indx[i], i);
    617     }
    618     return;
    619 }
    620 
    621 ------------------------------------------------------------------------------
    622  RESOURCES USED [optional]
    623 
    624  When the code is written for a specific target processor the
    625  the resources used should be documented below.
    626 
    627  HEAP MEMORY USED: x bytes
    628 
    629  STACK MEMORY USED: x bytes
    630 
    631  CLOCK CYCLES: (cycle count equation for this function) + (variable
    632                 used to represent cycle count for each subroutine
    633                 called)
    634      where: (cycle count variable) = cycle count for [subroutine
    635                                      name]
    636 
    637 ------------------------------------------------------------------------------
    638  CAUTION [optional]
    639  [State any special notes, constraints or cautions for users of this function]
    640 
    641 ------------------------------------------------------------------------------
    642 */
    643 
    644 /*----------------------------------------------------------------------------
    645 ; FUNCTION CODE
    646 ----------------------------------------------------------------------------*/
    647 void code_10i40_35bits(
    648     Word16 x[],     /* (i)   : target vector                                */
    649     Word16 cn[],    /* (i)   : residual after long term prediction          */
    650     Word16 h[],     /* (i)   : impulse response of weighted synthesis filter
    651                              h[-L_subfr..-1] must be set to zero            */
    652     Word16 cod[],   /* (o)   : algebraic (fixed) codebook excitation        */
    653     Word16 y[],     /* (o)   : filtered fixed codebook excitation           */
    654     Word16 indx[],  /* (o)   : index of 10 pulses (sign + position)         */
    655     Flag *pOverflow /* (i/o) : overflow Flag                                */
    656 )
    657 {
    658     Word16 ipos[NB_PULSE], pos_max[NB_TRACK], codvec[NB_PULSE];
    659     Word16 dn[L_CODE], sign[L_CODE];
    660     Word16 rr[L_CODE][L_CODE], i;
    661 
    662     cor_h_x(h, x, dn, 2, pOverflow);
    663     set_sign12k2(dn, cn, sign, pos_max, NB_TRACK, ipos, STEP, pOverflow);
    664     cor_h(h, sign, rr, pOverflow);
    665 
    666     search_10and8i40(NB_PULSE, STEP, NB_TRACK,
    667                      dn, rr, ipos, pos_max, codvec, pOverflow);
    668 
    669     build_code(codvec, sign, cod, h, y, indx, pOverflow);
    670     for (i = 0; i < 10; i++)
    671     {
    672         q_p(&indx[i], i);
    673     }
    674     return;
    675 }
    676 
    677