summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/amrnb/enc/src/c2_9pf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/codecs/amrnb/enc/src/c2_9pf.cpp')
-rw-r--r--media/libstagefright/codecs/amrnb/enc/src/c2_9pf.cpp1219
1 files changed, 1219 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/amrnb/enc/src/c2_9pf.cpp b/media/libstagefright/codecs/amrnb/enc/src/c2_9pf.cpp
new file mode 100644
index 0000000..a33cdf74
--- /dev/null
+++ b/media/libstagefright/codecs/amrnb/enc/src/c2_9pf.cpp
@@ -0,0 +1,1219 @@
+/* ------------------------------------------------------------------
+ * 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/c2_9pf.c
+ Funtions: code_2i40_9bits
+ search_2i40
+ Test_search_2i40
+ build_code
+ Test_build_code
+
+ Date: 05/26/2000
+
+------------------------------------------------------------------------------
+ REVISION HISTORY
+
+ Description: Changed template used to PV coding template. First attempt at
+ optimizing C code.
+
+ Description: Updated file per comments gathered from Phase 2/3 review.
+
+ Description: Added setting of Overflow flag in inlined code.
+
+ Description: Synchronized file with UMTS version 3.2.0. Updated coding
+ template.
+
+ Description: Replaced basic_op.h with the header files of the math functions
+ used by the file.
+
+ Description: Made the following changes per comments from Phase 2/3 review:
+ 1. Defined one local variable per line.
+
+ Description: Passed in pOverflow flag for EPOC compatibility.
+
+ Description: Optimized search_2i40() to reduce clock cycle usage.
+
+ Description: Removed unnecessary include files and #defines.
+
+ Description: Changed function name to pv_round to avoid conflict with
+ round function in C standard library.
+
+ Description: Replaced "int" and/or "char" with OSCL defined types.
+
+ Description: Added #ifdef __cplusplus around extern'ed table.
+
+ Description:
+
+------------------------------------------------------------------------------
+ MODULE DESCRIPTION
+
+ This file contains the functions that search a 9 bit algebraic codebook
+ containing 2 pulses in a frame of 40 samples.
+
+------------------------------------------------------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+#include "c2_9pf.h"
+#include "typedef.h"
+#include "basic_op.h"
+#include "inv_sqrt.h"
+#include "cnst.h"
+#include "cor_h.h"
+#include "cor_h_x.h"
+#include "set_sign.h"
+
+/*--------------------------------------------------------------------------*/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ /*----------------------------------------------------------------------------
+ ; MACROS
+ ; Define module specific macros here
+ ----------------------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------------------
+ ; DEFINES
+ ; Include all pre-processor statements here. Include conditional
+ ; compile variables also.
+ ----------------------------------------------------------------------------*/
+#define NB_PULSE 2
+
+ /*----------------------------------------------------------------------------
+ ; LOCAL FUNCTION DEFINITIONS
+ ; Function Prototype declaration
+ ----------------------------------------------------------------------------*/
+ static void search_2i40(
+ Word16 subNr, /* i : subframe number */
+ Word16 dn[], /* i : correlation between target and h[] */
+ Word16 rr[][L_CODE],/* i : matrix of autocorrelation */
+ Word16 codvec[], /* o : algebraic codebook vector */
+ Flag * pOverflow /* o : Flag set when overflow occurs */
+ );
+
+ static Word16 build_code(
+ Word16 subNr, /* i : subframe number */
+ Word16 codvec[], /* i : algebraic codebook vector */
+ Word16 dn_sign[], /* i : sign of dn[] */
+ Word16 cod[], /* o : algebraic (fixed) codebook excitation */
+ Word16 h[], /* i : impulse response of weighted synthesis filter */
+ Word16 y[], /* o : filtered fixed codebook excitation */
+ Word16 sign[], /* o : sign of 2 pulses */
+ Flag * pOverflow /* o : Flag set when overflow occurs */
+ );
+
+ /*----------------------------------------------------------------------------
+ ; LOCAL VARIABLE DEFINITIONS
+ ; Variable declaration - defined here and used outside this module
+ ----------------------------------------------------------------------------*/
+
+ const Word16 trackTable[4*5] =
+ {
+ 0, 1, 0, 1, -1, /* subframe 1; track to code;
+ * -1 do not code this position
+ */
+ 0, -1, 1, 0, 1, /* subframe 2 */
+ 0, 1, 0, -1, 1, /* subframe 3 */
+ 0, 1, -1, 0, 1
+ };/* subframe 4 */
+
+
+ /*----------------------------------------------------------------------------
+ ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
+ ; Declare variables used in this module but defined elsewhere
+ ----------------------------------------------------------------------------*/
+ extern const Word16 startPos[];
+
+ /*
+ ------------------------------------------------------------------------------
+ FUNCTION NAME: code_2i40_9bits
+ ------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ subNr = subframe number (Word16)
+ x = target buffer (Word16)
+ h = buffer containing the impulse response of the
+ weighted synthesis filter; h[-L_subfr .. -1] must be
+ set to zero (Word16)
+ T0 = pitch lag (Word16)
+ pitch_sharp = last quantized pitch gain (Word16)
+ code = buffer containing the innovative codebook (Word16)
+ y = buffer containing the filtered fixed codebook excitation (Word16)
+ sign = pointer to the signs of 2 pulses (Word16)
+
+ Outputs:
+ code buffer contains the new innovation vector gains
+
+ Returns:
+ index = code index (Word16)
+
+ Global Variables Used:
+ Overflow = overflow flag (Flag)
+
+ Local Variables Needed:
+ None
+
+ ------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function searches a 9 bit algebraic codebook containing 2 pulses in a
+ frame of 40 samples.
+
+ The code length is 40, containing 2 nonzero pulses: i0...i1. All pulses can
+ have two possible amplitudes: +1 or -1. Pulse i0 can have 8 possible positions,
+ pulse i1 can have 8 positions. Also coded is which track pair should be used,
+ i.e. first or second pair. Where each pair contains 2 tracks.
+
+ First subframe:
+ first i0 : 0, 5, 10, 15, 20, 25, 30, 35.
+ i1 : 2, 7, 12, 17, 22, 27, 32, 37.
+ second i0 : 1, 6, 11, 16, 21, 26, 31, 36.
+ i1 : 3, 8, 13, 18, 23, 28, 33, 38.
+
+ Second subframe:
+ first i0 : 0, 5, 10, 15, 20, 25, 30, 35.
+ i1 : 3, 8, 13, 18, 23, 28, 33, 38.
+ second i0 : 2, 7, 12, 17, 22, 27, 32, 37.
+ i1 : 4, 9, 14, 19, 24, 29, 34, 39.
+
+ Third subframe:
+ first i0 : 0, 5, 10, 15, 20, 25, 30, 35.
+ i1 : 2, 7, 12, 17, 22, 27, 32, 37.
+ second i0 : 1, 6, 11, 16, 21, 26, 31, 36.
+ i1 : 4, 9, 14, 19, 24, 29, 34, 39.
+
+ Fourth subframe:
+ first i0 : 0, 5, 10, 15, 20, 25, 30, 35.
+ i1 : 3, 8, 13, 18, 23, 28, 33, 38.
+ second i0 : 1, 6, 11, 16, 21, 26, 31, 36.
+ i1 : 4, 9, 14, 19, 24, 29, 34, 39.
+
+ ------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ None
+
+ ------------------------------------------------------------------------------
+ REFERENCES
+
+ [1] c2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
+
+ ------------------------------------------------------------------------------
+ PSEUDO-CODE
+
+ Word16 code_2i40_9bits(
+ Word16 subNr, // i : subframe number
+ Word16 x[], // i : target vector
+ Word16 h[], // i : impulse response of weighted synthesis filter
+ // h[-L_subfr..-1] must be set to zero.
+ Word16 T0, // i : Pitch lag
+ Word16 pitch_sharp, // i : Last quantized pitch gain
+ Word16 code[], // o : Innovative codebook
+ Word16 y[], // o : filtered fixed codebook excitation
+ Word16 * sign // o : Signs of 2 pulses
+ )
+ {
+ Word16 codvec[NB_PULSE];
+ Word16 dn[L_CODE], dn2[L_CODE], dn_sign[L_CODE];
+ Word16 rr[L_CODE][L_CODE];
+ Word16 i, index, sharp;
+
+ sharp = shl(pitch_sharp, 1);
+ if (sub(T0, L_CODE) < 0)
+ for (i = T0; i < L_CODE; i++) {
+ h[i] = add(h[i], mult(h[i - T0], sharp));
+ }
+ cor_h_x(h, x, dn, 1);
+ set_sign(dn, dn_sign, dn2, 8); // dn2[] not used in this codebook search
+ cor_h(h, dn_sign, rr);
+ search_2i40(subNr, dn, rr, codvec);
+ index = build_code(subNr, codvec, dn_sign, code, h, y, sign);
+
+ *-----------------------------------------------------------------*
+ * Compute innovation vector gain. *
+ * Include fixed-gain pitch contribution into code[]. *
+ *-----------------------------------------------------------------*
+
+ if (sub(T0, L_CODE) < 0)
+ for (i = T0; i < L_CODE; i++) {
+ code[i] = add(code[i], mult(code[i - T0], sharp));
+ }
+ return index;
+ }
+
+ ------------------------------------------------------------------------------
+ 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]
+
+ ------------------------------------------------------------------------------
+ */
+
+ Word16 code_2i40_9bits(
+ Word16 subNr, /* i : subframe number */
+ Word16 x[], /* i : target vector */
+ Word16 h[], /* i : impulse response of weighted synthesis */
+ /* filter h[-L_subfr..-1] must be set to 0. */
+ Word16 T0, /* i : Pitch lag */
+ Word16 pitch_sharp, /* i : Last quantized pitch gain */
+ Word16 code[], /* o : Innovative codebook */
+ Word16 y[], /* o : filtered fixed codebook excitation */
+ Word16 * sign, /* o : Signs of 2 pulses */
+ Flag * pOverflow /* o : Flag set when overflow occurs */
+ )
+ {
+ Word16 codvec[NB_PULSE];
+ Word16 dn[L_CODE];
+ Word16 dn2[L_CODE];
+ Word16 dn_sign[L_CODE];
+ Word16 rr[L_CODE][L_CODE];
+
+ register Word16 i;
+
+ Word16 index;
+ Word16 sharp;
+ Word16 temp;
+ Word32 L_temp;
+
+ L_temp = ((Word32) pitch_sharp) << 1;
+
+ /* Check for overflow condition */
+ if (L_temp != (Word32)((Word16) L_temp))
+ {
+ *(pOverflow) = 1;
+ sharp = (pitch_sharp > 0) ? MAX_16 : MIN_16;
+ }
+ else
+ {
+ sharp = (Word16) L_temp;
+ }
+
+ if (T0 < L_CODE)
+ {
+ for (i = T0; i < L_CODE; i++)
+ {
+ temp =
+ mult(
+ *(h + i - T0),
+ sharp,
+ pOverflow);
+
+ *(h + i) =
+ add(
+ *(h + i),
+ temp,
+ pOverflow);
+ }
+ }
+
+ cor_h_x(
+ h,
+ x,
+ dn,
+ 1,
+ pOverflow);
+
+ /* dn2[] not used in this codebook search */
+
+ set_sign(
+ dn,
+ dn_sign,
+ dn2,
+ 8);
+
+ cor_h(
+ h,
+ dn_sign,
+ rr,
+ pOverflow);
+
+ search_2i40(
+ subNr,
+ dn,
+ rr,
+ codvec,
+ pOverflow);
+
+ index =
+ build_code(
+ subNr,
+ codvec,
+ dn_sign,
+ code,
+ h,
+ y,
+ sign,
+ pOverflow);
+
+ /*-----------------------------------------------------------------*
+ * Compute innovation vector gain. *
+ * Include fixed-gain pitch contribution into code[]. *
+ *-----------------------------------------------------------------*/
+
+ if (T0 < L_CODE)
+ {
+ for (i = T0; i < L_CODE; i++)
+ {
+ temp =
+ mult(
+ *(code + i - T0),
+ sharp,
+ pOverflow);
+
+ *(code + i) =
+ add(
+ *(code + i),
+ temp,
+ pOverflow);
+ }
+ }
+
+ return(index);
+ }
+
+ /****************************************************************************/
+
+
+ /*
+ ------------------------------------------------------------------------------
+ FUNCTION NAME: search_2i40
+ ------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ subNr = subframe number (Word16)
+ dn = vector containing the correlation between target and the impulse
+ response of the weighted synthesis filter (Word16)
+ rr = autocorrelation matrix (Word16)
+ codvec = algebraic codebook vector (Word16)
+
+ Outputs:
+ codvec contains the newly calculated codevectors
+
+ Returns:
+ None
+
+ Global Variables Used:
+ None
+
+ Local Variables Needed:
+ startPos = table containing the start positions used by fixed codebook
+ routines (const Word16)
+
+ ------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function searches the best codevector and determines the positions of
+ the 2 pulses in the 40-sample frame.
+
+ ------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ None
+
+ ------------------------------------------------------------------------------
+ REFERENCES
+
+ [1] c2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
+
+ ------------------------------------------------------------------------------
+ PSEUDO-CODE
+
+ static void search_2i40(
+ Word16 subNr, // i : subframe number
+ Word16 dn[], // i : correlation between target and h[]
+ Word16 rr[][L_CODE], // i : matrix of autocorrelation
+ Word16 codvec[] // o : algebraic codebook vector
+ )
+ {
+ Word16 i0, i1;
+ Word16 ix = 0; // initialization only needed to keep gcc silent
+ Word16 track1, ipos[NB_PULSE];
+ Word16 psk, ps0, ps1, sq, sq1;
+ Word16 alpk, alp, alp_16;
+ Word32 s, alp0, alp1;
+ Word16 i;
+
+ psk = -1;
+ alpk = 1;
+ for (i = 0; i < NB_PULSE; i++)
+ {
+ codvec[i] = i;
+ }
+
+ for (track1 = 0; track1 < 2; track1++) {
+ // fix starting position
+
+ ipos[0] = startPos[subNr*2+8*track1];
+ ipos[1] = startPos[subNr*2+1+8*track1];
+
+
+ *----------------------------------------------------------------*
+ * i0 loop: try 8 positions. *
+ *----------------------------------------------------------------*
+
+ for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP) {
+
+ ps0 = dn[i0];
+ alp0 = L_mult(rr[i0][i0], _1_4);
+
+ *----------------------------------------------------------------*
+ * i1 loop: 8 positions. *
+ *----------------------------------------------------------------*
+
+ sq = -1;
+ alp = 1;
+ ix = ipos[1];
+
+ *-------------------------------------------------------------------*
+ * These index have low complexity address computation because *
+ * they are, in fact, pointers with fixed increment. For example, *
+ * "rr[i0][i2]" is a pointer initialized to "&rr[i0][ipos[2]]" *
+ * and incremented by "STEP". *
+ *-------------------------------------------------------------------*
+
+ for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP) {
+ ps1 = add(ps0, dn[i1]); // idx increment = STEP
+
+ // alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1];
+
+ alp1 = L_mac(alp0, rr[i1][i1], _1_4); // idx incr = STEP
+ alp1 = L_mac(alp1, rr[i0][i1], _1_2); // idx incr = STEP
+
+ sq1 = mult(ps1, ps1);
+
+ alp_16 = pv_round(alp1);
+
+ s = L_msu(L_mult(alp, sq1), sq, alp_16);
+
+ if (s > 0) {
+ sq = sq1;
+ alp = alp_16;
+ ix = i1;
+ }
+ }
+
+ *----------------------------------------------------------------*
+ * memorise codevector if this one is better than the last one. *
+ *----------------------------------------------------------------*
+
+ s = L_msu(L_mult(alpk, sq), psk, alp);
+
+ if (s > 0) {
+ psk = sq;
+ alpk = alp;
+ codvec[0] = i0;
+ codvec[1] = ix;
+ }
+ }
+ }
+
+ return;
+ }
+
+ ------------------------------------------------------------------------------
+ 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 search_2i40(
+ Word16 subNr, /* i : subframe number */
+ Word16 dn[], /* i : correlation between target and h[] */
+ Word16 rr[][L_CODE], /* i : matrix of autocorrelation */
+ Word16 codvec[], /* o : algebraic codebook vector */
+ Flag * pOverflow /* o : Flag set when overflow occurs */
+ )
+ {
+ register Word16 i0;
+ register Word16 i1;
+ Word16 ix = 0; /* initialization only needed to keep gcc silent */
+ register Word16 track1;
+ Word16 ipos[NB_PULSE];
+ Word16 psk;
+ Word16 ps0;
+ Word16 ps1;
+ Word16 sq;
+ Word16 sq1;
+ Word16 alpk;
+ Word16 alp;
+ Word16 alp_16;
+ Word32 s;
+ Word32 alp0;
+ Word32 alp1;
+ register Word16 i;
+ Word32 L_temp;
+ Word16 *p_codvec = &codvec[0];
+
+ OSCL_UNUSED_ARG(pOverflow);
+
+ psk = -1;
+ alpk = 1;
+
+ /* Unrolled the following FOR loop to save MIPS */
+ /* for (i = 0; i < NB_PULSE; i++) */
+ /* { */
+ /* *(codvec + i) = i; */
+ /* } */
+
+ *(p_codvec++) = 0;
+ *(p_codvec) = 1;
+
+ for (track1 = 0; track1 < 2; track1++)
+ {
+ /* fix starting position */
+
+ i = (subNr << 1) + (track1 << 3);
+ *ipos = *(startPos + i);
+ *(ipos + 1) = *(startPos + i + 1);
+
+
+ /*----------------------------------------------------------*
+ * i0 loop: try 8 positions. *
+ *----------------------------------------------------------*/
+
+ for (i0 = *ipos; i0 < L_CODE; i0 += STEP)
+ {
+ ps0 = *(dn + i0);
+
+ /* Left shift by 1 converts integer product to */
+ /* fractional product. */
+ alp0 = (Word32) rr[i0][i0] << 14;
+
+ /*--------------------------------------------------*
+ * i1 loop: 8 positions. *
+ *--------------------------------------------------*/
+
+ sq = -1;
+ alp = 1;
+ ix = *(ipos + 1);
+
+ /*--------------------------------------------------*
+ * These index have low complexity address *
+ * computation because they are, in fact, pointers *
+ * with fixed increment. For example, "rr[i0][i2]" *
+ * is a pointer initialized to "&rr[i0][ipos[2]]" *
+ * and incremented by "STEP". *
+ *---------------------------------------------------*/
+
+ for (i1 = *(ipos + 1); i1 < L_CODE; i1 += STEP)
+ {
+ /* idx increment = STEP */
+ /* ps1 = add(ps0, *(dn + i1), pOverflow); */
+ ps1 = ps0 + dn[i1];
+
+ /* alp1 = alp0+rr[i0][i1]+1/2*rr[i1][i1]; */
+
+ /* idx incr = STEP */
+ /* Extra left shift by 1 converts integer */
+ /* product to fractional product */
+ /* alp1 = L_add(alp0, s, pOverflow); */
+ alp1 = alp0 + ((Word32) rr[i1][i1] << 14);
+
+ /* idx incr = STEP */
+ /* Extra left shift by 1 converts integer */
+ /* product to fractional product */
+ /* alp1 = L_add(alp1, s, pOverflow); */
+ alp1 += (Word32) rr[i0][i1] << 15;
+
+ /* sq1 = mult(ps1, ps1, pOverflow); */
+ sq1 = (Word16)(((Word32) ps1 * ps1) >> 15);
+
+ /* alp_16 = pv_round(alp1, pOverflow); */
+ alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16);
+
+ /* L_temp = L_mult(alp, sq1, pOverflow); */
+ L_temp = ((Word32) alp * sq1) << 1;
+
+ /* s = L_msu(L_temp, sq, alp_16, pOverflow); */
+ s = L_temp - (((Word32) sq * alp_16) << 1);
+
+ if (s > 0)
+ {
+ sq = sq1;
+ alp = alp_16;
+ ix = i1;
+ }
+ }
+
+ /* memorize codevector if this one is better than the last one. */
+
+ /* L_temp = L_mult(alpk, sq, pOverflow); */
+ L_temp = ((Word32) alpk * sq) << 1;
+
+ /* s = L_msu(L_temp, psk, alp, pOverflow); */
+ s = L_temp - (((Word32) psk * alp) << 1);
+
+ if (s > 0)
+ {
+ psk = sq;
+ alpk = alp;
+ p_codvec = &codvec[0];
+ *(p_codvec++) = i0;
+ *(p_codvec) = ix;
+ }
+ }
+ }
+
+ return;
+ }
+
+ /****************************************************************************/
+
+ /*
+ ------------------------------------------------------------------------------
+ FUNCTION NAME: Test_search_2i40
+ ------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ subNr = subframe number (Word16)
+ dn = vector containing the correlation between target and the impulse
+ response of the weighted synthesis filter (Word16)
+ rr = autocorrelation matrix (Word16)
+ codvec = algebraic codebook vector (Word16)
+
+ Outputs:
+ codvec contains the newly calculated codevectors
+
+ Returns:
+ None
+
+ Global Variables Used:
+ None
+
+ Local Variables Needed:
+ startPos = table containing the start positions used by fixed codebook
+ routines (const Word16)
+
+ ------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function provides external access to the local function search_2i40.
+
+ ------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ None
+
+ ------------------------------------------------------------------------------
+ REFERENCES
+
+ [1] c2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
+
+ ------------------------------------------------------------------------------
+ PSEUDO-CODE
+
+ CALL search_2i40 ( subNr = subNr
+ dn = dn
+ rr = rr
+ codvec = codvec )
+ MODIFYING(nothing)
+ RETURNING(nothing)
+
+ ------------------------------------------------------------------------------
+ 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 Test_search_2i40(
+ Word16 subNr, /* i : subframe number */
+ Word16 dn[], /* i : correlation between target and h[] */
+ Word16 rr[][L_CODE], /* i : matrix of autocorrelation */
+ Word16 codvec[], /* o : algebraic codebook vector */
+ Flag * pOverflow /* o : Flag set when overflow occurs */
+ )
+ {
+ /*----------------------------------------------------------------------------
+ CALL search_2i40 ( subNr = subNr
+ dn = dn
+ rr = rr
+ codvec = codvec )
+ MODIFYING(nothing)
+ RETURNING(nothing)
+ ----------------------------------------------------------------------------*/
+ search_2i40(
+ subNr,
+ dn,
+ rr,
+ codvec,
+ pOverflow);
+
+ return;
+ }
+
+ /****************************************************************************/
+
+ /*
+ ------------------------------------------------------------------------------
+ FUNCTION NAME: build_code
+ ------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ subNr = subframe number (Word16)
+ codvec = vector containing the position of pulses (Word16)
+ dn_sign = vector containing the sign of pulses (Word16)
+ cod = innovative code vector (Word16)
+ h = vector containing the impulse response of the weighted
+ synthesis filter (Word16)
+ y = vector containing the filtered innovative code (Word16)
+ sign = vector containing the sign of 2 pulses (Word16)
+
+ Outputs:
+ cod vector contains the new innovative code
+ y vector contains the new filtered innovative code
+ sign vector contains the sign of 2 pulses
+
+ Returns:
+ indx = codebook index (Word16)
+
+ Global Variables Used:
+ None
+
+ Local Variables Needed:
+ trackTable = table used for tracking codewords (Word16)
+
+ ------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function builds the codeword, the filtered codeword and index of the
+ codevector, based on the signs and positions of 2 pulses.
+
+ ------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ None
+
+ ------------------------------------------------------------------------------
+ REFERENCES
+
+ [1] c2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
+
+ ------------------------------------------------------------------------------
+ PSEUDO-CODE
+
+ static Word16 build_code(
+ Word16 subNr, // i : subframe number
+ Word16 codvec[], // i : position of pulses
+ Word16 dn_sign[], // i : sign of pulses
+ Word16 cod[], // o : innovative code vector
+ Word16 h[], // i : impulse response of weighted synthesis filter
+ Word16 y[], // o : filtered innovative code
+ Word16 sign[] // o : sign of 2 pulses
+ )
+ {
+ Word16 i, j, k, track, first, index, _sign[NB_PULSE], indx, rsign;
+ Word16 *p0, *p1, *pt;
+ Word32 s;
+ static Word16 trackTable[4*5] = {
+ 0, 1, 0, 1, -1, // subframe 1; track to code; -1 do not code this position
+ 0, -1, 1, 0, 1, // subframe 2
+ 0, 1, 0, -1, 1, // subframe 3
+ 0, 1, -1, 0, 1};// subframe 4
+
+ pt = &trackTable[add(subNr, shl(subNr, 2))];
+
+ for (i = 0; i < L_CODE; i++) {
+ cod[i] = 0;
+ }
+
+ indx = 0;
+ rsign = 0;
+ for (k = 0; k < NB_PULSE; k++) {
+ i = codvec[k]; // read pulse position
+ j = dn_sign[i]; // read sign
+
+ index = mult(i, 6554); // index = pos/5
+ // track = pos%5
+ track = sub(i, extract_l(L_shr(L_mult(index, 5), 1)));
+
+ first = pt[track];
+
+ if (first == 0) {
+ if (k == 0) {
+ track = 0;
+ } else {
+ track = 1;
+ index = shl(index, 3);
+ }
+ } else {
+ if (k == 0) {
+ track = 0;
+ index = add(index, 64); // table bit is MSB
+ } else {
+ track = 1;
+ index = shl(index, 3);
+ }
+ }
+
+ if (j > 0) {
+ cod[i] = 8191;
+ _sign[k] = 32767;
+ rsign = add(rsign, shl(1, track));
+ } else {
+ cod[i] = -8192;
+ _sign[k] = (Word16) - 32768L;
+ }
+
+ indx = add(indx, index);
+ }
+ *sign = rsign;
+
+ p0 = h - codvec[0];
+ p1 = h - codvec[1];
+
+ for (i = 0; i < L_CODE; i++) {
+ s = 0;
+ s = L_mac(s, *p0++, _sign[0]);
+ s = L_mac(s, *p1++, _sign[1]);
+ y[i] = pv_round(s);
+ }
+
+ return indx;
+ }
+
+ ------------------------------------------------------------------------------
+ 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 Word16 build_code(
+ Word16 subNr, /* i : subframe number */
+ Word16 codvec[], /* i : position of pulses */
+ Word16 dn_sign[], /* i : sign of pulses */
+ Word16 cod[], /* o : innovative code vector */
+ Word16 h[], /* i : impulse response of weighted synthesis */
+ /* filter */
+ Word16 y[], /* o : filtered innovative code */
+ Word16 sign[], /* o : sign of 2 pulses */
+ Flag *pOverflow /* o : Flag set when overflow occurs */
+ )
+ {
+ register Word16 i;
+ register Word16 j;
+ register Word16 k;
+ register Word16 track;
+ register Word16 first;
+ register Word16 index;
+ register Word16 rsign;
+ Word16 indx;
+ Word16 _sign[NB_PULSE];
+ Word16 *p0;
+ Word16 *p1;
+
+ const Word16 *pt;
+
+ Word32 s;
+
+ pt = trackTable + subNr + (subNr << 2);
+
+ for (i = 0; i < L_CODE; i++)
+ {
+ *(cod + i) = 0;
+ }
+
+ indx = 0;
+ rsign = 0;
+
+ for (k = 0; k < NB_PULSE; k++)
+ {
+ i = *(codvec + k); /* read pulse position */
+ j = *(dn_sign + i); /* read sign */
+
+ s = ((Word32)(i * 6554)) >> 15;
+ index = (Word16) s; /* index = pos/5 */
+
+ track = i - (5 * index); /* track = pos%5 */
+
+ first = *(pt + track);
+
+
+ if (k == 0)
+ {
+ track = 0;
+
+ if (first != 0)
+ {
+ index += 64; /* table bit is MSB */
+ }
+ }
+ else
+ {
+ track = 1;
+ index <<= 3;
+ }
+
+ if (j > 0)
+ {
+ *(cod + i) = 8191;
+ *(_sign + k) = 32767;
+ rsign += (1 << track);
+ }
+ else
+ {
+ *(cod + i) = ~(8192) + 1;
+ *(_sign + k) = (Word16)(~(32768) + 1);
+ }
+
+ indx += index;
+ }
+
+ *sign = rsign;
+
+ p0 = h - *codvec;
+ p1 = h - *(codvec + 1);
+
+ for (i = 0; i < L_CODE; i++)
+ {
+ s = 0;
+ s =
+ L_mult(
+ *p0++,
+ *_sign,
+ pOverflow);
+
+ s =
+ L_mac(
+ s,
+ *p1++,
+ *(_sign + 1),
+ pOverflow);
+
+ *(y + i) =
+ pv_round(
+ s,
+ pOverflow);
+ }
+
+ return(indx);
+ }
+
+ /****************************************************************************/
+
+ /*
+ ------------------------------------------------------------------------------
+ FUNCTION NAME: Test_build_code
+ ------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ subNr = subframe number (Word16)
+ codvec = vector containing the position of pulses (Word16)
+ dn_sign = vector containing the sign of pulses (Word16)
+ cod = innovative code vector (Word16)
+ h = vector containing the impulse response of the weighted
+ synthesis filter (Word16)
+ y = vector containing the filtered innovative code (Word16)
+ sign = vector containing the sign of 2 pulses (Word16)
+
+ Outputs:
+ cod vector contains the new innovative code
+ y vector contains the new filtered innovative code
+ sign vector contains the sign of 2 pulses
+
+ Returns:
+ indx = codebook index (Word16)
+
+ Global Variables Used:
+ None
+
+ Local Variables Needed:
+ trackTable = table used for tracking codewords (Word16)
+
+ ------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function provides external access to the local function build_code.
+
+ ------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ None
+
+ ------------------------------------------------------------------------------
+ REFERENCES
+
+ [1] c2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
+
+ ------------------------------------------------------------------------------
+ PSEUDO-CODE
+
+ CALL build_code ( subNr = subNr
+ codvec = codvec
+ dn_sign = dn_sign
+ cod = cod
+ h = h
+ y = y
+ sign = sign )
+ MODIFYING(nothing)
+ RETURNING(indx)
+
+ ------------------------------------------------------------------------------
+ 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]
+
+ ------------------------------------------------------------------------------
+ */
+
+ Word16 Test_build_code(
+ Word16 subNr, /* i : subframe number */
+ Word16 codvec[], /* i : position of pulses */
+ Word16 dn_sign[], /* i : sign of pulses */
+ Word16 cod[], /* o : innovative code vector */
+ Word16 h[], /* i : impulse response of weighted synthesis */
+ /* filter */
+ Word16 y[], /* o : filtered innovative code */
+ Word16 sign[], /* o : sign of 2 pulses */
+ Flag * pOverflow /* o : Flag set when overflow occurs */
+ )
+ {
+ Word16 test_index;
+
+ /*----------------------------------------------------------------------------
+ CALL build_code ( subNr = subNr
+ codvec = codvec
+ dn_sign = dn_sign
+ cod = cod
+ h = h
+ y = y
+ sign = sign )
+ MODIFYING(nothing)
+ RETURNING(indx)
+ ----------------------------------------------------------------------------*/
+ test_index =
+ build_code(
+ subNr,
+ codvec,
+ dn_sign,
+ cod,
+ h,
+ y,
+ sign,
+ pOverflow);
+
+ return(test_index);
+ }
+
+#ifdef __cplusplus
+}
+#endif