Skip to content
Commits on Source (5)
...@@ -91,6 +91,7 @@ ...@@ -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_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_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 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 ############################ */ /* #################### Start BASOP porting switches ############################ */
...@@ -104,6 +105,7 @@ ...@@ -104,6 +105,7 @@
#define NONBE_FIX_1261_MASA_EXT_META_JBM /* Nokia: issue #1261: MASA metadata EXT output delay buffer init in JBM */ #define NONBE_FIX_1261_MASA_EXT_META_JBM /* Nokia: issue #1261: MASA metadata EXT output delay buffer init in JBM */
#define NONBE_FIX_1143_MASA_BRSW /* Nok: Fix for issue 1143: MSAN use of uninitialized value in masa decoding to binaural with dtx bitrate switching and 5 % FER */ #define NONBE_FIX_1143_MASA_BRSW /* Nok: Fix for issue 1143: MSAN use of uninitialized value in masa decoding to binaural with dtx bitrate switching and 5 % FER */
#define NONBE_FIX_1220_OMASA_JBM_EXT_USAN /* Nokia: fix issue 1220 OMASA EXT JBM USAN, also fix similar cases of free to avoid future problems */ #define NONBE_FIX_1220_OMASA_JBM_EXT_USAN /* Nokia: fix issue 1220 OMASA EXT JBM USAN, also fix similar cases of free to avoid future problems */
#define NONBE_FIX_1376_MDCT_CONCEALMENT /* FhG: fix concealment artifact in MDCT Stereo with DTX, in case transition frame gets lost */
#define FIX_CREND_SIMPLIFY_CODE #define FIX_CREND_SIMPLIFY_CODE
#ifdef FIX_CREND_SIMPLIFY_CODE #ifdef FIX_CREND_SIMPLIFY_CODE
#define FIX_989_TD_REND_ROM /* Eri: Clean-up for TD renderer and completion of ROM generation tool */ #define FIX_989_TD_REND_ROM /* Eri: Clean-up for TD renderer and completion of ROM generation tool */
......
...@@ -1695,7 +1695,17 @@ void ivas_mdct_core_tns_ns_fx( ...@@ -1695,7 +1695,17 @@ void ivas_mdct_core_tns_ns_fx(
q_x = add( q_x, 1 ); q_x = add( q_x, 1 );
} }
#ifdef NONBE_FIX_1376_MDCT_CONCEALMENT
/*
2025-09-07, mul:
in case of PLC, applying SNS up to L_spec might not be enough: In case the transition frame from DTX after an inactive period is lost, L_spec is assumed to represent a regular TCX frame,
however, this frame is nevertheless acting as an transition frame as also visible in L_frameTCX; thus, the safer approach to prevent high frequency artifacts is to apply the SNS up to L_frameTCX;
in case this is not necessary, x[] is filled with zeros, and the multiplication is not causing any additional harm
*/
v_multc_fixed( x_fx[ch][k] + st->hTcxCfg->psychParamsCurrent->nBins, sns_int_scf_fx[FDNS_NPTS - 1], x_fx[ch][k] + st->hTcxCfg->psychParamsCurrent->nBins, sub( s_max( L_spec[ch], L_frameTCX[ch] ), st->hTcxCfg->psychParamsCurrent->nBins ) );
#else
v_multc_fixed( x_fx[ch][k] + st->hTcxCfg->psychParamsCurrent->nBins, sns_int_scf_fx[FDNS_NPTS - 1], x_fx[ch][k] + st->hTcxCfg->psychParamsCurrent->nBins, sub( L_spec[ch], st->hTcxCfg->psychParamsCurrent->nBins ) ); v_multc_fixed( x_fx[ch][k] + st->hTcxCfg->psychParamsCurrent->nBins, sns_int_scf_fx[FDNS_NPTS - 1], x_fx[ch][k] + st->hTcxCfg->psychParamsCurrent->nBins, sub( L_spec[ch], st->hTcxCfg->psychParamsCurrent->nBins ) );
#endif
q_2 = sub( add( q_x, q_sns_int_scf ), 31 ); q_2 = sub( add( q_x, q_sns_int_scf ), 31 );
Scale_sig32( &x_fx[ch][k][0], st->hTcxCfg->psychParamsCurrent->nBins, sub( q_2, q_x ) ); Scale_sig32( &x_fx[ch][k][0], st->hTcxCfg->psychParamsCurrent->nBins, sub( q_2, q_x ) );
......
...@@ -76,7 +76,10 @@ struct apa_state_t ...@@ -76,7 +76,10 @@ struct apa_state_t
bool evs_compat_mode; bool evs_compat_mode;
Word16 *buf_out_fx; 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 buf_out_capacity;
UWord16 l_buf_out; UWord16 l_buf_out;
...@@ -190,6 +193,10 @@ ivas_error apa_init( ...@@ -190,6 +193,10 @@ ivas_error apa_init(
} }
memset( ps->buf_out_fx, 0, ( sizeof( Word16 ) * ps->buf_out_capacity ) ); memset( ps->buf_out_fx, 0, ( sizeof( Word16 ) * ps->buf_out_capacity ) );
ps->Q_buf_out = Q15; ps->Q_buf_out = Q15;
#ifdef FIX1998_APA_EXEC_SCALING
ps->Q_a_out_init_old = Q15;
move16();
#endif
move16(); move16();
ps->evs_compat_mode = false; ps->evs_compat_mode = false;
...@@ -272,6 +279,10 @@ UWord8 apa_reconfigure( ...@@ -272,6 +279,10 @@ UWord8 apa_reconfigure(
ps->buf_out_fx = (Word16 *) malloc( sizeof( Word16 ) * ps->buf_out_capacity ); ps->buf_out_fx = (Word16 *) malloc( sizeof( Word16 ) * ps->buf_out_capacity );
memset( ps->buf_out_fx, 0, ( sizeof( Word16 ) * ps->buf_out_capacity ) ); memset( ps->buf_out_fx, 0, ( sizeof( Word16 ) * ps->buf_out_capacity ) );
ps->Q_buf_out = Q15; ps->Q_buf_out = Q15;
#ifdef FIX1998_APA_EXEC_SCALING
ps->Q_a_out_init_old = Q15;
move16();
#endif
move16(); move16();
IF( !ps->buf_out_fx ) IF( !ps->buf_out_fx )
{ {
...@@ -897,8 +908,15 @@ UWord8 apa_exec_ivas_fx( ...@@ -897,8 +908,15 @@ UWord8 apa_exec_ivas_fx(
Word32 expScaling, actScaling; Word32 expScaling, actScaling;
UWord32 statsResetThreshold, statsResetShift; UWord32 statsResetThreshold, statsResetShift;
Word16 Q_a_out; 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 ); 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; statsResetThreshold = 1637;
move32(); move32();
statsResetShift = 2; statsResetShift = 2;
...@@ -965,7 +983,15 @@ UWord8 apa_exec_ivas_fx( ...@@ -965,7 +983,15 @@ UWord8 apa_exec_ivas_fx(
Word16 a_tmp[APA_BUF]; Word16 a_tmp[APA_BUF];
Word16 *buf_out_ptr = &( ps->buf_out_fx[ps->l_buf_out - ps->l_frm] ); 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 ); 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 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 ) ) IF( EQ_32( ps->scale, 100 ) )
{ {
...@@ -1079,6 +1105,10 @@ UWord8 apa_exec_ivas_fx( ...@@ -1079,6 +1105,10 @@ UWord8 apa_exec_ivas_fx(
} }
ps->l_buf_out = (UWord16) L_add( ps->l_buf_out, l_frm_out ); ps->l_buf_out = (UWord16) L_add( ps->l_buf_out, l_frm_out );
move16(); move16();
#ifdef FIX1998_APA_EXEC_SCALING
ps->Q_a_out_init_old = Q_a_out_init_old;
move16();
#endif
*l_out = l_frm_out; *l_out = l_frm_out;
move16(); move16();
...@@ -1086,6 +1116,7 @@ UWord8 apa_exec_ivas_fx( ...@@ -1086,6 +1116,7 @@ UWord8 apa_exec_ivas_fx(
ps->l_in_total = UL_addNsD( ps->l_in_total, ps->l_frm ); ps->l_in_total = UL_addNsD( ps->l_in_total, ps->l_frm );
move32(); move32();
test(); test();
IF( LT_32( L_abs( ps->diffSinceSetScale ), L_sub( 0x7FFFFF, L_sub( l_frm_out, ps->l_frm ) ) ) && IF( LT_32( L_abs( ps->diffSinceSetScale ), L_sub( 0x7FFFFF, L_sub( l_frm_out, ps->l_frm ) ) ) &&
LT_64( ps->nFramesSinceSetScale, statsResetThreshold ) ) LT_64( ps->nFramesSinceSetScale, statsResetThreshold ) )
......