summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/amrnb/enc/src/c1035pf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/codecs/amrnb/enc/src/c1035pf.cpp')
-rw-r--r--media/libstagefright/codecs/amrnb/enc/src/c1035pf.cpp676
1 files changed, 676 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/amrnb/enc/src/c1035pf.cpp b/media/libstagefright/codecs/amrnb/enc/src/c1035pf.cpp
new file mode 100644
index 0000000..d95995c
--- /dev/null
+++ b/media/libstagefright/codecs/amrnb/enc/src/c1035pf.cpp
@@ -0,0 +1,676 @@
+/* ------------------------------------------------------------------
+ * 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/c1035pf.c
+ Functions: q_p
+ build_code
+ code_10i40_35bits
+
+
+ Date: 09/28/2000
+
+------------------------------------------------------------------------------
+ REVISION HISTORY
+
+ Description: Updated template. Cleaned up code. Passing in a pointer to
+ overflow flag for build_code() and code_10i40_35bits() functions.
+ Removed unnecessary header files.
+
+ Description:
+ 1. Eliminated unused include files.
+ 2. Replaced array addressing by pointers
+ 3. Eliminated math operations that unnecessary checked for
+ saturation
+ 4. Replaced for-loops with memset()
+
+ Description: Changed function name to pv_round to avoid conflict with
+ round function in C standard library.
+
+ Description: Replaced OSCL mem type functions and eliminated include
+ files that now are chosen by OSCL definitions
+
+ Description: Replaced "int" and/or "char" with OSCL defined types.
+
+ Description:
+
+------------------------------------------------------------------------------
+ MODULE DESCRIPTION
+
+ This file contains the function that searches a 35 bit algebraic codebook
+ containing 10 pulses in a frame of 40 samples.
+
+------------------------------------------------------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+#include <string.h>
+
+#include "c1035pf.h"
+#include "cnst.h"
+#include "basic_op.h"
+#include "inv_sqrt.h"
+#include "set_sign.h"
+#include "cor_h.h"
+#include "cor_h_x.h"
+#include "s10_8pf.h"
+
+/*----------------------------------------------------------------------------
+; MACROS
+; [Define module specific macros here]
+----------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+; DEFINES
+; [Include all pre-processor statements here. Include conditional
+; compile variables also.]
+----------------------------------------------------------------------------*/
+#define NB_PULSE 10
+
+/*----------------------------------------------------------------------------
+; LOCAL FUNCTION DEFINITIONS
+; [List function prototypes here]
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL VARIABLE DEFINITIONS
+; [Variable declaration - defined here and used outside this module]
+----------------------------------------------------------------------------*/
+
+/*
+------------------------------------------------------------------------------
+ FUNCTION NAME: q_p
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ pShift_reg = pointer to Old CN generator shift register state (Word32)
+ no_bits = Number of bits (Word16)
+
+ Outputs:
+ pShift_reg -> Updated CN generator shift register state
+
+ Returns:
+ noise_bits = Generated random integer value (Word16)
+
+ Global Variables Used:
+ None
+
+ Local Variables Needed:
+ None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This is a local function that determnes the index of the pulses by looking up
+ the gray encoder table
+
+------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ None
+
+------------------------------------------------------------------------------
+ REFERENCES
+
+ c1035pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
+
+------------------------------------------------------------------------------
+ PSEUDO-CODE
+
+void q_p (
+ Word16 *ind, // Pulse position
+ Word16 n // Pulse number
+)
+{
+ Word16 tmp;
+
+ tmp = *ind;
+
+ if (sub (n, 5) < 0)
+ {
+ *ind = (tmp & 0x8) | gray[tmp & 0x7];
+ }
+ else
+ {
+ *ind = gray[tmp & 0x7];
+ }
+}
+
+------------------------------------------------------------------------------
+ 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]
+
+------------------------------------------------------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+; FUNCTION CODE
+----------------------------------------------------------------------------*/
+
+void q_p(
+ Word16 *pInd, /* Pulse position */
+ Word16 n /* Pulse number */
+)
+{
+ Word16 tmp;
+
+ tmp = *pInd;
+
+ if (n < 5)
+ {
+ *pInd = (tmp & 0x8) | gray[tmp & 0x7];
+ }
+ else
+ {
+ *pInd = gray[tmp & 0x7];
+ }
+}
+
+/*
+------------------------------------------------------------------------------
+ FUNCTION NAME: build_code
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ pSeed = pointer to the Old CN generator shift register state (Word32)
+ n_param = Number of parameters to randomize (Word16)
+ param_size_table = table holding paameter sizes (Word16)
+ param[] = array to hold CN generated paramters (Word16)
+ pOverflow = pointer to overflow flag (Flag)
+
+ Outputs:
+ param[] = CN generated parameters (Word16)
+ pSeed = Updated CN generator shift register state (Word16)
+ pOverflow -> 1 if overflow occured
+
+ Returns:
+ None
+
+ Global Variables Used:
+ None
+
+ Local Variables Needed:
+ None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function builds the codeword, the filtered codeword and index of the
+ codevector, based on the signs and positions of 10 pulses.
+------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ None
+
+------------------------------------------------------------------------------
+ REFERENCES
+
+ c1035pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
+
+------------------------------------------------------------------------------
+ PSEUDO-CODE
+static void build_code (
+ Word16 codvec[], // (i) : position of pulses
+ Word16 sign[], // (i) : sign of d[n]
+ Word16 cod[], // (o) : innovative code vector
+ Word16 h[], // (i) : impulse response of weighted synthesis filter
+ Word16 y[], // (o) : filtered innovative code
+ Word16 indx[] // (o) : index of 10 pulses (sign+position)
+)
+{
+ Word16 i, j, k, track, index, _sign[NB_PULSE];
+ Word16 *p0, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9;
+ Word32 s;
+
+ for (i = 0; i < L_CODE; i++)
+ {
+ cod[i] = 0;
+ }
+ for (i = 0; i < NB_TRACK; i++)
+ {
+ indx[i] = -1;
+ }
+
+ for (k = 0; k < NB_PULSE; k++)
+ {
+ // read pulse position
+ i = codvec[k];
+ // read sign
+ j = sign[i];
+
+ index = mult (i, 6554); // index = pos/5
+ // track = pos%5
+ track = sub (i, extract_l (L_shr (L_mult (index, 5), 1)));
+
+ if (j > 0)
+ {
+ cod[i] = add (cod[i], 4096);
+ _sign[k] = 8192;
+
+ }
+ else
+ {
+ cod[i] = sub (cod[i], 4096);
+ _sign[k] = -8192;
+ index = add (index, 8);
+ }
+
+ if (indx[track] < 0)
+ {
+ indx[track] = index;
+ }
+ else
+ {
+ if (((index ^ indx[track]) & 8) == 0)
+ {
+ // sign of 1st pulse == sign of 2nd pulse
+
+ if (sub (indx[track], index) <= 0)
+ {
+ indx[track + 5] = index;
+ }
+ else
+ {
+ indx[track + 5] = indx[track];
+ indx[track] = index;
+ }
+ }
+ else
+ {
+ // sign of 1st pulse != sign of 2nd pulse
+
+ if (sub ((Word16)(indx[track] & 7), (Word16)(index & 7)) <= 0)
+ {
+ indx[track + 5] = indx[track];
+ indx[track] = index;
+ }
+ else
+ {
+ indx[track + 5] = index;
+ }
+ }
+ }
+ }
+
+ p0 = h - codvec[0];
+ p1 = h - codvec[1];
+ p2 = h - codvec[2];
+ p3 = h - codvec[3];
+ p4 = h - codvec[4];
+ p5 = h - codvec[5];
+ p6 = h - codvec[6];
+ p7 = h - codvec[7];
+ p8 = h - codvec[8];
+ p9 = h - codvec[9];
+
+ for (i = 0; i < L_CODE; i++)
+ {
+ s = 0;
+ s = L_mac (s, *p0++, _sign[0]);
+ s = L_mac (s, *p1++, _sign[1]);
+ s = L_mac (s, *p2++, _sign[2]);
+ s = L_mac (s, *p3++, _sign[3]);
+ s = L_mac (s, *p4++, _sign[4]);
+ s = L_mac (s, *p5++, _sign[5]);
+ s = L_mac (s, *p6++, _sign[6]);
+ s = L_mac (s, *p7++, _sign[7]);
+ s = L_mac (s, *p8++, _sign[8]);
+ s = L_mac (s, *p9++, _sign[9]);
+ y[i] = pv_round (s);
+ }
+}
+
+------------------------------------------------------------------------------
+ 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]
+
+------------------------------------------------------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+; FUNCTION CODE
+----------------------------------------------------------------------------*/
+static void build_code(
+ Word16 codvec[], /* (i) : position of pulses */
+ Word16 sign[], /* (i) : sign of d[n] */
+ Word16 cod[], /* (o) : innovative code vector */
+ Word16 h[], /* (i) : impulse response of weighted synthesis filter*/
+ Word16 y[], /* (o) : filtered innovative code */
+ Word16 indx[], /* (o) : index of 10 pulses (sign+position) */
+ Flag *pOverflow /* i/o : overflow Flag */
+)
+{
+ Word16 i, k, track, index, _sign[NB_PULSE];
+ Word16 *p0, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9;
+ Word32 s;
+ Word16 temp;
+ Word16 *p__sign;
+ Word16 *p_y;
+ Word16 *p_codvec;
+
+ OSCL_UNUSED_ARG(pOverflow);
+
+ memset(cod, 0, L_CODE*sizeof(*cod));
+ memset(indx, 0xFF, NB_TRACK*sizeof(*indx));
+
+ p__sign = _sign;
+
+ p0 = &codvec[0];
+
+ for (k = 0; k < NB_PULSE; k++)
+ {
+ /* read pulse position */
+ i = *(p0++);
+ /* read sign */
+
+ index = ((Word32)i * 6554) >> 15; /* index = pos/5 */
+
+ /* track = pos%5 */
+ /* track = sub (i, extract_l (L_shr (L_mult (index, 5), 1))); */
+ track = i - (index * 5);
+
+ if (sign[i] > 0)
+ {
+ cod[i] += 4096;
+ *(p__sign++) = 8192;
+
+ }
+ else
+ {
+ cod[i] -= 4096;
+ *(p__sign++) = -8192;
+ /* index = add (index, 8); */
+ index += 8;
+ }
+
+ p1 = &indx[track];
+
+ temp = *p1;
+
+ if (temp < 0)
+ {
+ *p1 = index;
+ }
+ else
+ {
+ if (((index ^ temp) & 8) == 0)
+ {
+ /* sign of 1st pulse == sign of 2nd pulse */
+
+ /* if (sub (indx[track], index) <= 0) */
+ if (temp <= index)
+ {
+ *(p1 + 5) = index;
+ }
+ else
+ {
+ *(p1 + 5) = temp;
+ *p1 = index;
+ }
+ }
+ else
+ {
+ /* sign of 1st pulse != sign of 2nd pulse */
+
+ /* if (sub ((Word16)(indx[track] & 7), (Word16)(index & 7)) <= 0) */
+ if ((temp & 7) <= (index & 7))
+ {
+ *(p1 + 5) = temp;
+ *p1 = index;
+ }
+ else
+ {
+ *(p1 + 5) = index;
+ }
+ }
+ }
+ }
+
+ p_codvec = &codvec[0];
+
+ p0 = h - *(p_codvec++);
+ p1 = h - *(p_codvec++);
+ p2 = h - *(p_codvec++);
+ p3 = h - *(p_codvec++);
+ p4 = h - *(p_codvec++);
+ p5 = h - *(p_codvec++);
+ p6 = h - *(p_codvec++);
+ p7 = h - *(p_codvec++);
+ p8 = h - *(p_codvec++);
+ p9 = h - *(p_codvec++);
+
+ p_y = y;
+
+ for (i = L_CODE; i != 0; i--)
+ {
+ p__sign = _sign;
+
+ s = (*p0++ * *(p__sign++)) >> 7;
+ s += (*p1++ * *(p__sign++)) >> 7;
+ s += (*p2++ * *(p__sign++)) >> 7;
+ s += (*p3++ * *(p__sign++)) >> 7;
+ s += (*p4++ * *(p__sign++)) >> 7;
+ s += (*p5++ * *(p__sign++)) >> 7;
+ s += (*p6++ * *(p__sign++)) >> 7;
+ s += (*p7++ * *(p__sign++)) >> 7;
+ s += (*p8++ * *(p__sign++)) >> 7;
+ s += (*p9++ * *(p__sign++)) >> 7;
+
+ *(p_y++) = (s + 0x080) >> 8;
+ }
+
+}
+
+/*
+------------------------------------------------------------------------------
+ FUNCTION NAME: code_10i40_35bits
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ pSeed = pointer to the Old CN generator shift register state (Word32)
+ n_param = Number of parameters to randomize (Word16)
+ param_size_table = table holding paameter sizes (Word16)
+ param[] = array to hold CN generated paramters (Word16)
+ pOverflow = pointer to overflow flag (Flag)
+
+ Outputs:
+ param[] = CN generated parameters (Word16)
+ pSeed = Updated CN generator shift register state (Word16)
+ pOverflow -> 1 if overflow occured
+
+ Returns:
+ None
+
+ Global Variables Used:
+ None
+
+ Local Variables Needed:
+ None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function searches a 35 bit algebraic codebook containing 10 pulses in a
+ frame of 40 samples.
+
+ The code contains 10 nonzero pulses: i0...i9.
+ All pulses can have two possible amplitudes: +1 or -1.
+ The 40 positions in a subframe are divided into 5 tracks of
+ interleaved positions. Each track contains two pulses.
+ The pulses can have the following possible positions:
+
+ i0, i5 : 0, 5, 10, 15, 20, 25, 30, 35.
+ i1, i6 : 1, 6, 11, 16, 21, 26, 31, 36.
+ i2, i7 : 2, 7, 12, 17, 22, 27, 32, 37.
+ i3, i8 : 3, 8, 13, 18, 23, 28, 33, 38.
+ i4, i9 : 4, 9, 14, 19, 24, 29, 34, 39.
+
+ Each pair of pulses require 1 bit for their signs and 6 bits for their
+ positions (3 bits + 3 bits). This results in a 35 bit codebook.
+ The function determines the optimal pulse signs and positions, builds
+ the codevector, and computes the filtered codevector.
+
+------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ None
+
+------------------------------------------------------------------------------
+ REFERENCES
+
+ c1035pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
+
+------------------------------------------------------------------------------
+ PSEUDO-CODE
+void code_10i40_35bits (
+ Word16 x[], // (i) : target vector
+ Word16 cn[], // (i) : residual after long term prediction
+ Word16 h[], // (i) : impulse response of weighted synthesis filter
+ // h[-L_subfr..-1] must be set to zero
+ Word16 cod[], // (o) : algebraic (fixed) codebook excitation
+ Word16 y[], // (o) : filtered fixed codebook excitation
+ Word16 indx[] // (o) : index of 10 pulses (sign + position)
+)
+{
+ Word16 ipos[NB_PULSE], pos_max[NB_TRACK], codvec[NB_PULSE];
+ Word16 dn[L_CODE], sign[L_CODE];
+ Word16 rr[L_CODE][L_CODE], i;
+
+ cor_h_x (h, x, dn, 2);
+ set_sign12k2 (dn, cn, sign, pos_max, NB_TRACK, ipos, STEP);
+ cor_h (h, sign, rr);
+
+ search_10and8i40 (NB_PULSE, STEP, NB_TRACK,
+ dn, rr, ipos, pos_max, codvec);
+
+ build_code (codvec, sign, cod, h, y, indx);
+ for (i = 0; i < 10; i++)
+ {
+ q_p (&indx[i], i);
+ }
+ 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]
+
+------------------------------------------------------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+; FUNCTION CODE
+----------------------------------------------------------------------------*/
+void code_10i40_35bits(
+ Word16 x[], /* (i) : target vector */
+ Word16 cn[], /* (i) : residual after long term prediction */
+ Word16 h[], /* (i) : impulse response of weighted synthesis filter
+ h[-L_subfr..-1] must be set to zero */
+ Word16 cod[], /* (o) : algebraic (fixed) codebook excitation */
+ Word16 y[], /* (o) : filtered fixed codebook excitation */
+ Word16 indx[], /* (o) : index of 10 pulses (sign + position) */
+ Flag *pOverflow /* (i/o) : overflow Flag */
+)
+{
+ Word16 ipos[NB_PULSE], pos_max[NB_TRACK], codvec[NB_PULSE];
+ Word16 dn[L_CODE], sign[L_CODE];
+ Word16 rr[L_CODE][L_CODE], i;
+
+ cor_h_x(h, x, dn, 2, pOverflow);
+ set_sign12k2(dn, cn, sign, pos_max, NB_TRACK, ipos, STEP, pOverflow);
+ cor_h(h, sign, rr, pOverflow);
+
+ search_10and8i40(NB_PULSE, STEP, NB_TRACK,
+ dn, rr, ipos, pos_max, codvec, pOverflow);
+
+ build_code(codvec, sign, cod, h, y, indx, pOverflow);
+ for (i = 0; i < 10; i++)
+ {
+ q_p(&indx[i], i);
+ }
+ return;
+}
+