FreeCalypso > hg > gsm-codec-lib
changeset 415:01c4becb9fda
libtwamr: integrate pitch_ol.c
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 07 May 2024 03:01:01 +0000 |
parents | 028ed5114e52 |
children | 48c7f8e8c9af |
files | libtwamr/Makefile libtwamr/namespace.list libtwamr/pitch_ol.c libtwamr/pitch_ol.h |
diffstat | 4 files changed, 409 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/libtwamr/Makefile Tue May 07 02:06:47 2024 +0000 +++ b/libtwamr/Makefile Tue May 07 03:01:01 2024 +0000 @@ -10,13 +10,13 @@ g_adapt.o g_code.o g_pitch.o gain_q.o gains_tab.o gc_pred.o gmed_n.o \ graytab.o hp_max.o int_lpc.o int_lsf.o inter_36.o inv_sqrt.o lag_wind.o\ levinson.o lflg_upd.o log2.o lpc.o lsfwt.o lsp.o lsp_avg.o lsp_az.o \ - lsp_lsf.o lsp_tab.o mac_32.o oper_32b.o ph_disp.o pitch_fr.o post_pro.o\ - pow2.o pre_big.o pre_proc.o pred_lt.o preemph.o prm2bits.o prmno.o \ - pstfilt.o q_gain_c.o q_gain_p.o q_plsf.o q_plsf3_tab.o q_plsf5_tab.o \ - q_plsf_3.o q_plsf_5.o qgain475.o qgain795.o qua_gain.o qua_gain_tab.o \ - r_fft.o reorder.o residu.o s10_8pf.o set_sign.o sid_sync.o spreproc.o \ - spstproc.o sqrt_l.o syn_filt.o tls_flags.o ton_stab.o vad1.o vad2.o \ - vad_reset.o weight_a.o window.o + lsp_lsf.o lsp_tab.o mac_32.o oper_32b.o ph_disp.o pitch_fr.o pitch_ol.o\ + post_pro.o pow2.o pre_big.o pre_proc.o pred_lt.o preemph.o prm2bits.o \ + prmno.o pstfilt.o q_gain_c.o q_gain_p.o q_plsf.o q_plsf3_tab.o \ + q_plsf5_tab.o q_plsf_3.o q_plsf_5.o qgain475.o qgain795.o qua_gain.o \ + qua_gain_tab.o r_fft.o reorder.o residu.o s10_8pf.o set_sign.o \ + sid_sync.o spreproc.o spstproc.o sqrt_l.o syn_filt.o tls_flags.o \ + ton_stab.o vad1.o vad2.o vad_reset.o weight_a.o window.o HDRS= a_refl.h agc.h autocorr.h az_lsp.h b_cn_cod.h basic_op.h bgnscd.h \ bitno.h bits2prm.h c1035pf.h c2_11pf.h c2_9pf.h c3_14pf.h c4_17pf.h \ c8_31pf.h c_g_aver.h calc_cor.h calc_en.h cbsearch.h cl_ltp.h cnst.h \ @@ -28,10 +28,10 @@ int_lpc.h int_lsf.h inter_36.h inv_sqrt.h lag_wind.h levinson.h log2.h \ lpc.h lsfwt.h lsp.h lsp_avg.h lsp_az.h lsp_lsf.h lsp_tab.h mac_32.h \ memops.h namespace.h no_count.h oper_32b.h ph_disp.h pitch_fr.h \ - post_pro.h pow2.h pre_big.h pre_proc.h pred_lt.h preemph.h prm2bits.h \ - pstfilt.h q_gain_c.h q_gain_p.h q_plsf.h q_plsf3_tab.h q_plsf5_tab.h \ - qgain475.h qgain795.h qua_gain.h qua_gain_tab.h reorder.h residu.h \ - s10_8pf.h set_sign.h sid_sync.h spreproc.h spstproc.h sqrt_l.h \ + pitch_ol.h post_pro.h pow2.h pre_big.h pre_proc.h pred_lt.h preemph.h \ + prm2bits.h pstfilt.h q_gain_c.h q_gain_p.h q_plsf.h q_plsf3_tab.h \ + q_plsf5_tab.h qgain475.h qgain795.h qua_gain.h qua_gain_tab.h reorder.h\ + residu.h s10_8pf.h set_sign.h sid_sync.h spreproc.h spstproc.h sqrt_l.h\ syn_filt.h ton_stab.h tw_amr.h typedef.h vad.h vad1.h vad2.h weight_a.h\ window.h LIB= libtwamr.a
--- a/libtwamr/namespace.list Tue May 07 02:06:47 2024 +0000 +++ b/libtwamr/namespace.list Tue May 07 03:01:01 2024 +0000 @@ -27,7 +27,7 @@ Int_lsf Interpol_3or6 Lag_window Levinson Levinson_reset Lsf_lsp Lsp_lsf Reorder_lsf Lsf_wt Lsp_Az -Pitch_fr Pitch_fr_reset +Pitch_fr Pitch_fr_reset Pitch_ol Pre_Process Pre_Process_reset Pred_lt_3or6 Post_Filter Post_Filter_reset Post_Process Post_Process_reset Q_plsf_reset Q_plsf_3 Q_plsf_5 Qua_gain
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libtwamr/pitch_ol.c Tue May 07 03:01:01 2024 +0000 @@ -0,0 +1,347 @@ +/* +******************************************************************************** +* +* 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 : pitch_ol.c +* Purpose : Compute the open loop pitch lag. +* +******************************************************************************** +*/ +/* +******************************************************************************** +* MODULE INCLUDE FILE AND VERSION ID +******************************************************************************** +*/ +#include "namespace.h" +#include "pitch_ol.h" +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "typedef.h" +#include "basic_op.h" +#include "oper_32b.h" +#include "no_count.h" +#include "cnst.h" +#include "inv_sqrt.h" +#include "vad.h" +#include "calc_cor.h" +#include "hp_max.h" + +/* +******************************************************************************** +* LOCAL VARIABLES AND TABLES +******************************************************************************** +*/ +#define THRESHOLD 27853 + +/* +******************************************************************************** +* LOCAL PROGRAM CODE +******************************************************************************** +*/ +/************************************************************************* + * + * 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 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 */ + ) +{ + 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; move32 (); + p_max = lag_max; move16 (); + + for (i = lag_max, j = (PIT_MAX-lag_max-1); i >= lag_min; i--, j--) + { + test (); + if (L_sub (corr[-i], max) >= 0) + { + max = corr[-i]; move32 (); + p_max = i; move16 (); + } + } + + /* compute energy */ + + t0 = 0; move32 (); + p = &scal_sig[-p_max]; move16 (); + 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 */ + *rmax = max; move32(); + *r0 = t0; move32(); + /* check tone */ + if (!vadSt->use_vad2) + vad_tone_detection (&vadSt->u.v1, max, t0); + } + + t0 = Inv_sqrt (t0); move32 (); /* function result */ + + test(); + 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); + + test(); + 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); +} + +/* +******************************************************************************** +* PUBLIC PROGRAM CODE +******************************************************************************** +*/ +/************************************************************************* + * + * FUNCTION: Pitch_ol + * + * PURPOSE: Compute the open loop pitch lag. + * + * DESCRIPTION: + * The open-loop pitch lag is determined 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. + * + *************************************************************************/ +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; + Word32 r01, r02, r03; + Word32 rmax1, rmax2, rmax3; + Word16 corr_hp_max; + Word32 corr[PIT_MAX+1], *corr_ptr; + + /* Scaled signal */ + + Word16 scaled_signal[L_FRAME + PIT_MAX]; + Word16 *scal_sig, scal_fac; + + if (dtx && !vadSt->use_vad2) + { /* no test() call since this if is only in simulation env */ + /* update tone detection */ + test(); test(); + if ((sub(mode, MR475) == 0) || (sub(mode, MR515) == 0)) + { + vad_tone_detection_update (&vadSt->u.v1, 1); + } + else + { + vad_tone_detection_update (&vadSt->u.v1, 0); + } + } + + 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]>>3 * + * else if t0 < 1^20 -> scal_sig[i] = signal[i]<<3 * + * else -> scal_sig[i] = signal[i] * + *--------------------------------------------------------*/ + + /*--------------------------------------------------------* + * Verification for risk of overflow. * + *--------------------------------------------------------*/ + + 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 (); + } + scal_fac = 3; move16 (); + } + else if (L_sub (t0, (Word32) 1048576L) < (Word32) 0) + /* if (t0 < 2^20) */ + { + test (); + for (i = -pit_max; i < L_frame; i++) + { + scal_sig[i] = shl (signal[i], 3); move16 (); + } + scal_fac = -3; move16 (); + } + else + { + test (); + for (i = -pit_max; i < L_frame; i++) + { + scal_sig[i] = signal[i]; move16 (); + } + scal_fac = 0; 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); + + /*--------------------------------------------------------------------* + * 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 */ + test (); + if (sub(mode, MR122) == 0) + { + scal_flag = 1; move16 (); + } + else + { + scal_flag = 0; move16 (); + } + + j = shl (pit_min, 2); + p_max1 = Lag_max (vadSt, 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 (vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, + i, j, &max2, &rmax2, &r02, dtx); + + i = sub (j, 1); + p_max3 = Lag_max (vadSt, corr_ptr, scal_sig, scal_fac, scal_flag, L_frame, + i, pit_min, &max3, &rmax3, &r03, dtx); + + 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); + } + } + + /*--------------------------------------------------------------------* + * Compare the 3 sections maximum, and favor small lag. * + *--------------------------------------------------------------------*/ + + test (); + if (sub (mult (max1, THRESHOLD), max2) < 0) + { + max1 = max2; move16 (); + p_max1 = p_max2; move16 (); + if (dtx) + { + rmax1 = rmax2; move32 (); + r01 = r02; move32 (); + } + } + test (); + if (sub (mult (max1, THRESHOLD), max3) < 0) + { + p_max1 = p_max3; move16 (); + if (dtx) + { + rmax1 = rmax3; move32 (); + r01 = r03; move32 (); + } + } + + if (dtx && vadSt->use_vad2) + { + /* Save max correlation */ + vadSt->u.v2.L_Rmax = L_add(vadSt->u.v2.L_Rmax, rmax1); + /* Save max energy */ + vadSt->u.v2.L_R0 = L_add(vadSt->u.v2.L_R0, r01); + } + + return (p_max1); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libtwamr/pitch_ol.h Tue May 07 03:01:01 2024 +0000 @@ -0,0 +1,50 @@ +/* +******************************************************************************** +* +* 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 : pitch_ol.h +* Purpose : Compute the open loop pitch lag. +* +******************************************************************************** +*/ +#ifndef pitch_ol_h +#define pitch_ol_h "$Id $" + +/* +******************************************************************************** +* INCLUDE FILES +******************************************************************************** +*/ +#include "tw_amr.h" +#include "typedef.h" +#include "vad.h" + +/* +******************************************************************************** +* DEFINITION OF DATA TYPES +******************************************************************************** +*/ + +/* +******************************************************************************** +* DECLARATION OF PROTOTYPES +******************************************************************************** +*/ +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 */ + ); + +#endif