📄 pitch_ol.cpp
字号:
/* ------------------------------------------------------------------ * Copyright (C) 2008 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 licenseterms listed above has been obtained from the copyright holder.****************************************************************************************//*------------------------------------------------------------------------------ Pathname: ./audio/gsm-amr/c/src/pitch_ol.c Funtions: Pitch_ol Lag_max Date: 06/15/2000------------------------------------------------------------------------------ REVISION HISTORY Description: Placed into PV template and began optimization. Description: Made changes based on review meeting. Description: Fixed bug in Pitch_ol that causes function to not be bit-exact with the original version. This was done by adding an extra call to mult after the first IF statement when comparing the three section maximums (towards the end of the function). Fixed tabs. Synced-up Lag_max_wrapper with template. Description: Synchronized file with UMTS version 3.2.0. Updated coding template. Removed unnecessary include file. Description: Added code that compares max1 to THRESHOLD value prior to comparison with max3. Description: Replaced basic_op.h and oper_32b.h with the header files of the math functions used in this file. Fixed typecasting issue with the TI C compiler. Description: Made the following changes per comments from Phase 2/3 review: 1. Defined one local variable per line. 2. Added more comments to the code. Description: Passing in pointer to overflow flag for EPOC compatibility Description: For Lag_max() and Pitch_ol() 1. Eliminated unused include files. 2. Replaced array addressing by pointers 3. Eliminated math operations that unnecessary checked for saturation, in some cases this by shifting before adding and in other cases by evaluating the operands 4. Unrolled loops to speed up processing, use decrement loops 5. Eliminated if-else statements for sign extension when right-shifting 6. Replaced for-loop with memcpy() 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 l_add.h in Include section. Description: Using intrinsics from fxp_arithmetic.h . Description: Replacing fxp_arithmetic.h with basic_op.h. Description:------------------------------------------------------------------------------ MODULE DESCRIPTION The modules in this file compute the open loop pitch lag.------------------------------------------------------------------------------*//*----------------------------------------------------------------------------; INCLUDES----------------------------------------------------------------------------*/#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 "oscl_mem.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 VAD2static 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 )#elsestatic 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 VAD2static 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 */)#elsestatic 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++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -