📄 g729ev_g729_pitch.c
字号:
/* ITU-T G.729EV Optimization/Characterization Candidate *//* Version: 1.0.a *//* Revision Date: June 28, 2006 *//* ITU-T G.729EV Optimization/Characterization Candidate ANSI-C Source Code Copyright (c) 2006 France Telecom, Matsushita Electric, Mindspeed, Siemens AG, ETRI, VoiceAge Corp. All rights reserved*//*---------------------------------------------------------------------------* * procedure G729EV_G729_Pitch_ol * * ~~~~~~~~~~~~~~~~~~ * * Compute the open loop pitch lag. * * * *---------------------------------------------------------------------------*/#include "stl.h"#include "G729EV_MAIN_OPER_32B.h"#include "G729EV_G729_ld8k.h"#include "G729EV_G729_TAB_ld8k.h"#include "G729EV_MAIN_DSPFUNC.h"#include "G729EV_MAIN_defines.h"#if (WMOPS)#include "count.h"#endif/* local function */static Word16 G729EV_G729_Lag_max( /* output: lag found */ Word16 signal[], /* input : signal used to compute the open loop pitch */ Word16 L_frame, /* input : length of frame to compute pitch */ Word16 lag_max, /* input : maximum lag */ Word16 lag_min, /* input : minimum lag */ Word16 * cor_max, Word16 * voicing); /* output: normalized correlation of selected lag */static void G729EV_G729_Norm_Corr(Word16 exc[], Word16 xn[], Word16 h[], Word16 L_subfr, Word16 t_min, Word16 t_max, Word16 corr_norm[]);Word16 G729EV_G729_Pitch_ol( /* output: open loop pitch lag */ Word16 signal[], /* input : signal used to compute the open loop pitch */ /* signal[-pit_max] to signal[-1] should be known */ Word16 pit_min, /* input : minimum pitch lag */ Word16 pit_max, /* input : maximum pitch lag */ Word16 L_frame, /* input : length of frame to compute pitch */ Word16 * voicing, Word16 * pit_old){ Word32 t0, L_temp; Word16 i, j; Word16 max1, max2, max3; Word16 p_max1, p_max2, p_max3; /* Scaled signal */ Word16 scaled_signal[G729EV_G729_L_FRAME + G729EV_G729_PIT_MAX]; Word16 *scal_sig; Word16 thresh; scal_sig = &scaled_signal[pit_max]; /*--------------------------------------------------------* * Verification for risk of overflow. * *--------------------------------------------------------*/#if (WMOPS) move16(); move32();#endif Overflow = 0; t0 = 0; 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] * *--------------------------------------------------------*/ IF(sub((Word16) Overflow, 1) == 0) { FOR(i = -pit_max; i < L_frame; i++) { scal_sig[i] = shr(signal[i], 3);#if (WMOPS) move16();#endif } } ELSE { L_temp = L_sub(t0, (Word32) 1048576L); IF(L_temp < (Word32) 0) /* if (t0 < 2^20) */ { FOR(i = -pit_max; i < L_frame; i++) { scal_sig[i] = shl(signal[i], 3);#if (WMOPS) move16();#endif } } ELSE { FOR(i = -pit_max; i < L_frame; i++) {#if (WMOPS) move16();#endif scal_sig[i] = signal[i]; } } } /*--------------------------------------------------------------------* * 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 lag. * * * * 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 * *--------------------------------------------------------------------*/ j = shl(pit_min, 2); p_max1 = G729EV_G729_Lag_max(scal_sig, L_frame, pit_max, j, &max1, &voicing[0]); i = sub(j, 1); j = shl(pit_min, 1); p_max2 = G729EV_G729_Lag_max(scal_sig, L_frame, i, j, &max2, &voicing[1]); i = sub(j, 1); p_max3 = G729EV_G729_Lag_max(scal_sig, L_frame, i, pit_min, &max3, &voicing[2]); /*--------------------------------------------------------------------* * Compare the 3 sections maximum, and favor small lag. * *--------------------------------------------------------------------*/#if (WMOPS) move16();#endif IF(sub(abs_s(sub(*pit_old, p_max2)), 10) < 0) { thresh = 22938; /*0.7f */ } ELSE { thresh = 29491; /*0.9f */ } if (sub(mult(max1, thresh), max2) < 0) { max1 = max2; p_max1 = p_max2;#if (WMOPS) move16(); move16();#endif }#if (WMOPS) move16();#endif IF(sub(abs_s(sub(*pit_old, p_max3)), 5) < 0) { thresh = 22938; /*0.7f */ } ELSE { thresh = 29491; /*0.9f */ } if (sub(mult(max1, thresh), max3) < 0) { p_max1 = p_max3;#if (WMOPS) move16();#endif }#if (WMOPS) move16();#endif *pit_old = p_max1; /* Keep maximum voicing in voicing[0] */ if (sub(voicing[1], voicing[0]) > 0) {#if (WMOPS) move16();#endif voicing[0] = voicing[1]; } if (sub(voicing[2], voicing[0]) > 0) {#if (WMOPS) move16();#endif voicing[0] = voicing[2]; } return (p_max1);}/*---------------------------------------------------------------------------* * procedure G729EV_G729_Lag_max * * ~~~~~~~~~~~~~~~~~ * * Find the lag that has maximum correlation with scal_sig[] * * * *---------------------------------------------------------------------------* * arguments: * * * * signal[] :Signal used to compute the open loop pitch. * * L_frame :Length of frame to compute pitch. * * lag_max :Maximum lag * * lag_min :Minimum lag * * *cor_max ;Maximum of normalized correlation of lag found. * * * * Return lag found. * *--------------------------------------------------------------------------*/static Word16 G729EV_G729_Lag_max( /* output: lag found */ Word16 signal[], /* input : signal used to compute the open loop pitch */ Word16 L_frame, /* input : length of frame to compute pitch */ Word16 lag_max, /* input : maximum lag */ Word16 lag_min, /* input : minimum lag */ Word16 * cor_max, Word16 * voicing) /* output: normalized correlation of selected lag */{ Word32 max, t0, L_temp; Word32 t1; Word16 exp_h, exp_l; Word16 i, j; Word16 *p, *p1; Word16 max_h, max_l, ener_h, ener_l; Word16 p_max;#if (WMOPS) move16(); move32();#endif max = MIN_32; /* initialization used only to suppress Microsoft Visual C++ warnings */ p_max = lag_max; FOR(i = lag_max; i >= lag_min; i--) {#if (WMOPS) move32();#endif p = signal; p1 = &signal[-i]; t0 = 0; FOR(j = 0; j < L_frame; j++) { t0 = L_mac(t0, *p, *p1); p++; p1++; } L_temp = L_sub(t0, max); if (L_temp >= 0L) {#if (WMOPS) move32(); move16();#endif max = t0; p_max = i; } } /* compute energy */#if (WMOPS) move32();#endif t0 = 0; p = &signal[-p_max]; FOR(i = 0; i < L_frame; i++) { t0 = L_mac(t0, *p, *p); p++; }#if (WMOPS) move32();#endif L_temp = t0; /* 1/sqrt(energy), result in Q30 */ t0 = Inv_sqrt(t0); /* max = max/sqrt(energy) */ /* This result will always be on 16 bits !! */ 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); *cor_max = extract_l(t0);#if(WMOPS) move16(); move32();#endif t1 = 0; p = signal; FOR(i = 0; i < L_frame; i++) { t1 = L_mac(t1, *p, *p); p++; } L_Extract(L_temp, &ener_h, &ener_l); L_Extract(t1, &exp_h, &exp_l); t1 = L_shr(Mpy_32(exp_h, exp_l, ener_h, ener_l), 1); t1 = Inv_sqrt(t1); L_Extract(t1, &ener_h, &ener_l); t0 = Mpy_32(max_h, max_l, ener_h, ener_l); *voicing = extract_h(L_shl(t0, 16));#if(WMOPS) move16();#endif return (p_max);}/*--------------------------------------------------------------------------* * Function G729EV_G729_Pitch_fr3() * * ~~~~~~~~~~~~~~~~~~~~~ * * Find the pitch period with 1/3 subsample resolution. * *--------------------------------------------------------------------------*/ /* Local functions */Word16 G729EV_G729_Pitch_fr3( /* (o) : pitch period. */ Word16 exc[], /* (i) : excitation buffer */ Word16 xn[], /* (i) : target vector */ Word16 h[], /* (i) Q12 : impulse response of filters. */ Word16 L_subfr, /* (i) : Length of subframe */ Word16 t0_min, /* (i) : minimum value in the searched range. */ Word16 t0_max, /* (i) : maximum value in the searched range. */ Word16 i_subfr, /* (i) : indicator for first subframe. */ Word16 * pit_frac /* (o) : chosen fraction. */ ){ Word16 corr_v[40]; /* Total length = t0_max-t0_min+1+2*L_INTER */ Word16 *corr; Word16 i; Word16 t_min, t_max; Word16 max, lag, frac; Word16 corr_int; /* Find interval to compute normalized correlation */ t_min = sub(t0_min, G729EV_G729_L_INTER4); t_max = add(t0_max, G729EV_G729_L_INTER4); corr = &corr_v[-t_min]; /* Compute normalized correlation between target and filtered excitation */ G729EV_G729_Norm_Corr(exc, xn, h, L_subfr, t_min, t_max, corr); /* Find integer pitch */#if (WMOPS) move16(); move16();#endif max = corr[t0_min]; lag = t0_min; FOR(i = t0_min + (Word16) 1; i <= t0_max; i++) { if (sub(corr[i], max) >= 0) {#if (WMOPS) move16(); move16();#endif max = corr[i]; lag = i; } } /* If first subframe and lag > 84 do not search fractional pitch */#if (WMOPS) test();#endif if ((i_subfr == 0) && (sub(lag, 84) > 0)) {#if (WMOPS) move16();#endif *pit_frac = 0; return (lag); } /* Test the fractions around T0 and choose the one which maximizes */ /* the interpolated normalized correlation. */ max = G729EV_G729_Interpol_3(&corr[lag], -2);#if (WMOPS) move16();#endif frac = -2; FOR(i = -1; i <= 2; i++) { corr_int = G729EV_G729_Interpol_3(&corr[lag], i); if (sub(corr_int, max) > 0) {#if (WMOPS) move16(); move16();#endif max = corr_int; frac = i; } } /* limit the fraction value between -1 and 1 */ if (sub(frac, -2) == 0) {#if (WMOPS) move16();#endif frac = 1; lag = sub(lag, 1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -