FreeCalypso > hg > gsm-codec-lib
diff libtwamr/p_ol_wgh.c @ 416:48c7f8e8c9af
libtwamr: integrate p_ol_wgh.c
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 07 May 2024 03:15:19 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libtwamr/p_ol_wgh.c Tue May 07 03:15:19 2024 +0000 @@ -0,0 +1,290 @@ +/* +***************************************************************************** +* +* GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001 +* R99 Version 3.3.0 +* REL-4 Version 4.1.0 +* +***************************************************************************** +* +* File : p_ol_wgh.c +* Purpose : Compute the open loop pitch lag with weighting +* +*************************************************************************/ +/* +******************************************************************************** +* MODULE INCLUDE FILE AND VERSION ID +******************************************************************************** +*/ +#include "namespace.h" +#include "p_ol_wgh.h" + +/* +***************************************************************************** +* INCLUDE FILES +***************************************************************************** +*/ +#include "typedef.h" +#include "basic_op.h" +#include "oper_32b.h" +#include "no_count.h" +#include "cnst.h" +#include "corrwght.tab" +#include "gmed_n.h" +#include "inv_sqrt.h" +#include "vad.h" +#include "calc_cor.h" +#include "hp_max.h" + +/* +***************************************************************************** +* LOCAL VARIABLES AND TABLES +***************************************************************************** +*/ +/************************************************************************* + * + * FUNCTION: Lag_max + * + * PURPOSE: Find the lag that has maximum correlation of scal_sig[] in a + * given delay range. + * + * DESCRIPTION: + * The correlation is given by + * cor[t] = <scal_sig[n],scal_sig[n-t]>, t=lag_min,...,lag_max + * The functions outputs the maximum correlation after normalization + * and the corresponding lag. + * + *************************************************************************/ +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 L_frame, /* i : length of frame to compute pitch */ + Word16 lag_max, /* i : maximum lag */ + Word16 lag_min, /* i : minimum lag */ + Word16 old_lag, /* i : old open-loop lag */ + Word16 *cor_max, /* o : normalized correlation of selected lag */ + Word16 wght_flg, /* i : is weighting function used */ + Word16 *gain_flg, /* o : open-loop flag */ + Flag dtx /* i : dtx flag; use dtx=1, do not use dtx=0 */ + ) +{ + Word16 i, j; + Word16 *p, *p1; + Word32 max, t0; + Word16 t0_h, t0_l; + Word16 p_max; + const Word16 *ww, *we; + Word32 t1; + + ww = &corrweight[250]; move16 (); + we = &corrweight[123 + lag_max - old_lag]; move16 (); + + max = MIN_32; move32 (); + p_max = lag_max; move16 (); + + for (i = lag_max; i >= lag_min; i--) + { + t0 = corr[-i]; move32 (); + + /* Weighting of the correlation function. */ + L_Extract (corr[-i], &t0_h, &t0_l); + t0 = Mpy_32_16 (t0_h, t0_l, *ww); + ww--; move16(); + test (); + if (wght_flg > 0) { + /* Weight the neighbourhood of the old lag. */ + L_Extract (t0, &t0_h, &t0_l); + t0 = Mpy_32_16 (t0_h, t0_l, *we); + we--; move16(); + } + + test (); + if (L_sub (t0, max) >= 0) + { + max = t0; move32 (); + p_max = i; move16 (); + } + } + + p = &scal_sig[0]; move16 (); + p1 = &scal_sig[-p_max]; move16 (); + t0 = 0; move32 (); + t1 = 0; move32 (); + + for (j = 0; j < L_frame; j++, p++, p1++) + { + t0 = L_mac (t0, *p, *p1); + t1 = L_mac (t1, *p1, *p1); + } + + if (dtx) + { /* no test() call since this if is only in simulation env */ + if (vadSt->use_vad2) { + /* Save max correlation */ + vadSt->u.v2.L_Rmax = L_add(vadSt->u.v2.L_Rmax, t0); + /* Save max energy */ + vadSt->u.v2.L_R0 = L_add(vadSt->u.v2.L_R0, t1); + } else { + /* update and detect tone */ + vad_tone_detection_update (&vadSt->u.v1, 0); + vad_tone_detection (&vadSt->u.v1, t0, t1); + } + } + + /* gain flag is set according to the open_loop gain */ + /* is t2/t1 > 0.4 ? */ + *gain_flg = round(L_msu(t0, round(t1), 13107)); move16(); + + *cor_max = 0; move16 (); + + return (p_max); +} + +/* +***************************************************************************** +* PUBLIC PROGRAM CODE +***************************************************************************** +*/ + +/************************************************************************* +* +* Function: p_ol_wgh_reset +* Purpose: Initializes state memory to zero +* +************************************************************************** +*/ +void p_ol_wgh_reset (pitchOLWghtState *st) +{ + /* Reset pitch search states */ + st->old_T0_med = 40; + st->ada_w = 0; + st->wght_flg = 0; +} + +/************************************************************************* +* +* Function: p_ol_wgh +* Purpose: open-loop pitch search with weighting +* +************************************************************************** +*/ +Word16 Pitch_ol_wgh ( /* o : open loop pitch lag */ + pitchOLWghtState *st, /* i/o : State struct */ + vadState *vadSt, /* i/o : VAD state struct */ + 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 old_lags[], /* i : history with old stored Cl lags */ + Word16 ol_gain_flg[], /* i : OL gain flag */ + Word16 idx, /* i : index */ + Flag dtx /* i : dtx flag; use dtx=1, do not use dtx=0 */ + ) +{ + Word16 i; + Word16 max1; + Word16 p_max1; + Word32 t0; + Word16 corr_hp_max; + Word32 corr[PIT_MAX+1], *corr_ptr; + + /* Scaled signal */ + Word16 scaled_signal[PIT_MAX + L_FRAME]; + Word16 *scal_sig; + + scal_sig = &scaled_signal[pit_max]; move16 (); + + t0 = 0L; move32 (); + 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]>>2 * + * else if t0 < 1^22 -> scal_sig[i] = signal[i]<<2 * + * else -> scal_sig[i] = signal[i] * + *--------------------------------------------------------*/ + + /*--------------------------------------------------------* + * Verification for risk of overflow. * + *--------------------------------------------------------*/ + + test (); test (); + 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); move16 (); + } + } + else if (L_sub (t0, (Word32) 1048576L) < (Word32) 0) + { + for (i = -pit_max; i < L_frame; i++) + { + scal_sig[i] = shl (signal[i], 3); move16 (); + } + } + else + { + for (i = -pit_max; i < L_frame; i++) + { + scal_sig[i] = signal[i]; move16 (); + } + } + + /* calculate all coreelations of scal_sig, from pit_min to pit_max */ + corr_ptr = &corr[pit_max]; move32 (); + comp_corr (scal_sig, L_frame, pit_max, pit_min, corr_ptr); + + p_max1 = Lag_max (vadSt, corr_ptr, scal_sig, L_frame, pit_max, pit_min, + st->old_T0_med, &max1, st->wght_flg, &ol_gain_flg[idx], + dtx); + move16 (); + + test (); move16 (); + if (ol_gain_flg[idx] > 0) + { + /* Calculate 5-point median of previous lags */ + for (i = 4; i > 0; i--) /* Shift buffer */ + { + old_lags[i] = old_lags[i-1]; move16 (); + } + old_lags[0] = p_max1; move16 (); + st->old_T0_med = gmed_n (old_lags, 5); move16 (); + st->ada_w = 32767; move16 (); /* Q15 = 1.0 */ + } + else + { + st->old_T0_med = p_max1; move16 (); + st->ada_w = mult(st->ada_w, 29491); /* = ada_w = ada_w * 0.9 */ + } + + test (); + if (sub(st->ada_w, 9830) < 0) /* ada_w - 0.3 */ + { + st->wght_flg = 0; move16 (); + } + else + { + st->wght_flg = 1; move16 (); + } + + if (dtx && !vadSt->use_vad2) + { /* no test() call since this if is only in simulation env */ + test (); + 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->u.v1, corr_hp_max); + } + } + + return (p_max1); +}