diff options
Diffstat (limited to 'media/libstagefright/codecs/amrnb/enc/src/pitch_ol.cpp')
-rw-r--r-- | media/libstagefright/codecs/amrnb/enc/src/pitch_ol.cpp | 1213 |
1 files changed, 1213 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/amrnb/enc/src/pitch_ol.cpp b/media/libstagefright/codecs/amrnb/enc/src/pitch_ol.cpp new file mode 100644 index 0000000..d3a2ec0 --- /dev/null +++ b/media/libstagefright/codecs/amrnb/enc/src/pitch_ol.cpp @@ -0,0 +1,1213 @@ +/* ------------------------------------------------------------------ + * 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/pitch_ol.c + Funtions: Pitch_ol + Lag_max + +------------------------------------------------------------------------------ + MODULE DESCRIPTION + + The modules in this file compute the open loop pitch lag. +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include <string.h> + +#include "pitch_ol.h" +#include "typedef.h" +#include "basicop_malloc.h" +#include "cnst.h" +#include "inv_sqrt.h" +#include "vad.h" +#include "calc_cor.h" +#include "hp_max.h" +#include "basic_op.h" + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ +#define THRESHOLD 27853 + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL VARIABLE DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Lag_max +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS (If VAD2 is defined) + + Inputs + corr = pointer to buffer of correlation values (Word32) + scal_sig = pointer to buffer of scaled signal values (Word16) + scal_fac = scaled signal factor (Word16) + scal_flag = EFR compatible scaling flag (Word16) + L_frame = length of frame to compute pitch (Word16) + lag_max = maximum lag (Word16) + lag_min = minimum lag (Word16) + cor_max = pointer to the normalized correlation of selected lag (Word16) + rmax = pointer to max(<s[i]*s[j]>), (Word32) + r0 = pointer to the residual energy (Word32) + dtx = dtx flag; equal to 1, if dtx is enabled, 0, otherwise (Flag) + + Outputs: + cor_max contains the newly calculated normalized correlation of the + selected lag + rmax contains the newly calculated max(<s[i]*s[j]>) + r0 contains the newly calculated residual energy + + Returns: + p_max = lag of the max correlation found (Word16) + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS (If VAD2 is not defined) + + Inputs + vadSt = pointer to a vadState structure + corr = pointer to buffer of correlation values (Word32) + scal_sig = pointer to buffer of scaled signal values (Word16) + scal_fac = scaled signal factor (Word16) + scal_flag = EFR compatible scaling flag (Word16) + L_frame = length of frame to compute pitch (Word16) + lag_max = maximum lag (Word16) + lag_min = minimum lag (Word16) + cor_max = pointer to the normalized correlation of selected lag (Word16) + dtx = dtx flag; equal to 1, if dtx is enabled, 0, otherwise (Flag) + pOverflow = pointer to overflow indicator (Flag) + + Outputs: + cor_max contains the newly calculated normalized correlation of the + selected lag + vadSt contains the updated VAD state parameters + pOverflow -> 1 if the math operations called by this routine saturate + + Returns: + p_max = lag of the max correlation found (Word16) + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + Find the lag that has maximum correlation of scal_sig in a given delay range. + The correlation is given by: + + cor[t] = <scal_sig[n],scal_sig[n-t]>, t=lag_min,...,lag_max + + The function returns the maximum correlation after normalization and the + corresponding lag. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + pitch_ol.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +#ifdef VAD2 +static Word16 Lag_max ( // o : lag found + Word32 corr[], // i : correlation vector. + Word16 scal_sig[], // i : scaled signal. + Word16 scal_fac, // i : scaled signal factor. + Word16 scal_flag, // i : if 1 use EFR compatible scaling + Word16 L_frame, // i : length of frame to compute pitch + Word16 lag_max, // i : maximum lag + Word16 lag_min, // i : minimum lag + Word16 *cor_max, // o : normalized correlation of selected lag + Word32 *rmax, // o : max(<s[i]*s[j]>) + Word32 *r0, // o : residual energy + Flag dtx // i : dtx flag; use dtx=1, do not use dtx=0 + ) +#else +static Word16 Lag_max ( // o : lag found + vadState *vadSt, // i/o : VAD state struct + Word32 corr[], // i : correlation vector. + Word16 scal_sig[], // i : scaled signal. + Word16 scal_fac, // i : scaled signal factor. + Word16 scal_flag, // i : if 1 use EFR compatible scaling + Word16 L_frame, // i : length of frame to compute pitch + Word16 lag_max, // i : maximum lag + Word16 lag_min, // i : minimum lag + Word16 *cor_max, // o : normalized correlation of selected lag + Flag dtx // i : dtx flag; use dtx=1, do not use dtx=0 + ) +#endif +{ + Word16 i, j; + Word16 *p; + Word32 max, t0; + Word16 max_h, max_l, ener_h, ener_l; + Word16 p_max = 0; // initialization only needed to keep gcc silent + + max = MIN_32; + p_max = lag_max; + + for (i = lag_max, j = (PIT_MAX-lag_max-1); i >= lag_min; i--, j--) + { + if (L_sub (corr[-i], max) >= 0) + { + max = corr[-i]; + p_max = i; + } + } + + // compute energy + + t0 = 0; + p = &scal_sig[-p_max]; + for (i = 0; i < L_frame; i++, p++) + { + t0 = L_mac (t0, *p, *p); + } + // 1/sqrt(energy) + + if (dtx) + { // no test() call since this if is only in simulation env +#ifdef VAD2 + *rmax = max; + *r0 = t0; +#else + // check tone + vad_tone_detection (vadSt, max, t0); +#endif + } + + t0 = Inv_sqrt (t0); + + if (scal_flag) + { + t0 = L_shl (t0, 1); + } + + // max = max/sqrt(energy) + + L_Extract (max, &max_h, &max_l); + L_Extract (t0, &ener_h, &ener_l); + + t0 = Mpy_32 (max_h, max_l, ener_h, ener_l); + + if (scal_flag) + { + t0 = L_shr (t0, scal_fac); + *cor_max = extract_h (L_shl (t0, 15)); // divide by 2 + } + else + { + *cor_max = extract_l(t0); + } + + return (p_max); +} + +------------------------------------------------------------------------------ + 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] + +------------------------------------------------------------------------------ +*/ + +#ifdef VAD2 +static Word16 Lag_max( /* o : lag found */ + Word32 corr[], /* i : correlation vector. */ + Word16 scal_sig[], /* i : scaled signal. */ + Word16 scal_fac, /* i : scaled signal factor. */ + Word16 scal_flag, /* i : if 1 use EFR compatible scaling */ + Word16 L_frame, /* i : length of frame to compute pitch */ + Word16 lag_max, /* i : maximum lag */ + Word16 lag_min, /* i : minimum lag */ + Word16 *cor_max, /* o : normalized correlation of selected lag */ + Word32 *rmax, /* o : max(<s[i]*s[j]>) */ + Word32 *r0, /* o : residual energy */ + Flag dtx, /* i : dtx flag; use dtx=1, do not use dtx=0 */ + Flag *pOverflow /* i/o : overflow Flag */ +) +#else +static Word16 Lag_max( /* o : lag found */ + vadState *vadSt, /* i/o : VAD state struct */ + Word32 corr[], /* i : correlation vector. */ + Word16 scal_sig[], /* i : scaled signal. */ + Word16 scal_fac, /* i : scaled signal factor. */ + Word16 scal_flag, /* i : if 1 use EFR compatible scaling */ + Word16 L_frame, /* i : length of frame to compute pitch */ + Word16 lag_max, /* i : maximum lag */ + Word16 lag_min, /* i : minimum lag */ + Word16 *cor_max, /* o : normalized correlation of selected lag */ + Flag dtx, /* i : dtx flag; use dtx=1, do not use dtx=0 */ + Flag *pOverflow /* i/o : overflow Flag */ +) +#endif +{ + register Word16 i; + Word16 *p; + Word32 max; + Word32 t0; + Word16 max_h; + Word16 max_l; + Word16 ener_h; + Word16 ener_l; + Word16 p_max = 0; /* initialization only needed to keep gcc silent */ + Word32 L_temp; + Word32 L_temp_2; + Word32 L_temp_3; + Word32 *p_corr = &corr[-lag_max]; + + max = MIN_32; + p_max = lag_max; + + for (i = lag_max; i >= lag_min; i--) + { + /* The negative array index is equivalent to a negative */ + /* address offset, i.e., corr[-i] == *(corr - i) */ + if (*(p_corr++) >= max) + { + p_corr--; + max = *(p_corr++); + p_max = i; + } + } + + /* compute energy */ + + t0 = 0; + + /* The negative array index is equivalent to a negative */ + /* address offset, i.e., scal_sig[-p_max] == *(scal_sig - p_max) */ + p = &scal_sig[-p_max]; + for (i = (L_frame >> 2); i != 0; i--) + { + t0 = amrnb_fxp_mac_16_by_16bb((Word32) * (p), (Word32) * (p), t0); + p++; + t0 = amrnb_fxp_mac_16_by_16bb((Word32) * (p), (Word32) * (p), t0); + p++; + t0 = amrnb_fxp_mac_16_by_16bb((Word32) * (p), (Word32) * (p), t0); + p++; + t0 = amrnb_fxp_mac_16_by_16bb((Word32) * (p), (Word32) * (p), t0); + p++; + } + + t0 <<= 1; + /* 1/sqrt(energy) */ + + if (dtx) + { /* no test() call since this if is only in simulation env */ + /* check tone */ +#ifdef VAD2 + *rmax = max; + *r0 = t0; +#else + /* check tone */ + vad_tone_detection(vadSt, max, t0, pOverflow); +#endif + } + + t0 = Inv_sqrt(t0, pOverflow); + + if (scal_flag) + { + if (t0 > (Word32) 0x3fffffffL) + { + t0 = MAX_32; + } + else + { + t0 = t0 << 1; + } + } + + /* max = max/sqrt(energy) */ + /* The following code is an inlined version of */ + /* L_Extract (max, &max_h, &max_l), i.e. */ + /* */ + /* *max_h = extract_h (max); */ + max_h = (Word16)(max >> 16); + + /* L_temp_2 = L_shr(max,1), which is used in */ + /* the calculation of *max_l (see next operation) */ + L_temp_2 = max >> 1; + + /* *max_l = extract_l (L_msu (L_shr (max, 1), *max_h, 16384)); */ + L_temp_3 = (Word32)(max_h << 15); + + L_temp = L_temp_2 - L_temp_3; + + max_l = (Word16)L_temp; + + /* The following code is an inlined version of */ + /* L_Extract (t0, &ener_h, &ener_l), i.e. */ + /* */ + /* *ener_h = extract_h (t0); */ + ener_h = (Word16)(t0 >> 16); + + /* L_temp_2 = L_shr(t0,1), which is used in */ + /* the calculation of *ener_l (see next operation) */ + + L_temp_2 = t0 >> 1; + + L_temp_3 = (Word32)(ener_h << 15); + + L_temp = L_temp_2 - L_temp_3; + + ener_l = (Word16)L_temp; + + t0 = Mpy_32(max_h, max_l, ener_h, ener_l, pOverflow); + + if (scal_flag) + { + t0 = L_shr(t0, scal_fac, pOverflow); + + if (t0 > (Word32) 0X0000FFFFL) + { + *cor_max = MAX_16; + } + else if (t0 < (Word32) 0xFFFF0000L) + { + *cor_max = MIN_16; + } + else + { + *cor_max = (Word16)(t0 >> 1); + } + } + else + { + *cor_max = (Word16)t0; + } + + return (p_max); +} + +/*---------------------------------------------------------------------------- +; End Function: Lag_max +----------------------------------------------------------------------------*/ + + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Lag_max_wrapper +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs + corr = pointer to buffer of correlation values (Word32) + scal_sig = pointer to buffer of scaled signal values (Word16) + scal_fac = scaled signal factor (Word16) + scal_flag = EFR compatible scaling flag (Word16) + L_frame = length of frame to compute pitch (Word16) + lag_max = maximum lag (Word16) + lag_min = minimum lag (Word16) + cor_max = pointer to the normalized correlation of selected lag (Word16) + rmax = pointer to max(<s[i]*s[j]>), (Word32) + r0 = pointer to the residual energy (Word32) + dtx = dtx flag; equal to 1, if dtx is enabled, 0, otherwise (Flag) + pOverflow = pointer to overflow indicator (Flag) + + Outputs: + cor_max contains the newly calculated normalized correlation of the + selected lag + rmax contains the newly calculated max(<s[i]*s[j]>) + r0 contains the newly calculated residual energy + pOverflow -> 1 if the math operations called by this routine saturate + + Returns: + p_max = lag of the max correlation found (Word16) + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS (If VAD2 is not defined) + + Inputs + vadSt = pointer to a vadState structure + corr = pointer to buffer of correlation values (Word32) + scal_sig = pointer to buffer of scaled signal values (Word16) + scal_fac = scaled signal factor (Word16) + scal_flag = EFR compatible scaling flag (Word16) + L_frame = length of frame to compute pitch (Word16) + lag_max = maximum lag (Word16) + lag_min = minimum lag (Word16) + cor_max = pointer to the normalized correlation of selected lag (Word16) + dtx = dtx flag; equal to 1, if dtx is enabled, 0, otherwise (Flag) + pOverflow = pointer to overflow indicator (Flag) + + Outputs: + cor_max contains the newly calculated normalized correlation of the + selected lag + vadSt contains the updated VAD state parameters + pOverflow -> 1 if the math operations called by this routine saturate + + Returns: + p_max = lag of the max correlation found (Word16) + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function provides external access to the local function Lag_max. + +------------------------------------------------------------------------------ + REQUIREMENTS + + None + +------------------------------------------------------------------------------ + REFERENCES + + pitch_ol.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +#ifdef VAD2 + CALL Lag_max(corr = corr + scal_sig = scal_sig + scal_fac = scal_fac + scal_flag = scal_flag + L_frame = L_frame + lag_max = lag_max + lag_min = lag_min + cor_max = cor_max + rmax = rmax + r0 = r0 + dtx = dtx + pOverflow = pOverflow) + MODIFYING(nothing) + RETURNING(temp) + +#else + CALL Lag_max(vadSt = vadSt + corr = corr + scal_sig = scal_sig + scal_fac = scal_fac + scal_flag = scal_flag + L_frame = L_frame + lag_max = lag_max + lag_min = lag_min + cor_max = cor_max + dtx = dtx + pOverflow = pOverflow) + MODIFYING(nothing) + RETURNING(temp) + +#endif + +------------------------------------------------------------------------------ + 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] + +------------------------------------------------------------------------------ +*/ + +#ifdef VAD2 +Word16 Lag_max_wrapper( /* o : lag found */ + Word32 corr[], /* i : correlation vector. */ + Word16 scal_sig[], /* i : scaled signal. */ + Word16 scal_fac, /* i : scaled signal factor. */ + Word16 scal_flag, /* i : if 1 use EFR compatible scaling */ + Word16 L_frame, /* i : length of frame to compute pitch */ + Word16 lag_max, /* i : maximum lag */ + Word16 lag_min, /* i : minimum lag */ + Word16 *cor_max, /* o : normalized correlation of selected lag */ + Word32 *rmax, /* o : max(<s[i]*s[j]>) */ + Word32 *r0, /* o : residual energy */ + Flag dtx, /* i : dtx flag; use dtx=1, do not use dtx=0 */ + Flag *pOverflow /* i/o : overflow Flag */ +) +{ + Word16 temp; + + temp = Lag_max(corr, scal_sig, scal_fac, scal_flag, L_frame, lag_max, + lag_min, cor_max, rmax, r0, dtx, pOverflow); + + return(temp); +} + +#else +Word16 Lag_max_wrapper( /* o : lag found */ + vadState *vadSt, /* i/o : VAD state struct */ + Word32 corr[], /* i : correlation vector. */ + Word16 scal_sig[], /* i : scaled signal. */ + Word16 scal_fac, /* i : scaled signal factor. */ + Word16 scal_flag, /* i : if 1 use EFR compatible scaling */ + Word16 L_frame, /* i : length of frame to compute pitch */ + Word16 lag_max, /* i : maximum lag */ + Word16 lag_min, /* i : minimum lag */ + Word16 *cor_max, /* o : normalized correlation of selected lag */ + Flag dtx, /* i : dtx flag; use dtx=1, do not use dtx=0 */ + Flag *pOverflow /* i/o : overflow Flag */ +) +{ + Word16 temp; + + temp = Lag_max(vadSt, corr, scal_sig, scal_fac, scal_flag, L_frame, + lag_max, lag_min, cor_max, dtx, pOverflow); + + return(temp); +} + +#endif + +/*---------------------------------------------------------------------------- +; End Function: Lag_max_wrapper +----------------------------------------------------------------------------*/ + +/* +------------------------------------------------------------------------------ + FUNCTION NAME: Pitch_ol +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + vadSt = pointer to a vadState structure + mode = data of type enum Mode specifies the mode. + signal = pointer to buffer of signal used to compute the open loop + pitch + where signal[-pit_max] to signal[-1] should be known + pit_min = 16 bit value specifies the minimum pitch lag + pit_max = 16 bit value specifies the maximum pitch lag + L_frame = 16 bit value specifies the length of frame to compute pitch + idx = 16 bit value specifies the frame index + dtx = Data of type 'Flag' used for dtx. Use dtx=1, do not use dtx=0 + pOverflow = pointer to overflow indicator (Flag) + + Outputs + vadSt = The vadSt state structure may be modified. + pOverflow -> 1 if the math operations called by this routine saturate + + Returns: + p_max1 = 16 bit value representing the open loop pitch lag. + + Global Variables Used: + None. + + Local Variables Needed: + None. + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This function computes the open loop pitch lag based on the perceptually + weighted speech signal. This is done in the following steps: + - find three maxima of the correlation <sw[n],sw[n-T]>, + dividing the search range into three parts: + pit_min ... 2*pit_min-1 + 2*pit_min ... 4*pit_min-1 + 4*pit_min ... pit_max + - divide each maximum by <sw[n-t], sw[n-t]> where t is the delay at + that maximum correlation. + - select the delay of maximum normalized correlation (among the + three candidates) while favoring the lower delay ranges. + + +------------------------------------------------------------------------------ + REQUIREMENTS + + None. + +------------------------------------------------------------------------------ + REFERENCES + + pitch_ol.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 + +------------------------------------------------------------------------------ + PSEUDO-CODE + +Word16 Pitch_ol ( // o : open loop pitch lag + vadState *vadSt, // i/o : VAD state struct + enum Mode mode, // i : coder mode + Word16 signal[], // i : signal used to compute the open loop pitch + // signal[-pit_max] to signal[-1] should be known + Word16 pit_min, // i : minimum pitch lag + Word16 pit_max, // i : maximum pitch lag + Word16 L_frame, // i : length of frame to compute pitch + Word16 idx, // i : frame index + Flag dtx // i : dtx flag; use dtx=1, do not use dtx=0 + ) +{ + Word16 i, j; + Word16 max1, max2, max3; + Word16 p_max1, p_max2, p_max3; + Word16 scal_flag = 0; + Word32 t0; +#ifdef VAD2 + Word32 r01, r02, r03; + Word32 rmax1, rmax2, rmax3; +#else + Word16 corr_hp_max; +#endif + Word32 corr[PIT_MAX+1], *corr_ptr; + + // Scaled signal + + Word16 scaled_signal[L_FRAME + PIT_MAX]; + Word16 *scal_sig, scal_fac; + +#ifndef VAD2 + if (dtx) + { // no test() call since this if is only in simulation env + // update tone detection + if ((sub(mode, MR475) == 0) || (sub(mode, MR515) == 0)) + { + vad_tone_detection_update (vadSt, 1); + } + else + { + vad_tone_detection_update (vadSt, 0); + } + } +#endif + + scal_sig = &scaled_signal[pit_max]; + + t0 = 0L; + for (i = -pit_max; i < L_frame; i++) + { + t0 = L_mac (t0, signal[i], signal[i]); + } + + *--------------------------------------------------------* + * Scaling of input signal. * + * * + * if Overflow -> scal_sig[i] = signal[i]>>3 * + * else if t0 < 1^20 -> scal_sig[i] = signal[i]<<3 * + * else -> scal_sig[i] = signal[i] * + *--------------------------------------------------------* + + *--------------------------------------------------------* + * Verification for risk of overflow. * + *--------------------------------------------------------* + + if (L_sub (t0, MAX_32) == 0L) // Test for overflow + { + for (i = -pit_max; i < L_frame; i++) + { + scal_sig[i] = shr (signal[i], 3); + } + scal_fac = 3; + } + else if (L_sub (t0, (Word32) 1048576L) < (Word32) 0) + // if (t0 < 2^20) + { + for (i = -pit_max; i < L_frame; i++) + { + scal_sig[i] = shl (signal[i], 3); + } + scal_fac = -3; + } + else + { + for (i = -pit_max; i < L_frame; i++) + { + scal_sig[i] = signal[i]; + } + scal_fac = 0; + } + + // calculate all coreelations of scal_sig, from pit_min to pit_max + corr_ptr = &corr[pit_max]; + comp_corr (scal_sig, L_frame, pit_max, pit_min, corr_ptr); + + *--------------------------------------------------------------------* + * The pitch lag search is divided in three sections. * + * Each section cannot have a pitch multiple. * + * We find a maximum for each section. * + * We compare the maximum of each section by favoring small lags. * + * * + * First section: lag delay = pit_max downto 4*pit_min * + * Second section: lag delay = 4*pit_min-1 downto 2*pit_min * + * Third section: lag delay = 2*pit_min-1 downto pit_min * + *--------------------------------------------------------------------* + + // mode dependent scaling in Lag_max + if (sub(mode, MR122) == 0) + { + scal_flag = 1; + } + else + { + scal_flag = 0; + } + +#ifdef VAD2 + j = shl (pit_min, 2); + p_max1 = Lag_max (corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, + pit_max, j, &max1, &rmax1, &r01, dtx); + + i = sub (j, 1); + j = shl (pit_min, 1); + p_max2 = Lag_max (corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, + i, j, &max2, &rmax2, &r02, dtx); + + i = sub (j, 1); + p_max3 = Lag_max (corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, + i, pit_min, &max3, &rmax3, &r03, dtx); +#else + j = shl (pit_min, 2); + p_max1 = Lag_max (vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, + pit_max, j, &max1, dtx); + + i = sub (j, 1); + j = shl (pit_min, 1); + p_max2 = Lag_max (vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, + i, j, &max2, dtx); + + i = sub (j, 1); + p_max3 = Lag_max (vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, + i, pit_min, &max3, dtx); + + if (dtx) + { // no test() call since this if is only in simulation env + if (sub(idx, 1) == 0) + { + // calculate max high-passed filtered correlation of all lags + hp_max (corr_ptr, scal_sig, L_frame, pit_max, pit_min, &corr_hp_max); + + // update complex background detector + vad_complex_detection_update(vadSt, corr_hp_max); + } + } +#endif + + *--------------------------------------------------------------------* + * Compare the 3 sections maximum, and favor small lag. * + *--------------------------------------------------------------------* + + if (sub (mult (max1, THRESHOLD), max2) < 0) + { + max1 = max2; + p_max1 = p_max2; +#ifdef VAD2 + if (dtx) + { + rmax1 = rmax2; + r01 = r02; +#endif + } + if (sub (mult (max1, THRESHOLD), max3) < 0) + { + p_max1 = p_max3; +#ifdef VAD2 + if (dtx) + { + rmax1 = rmax3; + r01 = r03; + } +#endif + } + +#ifdef VAD2 + if (dtx) + { + vadSt->L_Rmax = L_add(vadSt->L_Rmax, rmax1); // Save max correlation + vadSt->L_R0 = L_add(vadSt->L_R0, r01); // Save max energy + } +#endif + + return (p_max1); +} + +------------------------------------------------------------------------------ + 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 Pitch_ol( /* o : open loop pitch lag */ + vadState *vadSt, /* i/o : VAD state struct */ + enum Mode mode, /* i : coder mode */ + Word16 signal[], /* i : signal used to compute the open loop pitch */ + /* signal[-pit_max] to signal[-1] should be known */ + Word16 pit_min, /* i : minimum pitch lag */ + Word16 pit_max, /* i : maximum pitch lag */ + Word16 L_frame, /* i : length of frame to compute pitch */ + Word16 idx, /* i : frame index */ + Flag dtx, /* i : dtx flag; use dtx=1, do not use dtx=0 */ + Flag *pOverflow /* i/o : overflow Flag */ +) +{ + Word16 i; + Word16 j; + Word16 max1; + Word16 max2; + Word16 max3; + Word16 p_max1; + Word16 p_max2; + Word16 p_max3; + Word16 scal_flag = 0; + Word32 t0; + +#ifdef VAD2 + Word32 r01; + Word32 r02; + Word32 r03; + Word32 rmax1; + Word32 rmax2; + Word32 rmax3; +#else + Word16 corr_hp_max; +#endif + Word32 corr[PIT_MAX+1]; + Word32 *corr_ptr; + + /* Scaled signal */ + + Word16 scaled_signal[L_FRAME + PIT_MAX]; + Word16 *scal_sig; + Word16 *p_signal; + Word16 scal_fac; + Word32 L_temp; + +#ifndef VAD2 + if (dtx) + { /* no test() call since this if is only in simulation env */ + /* update tone detection */ + if ((mode == MR475) || (mode == MR515)) + { + vad_tone_detection_update(vadSt, 1, pOverflow); + } + else + { + vad_tone_detection_update(vadSt, 0, pOverflow); + } + } +#endif + + + t0 = 0L; + p_signal = &signal[-pit_max]; + + for (i = -pit_max; i < L_frame; i++) + { + t0 += (((Word32) * (p_signal)) * *(p_signal)) << 1; + p_signal++; + if (t0 < 0) + { + t0 = MAX_32; + break; + } + + } + + /*--------------------------------------------------------* + * Scaling of input signal. * + * * + * if Overflow -> scal_sig[i] = signal[i]>>3 * + * else if t0 < 1^20 -> scal_sig[i] = signal[i]<<3 * + * else -> scal_sig[i] = signal[i] * + *--------------------------------------------------------*/ + + /*--------------------------------------------------------* + * Verification for risk of overflow. * + *--------------------------------------------------------*/ + + scal_sig = &scaled_signal[0]; + p_signal = &signal[-pit_max]; + + if (t0 == MAX_32) /* Test for overflow */ + { + + for (i = (pit_max + L_frame) >> 1; i != 0; i--) + { + *(scal_sig++) = (Word16)(((Word32) * (p_signal++) >> 3)); + *(scal_sig++) = (Word16)(((Word32) * (p_signal++) >> 3)); + } + + if ((pit_max + L_frame) & 1) + { + *(scal_sig) = (Word16)(((Word32) * (p_signal) >> 3)); + } + + scal_fac = 3; + } + else if (t0 < (Word32)1048576L) + /* if (t0 < 2^20) */ + { + for (i = (pit_max + L_frame) >> 1; i != 0; i--) + { + *(scal_sig++) = (Word16)(((Word32) * (p_signal++) << 3)); + *(scal_sig++) = (Word16)(((Word32) * (p_signal++) << 3)); + } + + if ((pit_max + L_frame) & 1) + { + *(scal_sig) = (Word16)(((Word32) * (p_signal) << 3)); + } + scal_fac = -3; + } + else + { + + memcpy(scal_sig, p_signal, (L_frame + pit_max)*sizeof(*signal)); + scal_fac = 0; + } + + /* calculate all coreelations of scal_sig, from pit_min to pit_max */ + corr_ptr = &corr[pit_max]; + + scal_sig = &scaled_signal[pit_max]; + + comp_corr(scal_sig, L_frame, pit_max, pit_min, corr_ptr); + + /*--------------------------------------------------------------------* + * The pitch lag search is divided in three sections. * + * Each section cannot have a pitch multiple. * + * We find a maximum for each section. * + * We compare the maximum of each section by favoring small lags. * + * * + * First section: lag delay = pit_max downto 4*pit_min * + * Second section: lag delay = 4*pit_min-1 downto 2*pit_min * + * Third section: lag delay = 2*pit_min-1 downto pit_min * + *--------------------------------------------------------------------*/ + + /* mode dependent scaling in Lag_max */ + + if (mode == MR122) + { + scal_flag = 1; + } + else + { + scal_flag = 0; + } + +#ifdef VAD2 + L_temp = ((Word32)pit_min) << 2; + if (L_temp != (Word32)((Word16) L_temp)) + { + *pOverflow = 1; + j = (pit_min > 0) ? MAX_16 : MIN_16; + } + else + { + j = (Word16)L_temp; + } + + p_max1 = Lag_max(corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, + pit_max, j, &max1, &rmax1, &r01, dtx, pOverflow); + + i = j - 1; + + j = pit_min << 1; + + p_max2 = Lag_max(corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, + i, j, &max2, &rmax2, &r02, dtx, pOverflow); + + i = j - 1; + + p_max3 = Lag_max(corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, + i, pit_min, &max3, &rmax3, &r03, dtx, pOverflow); + +#else + L_temp = ((Word32)pit_min) << 2; + if (L_temp != (Word32)((Word16) L_temp)) + { + *pOverflow = 1; + j = (pit_min > 0) ? MAX_16 : MIN_16; + } + else + { + j = (Word16)L_temp; + } + + p_max1 = Lag_max(vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, + pit_max, j, &max1, dtx, pOverflow); + + i = j - 1; + + + j = pit_min << 1; + + + p_max2 = Lag_max(vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, + i, j, &max2, dtx, pOverflow); + + i = j - 1; + p_max3 = Lag_max(vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, + i, pit_min, &max3, dtx, pOverflow); + + if (dtx) + { /* no test() call since this if is only in simulation env */ + + if (idx == 1) + { + /* calculate max high-passed filtered correlation of all lags */ + hp_max(corr_ptr, scal_sig, L_frame, pit_max, pit_min, &corr_hp_max, + pOverflow); + + /* update complex background detector */ + vad_complex_detection_update(vadSt, corr_hp_max); + } + } +#endif + + /*--------------------------------------------------------------------* + * Compare the 3 sections maximum, and favor small lag. * + *--------------------------------------------------------------------*/ + + i = mult(max1, THRESHOLD, pOverflow); + + if (i < max2) + { + max1 = max2; + p_max1 = p_max2; + +#ifdef VAD2 + if (dtx) + { + rmax1 = rmax2; + r01 = r02; + } +#endif + } + + i = mult(max1, THRESHOLD, pOverflow); + + if (i < max3) + { + p_max1 = p_max3; + +#ifdef VAD2 + if (dtx) + { + rmax1 = rmax3; + r01 = r03; + } +#endif + } + +#ifdef VAD2 + if (dtx) + { + /* Save max correlation */ + vadSt->L_Rmax = L_add(vadSt->L_Rmax, rmax1, pOverflow); + /* Save max energy */ + vadSt->L_R0 = L_add(vadSt->L_R0, r01, pOverflow); + } +#endif + + return (p_max1); +} |