summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/amrnb/common/src/q_plsf_3.cpp
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2009-12-08 15:40:06 -0800
committerAndreas Huber <andih@google.com>2009-12-10 12:23:55 -0800
commit4f1efc098cb5791c3e9f483f2af84aef70d2d0a0 (patch)
treea2873e84aed3eecb1198f85954e24cddb1bdc380 /media/libstagefright/codecs/amrnb/common/src/q_plsf_3.cpp
parentc54176addef15699a518b69cd6bbd40ffc95e72e (diff)
downloadframeworks_av-4f1efc098cb5791c3e9f483f2af84aef70d2d0a0.zip
frameworks_av-4f1efc098cb5791c3e9f483f2af84aef70d2d0a0.tar.gz
frameworks_av-4f1efc098cb5791c3e9f483f2af84aef70d2d0a0.tar.bz2
Initial check in of AMR (NB and WB) decoders based on PV source code.
Diffstat (limited to 'media/libstagefright/codecs/amrnb/common/src/q_plsf_3.cpp')
-rw-r--r--media/libstagefright/codecs/amrnb/common/src/q_plsf_3.cpp1226
1 files changed, 1226 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/amrnb/common/src/q_plsf_3.cpp b/media/libstagefright/codecs/amrnb/common/src/q_plsf_3.cpp
new file mode 100644
index 0000000..2b30bf4
--- /dev/null
+++ b/media/libstagefright/codecs/amrnb/common/src/q_plsf_3.cpp
@@ -0,0 +1,1226 @@
+/* ------------------------------------------------------------------
+ * 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/q_plsf_3.c
+ Funtions: Vq_subvec4
+ Test_Vq_subvec4
+ Vq_subvec3
+ Test_Vq_subvec3
+ Q_plsf_3
+
+------------------------------------------------------------------------------
+ REVISION HISTORY
+
+ Description: Updated template used to PV coding template. First attempt at
+ optimizing C code.
+
+ Description: Updated modules per Phase 2/3 review comments. Updated
+ Vq_subvec3 pseudo-code to reflect the new restructured code.
+
+ Description: Added setting of Overflow flag in inlined code.
+
+ Description: Synchronized file with UMTS version 3.2.0. Updated coding
+ template. Removed unnecessary include files.
+
+ Description: Replaced basic_op.h with the header file of the math functions
+ used in the file.
+
+ Description: Made the following changes per comments from Phase 2/3 review:
+ 1. Fixed typecasting issue with TI C compiler.
+ 2. Optimized IF stament in Vq_subvec3() function.
+ 3. Updated copyright year.
+
+ Description: Removed redundancy in the Vq_subvec4 function.
+
+ Description: Updated to accept new parameter, Flag *pOverflow.
+
+ Description: Per review comments, added pOverflow flag description
+ to the input/outputs section.
+
+ Description: Corrected missed Overflow global variables -- changed to
+ proper pOverflow.
+
+ Description: Optimized all functions to further reduce clock cycle usage.
+ Updated copyright year.
+
+ Description: Added left shift by 1 in line 1050 of Q_plsf_3().
+
+ 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: Added #ifdef __cplusplus around extern'ed table.
+
+ Who: Date:
+ Description:
+
+------------------------------------------------------------------------------
+ MODULE DESCRIPTION
+
+ This file contains the functions that perform the quantization of LSF
+ parameters with first order MA prediction and split by 3 vector
+ quantization (split-VQ).
+
+------------------------------------------------------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+
+#include <string.h>
+
+#include "q_plsf.h"
+#include "typedef.h"
+#include "lsp_lsf.h"
+#include "reorder.h"
+#include "lsfwt.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 PAST_RQ_INIT_SIZE 8
+
+ /*----------------------------------------------------------------------------
+ ; LOCAL FUNCTION DEFINITIONS
+ ; Function Prototype declaration
+ ----------------------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------------------
+ ; LOCAL VARIABLE DEFINITIONS
+ ; Variable declaration - defined here and used outside this module
+ ----------------------------------------------------------------------------*/
+
+ /*----------------------------------------------------------------------------
+ ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
+ ; Declare variables used in this module but defined elsewhere
+ ----------------------------------------------------------------------------*/
+ /* Codebooks of LSF prediction residual */
+ extern const Word16 mean_lsf_3[];
+
+ extern const Word16 pred_fac_3[];
+
+ extern const Word16 dico1_lsf_3[];
+ extern const Word16 dico2_lsf_3[];
+ extern const Word16 dico3_lsf_3[];
+
+ extern const Word16 mr515_3_lsf[];
+ extern const Word16 mr795_1_lsf[];
+
+ extern const Word16 past_rq_init[];
+
+ /*--------------------------------------------------------------------------*/
+#ifdef __cplusplus
+}
+#endif
+
+/*
+------------------------------------------------------------------------------
+ FUNCTION NAME: Vq_subvec4
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ lsf_r1 = pointer to the first LSF residual vector (Q15) (Word16)
+ dico = pointer to the quantization codebook (Q15) (const Word16)
+ wf1 = pointer to the first LSF weighting factor (Q13) (Word16)
+ dico_size = size of quantization codebook (Q0) (Word16)
+
+ Outputs:
+ buffer pointed to by lsf_r1 contains the selected vector
+ pOverflow -- pointer to Flag -- Flag set when overflow occurs
+
+ Returns:
+ index = quantization index (Q0) (Word16)
+
+ Global Variables Used:
+ None
+
+ Local Variables Needed:
+ None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function performs the quantization of a 4-dimensional subvector.
+
+------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ None
+
+------------------------------------------------------------------------------
+ REFERENCES
+
+ q_plsf_3.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
+
+------------------------------------------------------------------------------
+ PSEUDO-CODE
+
+static Word16
+Vq_subvec4( // o: quantization index, Q0
+ Word16 * lsf_r1, // i: 1st LSF residual vector, Q15
+ Word16 * dico, // i: quantization codebook, Q15
+ Word16 * wf1, // i: 1st LSF weighting factors, Q13
+ Word16 dico_size) // i: size of quantization codebook, Q0
+{
+ Word16 i, index = 0;
+ Word16 *p_dico, temp;
+ Word32 dist_min, dist;
+
+ dist_min = MAX_32;
+ p_dico = dico;
+
+ for (i = 0; i < dico_size; i++)
+ {
+ temp = sub (lsf_r1[0], *p_dico++);
+ temp = mult (wf1[0], temp);
+ dist = L_mult (temp, temp);
+
+ temp = sub (lsf_r1[1], *p_dico++);
+ temp = mult (wf1[1], temp);
+ dist = L_mac (dist, temp, temp);
+
+ temp = sub (lsf_r1[2], *p_dico++);
+ temp = mult (wf1[2], temp);
+ dist = L_mac (dist, temp, temp);
+
+ temp = sub (lsf_r1[3], *p_dico++);
+ temp = mult (wf1[3], temp);
+ dist = L_mac (dist, temp, temp);
+
+
+ if (L_sub (dist, dist_min) < (Word32) 0)
+ {
+ dist_min = dist;
+ index = i;
+ }
+ }
+
+ // Reading the selected vector
+
+ p_dico = &dico[shl (index, 2)];
+ lsf_r1[0] = *p_dico++;
+ lsf_r1[1] = *p_dico++;
+ lsf_r1[2] = *p_dico++;
+ lsf_r1[3] = *p_dico;
+
+ 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]
+
+------------------------------------------------------------------------------
+*/
+
+static Word16 Vq_subvec4( /* o: quantization index, Q0 */
+ Word16 * lsf_r1, /* i: 1st LSF residual vector, Q15 */
+ const Word16 * dico, /* i: quantization codebook, Q15 */
+ Word16 * wf1, /* i: 1st LSF weighting factors, Q13 */
+ Word16 dico_size, /* i: size of quantization codebook, Q0 */
+ Flag *pOverflow /* o : Flag set when overflow occurs */
+)
+{
+ register Word16 i;
+ Word16 temp;
+ const Word16 *p_dico;
+ Word16 index = 0;
+ Word32 dist_min;
+ Word32 dist;
+
+ Word16 lsf_r1_0;
+ Word16 lsf_r1_1;
+ Word16 lsf_r1_2;
+ Word16 lsf_r1_3;
+
+ Word16 wf1_0;
+ Word16 wf1_1;
+ Word16 wf1_2;
+ Word16 wf1_3;
+
+ OSCL_UNUSED_ARG(pOverflow);
+
+ dist_min = MAX_32;
+ p_dico = dico;
+
+ lsf_r1_0 = lsf_r1[0];
+ lsf_r1_1 = lsf_r1[1];
+ lsf_r1_2 = lsf_r1[2];
+ lsf_r1_3 = lsf_r1[3];
+
+ wf1_0 = wf1[0];
+ wf1_1 = wf1[1];
+ wf1_2 = wf1[2];
+ wf1_3 = wf1[3];
+
+ for (i = 0; i < dico_size; i++)
+ {
+ temp = lsf_r1_0 - (*p_dico++);
+ temp = (Word16)((((Word32) wf1_0) * temp) >> 15);
+ dist = ((Word32) temp) * temp;
+
+ temp = lsf_r1_1 - (*p_dico++);
+ temp = (Word16)((((Word32) wf1_1) * temp) >> 15);
+ dist += ((Word32) temp) * temp;
+
+ temp = lsf_r1_2 - (*p_dico++);
+ temp = (Word16)((((Word32) wf1_2) * temp) >> 15);
+ dist += ((Word32) temp) * temp;
+
+ temp = lsf_r1_3 - (*p_dico++);
+ temp = (Word16)((((Word32) wf1_3) * temp) >> 15);
+ dist += ((Word32) temp) * temp;
+
+ if (dist < dist_min)
+ {
+ dist_min = dist;
+ index = i;
+ }
+ }
+
+ /* Reading the selected vector */
+
+ p_dico = dico + (index << 2);
+ *lsf_r1++ = *p_dico++;
+ *lsf_r1++ = *p_dico++;
+ *lsf_r1++ = *p_dico++;
+ *lsf_r1 = *p_dico;
+
+ return(index);
+
+}
+
+/****************************************************************************/
+
+
+/*
+------------------------------------------------------------------------------
+ FUNCTION NAME: Test_Vq_subvec4
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ lsf_r1 = pointer to the first LSF residual vector (Q15) (Word16)
+ dico = pointer to the quantization codebook (Q15) (const Word16)
+ wf1 = pointer to the first LSF weighting factor (Q13) (Word16)
+ dico_size = size of quantization codebook (Q0) (Word16)
+
+ Outputs:
+ buffer pointed to by lsf_r1 contains the selected vector
+ pOverflow -- pointer to Flag -- Flag set when overflow occurs
+
+ Returns:
+ index = quantization index (Q0) (Word16)
+
+ Global Variables Used:
+ None
+
+ Local Variables Needed:
+ None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function calls the static function Vq_subvec4. It is used for testing
+ purposes only
+
+------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ None
+
+------------------------------------------------------------------------------
+ REFERENCES
+
+ None
+
+------------------------------------------------------------------------------
+ PSEUDO-CODE
+
+
+ CALL Vq_subvec4(lsf_r1 = lsf_r1
+ dico = dico
+ wf1 = wf1
+ dico_size = dico_size)
+ MODIFYING(nothing)
+ RETURNING(index = tst_index4)
+
+------------------------------------------------------------------------------
+ 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_Vq_subvec4(
+ Word16 * lsf_r1,
+ const Word16 * dico,
+ Word16 * wf1,
+ Word16 dico_size,
+ Flag *pOverflow)
+{
+ Word16 tst_index4 = 0;
+
+ /*------------------------------------------------------------------------
+ CALL Vq_subvec4(lsf_r1 = lsf_r1
+ dico = dico
+ wf1 = wf1
+ dico_size = dico_size)
+ MODIFYING(nothing)
+ RETURNING(index = index)
+ ------------------------------------------------------------------------*/
+ tst_index4 =
+ Vq_subvec4(
+ lsf_r1,
+ dico,
+ wf1,
+ dico_size,
+ pOverflow);
+
+ return(tst_index4);
+
+}
+
+/****************************************************************************/
+
+/*
+------------------------------------------------------------------------------
+ FUNCTION NAME: Vq_subvec3
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ lsf_r1 = pointer to the first LSF residual vector (Q15) (Word16)
+ dico = pointer to the quantization codebook (Q15) (const Word16)
+ wf1 = pointer to the first LSF weighting factor (Q13) (Word16)
+ dico_size = size of quantization codebook (Q0) (Word16)
+ use_half = flag to indicate use of every second entry in the
+ codebook (Flag)
+
+ Outputs:
+ buffer pointed to by lsf_r1 contains the selected vector
+ pOverflow -- pointer to Flag -- Flag set when overflow occurs
+
+ Returns:
+ index = quantization index (Q0) (Word16)
+
+ Global Variables Used:
+ None
+
+ Local Variables Needed:
+ None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function performs the quantization of a 3 dimensional subvector.
+
+------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ None
+
+------------------------------------------------------------------------------
+ REFERENCES
+
+ q_plsf_3.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
+
+------------------------------------------------------------------------------
+ PSEUDO-CODE
+
+static Word16
+Vq_subvec3( // o: quantization index, Q0
+ Word16 * lsf_r1, // i: 1st LSF residual vector, Q15
+ Word16 * dico, // i: quantization codebook, Q15
+ Word16 * wf1, // i: 1st LSF weighting factors, Q13
+ Word16 dico_size, // i: size of quantization codebook, Q0
+ Flag use_half) // i: use every second entry in codebook
+{
+ Word16 i, index = 0;
+ Word16 *p_dico, temp;
+ Word32 dist_min, dist;
+
+ dist_min = MAX_32;
+ p_dico = dico;
+
+ if (use_half == 0) {
+ for (i = 0; i < dico_size; i++)
+ {
+ temp = sub(lsf_r1[0], *p_dico++);
+ temp = mult(wf1[0], temp);
+ dist = L_mult(temp, temp);
+
+ temp = sub(lsf_r1[1], *p_dico++);
+ temp = mult(wf1[1], temp);
+ dist = L_mac(dist, temp, temp);
+
+ temp = sub(lsf_r1[2], *p_dico++);
+ temp = mult(wf1[2], temp);
+ dist = L_mac(dist, temp, temp);
+
+ if (L_sub(dist, dist_min) < (Word32) 0) {
+ dist_min = dist;
+ index = i;
+ }
+ }
+ p_dico = &dico[add(index, add(index, index))];
+ }
+ else
+ {
+ for (i = 0; i < dico_size; i++)
+ {
+ temp = sub(lsf_r1[0], *p_dico++);
+ temp = mult(wf1[0], temp);
+ dist = L_mult(temp, temp);
+
+ temp = sub(lsf_r1[1], *p_dico++);
+ temp = mult(wf1[1], temp);
+ dist = L_mac(dist, temp, temp);
+
+ temp = sub(lsf_r1[2], *p_dico++);
+ temp = mult(wf1[2], temp);
+ dist = L_mac(dist, temp, temp);
+
+ if (L_sub(dist, dist_min) < (Word32) 0)
+ {
+ dist_min = dist;
+ index = i;
+ }
+ p_dico = p_dico + 3; add(0,0);
+ }
+ p_dico = &dico[shl(add(index, add(index, index)),1)];
+ }
+
+
+ // Reading the selected vector
+ lsf_r1[0] = *p_dico++;
+ lsf_r1[1] = *p_dico++;
+ lsf_r1[2] = *p_dico++;
+
+ 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]
+
+------------------------------------------------------------------------------
+*/
+
+static Word16 Vq_subvec3( /* o: quantization index, Q0 */
+ Word16 * lsf_r1, /* i: 1st LSF residual vector, Q15 */
+ const Word16 * dico, /* i: quantization codebook, Q15 */
+ Word16 * wf1, /* i: 1st LSF weighting factors, Q13 */
+ Word16 dico_size, /* i: size of quantization codebook, Q0 */
+ Flag use_half, /* i: use every second entry in codebook */
+ Flag *pOverflow) /* o : Flag set when overflow occurs */
+{
+ register Word16 i;
+ Word16 temp;
+
+ const Word16 *p_dico;
+
+ Word16 p_dico_index = 0;
+ Word16 index = 0;
+
+ Word32 dist_min;
+ Word32 dist;
+
+ Word16 lsf_r1_0;
+ Word16 lsf_r1_1;
+ Word16 lsf_r1_2;
+
+ Word16 wf1_0;
+ Word16 wf1_1;
+ Word16 wf1_2;
+
+ OSCL_UNUSED_ARG(pOverflow);
+
+ dist_min = MAX_32;
+ p_dico = dico;
+
+ lsf_r1_0 = lsf_r1[0];
+ lsf_r1_1 = lsf_r1[1];
+ lsf_r1_2 = lsf_r1[2];
+
+ wf1_0 = wf1[0];
+ wf1_1 = wf1[1];
+ wf1_2 = wf1[2];
+
+ if (use_half != 0)
+ {
+ p_dico_index = 3;
+ }
+
+ for (i = 0; i < dico_size; i++)
+ {
+ temp = lsf_r1_0 - (*p_dico++);
+ temp = (Word16)((((Word32) wf1_0) * temp) >> 15);
+ dist = ((Word32) temp) * temp;
+
+ temp = lsf_r1_1 - (*p_dico++);
+ temp = (Word16)((((Word32) wf1_1) * temp) >> 15);
+ dist += ((Word32) temp) * temp;
+
+ temp = lsf_r1_2 - (*p_dico++);
+ temp = (Word16)((((Word32) wf1_2) * temp) >> 15);
+ dist += ((Word32) temp) * temp;
+
+ if (dist < dist_min)
+ {
+ dist_min = dist;
+ index = i;
+ }
+
+ p_dico = p_dico + p_dico_index;
+ }
+
+ p_dico = dico + (3 * index);
+
+ if (use_half != 0)
+ {
+ p_dico += (3 * index);
+ }
+
+ /* Reading the selected vector */
+ *lsf_r1++ = *p_dico++;
+ *lsf_r1++ = *p_dico++;
+ *lsf_r1 = *p_dico;
+
+ return(index);
+}
+
+/****************************************************************************/
+
+
+/*
+------------------------------------------------------------------------------
+ FUNCTION NAME: Test_Vq_subvec3
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ lsf_r1 = pointer to the first LSF residual vector (Q15) (Word16)
+ dico = pointer to the quantization codebook (Q15) (const Word16)
+ wf1 = pointer to the first LSF weighting factor (Q13) (Word16)
+ dico_size = size of quantization codebook (Q0) (Word16)
+ use_half = flag to indicate use of every second entry in the
+ codebook (Flag)
+
+ Outputs:
+ buffer pointed to by lsf_r1 contains the selected vector
+ pOverflow -- pointer to Flag -- Flag set when overflow occurs
+
+ Returns:
+ index = quantization index (Q0) (Word16)
+
+ Global Variables Used:
+ None
+
+ Local Variables Needed:
+ None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function calls the static function Vq_subvec3. It is used for testing
+ purposes only
+
+------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ None
+
+------------------------------------------------------------------------------
+ REFERENCES
+
+ None
+
+------------------------------------------------------------------------------
+ PSEUDO-CODE
+
+ CALL Vq_subvec3(lsf_r1 = lsf_r1
+ dico = dico
+ wf1 = wf1
+ dico_size = dico_size
+ use_half = use_half)
+ MODIFYING(nothing)
+ RETURNING(index = tst_index3)
+
+------------------------------------------------------------------------------
+ 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_Vq_subvec3(
+ Word16 * lsf_r1,
+ const Word16 * dico,
+ Word16 * wf1,
+ Word16 dico_size,
+ Flag use_half,
+ Flag *pOverflow)
+{
+ Word16 tst_index3 = 0;
+
+ /*------------------------------------------------------------------------
+ CALL Vq_subvec3(lsf_r1 = lsf_r1
+ dico = dico
+ wf1 = wf1
+ dico_size = dico_size
+ use_half = use_half)
+ MODIFYING(nothing)
+ RETURNING(index = index)
+ ------------------------------------------------------------------------*/
+ tst_index3 =
+ Vq_subvec3(
+ lsf_r1,
+ dico,
+ wf1,
+ dico_size,
+ use_half,
+ pOverflow);
+
+ return(tst_index3);
+
+}
+
+/****************************************************************************/
+
+
+/*
+------------------------------------------------------------------------------
+ FUNCTION NAME: Q_plsf_3
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ st = pointer to structures of type Q_plsfState (Q_plsfState)
+ mode = coder mode (enum)
+ lsp1 = pointer to the first LSP vector (Word16)
+ lsp1_q = pointer to the quantized first LSP vector (Word16)
+ indice = pointer to the quantization indices of 3 vectors (Word16)
+ pred_init_i = pointer to the index of the initial value for
+ MA prediction in DTX mode (Word16)
+
+ Outputs:
+ lsp1_q points to a vector containing the new quantized LSPs
+ indice points to the new quantization indices of 3 vectors
+ pred_init_i points to the new initial index for MA prediction
+ in DTX mode
+ past_rq field of structure pointed to by st contains the current
+ quantized LSF parameters
+ pOverflow -- pointer to Flag -- Flag set when overflow occurs
+
+ Returns:
+ None
+
+ Global Variables Used:
+ pred_fac = table containing prediction factors (const Word16)
+ dico1_lsf = quantization table for split_MQ of 2 sets of LSFs
+ in a 20 ms frame (const Word16)
+ dico2_lsf = quantization table for split_MQ of 2 sets of LSFs
+ in a 20 ms frame (const Word16)
+ dico3_lsf = quantization table for split_MQ of 2 sets of LSFs
+ in a 20 ms frame (const Word16)
+ mr515_3_lsf = third codebook for MR475 and MR515 modes (const Word16)
+ mr795_1_lsf = first codebook for MR795 mode (const Word16)
+ mean_lsf = table of mean LSFs (const Word16)
+ past_rq_init = initalization table for MA predictor in DTX mode
+ (const Word16)
+
+
+ Local Variables Needed:
+ None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function performs quantization of LSF parameters with 1st order MA
+ prediction and split by 3 vector quantization (split-VQ)
+
+------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ None
+
+------------------------------------------------------------------------------
+ REFERENCES
+
+ q_plsf_3.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
+
+------------------------------------------------------------------------------
+ PSEUDO-CODE
+
+void Q_plsf_3(
+ Q_plsfState *st, // i/o: state struct
+ enum Mode mode, // i : coder mode
+ Word16 *lsp1, // i : 1st LSP vector Q15
+ Word16 *lsp1_q, // o : quantized 1st LSP vector Q15
+ Word16 *indice, // o : quantization indices of 3 vectors Q0
+ Word16 *pred_init_i // o : init index for MA prediction in DTX mode
+)
+{
+ Word16 i, j;
+ Word16 lsf1[M], wf1[M], lsf_p[M], lsf_r1[M];
+ Word16 lsf1_q[M];
+
+ Word32 L_pred_init_err;
+ Word32 L_min_pred_init_err;
+ Word16 temp_r1[M];
+ Word16 temp_p[M];
+
+ // convert LSFs to normalize frequency domain 0..16384
+
+ Lsp_lsf(lsp1, lsf1, M);
+
+ // compute LSF weighting factors (Q13)
+
+ Lsf_wt(lsf1, wf1);
+
+ // Compute predicted LSF and prediction error
+ if (test(), sub(mode, MRDTX) != 0)
+ {
+ for (i = 0; i < M; i++)
+ {
+ lsf_p[i] = add(mean_lsf[i],
+ mult(st->past_rq[i],
+ pred_fac[i]));
+ lsf_r1[i] = sub(lsf1[i], lsf_p[i]);
+ }
+ }
+ else
+ {
+ // DTX mode, search the init vector that yields
+ // lowest prediction resuidual energy
+ *pred_init_i = 0;
+ L_min_pred_init_err = 0x7fffffff; // 2^31 - 1
+ for (j = 0; j < PAST_RQ_INIT_SIZE; j++)
+ {
+ L_pred_init_err = 0;
+ for (i = 0; i < M; i++)
+ {
+ temp_p[i] = add(mean_lsf[i], past_rq_init[j*M+i]);
+ temp_r1[i] = sub(lsf1[i],temp_p[i]);
+ L_pred_init_err = L_mac(L_pred_init_err, temp_r1[i], temp_r1[i]);
+ } // next i
+
+
+ if (L_sub(L_pred_init_err, L_min_pred_init_err) < (Word32) 0)
+ {
+ L_min_pred_init_err = L_pred_init_err;
+ Copy(temp_r1, lsf_r1, M);
+ Copy(temp_p, lsf_p, M);
+ // Set zerom
+ Copy(&past_rq_init[j*M], st->past_rq, M);
+ *pred_init_i = j;
+ } // endif
+ } // next j
+ } // endif MRDTX
+
+ //---- Split-VQ of prediction error ----
+ if (sub (mode, MR475) == 0 || sub (mode, MR515) == 0)
+ { // MR475, MR515
+
+
+ indice[0] = Vq_subvec3(&lsf_r1[0], dico1_lsf, &wf1[0], DICO1_SIZE, 0);
+
+ indice[1] = Vq_subvec3(&lsf_r1[3], dico2_lsf, &wf1[3], DICO2_SIZE/2, 1);
+
+ indice[2] = Vq_subvec4(&lsf_r1[6], mr515_3_lsf, &wf1[6], MR515_3_SIZE);
+
+ }
+ else if (sub (mode, MR795) == 0)
+ { // MR795
+
+
+ indice[0] = Vq_subvec3(&lsf_r1[0], mr795_1_lsf, &wf1[0], MR795_1_SIZE, 0);
+
+ indice[1] = Vq_subvec3(&lsf_r1[3], dico2_lsf, &wf1[3], DICO2_SIZE, 0);
+
+ indice[2] = Vq_subvec4(&lsf_r1[6], dico3_lsf, &wf1[6], DICO3_SIZE);
+
+ }
+ else
+ { // MR59, MR67, MR74, MR102 , MRDTX
+
+
+ indice[0] = Vq_subvec3(&lsf_r1[0], dico1_lsf, &wf1[0], DICO1_SIZE, 0);
+
+ indice[1] = Vq_subvec3(&lsf_r1[3], dico2_lsf, &wf1[3], DICO2_SIZE, 0);
+
+ indice[2] = Vq_subvec4(&lsf_r1[6], dico3_lsf, &wf1[6], DICO3_SIZE);
+
+ }
+
+
+ // Compute quantized LSFs and update the past quantized residual
+
+ for (i = 0; i < M; i++)
+ {
+ lsf1_q[i] = add(lsf_r1[i], lsf_p[i]);
+ st->past_rq[i] = lsf_r1[i];
+ }
+
+ // verification that LSFs has mimimum distance of LSF_GAP Hz
+
+ Reorder_lsf(lsf1_q, LSF_GAP, M);
+
+ // convert LSFs to the cosine domain
+
+ Lsf_lsp(lsf1_q, lsp1_q, M);
+}
+
+------------------------------------------------------------------------------
+ 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 Q_plsf_3(
+ Q_plsfState *st, /* i/o: state struct */
+ enum Mode mode, /* i : coder mode */
+ Word16 *lsp1, /* i : 1st LSP vector Q15 */
+ Word16 *lsp1_q, /* o : quantized 1st LSP vector Q15 */
+ Word16 *indice, /* o : quantization indices of 3 vectors Q0 */
+ Word16 *pred_init_i,/* o : init index for MA prediction in DTX mode */
+ Flag *pOverflow /* o : Flag set when overflow occurs */
+)
+{
+ register Word16 i, j;
+ Word16 lsf1[M];
+ Word16 wf1[M];
+ Word16 lsf_p[M];
+ Word16 lsf_r1[M];
+ Word16 lsf1_q[M];
+
+ Word32 L_pred_init_err;
+ Word32 L_min_pred_init_err;
+ Word32 L_temp;
+ Word16 temp_r1[M];
+ Word16 temp_p[M];
+ Word16 temp;
+
+ /* convert LSFs to normalize frequency domain 0..16384 */
+
+ Lsp_lsf(
+ lsp1,
+ lsf1,
+ M,
+ pOverflow);
+
+ /* compute LSF weighting factors (Q13) */
+
+ Lsf_wt(
+ lsf1,
+ wf1,
+ pOverflow);
+
+ /* Compute predicted LSF and prediction error */
+ if (mode != MRDTX)
+ {
+ for (i = 0; i < M; i++)
+ {
+ temp = (Word16)((((Word32) st->past_rq[i]) *
+ (*(pred_fac_3 + i))) >> 15);
+
+ *(lsf_p + i) = *(mean_lsf_3 + i) + temp;
+
+ *(lsf_r1 + i) = *(lsf1 + i) - *(lsf_p + i);
+ }
+ }
+ else
+ {
+ /* DTX mode, search the init vector that yields */
+ /* lowest prediction resuidual energy */
+ *pred_init_i = 0;
+ L_min_pred_init_err = 0x7fffffff; /* 2^31 - 1 */
+
+ for (j = 0; j < PAST_RQ_INIT_SIZE; j++)
+ {
+ L_pred_init_err = 0;
+ for (i = 0; i < M; i++)
+ {
+ *(temp_p + i) = *(mean_lsf_3 + i) + *(past_rq_init + j * M + i);
+
+ *(temp_r1 + i) = *(lsf1 + i) - *(temp_p + i);
+
+ L_temp = ((Word32) * (temp_r1 + i)) * *(temp_r1 + i);
+
+ L_pred_init_err = L_pred_init_err + (L_temp << 1);
+
+ } /* next i */
+
+
+ if (L_pred_init_err < L_min_pred_init_err)
+ {
+ L_min_pred_init_err = L_pred_init_err;
+
+ memcpy(
+ lsf_r1,
+ temp_r1,
+ M*sizeof(Word16));
+
+ memcpy(
+ lsf_p,
+ temp_p,
+ M*sizeof(Word16));
+
+ /* Set zerom */
+ memcpy(
+ st->past_rq,
+ &past_rq_init[j*M],
+ M*sizeof(Word16));
+
+ *pred_init_i = j;
+
+ } /* endif */
+ } /* next j */
+ } /* endif MRDTX */
+
+ /*---- Split-VQ of prediction error ----*/
+ if ((mode == MR475) || (mode == MR515))
+ { /* MR475, MR515 */
+
+ *indice =
+ Vq_subvec3(
+ lsf_r1,
+ dico1_lsf_3,
+ wf1,
+ DICO1_SIZE,
+ 0,
+ pOverflow);
+
+ *(indice + 1) =
+ Vq_subvec3(
+ lsf_r1 + 3,
+ dico2_lsf_3,
+ wf1 + 3,
+ DICO2_SIZE / 2,
+ 1,
+ pOverflow);
+
+ *(indice + 2) =
+ Vq_subvec4(
+ lsf_r1 + 6,
+ mr515_3_lsf,
+ wf1 + 6,
+ MR515_3_SIZE,
+ pOverflow);
+
+ }
+ else if (mode == MR795)
+ { /* MR795 */
+
+ *indice =
+ Vq_subvec3(
+ lsf_r1,
+ mr795_1_lsf,
+ wf1,
+ MR795_1_SIZE,
+ 0,
+ pOverflow);
+
+ *(indice + 1) =
+ Vq_subvec3(
+ lsf_r1 + 3,
+ dico2_lsf_3,
+ wf1 + 3,
+ DICO2_SIZE,
+ 0,
+ pOverflow);
+
+ *(indice + 2) =
+ Vq_subvec4(
+ lsf_r1 + 6,
+ dico3_lsf_3,
+ wf1 + 6,
+ DICO3_SIZE,
+ pOverflow);
+
+ }
+ else
+ { /* MR59, MR67, MR74, MR102 , MRDTX */
+
+ *indice =
+ Vq_subvec3(
+ lsf_r1,
+ dico1_lsf_3,
+ wf1,
+ DICO1_SIZE,
+ 0,
+ pOverflow);
+
+ *(indice + 1) =
+ Vq_subvec3(
+ lsf_r1 + 3,
+ dico2_lsf_3,
+ wf1 + 3,
+ DICO2_SIZE,
+ 0,
+ pOverflow);
+
+ *(indice + 2) =
+ Vq_subvec4(
+ lsf_r1 + 6,
+ dico3_lsf_3,
+ wf1 + 6,
+ DICO3_SIZE,
+ pOverflow);
+
+ }
+
+
+ /* Compute quantized LSFs and update the past quantized residual */
+
+ for (i = 0; i < M; i++)
+ {
+ *(lsf1_q + i) = *(lsf_r1 + i) + *(lsf_p + i);
+ st->past_rq[i] = *(lsf_r1 + i);
+ }
+
+ /* verification that LSFs has mimimum distance of LSF_GAP Hz */
+
+ Reorder_lsf(
+ lsf1_q,
+ LSF_GAP,
+ M,
+ pOverflow);
+
+ /* convert LSFs to the cosine domain */
+
+ Lsf_lsp(
+ lsf1_q,
+ lsp1_q,
+ M,
+ pOverflow);
+
+ return;
+
+}