diff --git a/lib_com/options.h b/lib_com/options.h index 1226491d10e2f56176913942bc9e905ad1fde580..b3fbecfb0ce2b33a8c1bb76f5a28822ec22538a6 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -91,6 +91,7 @@ #define FIX_1990_SANITIZER_IN_REVERB_LOAD /* Nokia: Fix issue part of issue 1990 by introducing missing free of structure. */ #define FIX_1995_REVERB_INIT /* VA/Nokia: issue 1995: Fix use-of-uninitialized-value in ivas_binaural_reverb_init() */ #define FIX_1996_MASKING_NOISE /* Dlb: Heavy precision loss in ola buffers causing discontinuity*/ +#define FIX1998_APA_EXEC_SCALING /* FhG: fix scaling of apa_exec_ivas_fx(); avoid continuously worse scaling with previous data */ /* #################### Start BASOP porting switches ############################ */ diff --git a/lib_dec/jbm_pcmdsp_apa_fx.c b/lib_dec/jbm_pcmdsp_apa_fx.c index 0fde6543fc8d7204163a0e83800fca78cb37bdda..94b4cb6bd2dfd1c680ce42e927414bd24934c6d3 100644 --- a/lib_dec/jbm_pcmdsp_apa_fx.c +++ b/lib_dec/jbm_pcmdsp_apa_fx.c @@ -76,7 +76,10 @@ struct apa_state_t bool evs_compat_mode; Word16 *buf_out_fx; - Word16 Q_buf_out; + Word16 Q_buf_out; /* stores the scaling of buf_out_fx */ +#ifdef FIX1998_APA_EXEC_SCALING + Word16 Q_a_out_init_old; /* stores initially determined max. scaling of data in buf_out_fx, before beeing adjusted to previous frame scaling */ +#endif UWord16 buf_out_capacity; UWord16 l_buf_out; @@ -190,6 +193,10 @@ ivas_error apa_init( } memset( ps->buf_out_fx, 0, ( sizeof( Word16 ) * ps->buf_out_capacity ) ); ps->Q_buf_out = Q15; +#ifdef FIX1998_APA_EXEC_SCALING + ps->Q_a_out_init_old = Q15; + move16(); +#endif move16(); ps->evs_compat_mode = false; @@ -272,6 +279,10 @@ UWord8 apa_reconfigure( ps->buf_out_fx = (Word16 *) malloc( sizeof( Word16 ) * ps->buf_out_capacity ); memset( ps->buf_out_fx, 0, ( sizeof( Word16 ) * ps->buf_out_capacity ) ); ps->Q_buf_out = Q15; +#ifdef FIX1998_APA_EXEC_SCALING + ps->Q_a_out_init_old = Q15; + move16(); +#endif move16(); IF( !ps->buf_out_fx ) { @@ -897,8 +908,15 @@ UWord8 apa_exec_ivas_fx( Word32 expScaling, actScaling; UWord32 statsResetThreshold, statsResetShift; Word16 Q_a_out; +#ifdef FIX1998_APA_EXEC_SCALING + Word16 Q_a_out_init_old; +#endif Q_a_out = add( getScaleFactor32_copy( a_in, L_mult0( ps->num_channels, APA_BUF_PER_CHANNEL ) ), Q11 - Q16 - Q1 ); +#ifdef FIX1998_APA_EXEC_SCALING + Q_a_out_init_old = Q_a_out; /* store the possible scaling of a_in, to be re-used in the next frame */ + move16(); +#endif statsResetThreshold = 1637; move32(); statsResetShift = 2; @@ -965,7 +983,15 @@ UWord8 apa_exec_ivas_fx( Word16 a_tmp[APA_BUF]; Word16 *buf_out_ptr = &( ps->buf_out_fx[ps->l_buf_out - ps->l_frm] ); +#ifdef FIX1998_APA_EXEC_SCALING + /* + don't compare against actual scaling in ps->Q_buf_out, but possible scaling in ps->Q_a_out_init_old; otherwise we are constantly reducing the scaling over time, leading to precision issues + alternative approach: determine scaling of ps->buf_out_fx, but this is costly due to the sheer amount of samples stored there... + */ + Q_a_out = s_min( Q_a_out, ps->Q_a_out_init_old ); +#else Q_a_out = s_min( Q_a_out, ps->Q_buf_out ); +#endif Scale_sig( ps->buf_out_fx, ps->buf_out_capacity, sub( Q_a_out, ps->Q_buf_out ) ); // Q_buf_out -> Q_a_out IF( EQ_32( ps->scale, 100 ) ) { @@ -1079,6 +1105,10 @@ UWord8 apa_exec_ivas_fx( } ps->l_buf_out = (UWord16) L_add( ps->l_buf_out, l_frm_out ); move16(); +#ifdef FIX1998_APA_EXEC_SCALING + ps->Q_a_out_init_old = Q_a_out_init_old; + move16(); +#endif *l_out = l_frm_out; move16(); @@ -1086,6 +1116,7 @@ UWord8 apa_exec_ivas_fx( ps->l_in_total = UL_addNsD( ps->l_in_total, ps->l_frm ); move32(); + test(); IF( LT_32( L_abs( ps->diffSinceSetScale ), L_sub( 0x7FFFFF, L_sub( l_frm_out, ps->l_frm ) ) ) && LT_64( ps->nFramesSinceSetScale, statsResetThreshold ) )