summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/amrnb/enc/src/hp_max.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/codecs/amrnb/enc/src/hp_max.cpp')
-rw-r--r--media/libstagefright/codecs/amrnb/enc/src/hp_max.cpp332
1 files changed, 332 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/amrnb/enc/src/hp_max.cpp b/media/libstagefright/codecs/amrnb/enc/src/hp_max.cpp
new file mode 100644
index 0000000..d086594
--- /dev/null
+++ b/media/libstagefright/codecs/amrnb/enc/src/hp_max.cpp
@@ -0,0 +1,332 @@
+/* ------------------------------------------------------------------
+ * 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.
+****************************************************************************************/
+/*
+------------------------------------------------------------------------------
+
+
+
+ Filename: /audio/gsm_amr/c/src/hp_max.c
+
+ Date: 02/01/2002
+
+------------------------------------------------------------------------------
+ REVISION HISTORY
+
+ Description: Replaced "int" and/or "char" with OSCL defined types.
+
+ Description:
+
+------------------------------------------------------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+#include "hp_max.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.]
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL FUNCTION DEFINITIONS
+; [List function prototypes here]
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL VARIABLE DEFINITIONS
+; [Variable declaration - defined here and used outside this module]
+----------------------------------------------------------------------------*/
+
+/*
+------------------------------------------------------------------------------
+ FUNCTION NAME: hp_max
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ corr[] = correlation vector (Word16)
+ scal_sig[] = scaled signal vector (Word16)
+ L_frame = length of frame to compute pitch (Word16
+ lag_max = maximum lag (Word16)
+ lag_min = minimum lag (Word16)
+ cor_hp_max = pointer to max high-pass filtered norm. correlation (Word16)
+ pOverflow = pointer to overflow (Flag)
+
+ Outputs:
+ cor_hp_max contains max high-pass filtered norm. correlation (Word16)
+ pOverflow -> 1 if the maximum correlation computation resulted in overflow
+
+ Returns:
+ 0 (Word16)
+
+ Global Variables Used:
+ None
+
+ Local Variables Needed:
+ None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function finds the maximum high-pass filtered correlation of scal_sig[]
+ in a given delay range.
+
+ The correlation is given by
+ corr[t] = <scal_sig[n],scal_sig[n-t]>, t=lag_min,...,lag_max
+ The functions outputs the maximum high-pass filtered correlation after
+ normalization.
+
+------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ None
+
+------------------------------------------------------------------------------
+ REFERENCES
+
+ [1] hp_max.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
+
+------------------------------------------------------------------------------
+ PSEUDO-CODE
+
+Word16 hp_max (
+ Word32 corr[], // i : correlation vector
+ Word16 scal_sig[], // i : scaled signal
+ Word16 L_frame, // i : length of frame to compute pitch
+ Word16 lag_max, // i : maximum lag
+ Word16 lag_min, // i : minimum lag
+ Word16 *cor_hp_max) // o : max high-pass filtered norm. correlation
+{
+ Word16 i;
+ Word16 *p, *p1;
+ Word32 max, t0, t1;
+ Word16 max16, t016, cor_max;
+ Word16 shift, shift1, shift2;
+
+ max = MIN_32;
+ t0 = 0L;
+* The reference ETSI code uses a global flag for Overflow inside the math functions
+* saturate(). In the actual implementation a pointer to Overflow flag is passed in
+* as a parameter to the function
+
+ for (i = lag_max-1; i > lag_min; i--)
+ {
+ // high-pass filtering
+ t0 = L_sub (L_sub(L_shl(corr[-i], 1), corr[-i-1]), corr[-i+1]);
+ t0 = L_abs (t0);
+
+ if (L_sub (t0, max) >= 0)
+ {
+ max = t0;
+ }
+ }
+
+ // compute energy
+ p = scal_sig;
+ p1 = &scal_sig[0];
+ t0 = 0L;
+ for (i = 0; i < L_frame; i++, p++, p1++)
+ {
+ t0 = L_mac (t0, *p, *p1);
+ }
+
+ p = scal_sig;
+ p1 = &scal_sig[-1];
+ t1 = 0L;
+ for (i = 0; i < L_frame; i++, p++, p1++)
+ {
+ t1 = L_mac (t1, *p, *p1);
+ }
+
+ // high-pass filtering
+ t0 = L_sub(L_shl(t0, 1), L_shl(t1, 1));
+ t0 = L_abs (t0);
+
+ // max/t0
+ shift1 = sub(norm_l(max), 1);
+ max16 = extract_h(L_shl(max, shift1));
+ shift2 = norm_l(t0);
+ t016 = extract_h(L_shl(t0, shift2));
+
+ if (t016 != 0)
+ {
+ cor_max = div_s(max16, t016);
+ }
+ else
+ {
+ cor_max = 0;
+ }
+
+ shift = sub(shift1, shift2);
+
+ if (shift >= 0)
+ {
+ *cor_hp_max = shr(cor_max, shift); // Q15
+ }
+ else
+ {
+ *cor_hp_max = shl(cor_max, negate(shift)); // Q15
+ }
+
+ return 0;
+}
+
+
+------------------------------------------------------------------------------
+ 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
+----------------------------------------------------------------------------*/
+Word16 hp_max(
+ Word32 corr[], /* i : correlation vector. */
+ Word16 scal_sig[], /* i : scaled signal. */
+ Word16 L_frame, /* i : length of frame to compute pitch */
+ Word16 lag_max, /* i : maximum lag */
+ Word16 lag_min, /* i : minimum lag */
+ Word16 *cor_hp_max, /* o : max high-pass filtered norm. correlation */
+ Flag *pOverflow /* i/o : overflow Flag */
+)
+{
+ Word16 i;
+ Word16 *p, *p1;
+ Word32 max, t0, t1;
+ Word16 max16, t016, cor_max;
+ Word16 shift, shift1, shift2;
+ Word32 L_temp;
+
+ max = MIN_32;
+ t0 = 0L;
+
+ for (i = lag_max - 1; i > lag_min; i--)
+ {
+ /* high-pass filtering */
+ t0 = L_shl(corr[-i], 1, pOverflow);
+ L_temp = L_sub(t0, corr[-i-1], pOverflow);
+ t0 = L_sub(L_temp, corr[-i+1], pOverflow);
+ t0 = L_abs(t0);
+
+ if (t0 >= max)
+ {
+ max = t0;
+ }
+ }
+
+ /* compute energy */
+ p = scal_sig;
+ p1 = &scal_sig[0];
+ t0 = 0L;
+ for (i = 0; i < L_frame; i++, p++, p1++)
+ {
+ t0 = L_mac(t0, *p, *p1, pOverflow);
+ }
+
+ p = scal_sig;
+ p1 = &scal_sig[-1];
+ t1 = 0L;
+ for (i = 0; i < L_frame; i++, p++, p1++)
+ {
+ t1 = L_mac(t1, *p, *p1, pOverflow);
+ }
+
+ /* high-pass filtering */
+ L_temp = L_shl(t0, 1, pOverflow);
+ t1 = L_shl(t1, 1, pOverflow);
+ t0 = L_sub(L_temp, t1, pOverflow);
+ t0 = L_abs(t0);
+
+ /* max/t0 */
+ /* shift1 = sub(norm_l(max), 1);
+ max16 = extract_h(L_shl(max, shift1));
+ shift2 = norm_l(t0);
+ t016 = extract_h(L_shl(t0, shift2)); */
+
+ t016 = norm_l(max);
+ shift1 = sub(t016, 1, pOverflow);
+
+ L_temp = L_shl(max, shift1, pOverflow);
+ max16 = (Word16)(L_temp >> 16);
+
+ shift2 = norm_l(t0);
+ L_temp = L_shl(t0, shift2, pOverflow);
+ t016 = (Word16)(L_temp >> 16);
+
+ if (t016 != 0)
+ {
+ cor_max = div_s(max16, t016);
+ }
+ else
+ {
+ cor_max = 0;
+ }
+
+ shift = sub(shift1, shift2, pOverflow);
+
+ if (shift >= 0)
+ {
+ *cor_hp_max = shr(cor_max, shift, pOverflow); /* Q15 */
+ }
+ else
+ {
+ *cor_hp_max = shl(cor_max, negate(shift), pOverflow); /* Q15 */
+ }
+
+ return 0;
+}
+