| /* ------------------------------------------------------------------ |
| * Copyright (C) 1998-2009 PacketVideo |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either |
| * express or implied. |
| * See the License for the specific language governing permissions |
| * and limitations under the License. |
| * ------------------------------------------------------------------- |
| */ |
| /**************************************************************************************** |
| Portions of this file are derived from the following 3GPP standard: |
| |
| 3GPP TS 26.073 |
| ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec |
| Available from http://www.3gpp.org |
| |
| (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) |
| Permission to distribute, modify and use this file under the standard license |
| terms listed above has been obtained from the copyright holder. |
| ****************************************************************************************/ |
| /* |
| ------------------------------------------------------------------------------ |
| |
| |
| |
| Pathname: ./audio/gsm-amr/c/src/d8_31pf.c |
| Functions: |
| |
| |
| Date: 01/28/2002 |
| |
| ------------------------------------------------------------------------------ |
| REVISION HISTORY |
| |
| Description: Modified to pass overflow flag through to basic math function. |
| The flag is passed back to the calling function by pointer reference. |
| |
| Description: Per review comments... |
| (1) Removed include of "count.h" and "basic_op.h" |
| (2) Added includes of mult.h, shl.h, shr.h, add.h, sub.h, negate.h, |
| L_mult.h, and L_shr.h |
| |
| Description: Replaced "int" and/or "char" with OSCL defined types. |
| |
| Description: |
| |
| ------------------------------------------------------------------------------ |
| MODULE DESCRIPTION |
| */ |
| |
| /*---------------------------------------------------------------------------- |
| ; INCLUDES |
| ----------------------------------------------------------------------------*/ |
| #include "d8_31pf.h" |
| #include "typedef.h" |
| #include "basic_op.h" |
| #include "cnst.h" |
| |
| |
| /*---------------------------------------------------------------------------- |
| ; MACROS |
| ; Define module specific macros here |
| ----------------------------------------------------------------------------*/ |
| |
| /*---------------------------------------------------------------------------- |
| ; DEFINES |
| ; Include all pre-processor statements here. Include conditional |
| ; compile variables also. |
| ----------------------------------------------------------------------------*/ |
| #define NB_PULSE 8 /* number of pulses */ |
| |
| /* define values/representation for output codevector and sign */ |
| #define POS_CODE 8191 |
| #define NEG_CODE 8191 |
| |
| |
| /*---------------------------------------------------------------------------- |
| ; LOCAL FUNCTION DEFINITIONS |
| ; Function Prototype declaration |
| ----------------------------------------------------------------------------*/ |
| |
| /*---------------------------------------------------------------------------- |
| ; LOCAL VARIABLE DEFINITIONS |
| ; Variable declaration - defined here and used outside this module |
| ----------------------------------------------------------------------------*/ |
| |
| /* |
| ------------------------------------------------------------------------------ |
| FUNCTION NAME: decompress10 |
| ------------------------------------------------------------------------------ |
| INPUT AND OUTPUT DEFINITIONS |
| |
| Inputs: |
| MSBs -- Word16 -- MSB part of the index |
| LSBs -- Word16 -- LSB part of the index |
| index1 -- Word16 -- index for first pos in pos_index[] |
| index2 -- Word16 -- index for second pos in pos_index[] |
| index3 -- Word16 -- index for third pos in pos_index[] |
| |
| Outputs: |
| pos_indx[] -- array of type Word16 -- position of 3 pulses (decompressed) |
| |
| pOverflow Flag set when overflow occurs, pointer of type Flag * |
| |
| Returns: |
| None |
| |
| Global Variables Used: |
| None |
| |
| Local Variables Needed: |
| None |
| |
| ------------------------------------------------------------------------------ |
| FUNCTION DESCRIPTION |
| |
| |
| ------------------------------------------------------------------------------ |
| REQUIREMENTS |
| |
| None |
| |
| ------------------------------------------------------------------------------ |
| REFERENCES |
| |
| d8_31pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 |
| |
| ------------------------------------------------------------------------------ |
| PSEUDO-CODE |
| |
| |
| ------------------------------------------------------------------------------ |
| RESOURCES USED [optional] |
| |
| When the code is written for a specific target processor the |
| the resources used should be documented below. |
| |
| HEAP MEMORY USED: x bytes |
| |
| STACK MEMORY USED: x bytes |
| |
| CLOCK CYCLES: (cycle count equation for this function) + (variable |
| used to represent cycle count for each subroutine |
| called) |
| where: (cycle count variable) = cycle count for [subroutine |
| name] |
| |
| ------------------------------------------------------------------------------ |
| CAUTION [optional] |
| [State any special notes, constraints or cautions for users of this function] |
| |
| ------------------------------------------------------------------------------ |
| */ |
| |
| static void decompress10( |
| Word16 MSBs, /* i : MSB part of the index */ |
| Word16 LSBs, /* i : LSB part of the index */ |
| Word16 index1, /* i : index for first pos in pos_index[] */ |
| Word16 index2, /* i : index for second pos in pos_index[] */ |
| Word16 index3, /* i : index for third pos in pos_index[] */ |
| Word16 pos_indx[], /* o : position of 3 pulses (decompressed) */ |
| Flag *pOverflow) /* o : Flag set when overflow occurs */ |
| { |
| Word16 ia; |
| Word16 ib; |
| Word16 ic; |
| Word32 tempWord32; |
| |
| /* |
| pos_indx[index1] = ((MSBs-25*(MSBs/25))%5)*2 + (LSBs-4*(LSBs/4))%2; |
| pos_indx[index2] = ((MSBs-25*(MSBs/25))/5)*2 + (LSBs-4*(LSBs/4))/2; |
| pos_indx[index3] = (MSBs/25)*2 + LSBs/4; |
| */ |
| |
| if (MSBs > 124) |
| { |
| MSBs = 124; |
| } |
| |
| ia = |
| mult( |
| MSBs, |
| 1311, |
| pOverflow); |
| |
| tempWord32 = |
| L_mult( |
| ia, |
| 25, |
| pOverflow); |
| |
| |
| ia = (Word16)(MSBs - (tempWord32 >> 1)); |
| ib = |
| mult( |
| ia, |
| 6554, |
| pOverflow); |
| |
| tempWord32 = |
| L_mult( |
| ib, |
| 5, |
| pOverflow); |
| |
| ib = ia - (Word16)(tempWord32 >> 1); |
| |
| ib = |
| shl( |
| ib, |
| 1, |
| pOverflow); |
| |
| |
| ic = LSBs - ((LSBs >> 2) << 2); |
| |
| |
| pos_indx[index1] = ib + (ic & 1); |
| |
| |
| ib = |
| mult( |
| ia, |
| 6554, |
| pOverflow); |
| |
| ib = |
| shl( |
| ib, |
| 1, |
| pOverflow); |
| |
| |
| pos_indx[index2] = ib + (ic >> 1); |
| |
| |
| ib = LSBs >> 2; |
| |
| ic = |
| mult( |
| MSBs, |
| 1311, |
| pOverflow); |
| |
| ic = |
| shl( |
| ic, |
| 1, |
| pOverflow); |
| |
| pos_indx[index3] = |
| add( |
| ib, |
| ic, |
| pOverflow); |
| |
| return; |
| } |
| |
| |
| /* |
| ------------------------------------------------------------------------------ |
| FUNCTION NAME: decompress_code |
| ------------------------------------------------------------------------------ |
| INPUT AND OUTPUT DEFINITIONS |
| |
| Inputs: |
| indx[] -- array of type Word16 -- position and sign of |
| 8 pulses (compressed) |
| |
| Outputs: |
| sign_indx[] -- array of type Word16 -- signs of 4 pulses (signs only) |
| pos_indx[] -- array of type Word16 -- position index of 8 pulses |
| (position only) |
| pOverflow pointer to type Flag -- Flag set when overflow occurs |
| |
| Returns: |
| None |
| |
| Global Variables Used: |
| None |
| |
| Local Variables Needed: |
| None |
| |
| ------------------------------------------------------------------------------ |
| FUNCTION DESCRIPTION |
| |
| PURPOSE: decompression of the linear codewords to 4+three indeces |
| one bit from each pulse is made robust to errors by |
| minimizing the phase shift of a bit error. |
| 4 signs (one for each track) |
| i0,i4,i1 => one index (7+3) bits, 3 LSBs more robust |
| i2,i6,i5 => one index (7+3) bits, 3 LSBs more robust |
| i3,i7 => one index (5+2) bits, 2-3 LSbs more robust |
| |
| ------------------------------------------------------------------------------ |
| REQUIREMENTS |
| |
| None |
| |
| ------------------------------------------------------------------------------ |
| REFERENCES |
| |
| d8_31pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 |
| |
| ------------------------------------------------------------------------------ |
| PSEUDO-CODE |
| |
| |
| ------------------------------------------------------------------------------ |
| RESOURCES USED [optional] |
| |
| When the code is written for a specific target processor the |
| the resources used should be documented below. |
| |
| HEAP MEMORY USED: x bytes |
| |
| STACK MEMORY USED: x bytes |
| |
| CLOCK CYCLES: (cycle count equation for this function) + (variable |
| used to represent cycle count for each subroutine |
| called) |
| where: (cycle count variable) = cycle count for [subroutine |
| name] |
| |
| ------------------------------------------------------------------------------ |
| CAUTION [optional] |
| [State any special notes, constraints or cautions for users of this function] |
| |
| ------------------------------------------------------------------------------ |
| */ |
| |
| static void decompress_code( |
| Word16 indx[], /* i : position and sign of 8 pulses (compressed) */ |
| Word16 sign_indx[], /* o : signs of 4 pulses (signs only) */ |
| Word16 pos_indx[], /* o : position index of 8 pulses (position only) */ |
| Flag *pOverflow /* o : Flag set when overflow occurs */ |
| ) |
| { |
| Word16 i; |
| Word16 ia; |
| Word16 ib; |
| Word16 MSBs; |
| Word16 LSBs; |
| Word16 MSBs0_24; |
| Word32 tempWord32; |
| |
| for (i = 0; i < NB_TRACK_MR102; i++) |
| { |
| sign_indx[i] = indx[i]; |
| } |
| |
| /* |
| First index: 10x10x10 -> 2x5x2x5x2x5-> 125x2x2x2 -> 7+1x3 bits |
| MSBs = indx[NB_TRACK]/8; |
| LSBs = indx[NB_TRACK]%8; |
| */ |
| MSBs = indx[NB_TRACK_MR102] >> 3; |
| |
| LSBs = indx[NB_TRACK_MR102] & 0x7; |
| |
| decompress10( |
| MSBs, |
| LSBs, |
| 0, |
| 4, |
| 1, |
| pos_indx, |
| pOverflow); |
| |
| /* |
| Second index: 10x10x10 -> 2x5x2x5x2x5-> 125x2x2x2 -> 7+1x3 bits |
| MSBs = indx[NB_TRACK+1]/8; |
| LSBs = indx[NB_TRACK+1]%8; |
| */ |
| MSBs = indx[NB_TRACK_MR102+1] >> 3; |
| |
| LSBs = indx[NB_TRACK_MR102+1] & 0x7; |
| |
| decompress10( |
| MSBs, |
| LSBs, |
| 2, |
| 6, |
| 5, |
| pos_indx, |
| pOverflow); |
| |
| /* |
| Third index: 10x10 -> 2x5x2x5-> 25x2x2 -> 5+1x2 bits |
| MSBs = indx[NB_TRACK+2]/4; |
| LSBs = indx[NB_TRACK+2]%4; |
| MSBs0_24 = (MSBs*25+12)/32; |
| if ((MSBs0_24/5)%2==1) |
| pos_indx[3] = (4-(MSBs0_24%5))*2 + LSBs%2; |
| else |
| pos_indx[3] = (MSBs0_24%5)*2 + LSBs%2; |
| pos_indx[7] = (MSBs0_24/5)*2 + LSBs/2; |
| */ |
| |
| MSBs = indx[NB_TRACK_MR102+2] >> 2; |
| |
| LSBs = indx[NB_TRACK_MR102+2] & 0x3; |
| |
| tempWord32 = |
| L_mult( |
| MSBs, |
| 25, |
| pOverflow); |
| |
| ia = |
| (Word16) |
| L_shr( |
| tempWord32, |
| 1, |
| pOverflow); |
| |
| ia += 12; |
| |
| MSBs0_24 = ia >> 5; |
| |
| |
| ia = |
| mult( |
| MSBs0_24, |
| 6554, |
| pOverflow); |
| |
| ia &= 1; |
| |
| |
| ib = |
| mult( |
| MSBs0_24, |
| 6554, |
| pOverflow); |
| |
| tempWord32 = |
| L_mult( |
| ib, |
| 5, |
| pOverflow); |
| |
| |
| ib = MSBs0_24 - (Word16)(tempWord32 >> 1); |
| |
| if (ia == 1) |
| { |
| ib = 4 - ib; |
| |
| } |
| |
| |
| ib = |
| shl( |
| ib, |
| 1, |
| pOverflow); |
| |
| ia = LSBs & 0x1; |
| |
| pos_indx[3] = |
| add( |
| ib, |
| ia, |
| pOverflow); |
| |
| ia = |
| mult( |
| MSBs0_24, |
| 6554, |
| pOverflow); |
| |
| ia = |
| shl( |
| ia, |
| 1, |
| pOverflow); |
| |
| pos_indx[7] = ia + (LSBs >> 1); |
| |
| } |
| |
| /* |
| ------------------------------------------------------------------------------ |
| FUNCTION NAME: dec_8i40_31bits |
| ------------------------------------------------------------------------------ |
| INPUT AND OUTPUT DEFINITIONS |
| |
| Inputs: |
| index array of type Word16 -- index of 8 pulses (sign+position) |
| |
| Outputs: |
| cod array of type Word16 -- algebraic (fixed) codebook excitation |
| pOverflow pointer to type Flag -- Flag set when overflow occurs |
| |
| Returns: |
| None |
| |
| Global Variables Used: |
| None |
| |
| Local Variables Needed: |
| None |
| |
| ------------------------------------------------------------------------------ |
| FUNCTION DESCRIPTION |
| |
| PURPOSE: Builds the innovative codevector from the received |
| index of algebraic codebook. |
| |
| ------------------------------------------------------------------------------ |
| REQUIREMENTS |
| |
| None |
| |
| ------------------------------------------------------------------------------ |
| REFERENCES |
| |
| d8_31pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 |
| |
| ------------------------------------------------------------------------------ |
| PSEUDO-CODE |
| |
| |
| ------------------------------------------------------------------------------ |
| RESOURCES USED [optional] |
| |
| When the code is written for a specific target processor the |
| the resources used should be documented below. |
| |
| HEAP MEMORY USED: x bytes |
| |
| STACK MEMORY USED: x bytes |
| |
| CLOCK CYCLES: (cycle count equation for this function) + (variable |
| used to represent cycle count for each subroutine |
| called) |
| where: (cycle count variable) = cycle count for [subroutine |
| name] |
| |
| ------------------------------------------------------------------------------ |
| CAUTION [optional] |
| [State any special notes, constraints or cautions for users of this function] |
| |
| ------------------------------------------------------------------------------ |
| */ |
| |
| void dec_8i40_31bits( |
| Word16 index[], /* i : index of 8 pulses (sign+position) */ |
| Word16 cod[], /* o : algebraic (fixed) codebook excitation */ |
| Flag *pOverflow /* o : Flag set when overflow occurs */ |
| ) |
| { |
| Word16 i; |
| Word16 j; |
| Word16 pos1; |
| Word16 pos2; |
| Word16 sign; |
| |
| Word16 linear_signs[NB_TRACK_MR102]; |
| Word16 linear_codewords[NB_PULSE]; |
| |
| for (i = 0; i < L_CODE; i++) |
| { |
| cod[i] = 0; |
| } |
| |
| decompress_code( |
| index, |
| linear_signs, |
| linear_codewords, |
| pOverflow); |
| |
| /* decode the positions and signs of pulses and build the codeword */ |
| for (j = 0; j < NB_TRACK_MR102; j++) /* NB_TRACK_MR102 = 4 */ |
| { |
| /* position of pulse "j" */ |
| |
| pos1 = (linear_codewords[j] << 2) + j; |
| |
| |
| if (linear_signs[j] == 0) |
| { |
| sign = POS_CODE; /* +1.0 */ |
| } |
| else |
| { |
| sign = -NEG_CODE; /* -1.0 */ |
| } |
| |
| if (pos1 < L_SUBFR) |
| { |
| cod[pos1] = sign; /* avoid buffer overflow */ |
| } |
| |
| /* compute index i */ |
| /* position of pulse "j+4" */ |
| |
| pos2 = (linear_codewords[j + 4] << 2) + j; |
| |
| |
| if (pos2 < pos1) |
| { |
| sign = negate(sign); |
| } |
| |
| if (pos2 < L_SUBFR) |
| { |
| cod[pos2] += sign; /* avoid buffer overflow */ |
| } |
| |
| |
| } /* for (j = 0; j < NB_TRACK_MR102; j++) */ |
| |
| return; |
| } |