diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 1cc1a8ffefaa48c4b964a11b599e1da102b41fc2..379dd7c85efcc4364abdc8ace259b771f93d7c8c 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -785,6 +785,9 @@ enum #define L_HP20_MEM 4 /* HP20 filter memory length */ #define CLDFB_NO_CHANNELS_MAX 60 /* CLDFB resampling - max number of CLDFB channels, == IVAS_CLDFB_NO_CHANNELS_MAX */ +#ifdef FIX_867_CLDFB_NRG_SCALE +#define CLDFB_NO_CHANNELS_HALF 30 /* CLDFB resampling - max number of CLDFB channels, == IVAS_CLDFB_NO_CHANNELS_MAX */ +#endif #define CLDFB_NO_CHANNELS_MAX_FX 30720 /*Q9*/ #define CLDFB_NO_COL_MAX 16 /* CLDFB resampling - max number of CLDFB col., == IVAS_CLDFB_NO_COL_MAX */ #define CLDFB_NO_COL_MAX_SWITCH 6 /* CLDFB resampling - max number of CLDFB col. for switching */ diff --git a/lib_com/options.h b/lib_com/options.h index 2b88deb5d39f9ae94fa912bfb6ff6033475c9488..91ee90e2bd665a8336e5084674fd34f16d1c6555 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -67,6 +67,8 @@ #define BASOP_NOGLOB_DECLARE_LOCAL #endif +#define FIX_867_CLDFB_NRG_SCALE + #define FIX_1378_ACELP_OUT_OF_BOUNDS /* Note: each compile switch (FIX_1101_...) is independent from the other ones */ diff --git a/lib_dec/ivas_dirac_dec_fx.c b/lib_dec/ivas_dirac_dec_fx.c index e6c08669e3e9a256caaabf747b713651705c71f7..bbd4641b1184a7fc71cd906b5968738001a30bef 100644 --- a/lib_dec/ivas_dirac_dec_fx.c +++ b/lib_dec/ivas_dirac_dec_fx.c @@ -2220,7 +2220,12 @@ void ivas_dirac_dec_render_sf_fx( DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params; DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state; Word16 num_channels_dir, exp; +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 q_diffuseness_vector = Q31, q_reference_power_smooth[2] = { Q31, Q31 }; + move16(); +#else Word16 q_diffuseness_vector = Q31, q_reference_power_smooth = Q31; +#endif move16(); move16(); Word16 proto_power_smooth_len = 0; @@ -2460,10 +2465,37 @@ void ivas_dirac_dec_render_sf_fx( scale_sig32( hDirACRend->h_output_synthesis_psd_state.cy_auto_diff_smooth_prev_fx, imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->hOutSetup.nchan_out_woLFE ), tmp1 ); // Q(hDirACRend->h_output_synthesis_psd_state.q_cy_auto_diff_smooth_prev+ tmp1) hDirACRend->h_output_synthesis_psd_state.q_cy_auto_diff_smooth_prev = add( hDirACRend->h_output_synthesis_psd_state.q_cy_auto_diff_smooth_prev, tmp1 ); move16(); +#ifdef FIX_867_CLDFB_NRG_SCALE + tmp1 = 31; + move16(); + FOR( i = 0; i < i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir ); i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + tmp1 = s_min( tmp1, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + i, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + } + FOR( i = 0; i < i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir ); i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + i, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), tmp1 ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q tmp1) + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], tmp1 ); + move16(); + tmp1 = 31; + move16(); + FOR( i = 0; i < i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir ); i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + tmp1 = s_min( tmp1, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + i, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); + } + FOR( i = 0; i < i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir ); i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + i, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), tmp1 ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q tmp1) + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], tmp1 ); + move16(); +#else tmp1 = L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, imult1616( hDirACRend->num_protos_dir, hSpatParamRendCom->num_freq_bands ) ); scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, imult1616( hDirACRend->num_protos_dir, hSpatParamRendCom->num_freq_bands ), tmp1 ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q tmp1) hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, tmp1 ); move16(); +#endif IF( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_fx != 0 ) { tmp1 = L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_fx, imult1616( hDirACRend->h_output_synthesis_psd_params.max_band_decorr, hDirACRend->hOutSetup.nchan_out_woLFE ) ); @@ -2808,7 +2840,11 @@ void ivas_dirac_dec_render_sf_fx( &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_fx, &hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q, +#ifdef FIX_867_CLDFB_NRG_SCALE + reference_power_fx, DirAC_mem.reference_power_q, +#else reference_power_fx, &DirAC_mem.reference_power_q, +#endif slot_idx, nchan_transport, hDirACRend->num_outputs_diff, hSpatParamRendCom->num_freq_bands, @@ -2821,7 +2857,11 @@ void ivas_dirac_dec_render_sf_fx( &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_fx, &hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q, +#ifdef FIX_867_CLDFB_NRG_SCALE + reference_power_fx, DirAC_mem.reference_power_q, +#else reference_power_fx, &DirAC_mem.reference_power_q, +#endif slot_idx, nchan_transport, hDirACRend->num_outputs_diff, hSpatParamRendCom->num_freq_bands, @@ -2840,9 +2880,17 @@ void ivas_dirac_dec_render_sf_fx( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx, &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, reference_power_fx, +#ifdef FIX_867_CLDFB_NRG_SCALE + DirAC_mem.reference_power_q, +#else &DirAC_mem.reference_power_q, +#endif hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, +#ifdef FIX_867_CLDFB_NRG_SCALE + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#else &hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#endif 0, slot_idx, hSpatParamRendCom->num_freq_bands, hDirACRend->masa_stereo_type_detect, q_cldfb ); @@ -2866,9 +2914,17 @@ void ivas_dirac_dec_render_sf_fx( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx, &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, reference_power_fx, +#ifdef FIX_867_CLDFB_NRG_SCALE + DirAC_mem.reference_power_q, +#else &DirAC_mem.reference_power_q, +#endif hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, +#ifdef FIX_867_CLDFB_NRG_SCALE + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#else &hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#endif slot_idx, hDirACRend->num_outputs_diff, hSpatParamRendCom->num_freq_bands, hDirACRend->hoa_decoder, @@ -2883,9 +2939,17 @@ void ivas_dirac_dec_render_sf_fx( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx, &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, reference_power_fx, +#ifdef FIX_867_CLDFB_NRG_SCALE + DirAC_mem.reference_power_q, +#else &DirAC_mem.reference_power_q, +#endif hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, +#ifdef FIX_867_CLDFB_NRG_SCALE + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#else &hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#endif hDirACRend->hOutSetup.is_loudspeaker_setup, slot_idx, hSpatParamRendCom->num_freq_bands, @@ -2908,9 +2972,17 @@ void ivas_dirac_dec_render_sf_fx( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx, &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, reference_power_fx, +#ifdef FIX_867_CLDFB_NRG_SCALE + DirAC_mem.reference_power_q, +#else &DirAC_mem.reference_power_q, +#endif hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, +#ifdef FIX_867_CLDFB_NRG_SCALE + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#else &hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#endif slot_idx, hDirACRend->num_protos_diff, hSpatParamRendCom->num_freq_bands, q_cldfb ); @@ -2973,7 +3045,12 @@ void ivas_dirac_dec_render_sf_fx( num_freq_bands, azimuth, elevation ); Copy32( reference_power_fx, &( hDirACRend->buffer_energy_fx[i_mult( sub( index, 1 ), num_freq_bands )] ), num_freq_bands ); +#ifdef FIX_867_CLDFB_NRG_SCALE + Scale_sig32( &( hDirACRend->buffer_energy_fx[add( i_mult( sub( index, 1 ), num_freq_bands ), CLDFB_NO_CHANNELS_HALF )] ), s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_q[1] ) ); + hDirACRend->q_buffer_energy[index - 1] = DirAC_mem.reference_power_q[0]; +#else hDirACRend->q_buffer_energy[index - 1] = DirAC_mem.reference_power_q; +#endif move16(); computeDiffuseness_fixed( hDirACRend->buffer_intensity_real_fx, hDirACRend->buffer_energy_fx, num_freq_bands, hSpatParamRendCom->diffuseness_vector_fx[md_idx], hDirACRend->q_buffer_intensity_real, hDirACRend->q_buffer_energy, &hSpatParamRendCom->q_diffuseness_vector ); @@ -3205,6 +3282,18 @@ void ivas_dirac_dec_render_sf_fx( IF( NE_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) { +#ifdef FIX_867_CLDFB_NRG_SCALE + v_add_fixed_me( reference_power_fx, sub( 31, DirAC_mem.reference_power_q[0] ), + reference_power_smooth_fx, sub( 31, q_reference_power_smooth[0] ), + reference_power_smooth_fx, &temp_q, + s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), 1 ); + q_reference_power_smooth[0] = sub( 31, temp_q ); + v_add_fixed_me( reference_power_fx + CLDFB_NO_CHANNELS_HALF, sub( 31, DirAC_mem.reference_power_q[1] ), + reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, sub( 31, q_reference_power_smooth[1] ), + reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, &temp_q, + s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), 1 ); + q_reference_power_smooth[1] = sub( 31, temp_q ); +#else IF( LT_16( q_reference_power_smooth, DirAC_mem.reference_power_q ) ) { Word32 temp; @@ -3247,6 +3336,7 @@ void ivas_dirac_dec_render_sf_fx( } v_add_fixed( reference_power_fx, reference_power_smooth_fx, reference_power_smooth_fx, hSpatParamRendCom->num_freq_bands, 1 ); q_reference_power_smooth = sub( q_reference_power_smooth, 1 ); +#endif } } @@ -3445,6 +3535,51 @@ void ivas_dirac_dec_render_sf_fx( Scale_sig32( hDirACRend->h_output_synthesis_psd_state.direct_responses_square_fx, i_mult( hDirACRend->num_outputs_dir, hSpatParamRendCom->num_freq_bands ), sub( Q31, hDirACRend->h_output_synthesis_psd_state.direct_responses_square_q ) ); // Q31 } +#ifdef FIX_867_CLDFB_NRG_SCALE + exp = L_norm_arr( reference_power_smooth_fx, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); + scale_sig32( reference_power_smooth_fx, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), exp ); // q_reference_power_smooth[0] + exp + q_reference_power_smooth[0] = add( q_reference_power_smooth[0], exp ); + IF( LT_16( q_reference_power_smooth[0], hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] ) ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_reference_power_smooth[0], hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] ) ); // q_reference_power_smooth[0] + hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] = q_reference_power_smooth[0]; + move16(); + } + ELSE + { + Word32 temp; + FOR( i = 0; i < s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ); i++ ) + { + temp = L_shl( reference_power_smooth_fx[i], sub( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], q_reference_power_smooth[0] ) ); + reference_power_smooth_fx[i] = L_max( temp, L_min( reference_power_smooth_fx[i], 1 ) ); + move32(); + } + q_reference_power_smooth[0] = hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0]; + move16(); + } + + exp = L_norm_arr( reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + scale_sig32( reference_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), exp ); // q_reference_power_smooth + exp + q_reference_power_smooth[1] = add( q_reference_power_smooth[1], exp ); + IF( LT_16( q_reference_power_smooth[1], hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] ) ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_reference_power_smooth[1], hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] ) ); // q_reference_power_smooth + hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] = q_reference_power_smooth[1]; + move16(); + } + ELSE + { + Word32 temp; + FOR( i = CLDFB_NO_CHANNELS_HALF; i < hSpatParamRendCom->num_freq_bands; i++ ) + { + temp = L_shl( reference_power_smooth_fx[i], sub( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], q_reference_power_smooth[1] ) ); + reference_power_smooth_fx[i] = L_max( temp, L_min( reference_power_smooth_fx[i], 1 ) ); + move32(); + } + q_reference_power_smooth[1] = hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1]; + move16(); + } +#else exp = L_norm_arr( reference_power_smooth_fx, hSpatParamRendCom->num_freq_bands ); scale_sig32( reference_power_smooth_fx, hSpatParamRendCom->num_freq_bands, exp ); // q_reference_power_smooth + exp q_reference_power_smooth = add( q_reference_power_smooth, exp ); @@ -3475,6 +3610,7 @@ void ivas_dirac_dec_render_sf_fx( q_reference_power_smooth = hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q; move16(); } +#endif IF( hDirACRend->masa_stereo_type_detect != NULL ) { @@ -3494,6 +3630,69 @@ void ivas_dirac_dec_render_sf_fx( } } +#ifdef FIX_867_CLDFB_NRG_SCALE + exp = 31; + move16(); + FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + exp = s_min( exp, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + i, s_min( CLDFB_NO_CHANNELS_HALF, hSpatParamRendCom->num_freq_bands ) ) ); + } + FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + i, s_min( CLDFB_NO_CHANNELS_HALF, hSpatParamRendCom->num_freq_bands ), exp ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + exp) + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], exp ); + move16(); + exp = 31; + move16(); + FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + exp = s_min( exp, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + i, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); + } + FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + i, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), exp ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + exp) + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], exp ); + move16(); + + IF( LT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ) + { + FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + i, s_min( CLDFB_NO_CHANNELS_HALF, hSpatParamRendCom->num_freq_bands ), sub( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // proto_power_smooth_q + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0]; + move16(); + } + ELSE + { + FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + i, s_min( CLDFB_NO_CHANNELS_HALF, hSpatParamRendCom->num_freq_bands ), sub( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // proto_power_smooth_prev_q + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0]; + move16(); + } + IF( LT_16( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ) + { + FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + i, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // proto_power_smooth_q + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1]; + move16(); + } + ELSE + { + FOR( i = 0; proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + i, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // proto_power_smooth_prev_q + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1]; + move16(); + } +#else exp = getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, proto_power_smooth_len ); scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, proto_power_smooth_len, exp ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + exp) hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, exp ); @@ -3510,6 +3709,7 @@ void ivas_dirac_dec_render_sf_fx( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q; move16(); } +#endif exp = getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_fx, i_mult( hDirACRend->h_output_synthesis_psd_params.max_band_decorr, hDirACRend->hOutSetup.nchan_out_woLFE ) ); scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_fx, i_mult( hDirACRend->h_output_synthesis_psd_params.max_band_decorr, hDirACRend->hOutSetup.nchan_out_woLFE ), exp ); // Q(hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q + exp) @@ -3553,11 +3753,37 @@ void ivas_dirac_dec_render_sf_fx( hSpatParamRendCom->subframe_nbslots[subframe_idx], diffuseness_vector_fx, reference_power_smooth_fx, +#ifdef FIX_867_CLDFB_NRG_SCALE + q_reference_power_smooth, +#else &q_reference_power_smooth, +#endif qualityBasedSmFactor_fx, hDirAC->hConfig->enc_param_start_band, &q_Cldfb ); +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 allZero = 1; + move16(); + FOR( i = 0; i < proto_power_smooth_len; i++ ) + { + if ( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx[i] != 0 ) + { + allZero = 0; + move16(); + } + } + if ( allZero ) + { + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = 31; + move16(); + } + if ( allZero ) + { + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = 31; + move16(); + } +#else Word16 sh = hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q; move16(); hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q = 31; @@ -3570,6 +3796,7 @@ void ivas_dirac_dec_render_sf_fx( move16(); } } +#endif FOR( ch = 0; ch < hDirACRend->hOutSetup.nchan_out_woLFE; ch++ ) { diff --git a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c index 454cf4ed1a15a8811e1dd3ef66b5c1859d10d1aa..7b446a80e77b5a241d8c5d5494857461f6d1f885 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec_fx.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec_fx.c @@ -305,8 +305,15 @@ ivas_error ivas_dirac_dec_output_synthesis_open_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) ); } set32_fx( dirac_output_synthesis_state->reference_power_smooth_prev_fx, 0, hSpatParamRendCom->num_freq_bands ); +#ifdef FIX_867_CLDFB_NRG_SCALE + dirac_output_synthesis_state->reference_power_smooth_prev_q[0] = Q31; + dirac_output_synthesis_state->reference_power_smooth_prev_q[1] = Q31; + move16(); + move16(); +#else dirac_output_synthesis_state->reference_power_smooth_prev_q = Q31; move16(); +#endif IF( ( dirac_output_synthesis_state->direction_smoothness_prev_fx = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( Word32 ) ) ) == NULL ) { @@ -487,8 +494,15 @@ void ivas_dirac_dec_output_synthesis_init_fx( IF( h_dirac_output_synthesis_state->proto_power_smooth_prev_fx != NULL ) { set32_fx( h_dirac_output_synthesis_state->proto_power_smooth_prev_fx, 0, imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir ) ); +#ifdef FIX_867_CLDFB_NRG_SCALE + h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] = Q31; + h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] = Q31; + move16(); + move16(); +#else h_dirac_output_synthesis_state->proto_power_smooth_prev_q = Q31; move16(); +#endif } set32_fx( h_dirac_output_synthesis_state->gains_dir_prev_fx, 0, size ); h_dirac_output_synthesis_state->gains_dir_prev_q = 0; @@ -623,9 +637,13 @@ void ivas_dirac_dec_output_synthesis_close_fx( *------------------------------------------------------------------------*/ void ivas_dirac_dec_output_synthesis_process_slot_fx( - const Word32 *reference_power, /* i : Estimated power Q(q_reference_power)*/ + const Word32 *reference_power, /* i : Estimated power Q(q_reference_power)*/ +#ifdef FIX_867_CLDFB_NRG_SCALE + const Word16 *q_reference_power, /* i : Estimated power Q */ +#else const Word16 q_reference_power, /* i : Estimated power Q */ - const Word32 *onset, /* i : onset filter Q31*/ +#endif + const Word32 *onset, /* i : onset filter Q31*/ const Word16 *azimuth, const Word16 *elevation, const Word32 *diffuseness, /* Q(q_diffuseness)*/ @@ -1244,7 +1262,11 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( hDirACRend->proto_index_diff, h_dirac_output_synthesis_state->diffuse_power_factor_fx, reference_power, +#ifdef FIX_867_CLDFB_NRG_SCALE + q_reference_power, +#else &q_reference_power, +#endif h_dirac_output_synthesis_state->diffuse_responses_square_fx, onset, h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, @@ -1257,9 +1279,15 @@ void ivas_dirac_dec_output_synthesis_process_slot_fx( /* process other PSDs only slot wise for 4 transport channels */ IF( EQ_16( dec_param_estim, TRUE ) ) { +#ifdef FIX_867_CLDFB_NRG_SCALE + computeTargetPSDs_direct_fx( num_channels_dir, num_freq_bands, h_dirac_output_synthesis_state->direct_power_factor_fx, reference_power, q_reference_power, h_dirac_output_synthesis_state->direct_responses_fx, h_dirac_output_synthesis_state->direct_responses_square_fx, h_dirac_output_synthesis_state->cy_auto_dir_smooth_fx, &h_dirac_output_synthesis_state->q_cy_auto_dir_smooth, h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx, &h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ); + + computeTargetPSDs_diffuse_fx( num_channels_dir, num_freq_bands, diff_start_band, h_dirac_output_synthesis_state->diffuse_power_factor_fx, reference_power, q_reference_power, h_dirac_output_synthesis_state->diffuse_responses_square_fx, h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, &h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ); +#else computeTargetPSDs_direct_fx( num_channels_dir, num_freq_bands, h_dirac_output_synthesis_state->direct_power_factor_fx, reference_power, &q_reference_power, h_dirac_output_synthesis_state->direct_responses_fx, h_dirac_output_synthesis_state->direct_responses_square_fx, h_dirac_output_synthesis_state->cy_auto_dir_smooth_fx, &h_dirac_output_synthesis_state->q_cy_auto_dir_smooth, h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx, &h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ); computeTargetPSDs_diffuse_fx( num_channels_dir, num_freq_bands, diff_start_band, h_dirac_output_synthesis_state->diffuse_power_factor_fx, reference_power, &q_reference_power, h_dirac_output_synthesis_state->diffuse_responses_square_fx, h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, &h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ); +#endif } return; @@ -2022,6 +2050,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx, &h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ); +#ifndef FIX_867_CLDFB_NRG_SCALE // Scale cy_auto_diff_smooth_fx if required IF( diff_start_band != 0 ) { @@ -2039,6 +2068,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( h_dirac_output_synthesis_state->q_cy_auto_diff_smooth = q_com; move16(); } +#endif computeTargetPSDs_diffuse_subframe_fx( nchan_target_psds, num_freq_bands, diff_start_band, h_dirac_output_synthesis_state->diffuse_power_factor_fx, @@ -2173,6 +2203,12 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( prevWeight = Mpy_32_32( L_sub( ONE_IN_Q31, DIRECTION_SMOOTHNESS_ALPHA_Q31 ), h_dirac_output_synthesis_state->reference_power_smooth_prev_fx[l] ); //(Q31, q_reference_power_smooth) -> q_reference_power_smooth +#ifdef FIX_867_CLDFB_NRG_SCALE + assert( q_reference_power_smooth[0] == h_dirac_output_synthesis_state->reference_power_smooth_prev_q[0] ); + assert( q_reference_power_smooth[1] == h_dirac_output_synthesis_state->reference_power_smooth_prev_q[1] ); +#else + assert( *q_reference_power_smooth == h_dirac_output_synthesis_state->reference_power_smooth_prev_q ); +#endif weightedDirectionSmoothness = L_add( Mpy_32_32( currWeight, instDirectionSmoothness ), Mpy_32_32( prevWeight, h_dirac_output_synthesis_state->direction_smoothness_prev_fx[l] ) ); //(q_reference_power_smooth, Q31) -> q_reference_power_smooth @@ -2180,6 +2216,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( exp = 0; move16(); + tmp = BASOP_Util_Divide3232_Scale( weightedDirectionSmoothness, L_add( sumWeight, EPSILON_FX ), &exp ); /*Q(15-exp)*/ smoothedDirectionSmoothness = L_shl_sat( L_deposit_l( tmp ), add( sub( Q31, Q15 ), exp ) ); // Q31 @@ -2222,6 +2259,12 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( *( p_power_smooth_prev ) = L_add( *( p_power_smooth_prev ), Mpy_32_32( g1, ( *p_power_smooth ) ) ); //(Q31, q_proto_power_smooth) -> q_proto_power_smooth move32(); +#ifdef FIX_867_CLDFB_NRG_SCALE + assert( h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] == h_dirac_output_synthesis_state->proto_power_smooth_q[0] ); + assert( h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] == h_dirac_output_synthesis_state->proto_power_smooth_q[1] ); +#else + assert( h_dirac_output_synthesis_state->proto_power_smooth_prev_q == h_dirac_output_synthesis_state->proto_power_smooth_q ); +#endif IF( EQ_32( *( p_power_smooth_prev ), EPSILON_FX ) ) { p_power_smooth_prev++; @@ -2245,6 +2288,61 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( } // Move proto_power_smooth_fx to common Q-factor + +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 min_exp2 = -64; + min_exp = MIN_16; + move16(); + move16(); + Word16 q_tmp2 = Q31; + q_tmp = Q31; + move16(); + move16(); + + FOR( k = 0; k < num_protos_dir; k++ ) + { + FOR( l = 0; l < s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ); l++ ) + { + min_exp = s_max( min_exp, exp_arr[k * num_freq_bands + l] ); + } + FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ ) + { + min_exp2 = s_max( min_exp2, exp_arr[k * num_freq_bands + l] ); + } + } + + p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth_fx; + + FOR( k = 0; k < num_protos_dir; k++ ) + { + FOR( l = 0; l < s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ); l++ ) + { + *p_power_smooth = L_shr( *p_power_smooth, sub( min_exp, exp_arr[k * num_freq_bands + l] ) ); /*(31-(exp-(31-q_proto_power_smooth)))->(31-(min_exp-(31-q_proto_power_smooth)))*/ + move32(); + p_power_smooth++; + } + FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ ) + { + *p_power_smooth = L_shr( *p_power_smooth, sub( min_exp2, exp_arr[k * num_freq_bands + l] ) ); /*(31-(exp-(31-q_proto_power_smooth)))->(31-(min_exp-(31-q_proto_power_smooth)))*/ + move32(); + p_power_smooth++; + } + } + + // Update the Q-factor + h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] = s_min( h_dirac_output_synthesis_state->proto_power_smooth_q[0], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] ); + h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] = s_min( h_dirac_output_synthesis_state->proto_power_smooth_q[1], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] ); + move16(); + move16(); + + q_tmp = add( sub( Q31, min_exp ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] ) ); + q_tmp2 = add( sub( Q31, min_exp2 ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] ) ); + + h_dirac_output_synthesis_state->proto_power_smooth_q[0] = q_tmp; + h_dirac_output_synthesis_state->proto_power_smooth_q[1] = q_tmp2; + move16(); + move16(); +#else min_exp = MIN_16; move16(); q_tmp = Q31; @@ -2281,6 +2379,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( move16(); h_dirac_output_synthesis_state->proto_power_smooth_q = q_tmp; move16(); +#endif /*Direct gains and diffuse gains on number of output channels*/ p_power_diff_smooth_prev = h_dirac_output_synthesis_state->proto_power_diff_smooth_prev_fx; @@ -2328,6 +2427,9 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( FOR( k = 0; k < nchan_out_woLFE; k++ ) { Word32 power_smooth_temp; +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 qidx; +#endif p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth_fx + i_mult( proto_direct_index[k], num_freq_bands ); // q_proto_power_smooth FOR( l = 0; l < h_dirac_output_synthesis_params->max_band_decorr; l++ ) { @@ -2335,18 +2437,28 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( g1 = alpha[l]; // Q31 move32(); g2 = L_sub( ONE_IN_Q31, g1 ); // Q31 + assert( q_cy_auto_dir_smooth_local[k] == q_cy_auto_dir_smooth_prev_local[k] ); *( p_cy_auto_dir_smooth_prev ) = L_add( Mpy_32_32( g1, ( *( p_cy_auto_dir_smooth++ ) ) ), Mpy_32_32( g2, ( *( p_cy_auto_dir_smooth_prev ) ) ) ); // (Q31, q_cy_auto_dir_smooth_prev_local) -> q_cy_auto_dir_smooth_prev_local move32(); + assert( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth == h_dirac_output_synthesis_state->q_cy_cross_dir_smooth_prev ); *( p_cy_cross_dir_smooth_prev ) = L_add( Mpy_32_32( g1, ( *( p_cy_cross_dir_smooth++ ) ) ), Mpy_32_32( g2, ( *( p_cy_cross_dir_smooth_prev ) ) ) ); // (Q31, q_cy_cross_dir_smooth_prev) -> q_cy_cross_dir_smooth_prev move32(); power_smooth_temp = L_shl( *p_power_smooth, norm_l( *p_power_smooth ) ); // proto_power_smooth_q + norm_l( *p_power_smooth ) L_tmp = Mpy_32_32( power_smooth_temp, ( *( p_cy_auto_dir_smooth_prev++ ) ) ); // proto_power_smooth_q + norm_l( *p_power_smooth ) ) + q_cy_auto_dir_smooth_prev_local - 31 +#ifdef FIX_867_CLDFB_NRG_SCALE + qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); + exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q[qidx], norm_l( *p_power_smooth ) ), + q_cy_auto_dir_smooth_prev_local[k] ), + Q31 ) ); + +#else exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q, norm_l( *p_power_smooth ) ), q_cy_auto_dir_smooth_prev_local[k] ), Q31 ) ); +#endif p_power_smooth++; *( p_gains_dir ) = Sqrt32( L_tmp, &exp ); // (Q31 - exp) @@ -2430,9 +2542,16 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( ( p_cy_cross_dir_smooth++ ); power_smooth_temp = L_shl( *p_power_smooth, norm_l( *p_power_smooth ) ); L_tmp = Mpy_32_32( power_smooth_temp, L_tmp ); // proto_power_smooth_q + norm_l( *p_power_smooth ) ) + q_cy_auto_dir_smooth_prev_local - 31 +#ifdef FIX_867_CLDFB_NRG_SCALE + qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); + exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q[qidx], norm_l( *p_power_smooth ) ), + add( q_cy_auto_dir_smooth_prev_local[k], q_tmp ) ), + Q31 ) ); +#else exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q, norm_l( *p_power_smooth ) ), add( q_cy_auto_dir_smooth_prev_local[k], q_tmp ) ), Q31 ) ); +#endif *( p_gains_dir ) = Sqrt32( L_tmp, &exp ); // (Q31 - exp) move32(); @@ -2481,9 +2600,15 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( move32(); } ( p_cy_auto_diff_smooth_prev++ ); +#ifdef FIX_867_CLDFB_NRG_SCALE + exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q[qidx], norm_l( *p_power_smooth ) ), + h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev ), + Q31 ) ); +#else exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q, norm_l( *p_power_smooth ) ), h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev ), Q31 ) ); +#endif p_power_smooth++; *( p_gains_diff ) = Sqrt32( L_tmp, &exp ); /*31-exp*/ @@ -3956,21 +4081,36 @@ static void computeTargetPSDs_direct_fx( /* estimate direct and diffuse power */ v_mult_fixed( direct_power_factor, reference_power, direct_power, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 common1_q = s_min( *q_cy_auto_dir_smooth, s_min( q_reference_power[0], q_reference_power[1] ) ); + Word16 common2_q = s_min( *q_cy_cross_dir_smooth, s_min( q_reference_power[0], q_reference_power[1] ) ); +#else Word16 common1_q = s_min( *q_cy_auto_dir_smooth, *q_reference_power ); Word16 common2_q = s_min( *q_cy_cross_dir_smooth, *q_reference_power ); +#endif /* compute target auto and cross PSDs of current frame (smoothed) */ FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { cur_idx = imult1616( ch_idx, num_freq_bands ); - v_mult_fixed( direct_power, &direct_responses_square[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ - scale_sig32( aux_buffer_res, num_freq_bands, sub( common1_q, *q_reference_power ) ); /* Q(common1_q) */ + v_mult_fixed( direct_power, &direct_responses_square[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ +#ifdef FIX_867_CLDFB_NRG_SCALE + scale_sig32( aux_buffer_res, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( common1_q, q_reference_power[0] ) ); /* Q(common1_q) */ + scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( common1_q, q_reference_power[1] ) ); /* Q(common1_q) */ +#else + scale_sig32( aux_buffer_res, num_freq_bands, sub( common1_q, *q_reference_power ) ); /* Q(common1_q) */ +#endif scale_sig32( &cy_auto_dir_smooth[cur_idx], num_freq_bands, sub( common1_q, *q_cy_auto_dir_smooth ) ); /* Q(common1_q) */ v_add_fixed( &cy_auto_dir_smooth[cur_idx], aux_buffer_res, &cy_auto_dir_smooth[cur_idx], num_freq_bands, Q1 ); /* Q(common1_q) - Q1 */ - v_mult_fixed( direct_power, &direct_responses[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ - scale_sig32( aux_buffer_res, num_freq_bands, sub( common2_q, *q_reference_power ) ); /* Q(common2_q) */ + v_mult_fixed( direct_power, &direct_responses[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ +#ifdef FIX_867_CLDFB_NRG_SCALE + scale_sig32( aux_buffer_res, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( common2_q, q_reference_power[0] ) ); /* Q(common2_q) */ + scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( common2_q, q_reference_power[1] ) ); /* Q(common2_q) */ +#else + scale_sig32( aux_buffer_res, num_freq_bands, sub( common2_q, *q_reference_power ) ); /* Q(common2_q) */ +#endif scale_sig32( &cy_cross_dir_smooth[cur_idx], num_freq_bands, sub( common2_q, *q_cy_cross_dir_smooth ) ); /* Q(common2_q) */ v_add_fixed( &cy_cross_dir_smooth[cur_idx], aux_buffer_res, &cy_cross_dir_smooth[cur_idx], num_freq_bands, Q1 ); /* Q(common2_q) - Q1 */ } @@ -3998,14 +4138,21 @@ static void computeTargetPSDs_direct_subframe_fx( Word32 *cy_cross_dir_smooth, /*q_cy_cross_dir_smooth*/ Word16 *q_cy_cross_dir_smooth ) { +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 ch_idx, cur_idx, q_tmp; + Word32 L_tmp[CLDFB_NO_CHANNELS_MAX]; + Word16 q_cy_auto_dir_smooth_local[2]; +#else Word16 ch_idx, cur_idx, i, q_tmp; Word64 W_tmp[CLDFB_NO_CHANNELS_MAX], W_max; set64_fx( W_tmp, 0, CLDFB_NO_CHANNELS_MAX ); +#endif /* segment auxiliary buffer */ Word32 direct_power[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */ /* estimate direct and diffuse power */ +#ifndef FIX_867_CLDFB_NRG_SCALE FOR( i = 0; i < num_freq_bands; i++ ) { direct_power[i] = Mpy_32_32( direct_power_factor[i], reference_power[i] ); @@ -4017,11 +4164,15 @@ static void computeTargetPSDs_direct_subframe_fx( move32(); } } +#else + v_mult_fixed( direct_power_factor, reference_power, direct_power, num_freq_bands ); +#endif /* compute target auto and cross PSDs of current frame (smoothed) */ FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { cur_idx = imult1616( ch_idx, num_freq_bands ); +#ifndef FIX_867_CLDFB_NRG_SCALE W_max = 0; move64(); FOR( i = 0; i < num_freq_bands; i++ ) @@ -4034,6 +4185,21 @@ static void computeTargetPSDs_direct_subframe_fx( } } q_tmp = W_norm( W_max ); +#ifdef FIX_867_CLDFB_NRG_SCALE + FOR( i = 0; i < s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ); i++ ) + { + cy_auto_dir_smooth[cur_idx + i] = W_extract_h( W_shl( W_tmp[i], q_tmp ) ); /*q_reference_power[0]+q_tmp*/ + move32(); + } + Word16 q_tmp2 = sub( q_tmp, sub( q_reference_power[1], q_reference_power[0] ) ); + FOR( i = CLDFB_NO_CHANNELS_HALF; i < num_freq_bands; i++ ) + { + cy_auto_dir_smooth[cur_idx + i] = W_extract_h( W_shl( W_tmp[i], q_tmp2 ) ); /*q_reference_power[1]+q_tmp*/ + move32(); + } + q_cy_auto_dir_smooth[ch_idx] = add( q_reference_power[0], q_tmp ); + move16(); +#else FOR( i = 0; i < num_freq_bands; i++ ) { cy_auto_dir_smooth[cur_idx + i] = W_extract_h( W_shl( W_tmp[i], q_tmp ) ); /*q_reference_power+q_tmp*/ @@ -4041,11 +4207,34 @@ static void computeTargetPSDs_direct_subframe_fx( } q_cy_auto_dir_smooth[ch_idx] = add( *q_reference_power, q_tmp ); move16(); +#endif +#else + q_tmp = L_norm_arr( &direct_responses_square[cur_idx], num_freq_bands ); + Copy_Scale_sig32( &direct_responses_square[cur_idx], L_tmp, num_freq_bands, q_tmp ); + v_mult_fixed( direct_power, L_tmp, &cy_auto_dir_smooth[cur_idx], num_freq_bands ); // (q_reference_power, q_tmp) -> q_reference_power + q_tmp + + q_cy_auto_dir_smooth_local[0] = add( add( q_reference_power[0], q_tmp ), L_norm_arr( cy_auto_dir_smooth + cur_idx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + q_cy_auto_dir_smooth_local[1] = add( add( q_reference_power[1], q_tmp ), L_norm_arr( cy_auto_dir_smooth + cur_idx + CLDFB_NO_CHANNELS_HALF, s_max( sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), 0 ) ) ); + q_cy_auto_dir_smooth[ch_idx] = s_min( q_cy_auto_dir_smooth_local[0], q_cy_auto_dir_smooth_local[1] ); + move16(); + + Scale_sig32( cy_auto_dir_smooth + cur_idx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_cy_auto_dir_smooth[ch_idx], add( q_reference_power[0], q_tmp ) ) ); + Scale_sig32( cy_auto_dir_smooth + cur_idx + CLDFB_NO_CHANNELS_HALF, s_max( sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), 0 ), sub( q_cy_auto_dir_smooth[ch_idx], add( q_reference_power[1], q_tmp ) ) ); + +#endif v_mult_fixed( direct_power, &direct_responses[cur_idx], &cy_cross_dir_smooth[cur_idx], num_freq_bands ); // (q_reference_power, Q31) -> q_reference_power +#ifdef FIX_867_CLDFB_NRG_SCALE + Scale_sig32( &cy_cross_dir_smooth[cur_idx] + CLDFB_NO_CHANNELS_HALF, s_max( sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), 0 ), sub( q_reference_power[0], q_reference_power[1] ) ); +#endif } +#ifdef FIX_867_CLDFB_NRG_SCALE + *q_cy_cross_dir_smooth = q_reference_power[0]; + move16(); +#else *q_cy_cross_dir_smooth = *q_reference_power; move16(); +#endif return; } @@ -4071,15 +4260,24 @@ static void computeTargetPSDs_diffuse_fx( /* estimate direct and diffuse power */ v_mult_fixed( diffuse_power_factor, reference_power, diffuse_power, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 common_q = s_min( *q_cy_auto_diff_smooth, s_min( q_reference_power[0], q_reference_power[1] ) ); +#else Word16 common_q = s_min( *q_cy_auto_diff_smooth, *q_reference_power ); +#endif /* compute target auto and cross PSDs of current frame (smoothed) */ FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { cur_idx = imult1616( ch_idx, num_freq_bands ); - v_multc_fixed( &diffuse_power[start_band], diffuse_responses_square[ch_idx], aux_buffer_res, sub( num_freq_bands, start_band ) ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ - scale_sig32( aux_buffer_res, sub( num_freq_bands, start_band ), sub( common_q, *q_reference_power ) ); /* Q(common_q) */ + v_multc_fixed( &diffuse_power[start_band], diffuse_responses_square[ch_idx], aux_buffer_res, sub( num_freq_bands, start_band ) ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ +#ifdef FIX_867_CLDFB_NRG_SCALE + scale_sig32( aux_buffer_res, s_min( sub( num_freq_bands, start_band ), CLDFB_NO_CHANNELS_HALF ), sub( common_q, q_reference_power[0] ) ); /* Q(common_q) */ + scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( sub( num_freq_bands, start_band ), CLDFB_NO_CHANNELS_HALF ) ), sub( common_q, q_reference_power[1] ) ); /* Q(common_q) */ +#else + scale_sig32( aux_buffer_res, sub( num_freq_bands, start_band ), sub( common_q, *q_reference_power ) ); /* Q(common_q) */ +#endif scale_sig32( &cy_auto_diff_smooth[cur_idx + start_band], sub( num_freq_bands, start_band ), sub( common_q, *q_cy_auto_diff_smooth ) ); /* Q(common_q) */ v_add_fixed( &cy_auto_diff_smooth[cur_idx + start_band], aux_buffer_res, &cy_auto_diff_smooth[cur_idx + start_band], sub( num_freq_bands, start_band ), Q1 ); /* Q(common_q) - Q1 */ } @@ -4105,20 +4303,46 @@ static void computeTargetPSDs_diffuse_subframe_fx( { Word16 ch_idx, cur_idx; Word32 diffuse_power[CLDFB_NO_CHANNELS_MAX]; /* segment auxiliary buffer; size: num_freq_bands. */ +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 q_cy_auto_diff_smooth_new, q_diffuse_power; +#endif /* estimate direct and diffuse power */ v_mult_fixed( diffuse_power_factor, reference_power, diffuse_power, num_freq_bands ); // (Q31, q_reference_power) -> q_reference_power +#ifdef FIX_867_CLDFB_NRG_SCALE + q_diffuse_power = s_min( q_reference_power[0], q_reference_power[1] ); + Scale_sig32( diffuse_power, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_diffuse_power, q_reference_power[0] ) ); + Scale_sig32( diffuse_power + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_diffuse_power, q_reference_power[1] ) ); + q_cy_auto_diff_smooth_new = q_diffuse_power; + IF( LT_16( *q_cy_auto_diff_smooth, q_diffuse_power ) ) + { + Scale_sig32( diffuse_power, num_freq_bands, sub( *q_cy_auto_diff_smooth, q_cy_auto_diff_smooth_new ) ); + q_cy_auto_diff_smooth_new = *q_cy_auto_diff_smooth; + move16(); + } +#endif /* compute target auto and cross PSDs of current frame (smoothed) */ FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { cur_idx = imult1616( ch_idx, num_freq_bands ); +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( GT_16( *q_cy_auto_diff_smooth, q_diffuse_power ) ) + { + Scale_sig32( &cy_auto_diff_smooth[cur_idx], start_band, sub( q_diffuse_power, *q_cy_auto_diff_smooth ) ); + } +#endif v_multc_fixed( &diffuse_power[start_band], diffuse_responses_square[ch_idx], &cy_auto_diff_smooth[cur_idx + start_band], sub( num_freq_bands, start_band ) ); // (q_reference_power, Q31) -> q_reference_power } +#ifdef FIX_867_CLDFB_NRG_SCALE + *q_cy_auto_diff_smooth = q_cy_auto_diff_smooth_new; + move16(); +#else *q_cy_auto_diff_smooth = *q_reference_power; move16(); +#endif return; } @@ -4142,14 +4366,23 @@ static void computeTargetPSDs_diffuse_with_onsets_fx( /* segment auxiliary buffer */ Word32 diffuse_power[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */ Word32 aux_buffer_res[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */ +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 q_common, q_reference_power_min_one[2]; + q_reference_power_min_one[0] = sub( q_reference_power[0], Q1 ); + q_reference_power_min_one[1] = sub( q_reference_power[1], Q1 ); +#else Word16 q_common, q_reference_power_min_one; q_reference_power_min_one = sub( *q_reference_power, Q1 ); +#endif /* estimate direct and diffuse power */ v_mult_fixed( diffuse_power_factor, reference_power, diffuse_power, num_decorr_freq_bands ); // (Q31, q_reference_power) -> q_reference_power +#ifdef FIX_867_CLDFB_NRG_SCALE + q_common = s_min( *q_cy_auto_diff_smooth, s_min( q_reference_power_min_one[0], q_reference_power_min_one[1] ) ); +#else IF( GT_16( *q_cy_auto_diff_smooth, q_reference_power_min_one ) ) { q_common = q_reference_power_min_one; @@ -4160,6 +4393,7 @@ static void computeTargetPSDs_diffuse_with_onsets_fx( q_common = *q_cy_auto_diff_smooth; move16(); } +#endif /* compute target auto and cross PSDs of current frame (smoothed) */ FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) @@ -4176,6 +4410,22 @@ static void computeTargetPSDs_diffuse_with_onsets_fx( v_add_fixed( aux_buffer_res1, aux_buffer_res, aux_buffer_res, num_decorr_freq_bands, Q1 ); // Q30 v_mult_fixed( aux_buffer_res, diffuse_power, aux_buffer_res, num_decorr_freq_bands ); // (Q30, q_reference_power) -> q_reference_power - Q1 +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( NE_16( q_common, q_reference_power_min_one[0] ) ) + { + scale_sig32( aux_buffer_res, s_min( num_decorr_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_common, q_reference_power_min_one[0] ) ); // q_common + } + IF( NE_16( q_common, q_reference_power_min_one[1] ) ) + { + scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_decorr_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_common, q_reference_power_min_one[1] ) ); // q_common + } + IF( NE_16( q_common, *q_cy_auto_diff_smooth ) ) + { + scale_sig32( &cy_auto_diff_smooth[cur_idx], num_decorr_freq_bands, sub( q_common, *q_cy_auto_diff_smooth ) ); // q_common + } + v_add_fixed( &cy_auto_diff_smooth[cur_idx], aux_buffer_res, &cy_auto_diff_smooth[cur_idx], num_decorr_freq_bands, Q1 ); // (q_common - Q1) + scale_sig32( &cy_auto_diff_smooth[cur_idx + num_decorr_freq_bands], sub( num_freq_bands, num_decorr_freq_bands ), sub( sub( q_common, Q1 ), *q_cy_auto_diff_smooth ) ); // (q_common - Q1) +#else IF( NE_16( q_common, q_reference_power_min_one ) ) { scale_sig32( aux_buffer_res, num_decorr_freq_bands, sub( q_common, q_reference_power_min_one ) ); // q_common @@ -4186,6 +4436,7 @@ static void computeTargetPSDs_diffuse_with_onsets_fx( } v_add_fixed( &cy_auto_diff_smooth[cur_idx], aux_buffer_res, &cy_auto_diff_smooth[cur_idx], num_decorr_freq_bands, Q1 ); // (q_common - Q1) scale_sig32( &cy_auto_diff_smooth[cur_idx + num_decorr_freq_bands], sub( num_freq_bands, num_decorr_freq_bands ), sub( sub( q_common, Q1 ), *q_cy_auto_diff_smooth ) ); // (q_common - Q1) +#endif } /* Q adjustment */ diff --git a/lib_rend/ivas_dirac_rend_fx.c b/lib_rend/ivas_dirac_rend_fx.c index efa0b35e614716510e1f53e8f35921981e098c37..f67f3761bee66257e79a5fc22dce5e97b9af76c5 100644 --- a/lib_rend/ivas_dirac_rend_fx.c +++ b/lib_rend/ivas_dirac_rend_fx.c @@ -783,10 +783,21 @@ ivas_error ivas_dirac_alloc_mem_fx( } } hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx = hDirAC_mem->proto_power_smooth_fx; +#ifdef FIX_867_CLDFB_NRG_SCALE + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = Q31; + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = Q31; + move16(); + move16(); + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] = Q31; + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] = Q31; + move16(); + move16(); +#else hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q = Q31; move16(); hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q = Q31; move16(); +#endif hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_fx = hDirAC_mem->proto_power_diff_smooth_fx; hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q = hDirAC_mem->proto_power_diff_smooth_q; move16(); @@ -940,10 +951,21 @@ ivas_error ivas_dirac_alloc_mem_fx( hDirAC_mem->reference_power_len = imult1616( 2, num_freq_bands ); move16(); +#ifdef FIX_867_CLDFB_NRG_SCALE + hDirAC_mem->reference_power_q[0] = Q31; + hDirAC_mem->reference_power_q[1] = Q31; + move16(); + move16(); + hDirAC_mem->reference_power_smooth_q[0] = Q31; + hDirAC_mem->reference_power_smooth_q[1] = Q31; + move16(); + move16(); +#else hDirAC_mem->reference_power_q = Q31; move16(); hDirAC_mem->reference_power_smooth_q = Q31; move16(); +#endif IF( hDirACRend->proto_signal_decorr_on ) { IF( ( hDirAC_mem->onset_filter_fx = (Word32 *) malloc( sizeof( Word32 ) * num_outputs_diff * num_freq_bands ) ) == NULL ) @@ -1466,8 +1488,14 @@ void protoSignalComputation_shd_fx( *proto_direct_buffer_f_q = add( q_cldfb, min_q_shift ); move16(); +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); + reference_power_q[qidx] = sub( add( *proto_direct_buffer_f_q, *proto_direct_buffer_f_q ), 31 ); + move16(); +#else *reference_power_q = sub( add( *proto_direct_buffer_f_q, *proto_direct_buffer_f_q ), 31 ); move16(); +#endif Word16 shift = sub( *proto_direct_buffer_f_q, q_cldfb ); FOR( k = 1; k < 4; k++ ) @@ -1502,8 +1530,15 @@ void protoSignalComputation_shd_fx( } *proto_direct_buffer_f_q = q_cldfb; move16(); +#ifdef FIX_867_CLDFB_NRG_SCALE + reference_power_q[0] = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); + reference_power_q[1] = reference_power_q[0]; + move16(); + move16(); +#else *reference_power_q = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); move16(); +#endif } /* Additional transport channels = planar SBA components of degree higher than 1*/ @@ -1565,7 +1600,11 @@ void protoSignalComputation1_fx( { Word16 l, k, idx; Word32 *p_proto_buffer_fx; +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 proto_power_smooth_fx_q[2], min_q_shift, q_shift; +#else Word16 proto_power_smooth_fx_q, min_q_shift, q_shift; +#endif Word32 re, im; min_q_shift = Q31; @@ -1588,17 +1627,48 @@ void protoSignalComputation1_fx( q_shift = sub( q_shift, find_guarded_bits_fx( 2 ) ); Scale_sig32( proto_power_smooth_fx, num_freq_bands, q_shift ); /*proto_power_smooth_q+q_shift*/ +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_q[0] = add( proto_power_smooth_q[0], q_shift ); + proto_power_smooth_q[1] = add( proto_power_smooth_q[1], q_shift ); + proto_power_smooth_fx_q[0] = proto_power_smooth_q[0]; + proto_power_smooth_fx_q[1] = proto_power_smooth_q[1]; + move16(); + move16(); +#else *proto_power_smooth_q = add( *proto_power_smooth_q, q_shift ); proto_power_smooth_fx_q = *proto_power_smooth_q; move16(); +#endif FOR( l = 0; l < num_freq_bands; l++ ) { +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); +#endif re = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift im = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift reference_power_fx[l] = Madd_32_32( Mpy_32_32( re, re ), im, im ); // 2*(q_cldfb+min_q_shift)-31 move32(); +#ifdef FIX_867_CLDFB_NRG_SCALE + reference_power_q[qidx] = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); + move16(); + + IF( LT_16( reference_power_q[qidx], proto_power_smooth_q[qidx] ) ) + { + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( proto_power_smooth_q[qidx], reference_power_q[qidx] ) ), reference_power_fx[l] ); // reference_power_q + move32(); + proto_power_smooth_fx_q[qidx] = reference_power_q[qidx]; + move16(); + } + ELSE + { + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( reference_power_fx[l], sub( reference_power_q[qidx], proto_power_smooth_q[qidx] ) ) ); // proto_power_smooth_q + move32(); + proto_power_smooth_fx_q[qidx] = proto_power_smooth_q[qidx]; + move16(); + } +#else *reference_power_q = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); move16(); @@ -1616,6 +1686,7 @@ void protoSignalComputation1_fx( proto_power_smooth_fx_q = *proto_power_smooth_q; move16(); } +#endif idx = 2 * l; p_proto_buffer_fx[idx] = RealBuffer_fx[0][0][l]; // q_cldfb @@ -1637,8 +1708,15 @@ void protoSignalComputation1_fx( move16(); *proto_direct_buffer_f_q = q_cldfb; move16(); +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_q[0] = proto_power_smooth_fx_q[0]; + proto_power_smooth_q[1] = proto_power_smooth_fx_q[1]; + move16(); + move16(); +#else *proto_power_smooth_q = proto_power_smooth_fx_q; move16(); +#endif return; } @@ -1684,15 +1762,29 @@ void protoSignalComputation2_fx( Word32 a_fx, b_fx, a2_fx, b2_fx; Word16 interpolatorSpaced_fx, interpolatorDmx_fx; Word32 tempSpaced_fx, tempDmx_fx; +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 q_shift, min_q_shift[2], exp, q_temp[2], temp_q_shift, q_temp2; +#else Word16 q_shift, min_q_shift, exp, q_temp, temp_q_shift, q_temp2; +#endif Word32 temp; Word64 W_tmp1, W_tmp2; Word64 reference_power_64fx[CLDFB_NO_CHANNELS_MAX]; Word16 q_reference_power_64fx; Word16 head_room, q_Left_Right_power; +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 num_proto = 3; +#endif /* Calculate maximum possible shift for the buffers RealBuffer_fx and ImagBuffer_fx */ +#ifdef FIX_867_CLDFB_NRG_SCALE + min_q_shift[0] = Q31; + min_q_shift[1] = Q31; + move16(); + move16(); +#else min_q_shift = Q31; move16(); +#endif temp_q_shift = Q31; move16(); q_sum_total_ratio = Q31; @@ -1707,17 +1799,71 @@ void protoSignalComputation2_fx( /* Calculate the max shift possible for the buffers RealBuffer_fx and ImagBuffer_fx */ FOR( l = 0; l < 2; l++ ) { +#ifdef FIX_867_CLDFB_NRG_SCALE + q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0], s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ) ), L_norm_arr( ImagBuffer_fx[l][0], s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ) ) ); + min_q_shift[0] = s_min( min_q_shift[0], q_shift ); + q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0] + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ), L_norm_arr( ImagBuffer_fx[l][0] + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); + min_q_shift[1] = s_min( min_q_shift[1], q_shift ); +#if ( MASA_SUM_FREQ_RANGE_BINS > CLDFB_NO_CHANNELS_HALF ) +#error MASA_SUM_FREQ_RANGE_BINS if greater than CLDFB_NO_CHANNELS_HALF, this does not work +#endif +#else q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0], num_freq_bands ), L_norm_arr( ImagBuffer_fx[l][0], num_freq_bands ) ); min_q_shift = s_min( min_q_shift, q_shift ); - +#endif q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0], s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) ), L_norm_arr( ImagBuffer_fx[l][0], s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) ) ); temp_q_shift = s_min( temp_q_shift, q_shift ); } - min_q_shift = sub( min_q_shift, 2 ); // guard bits +#ifdef FIX_867_CLDFB_NRG_SCALE + min_q_shift[0] = sub( min_q_shift[0], 2 ); // guard bits + min_q_shift[1] = sub( min_q_shift[1], 2 ); // guard bits +#else + min_q_shift = sub( min_q_shift, 2 ); // guard bits +#endif temp_q_shift = sub( temp_q_shift, 2 ); // guard bits /* Upscaling of the buffer proto_power_smooth_fx */ +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( isloudspeaker ) + { + num_proto = 3; + q_shift = L_norm_arr( proto_power_smooth_fx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); + q_shift = s_min( q_shift, L_norm_arr( proto_power_smooth_fx + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + q_shift = s_min( q_shift, L_norm_arr( proto_power_smooth_fx + num_freq_bands + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + scale_sig32( proto_power_smooth_fx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx + num_freq_bands + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + } + ELSE + { + num_proto = 2; + q_shift = L_norm_arr( proto_power_smooth_fx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ); + q_shift = s_min( q_shift, L_norm_arr( proto_power_smooth_fx + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + scale_sig32( proto_power_smooth_fx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + } + q_proto_power_smooth[0] = add( q_proto_power_smooth[0], sub( q_shift, 1 ) ); + move16(); + IF( isloudspeaker ) + { + q_shift = L_norm_arr( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + q_shift = s_min( q_shift, L_norm_arr( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); + q_shift = s_min( q_shift, L_norm_arr( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); + scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + } + ELSE + { + q_shift = L_norm_arr( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + q_shift = s_min( q_shift, L_norm_arr( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); + scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1 + } + q_proto_power_smooth[1] = add( q_proto_power_smooth[1], sub( q_shift, 1 ) ); + move16(); +#else IF( isloudspeaker ) { q_shift = getScaleFactor32( proto_power_smooth_fx, i_mult( 3, num_freq_bands ) ); @@ -1730,20 +1876,35 @@ void protoSignalComputation2_fx( } *q_proto_power_smooth = add( *q_proto_power_smooth, sub( q_shift, 1 ) ); move16(); +#endif IF( isloudspeaker ) { p_proto_buffer_fx = proto_direct_buffer_f_fx + i_mult( i_mult( i_mult( slot_index, 2 ), num_freq_bands ), 3 ); // q_proto_direct_buffer_f +#ifdef FIX_867_CLDFB_NRG_SCALE + q_temp[0] = sub( add( add( q_cldfb, min_q_shift[0] ), add( q_cldfb, min_q_shift[0] ) ), 31 ); + q_temp[1] = sub( add( add( q_cldfb, min_q_shift[1] ), add( q_cldfb, min_q_shift[1] ) ), 31 ); +#else q_temp = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); move16(); +#endif FOR( l = 0; l < num_freq_bands; l++ ) { +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); + + re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift + im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift + re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift + im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift +#else re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift +#endif Real_aux_fx = L_add( re1, re2 ); // q_cldfb+min_q_shift Imag_aux_fx = L_add( im1, im2 ); // q_cldfb+min_q_shift @@ -1760,14 +1921,26 @@ void protoSignalComputation2_fx( temp = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift)-31 +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) +#else IF( LT_16( q_temp, *q_proto_power_smooth ) ) +#endif { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp +#else proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp +#endif move32(); } ELSE { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth +#else proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth +#endif move32(); } @@ -1778,14 +1951,26 @@ void protoSignalComputation2_fx( temp = Madd_32_32( Mpy_32_32( re1, re1 ), im1, im1 ); // 2*(q_cldfb+min_q_shift)-31 +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) +#else IF( LT_16( q_temp, *q_proto_power_smooth ) ) +#endif { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp +#else proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp +#endif move32(); } ELSE { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth +#else proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth +#endif move32(); } @@ -1795,14 +1980,26 @@ void protoSignalComputation2_fx( move32(); temp = Madd_32_32( Mpy_32_32( re2, re2 ), im2, im2 ); // 2*(q_cldfb+min_q_shift)-31 +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) +#else IF( LT_16( q_temp, *q_proto_power_smooth ) ) +#endif { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( L_shr( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp +#else proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( L_shr( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp +#endif move32(); } ELSE { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth +#else proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth +#endif move32(); } @@ -1873,19 +2070,39 @@ void protoSignalComputation2_fx( } } +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 total_shift[2], q_temp_total; + /* total_shift shift required to get common Q of sum power values */ + total_shift[0] = shl( s_max( 0, sub( min_q_shift[0], min_q_shift[1] ) ), 1 ); + total_shift[1] = shl( s_max( 0, sub( min_q_shift[1], min_q_shift[0] ) ), 1 ); + min_q_shift[0] = sub( min_q_shift[0], idiv1616( find_guarded_bits_fx( num_freq_bands ), 2 ) ); + min_q_shift[1] = sub( min_q_shift[1], idiv1616( find_guarded_bits_fx( num_freq_bands ), 2 ) ); + q_temp[0] = sub( add( add( q_cldfb, min_q_shift[0] ), add( q_cldfb, min_q_shift[0] ) ), 31 ); + q_temp[1] = sub( add( add( q_cldfb, min_q_shift[1] ), add( q_cldfb, min_q_shift[1] ) ), 31 ); + q_temp_total = s_min( q_temp[0], q_temp[1] ); +#else min_q_shift = sub( min_q_shift, idiv1616( find_guarded_bits_fx( num_freq_bands ), 2 ) ); q_temp = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); +#endif q_temp2 = sub( add( add( q_cldfb, temp_q_shift ), add( q_cldfb, temp_q_shift ) ), 31 ); head_room = 63; move16(); FOR( l = 0; l < num_freq_bands; l++ ) { +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); + re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift + im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift + re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift + im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift +#else re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift +#endif W_tmp1 = W_add( W_mult0_32_32( re1, re1 ), W_mult0_32_32( im1, im1 ) ); W_tmp2 = W_add( W_mult0_32_32( re2, re2 ), W_mult0_32_32( im2, im2 ) ); @@ -1893,14 +2110,30 @@ void protoSignalComputation2_fx( head_room = s_min( head_room, W_norm( W_add( W_tmp1, W_tmp2 ) ) ); } head_room = sub( head_room, find_guarded_bits_fx( num_freq_bands ) ); + +#ifdef FIX_867_CLDFB_NRG_SCALE +#if ( MASA_SUM_FREQ_RANGE_BINS > CLDFB_NO_CHANNELS_HALF ) +#error MASA_SUM_FREQ_RANGE_BINS must be less than CLDFB_NO_CHANNELS_HALF +#endif + q_Left_Right_power = add( shl( add( q_cldfb, min_q_shift[0] ), 1 ), sub( head_room, 32 ) ); +#else q_Left_Right_power = add( shl( add( q_cldfb, min_q_shift ), 1 ), sub( head_room, 32 ) ); +#endif FOR( l = 0; l < num_freq_bands; l++ ) { - re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift - im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift - re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift - im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); + re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift + im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift + re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift + im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift +#else + re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift + im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift + re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift + im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+min_q_shift +#endif /* Compute sum signal */ Real_aux_fx = L_add( re1, re2 ); // q_cldfb+min_q_shift @@ -1910,6 +2143,7 @@ void protoSignalComputation2_fx( // Left_power_fx = Madd_32_32( Mpy_32_32( re1, re1 ), im1, im1 ); W_tmp1 = W_add( W_mult0_32_32( re1, re1 ), W_mult0_32_32( im1, im1 ) ); // 2*(q_cldfb+min_q_shift) Left_power_fx = W_extract_h( W_shl( W_tmp1, head_room ) ); // q_Left_Right_power + // Right_power_fx = Madd_32_32( Mpy_32_32( re2, re2 ), im2, im2 ); W_tmp2 = W_add( W_mult0_32_32( re2, re2 ), W_mult0_32_32( im2, im2 ) ); // 2*(q_cldfb+min_q_shift) Right_power_fx = W_extract_h( W_shl( W_tmp2, head_room ) ); // q_Left_Right_power @@ -1918,23 +2152,41 @@ void protoSignalComputation2_fx( reference_power_64fx[l] = W_add( W_tmp1, W_tmp2 ); // 2*(q_cldfb+min_q_shift) move64(); +#ifdef FIX_867_CLDFB_NRG_SCALE + Left_power_fx = L_shr( Left_power_fx, total_shift[qidx] ); + Right_power_fx = L_shr( Right_power_fx, total_shift[qidx] ); + left_bb_power_fx = L_add( left_bb_power_fx, Left_power_fx ); // q_Left_Right_power + right_bb_power_fx = L_add( right_bb_power_fx, Right_power_fx ); // q_Left_Right_power + // total_bb_power_fx = L_add( total_bb_power_fx, reference_power_fx[l] ); + total_bb_power_fx = L_add( total_bb_power_fx, W_extract_h( W_shl( reference_power_64fx[l], sub( head_room, total_shift[qidx] ) ) ) ); // q_Left_Right_power +#else left_bb_power_fx = L_add( left_bb_power_fx, Left_power_fx ); // q_Left_Right_power right_bb_power_fx = L_add( right_bb_power_fx, Right_power_fx ); // q_Left_Right_power // total_bb_power_fx = L_add( total_bb_power_fx, reference_power_fx[l] ); - total_bb_power_fx = L_add( total_bb_power_fx, W_extract_h( W_shl( reference_power_64fx[l], head_room ) ) ); // q_Left_Right_power + total_bb_power_fx = L_add( total_bb_power_fx, W_extract_h( W_shl( reference_power_64fx[l], head_room ) ) ); // q_Left_Right_power +#endif IF( GT_16( l, MASA_HI_FREQ_START_BIN ) ) { left_hi_power_fx = L_add( left_hi_power_fx, Left_power_fx ); // q_Left_Right_power right_hi_power_fx = L_add( right_hi_power_fx, Right_power_fx ); // q_Left_Right_power - // total_hi_power_fx = L_add( total_hi_power_fx, reference_power_fx[l] ); + // total_hi_power_fx = L_add( total_hi_power_fx, reference_power_fx[l] ); +#ifdef FIX_867_CLDFB_NRG_SCALE + total_hi_power_fx = L_add( total_hi_power_fx, W_extract_h( W_shl( reference_power_64fx[l], sub( head_room, total_shift[qidx] ) ) ) ); // q_Left_Right_power +#else total_hi_power_fx = L_add( total_hi_power_fx, W_extract_h( W_shl( reference_power_64fx[l], head_room ) ) ); // q_Left_Right_power +#endif } IF( LT_16( l, s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) ) ) { - re_aux = L_shl( Real_aux_fx, sub( temp_q_shift, min_q_shift ) ); // q_cldfb+temp_q_shift - im_aux = L_shl( Imag_aux_fx, sub( temp_q_shift, min_q_shift ) ); // q_cldfb+temp_q_shift +#ifdef FIX_867_CLDFB_NRG_SCALE + re_aux = L_shl( Real_aux_fx, sub( temp_q_shift, min_q_shift[0] ) ); // q_cldfb+temp_q_shift + im_aux = L_shl( Imag_aux_fx, sub( temp_q_shift, min_q_shift[0] ) ); // q_cldfb+temp_q_shift +#else + re_aux = L_shl( Real_aux_fx, sub( temp_q_shift, min_q_shift ) ); // q_cldfb+temp_q_shift + im_aux = L_shl( Imag_aux_fx, sub( temp_q_shift, min_q_shift ) ); // q_cldfb+temp_q_shift +#endif sum_power_fx = Madd_32_32( Mpy_32_32( re_aux, re_aux ), im_aux, im_aux ); // 2*(q_cldfb+temp_q_shift)-31 temp = Mpy_32_32( a_fx, sum_power_fx ); // 2*(q_cldfb+temp_q_shift)-31 @@ -1950,7 +2202,20 @@ void protoSignalComputation2_fx( move32(); } - temp = Mpy_32_32( a_fx, W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // 2*(q_cldfb+min_q_shift) -31 +#ifdef FIX_867_CLDFB_NRG_SCALE + temp = Mpy_32_32( a_fx, W_extract_l( W_shr( reference_power_64fx[l], add( 31, total_shift[qidx] ) ) ) ); // 2*(q_cldfb+min_q_shift) -31 + IF( LT_16( q_temp_total, stereo_type_detect->q_total_power ) ) + { + stereo_type_detect->total_power_fx[l] = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->total_power_fx[l] ), sub( stereo_type_detect->q_total_power, q_temp_total ) ) ); // q_temp + move32(); + } + ELSE + { + stereo_type_detect->total_power_fx[l] = L_add( L_shr( temp, sub( q_temp_total, stereo_type_detect->q_total_power ) ), Mpy_32_32( b_fx, stereo_type_detect->total_power_fx[l] ) ); // stereo_type_detect->q_total_power + move32(); + } +#else + temp = Mpy_32_32( a_fx, W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // 2*(q_cldfb+min_q_shift) -31 IF( LT_16( q_temp, stereo_type_detect->q_total_power ) ) { stereo_type_detect->total_power_fx[l] = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->total_power_fx[l] ), sub( stereo_type_detect->q_total_power, q_temp ) ) ); // q_temp @@ -1961,6 +2226,7 @@ void protoSignalComputation2_fx( stereo_type_detect->total_power_fx[l] = L_add( L_shr( temp, sub( q_temp, stereo_type_detect->q_total_power ) ), Mpy_32_32( b_fx, stereo_type_detect->total_power_fx[l] ) ); // stereo_type_detect->q_total_power move32(); } +#endif test(); IF( ( stereo_type_detect->sum_power_fx[l] == 0 ) && ( stereo_type_detect->total_power_fx[l] == 0 ) ) @@ -1977,7 +2243,11 @@ void protoSignalComputation2_fx( { sum_total_ratio_fx[l] = BASOP_Util_Divide3232_Scale( stereo_type_detect->sum_power_fx[l], stereo_type_detect->total_power_fx[l], &exp ); // 15-(exp+s_min( stereo_type_detect->q_total_power, q_temp )-s_min( stereo_type_detect->q_sum_power, q_temp2 )) move32(); +#ifdef FIX_867_CLDFB_NRG_SCALE + q_sum_total_ratio = add( sub( 15, exp ), sub( s_min( stereo_type_detect->q_sum_power, q_temp2 ), s_min( stereo_type_detect->q_total_power, q_temp_total ) ) ); +#else q_sum_total_ratio = add( sub( 15, exp ), sub( s_min( stereo_type_detect->q_sum_power, q_temp2 ), s_min( stereo_type_detect->q_total_power, q_temp ) ) ); +#endif sum_total_ratio_fx[l] = L_shl( sum_total_ratio_fx[l], sub( Q15, q_sum_total_ratio ) ); // q15 move32(); } @@ -1989,6 +2259,22 @@ void protoSignalComputation2_fx( ImagSubtract_fx = L_sub( im1, im2 ); // q_cldfb+min_q_shift temp = Madd_32_32( Mpy_32_32( RealSubtract_fx, RealSubtract_fx ), ImagSubtract_fx, ImagSubtract_fx ); // 2*(q_cldfb+min_q_shift)-31 +#ifdef FIX_867_CLDFB_NRG_SCALE + assert( qidx == 0 ); + IF( LT_16( q_temp[qidx], stereo_type_detect->q_subtract_power_y ) ) + { + stereo_type_detect->subtract_power_y_fx = L_add( L_shr( stereo_type_detect->subtract_power_y_fx, sub( stereo_type_detect->q_subtract_power_y, q_temp[qidx] ) ), temp ); // q_temp + move32(); + stereo_type_detect->q_subtract_power_y = q_temp[qidx]; + move16(); + } + ELSE + { + stereo_type_detect->subtract_power_y_fx = L_add( stereo_type_detect->subtract_power_y_fx, L_shr( temp, sub( q_temp[qidx], stereo_type_detect->q_subtract_power_y ) ) ); // stereo_type_detect->q_subtract_power_y + move32(); + } + +#else IF( LT_16( q_temp, stereo_type_detect->q_subtract_power_y ) ) { stereo_type_detect->subtract_power_y_fx = L_add( L_shr( stereo_type_detect->subtract_power_y_fx, sub( stereo_type_detect->q_subtract_power_y, q_temp ) ), temp ); // q_temp @@ -2001,6 +2287,7 @@ void protoSignalComputation2_fx( stereo_type_detect->subtract_power_y_fx = L_add( stereo_type_detect->subtract_power_y_fx, L_shr( temp, sub( q_temp, stereo_type_detect->q_subtract_power_y ) ) ); // stereo_type_detect->q_subtract_power_y move32(); } +#endif } /* Compute protos (and their power) for direct sound rendering */ @@ -2014,14 +2301,26 @@ void protoSignalComputation2_fx( Imag_aux_fx = Madd_32_16( Mpy_32_16_1( Imag_aux_fx, shr( interpolatorSpaced_fx, 1 ) ), Imag_aux_fx, interpolatorDmx_fx ); // q_cldfb+min_q_shift temp = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift) -31 +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) +#else IF( LT_16( q_temp, *q_proto_power_smooth ) ) +#endif { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp +#else proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp +#endif move32(); } ELSE { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth +#else proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth +#endif move32(); } @@ -2036,14 +2335,26 @@ void protoSignalComputation2_fx( tempDmx_fx = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift)-31 temp = Madd_32_16( Mpy_32_16_1( tempSpaced_fx, interpolatorSpaced_fx ), tempDmx_fx, interpolatorDmx_fx ); // 2*(q_cldfb+min_q_shift)-31 +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) +#else IF( LT_16( q_temp, *q_proto_power_smooth ) ) +#endif { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp +#else proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp +#endif move32(); } ELSE { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth +#else proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth +#endif move32(); } @@ -2060,14 +2371,26 @@ void protoSignalComputation2_fx( Real_aux_fx = L_shr( Real_aux_fx, 1 ); // q_cldfb+min_q_shift Imag_aux_fx = L_shr( Imag_aux_fx, 1 ); // q_cldfb+min_q_shift temp = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift)-31 +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) +#else IF( LT_16( q_temp, *q_proto_power_smooth ) ) +#endif { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp +#else proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp +#endif move32(); } ELSE { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth +#else proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth +#endif move32(); } @@ -2079,14 +2402,26 @@ void protoSignalComputation2_fx( ELSE { temp = Madd_32_32( Mpy_32_32( re1, re1 ), im1, im1 ); // 2*(q_cldfb+min_q_shift)-31 +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) +#else IF( LT_16( q_temp, *q_proto_power_smooth ) ) +#endif { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp +#else proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp +#endif move32(); } ELSE { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth +#else proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth +#endif move32(); } @@ -2099,14 +2434,26 @@ void protoSignalComputation2_fx( ELSE { temp = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift)-31 +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) +#else IF( LT_16( q_temp, *q_proto_power_smooth ) ) +#endif { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp +#else proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp +#endif move32(); } ELSE { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth +#else proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth +#endif move32(); } @@ -2142,14 +2489,26 @@ void protoSignalComputation2_fx( } temp = Madd_32_32( Mpy_32_32( p_proto_buffer_fx[2 * ( num_freq_bands + l )], p_proto_buffer_fx[2 * ( num_freq_bands + l )] ), p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1], p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] ); // 2*(q_cldfb+min_q_shift)-31 +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) +#else IF( LT_16( q_temp, *q_proto_power_smooth ) ) +#endif { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp +#else proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp +#endif move32(); } ELSE { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth +#else proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth +#endif move32(); } } @@ -2172,14 +2531,26 @@ void protoSignalComputation2_fx( move32(); temp = Madd_32_32( Mpy_32_32( p_proto_buffer_fx[2 * ( num_freq_bands + l )], p_proto_buffer_fx[2 * ( num_freq_bands + l )] ), p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1], p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] ); // 2*(q_cldfb+min_q_shift)-31 +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) +#else IF( LT_16( q_temp, *q_proto_power_smooth ) ) +#endif { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp +#else proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp +#endif move32(); } ELSE { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth +#else proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth +#endif move32(); } } @@ -2201,14 +2572,26 @@ void protoSignalComputation2_fx( move32(); temp = Madd_32_32( Mpy_32_32( p_proto_buffer_fx[2 * ( num_freq_bands + l )], p_proto_buffer_fx[2 * ( num_freq_bands + l )] ), p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1], p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] ); // 2*(q_cldfb+min_q_shift)-31 +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) +#else IF( LT_16( q_temp, *q_proto_power_smooth ) ) +#endif { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp +#else proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp +#endif move32(); } ELSE { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth +#else proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth +#endif move32(); } } @@ -2230,8 +2613,13 @@ void protoSignalComputation2_fx( stereo_type_detect->q_sum_power = s_min( stereo_type_detect->q_sum_power, q_temp2 ); move16(); +#ifdef FIX_867_CLDFB_NRG_SCALE + stereo_type_detect->q_total_power = s_min( stereo_type_detect->q_total_power, q_temp_total ); + move16(); +#else stereo_type_detect->q_total_power = s_min( stereo_type_detect->q_total_power, q_temp ); move16(); +#endif q_sum_total_ratio = Q15; move16(); @@ -2314,6 +2702,18 @@ void protoSignalComputation2_fx( // 20480 = 10 in Q11 lr_total_bb_ratio_fx = Mpy_32_16_1( temp, 20480 ); // Q21 +#ifdef FIX_867_CLDFB_NRG_SCALE + stereo_type_detect->left_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, left_hi_power_fx ), sub( 31, q_temp_total ), Mpy_32_32( b2_fx, stereo_type_detect->left_hi_power_fx ), sub( 31, stereo_type_detect->q_left_hi_power ), &stereo_type_detect->q_left_hi_power ); + move32(); + stereo_type_detect->q_left_hi_power = sub( 31, stereo_type_detect->q_left_hi_power ); + move16(); + stereo_type_detect->right_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, right_hi_power_fx ), sub( 31, q_temp_total ), Mpy_32_32( b2_fx, stereo_type_detect->right_hi_power_fx ), sub( 31, stereo_type_detect->q_right_hi_power ), &stereo_type_detect->q_right_hi_power ); + move32(); + stereo_type_detect->q_right_hi_power = sub( 31, stereo_type_detect->q_right_hi_power ); + move16(); + stereo_type_detect->total_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, total_hi_power_fx ), sub( 31, q_temp_total ), Mpy_32_32( b2_fx, stereo_type_detect->total_hi_power_fx ), sub( 31, stereo_type_detect->q_total_hi_power ), &stereo_type_detect->q_total_hi_power ); + move32(); +#else stereo_type_detect->left_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, left_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b2_fx, stereo_type_detect->left_hi_power_fx ), sub( 31, stereo_type_detect->q_left_hi_power ), &stereo_type_detect->q_left_hi_power ); move32(); stereo_type_detect->q_left_hi_power = sub( 31, stereo_type_detect->q_left_hi_power ); @@ -2324,6 +2724,7 @@ void protoSignalComputation2_fx( move16(); stereo_type_detect->total_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, total_hi_power_fx ), sub( 31, q_temp ), Mpy_32_32( b2_fx, stereo_type_detect->total_hi_power_fx ), sub( 31, stereo_type_detect->q_total_hi_power ), &stereo_type_detect->q_total_hi_power ); move32(); +#endif stereo_type_detect->q_total_hi_power = sub( 31, stereo_type_detect->q_total_hi_power ); move16(); @@ -2373,14 +2774,27 @@ void protoSignalComputation2_fx( { p_proto_buffer_fx = proto_direct_buffer_f_fx + ( slot_index * num_freq_bands * 4 ); // q_proto_direct_buffer_f +#ifdef FIX_867_CLDFB_NRG_SCALE + q_temp[0] = sub( add( add( q_cldfb, min_q_shift[0] ), add( q_cldfb, min_q_shift[0] ) ), 31 ); + q_temp[1] = sub( add( add( q_cldfb, min_q_shift[1] ), add( q_cldfb, min_q_shift[1] ) ), 31 ); +#else q_temp = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); +#endif FOR( l = 0; l < num_freq_bands; l++ ) { +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) ); + re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+ min_q_shift + re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+ min_q_shift + im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+ min_q_shift + im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+ min_q_shift +#else re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+ min_q_shift re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+ min_q_shift im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+ min_q_shift im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); // q_cldfb+ min_q_shift +#endif Real_aux_fx = L_add( re1, re2 ); // q_cldfb+ min_q_shift Imag_aux_fx = L_add( im1, im2 ); // q_cldfb+ min_q_shift @@ -2389,14 +2803,26 @@ void protoSignalComputation2_fx( reference_power_64fx[l] = W_add( W_mult0_32_32( Real_aux_fx, Real_aux_fx ), W_mult0_32_32( Imag_aux_fx, Imag_aux_fx ) ); // q_temp move64(); +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) +#else IF( LT_16( q_temp, *q_proto_power_smooth ) ) +#endif { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // q_temp +#else proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( *q_proto_power_smooth, q_temp ) ), W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // q_temp +#endif move32(); } ELSE { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( W_extract_l( W_shr( reference_power_64fx[l], 31 ) ), sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth +#else proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( W_extract_l( W_shr( reference_power_64fx[l], 31 ) ), sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth +#endif move32(); } @@ -2411,14 +2837,26 @@ void protoSignalComputation2_fx( move32(); temp = Madd_32_32( Mpy_32_32( p_proto_buffer_fx[2 * ( num_freq_bands + l )], p_proto_buffer_fx[2 * ( num_freq_bands + l )] ), p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1], p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] ); // q_temp +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) ) +#else IF( LT_16( q_temp, *q_proto_power_smooth ) ) +#endif { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp +#else proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( *q_proto_power_smooth, q_temp ) ), temp ); // q_temp +#endif move32(); } ELSE { +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth +#else proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp, *q_proto_power_smooth ) ) ); // q_proto_power_smooth +#endif move32(); } @@ -2437,6 +2875,44 @@ void protoSignalComputation2_fx( move32(); } } +#ifdef FIX_867_CLDFB_NRG_SCALE + q_reference_power_64fx = shl( add( q_cldfb, min_q_shift[0] ), 1 ); + + Word16 norm_shift = 63; + move16(); + FOR( l = 0; l < s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ); l++ ) + { + IF( reference_power_64fx[l] ) + { + norm_shift = s_min( norm_shift, W_norm( reference_power_64fx[l] ) ); + } + } + FOR( l = 0; l < s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ); l++ ) + { + reference_power_fx[l] = W_extract_h( W_shl( reference_power_64fx[l], norm_shift ) ); // q_reference_power_64fx+norm_shift-32 + move32(); + } + q_reference_power[0] = sub( add( q_reference_power_64fx, norm_shift ), 32 ); + move16(); + + q_reference_power_64fx = shl( add( q_cldfb, min_q_shift[1] ), 1 ); + norm_shift = 63; + move16(); + FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ ) + { + IF( reference_power_64fx[l] ) + { + norm_shift = s_min( norm_shift, W_norm( reference_power_64fx[l] ) ); + } + } + FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ ) + { + reference_power_fx[l] = W_extract_h( W_shl( reference_power_64fx[l], norm_shift ) ); // q_reference_power_64fx+norm_shift-32 + move32(); + } + q_reference_power[1] = sub( add( q_reference_power_64fx, norm_shift ), 32 ); + move16(); +#else q_reference_power_64fx = shl( add( q_cldfb, min_q_shift ), 1 ); Word16 norm_shift = 63; move16(); @@ -2454,13 +2930,60 @@ void protoSignalComputation2_fx( } *q_reference_power = sub( add( q_reference_power_64fx, norm_shift ), 32 ); move16(); +#endif +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( GT_16( min_q_shift[0], min_q_shift[1] ) ) + { + FOR( l = 0; l < i_mult( num_proto, num_freq_bands ); l += num_freq_bands ) + { + Scale_sig32( proto_frame_f_fx + shl( l, 1 ), shl( s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ), 1 ), sub( min_q_shift[1], min_q_shift[0] ) ); + } + *q_proto_frame_f = add( q_cldfb, min_q_shift[1] ); + move16(); + } + ELSE + { + FOR( l = 0; l < i_mult( num_proto, num_freq_bands ); l += num_freq_bands ) + { + Scale_sig32( proto_frame_f_fx + shl( add( l, CLDFB_NO_CHANNELS_HALF ), 1 ), shl( s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), 1 ), sub( min_q_shift[0], min_q_shift[1] ) ); + } + *q_proto_frame_f = add( q_cldfb, min_q_shift[0] ); + move16(); + } + IF( GT_16( min_q_shift[0], min_q_shift[1] ) ) + { + FOR( l = 0; l < i_mult( num_proto, num_freq_bands ); l += num_freq_bands ) + { + Scale_sig32( p_proto_buffer_fx + shl( l, 1 ), shl( s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ), 1 ), sub( min_q_shift[1], min_q_shift[0] ) ); + } + *q_proto_direct_buffer_f = add( q_cldfb, min_q_shift[1] ); + move16(); + } + ELSE + { + FOR( l = 0; l < i_mult( num_proto, num_freq_bands ); l += num_freq_bands ) + { + Scale_sig32( p_proto_buffer_fx + shl( add( l, CLDFB_NO_CHANNELS_HALF ), 1 ), shl( s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), 1 ), sub( min_q_shift[0], min_q_shift[1] ) ); + } + *q_proto_direct_buffer_f = add( q_cldfb, min_q_shift[0] ); + move16(); + } +#else *q_proto_frame_f = add( q_cldfb, min_q_shift ); move16(); *q_proto_direct_buffer_f = add( q_cldfb, min_q_shift ); move16(); +#endif +#ifdef FIX_867_CLDFB_NRG_SCALE + q_proto_power_smooth[0] = s_min( q_proto_power_smooth[0], q_temp[0] ); + q_proto_power_smooth[1] = s_min( q_proto_power_smooth[1], q_temp[1] ); + move16(); + move16(); +#else *q_proto_power_smooth = s_min( *q_proto_power_smooth, q_temp ); move16(); +#endif return; } @@ -2496,6 +3019,9 @@ void protoSignalComputation4_fx( Word32 sq_tmp_fx; Word32 *p_proto_buffer_fx; Word16 min_q_shift, q_shift; +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 min_q_shift2, q_shift2; +#endif Word32 re, im; Word16 proto_power_smooth_fx_q, sq_tmp_q; @@ -2503,6 +3029,12 @@ void protoSignalComputation4_fx( move16(); q_shift = Q31; move16(); +#ifdef FIX_867_CLDFB_NRG_SCALE + min_q_shift2 = Q31; + move16(); + q_shift2 = Q31; + move16(); +#endif sq_tmp_q = 0; move16(); @@ -2511,16 +3043,53 @@ void protoSignalComputation4_fx( /* calculate the shift possible for both RealBuffer_fx and ImagBuffer_fx buffers*/ FOR( k = 0; k < s_max( 4, nchan_transport ); k++ ) { +#ifdef FIX_867_CLDFB_NRG_SCALE + q_shift = L_norm_arr( RealBuffer_fx[k][0], s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ) ); + min_q_shift = s_min( q_shift, min_q_shift ); + q_shift = L_norm_arr( ImagBuffer_fx[k][0], s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ) ); + min_q_shift = s_min( q_shift, min_q_shift ); + q_shift2 = L_norm_arr( RealBuffer_fx[k][0] + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + min_q_shift2 = s_min( q_shift2, min_q_shift2 ); + q_shift2 = L_norm_arr( ImagBuffer_fx[k][0] + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + min_q_shift2 = s_min( q_shift2, min_q_shift2 ); +#else q_shift = L_norm_arr( RealBuffer_fx[k][0], num_freq_bands ); min_q_shift = s_min( q_shift, min_q_shift ); q_shift = L_norm_arr( ImagBuffer_fx[k][0], num_freq_bands ); min_q_shift = s_min( q_shift, min_q_shift ); +#endif } q_shift = min_q_shift; min_q_shift = sub( min_q_shift, find_guarded_bits_fx( i_mult( 2, 4 ) ) ); +#ifdef FIX_867_CLDFB_NRG_SCALE + q_shift2 = min_q_shift2; + min_q_shift2 = sub( min_q_shift2, find_guarded_bits_fx( i_mult( 2, 4 ) ) ); +#endif FOR( k = 0; k < 4; k++ ) { +#ifdef FIX_867_CLDFB_NRG_SCALE + FOR( l = 0; l < s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ); l++ ) + { + re = L_shl( RealBuffer_fx[k][0][l], min_q_shift ); // q_cldfb+min_q_shift + im = L_shl( ImagBuffer_fx[k][0][l], min_q_shift ); // q_cldfb+min_q_shift + + sq_tmp_fx = Madd_32_32( Mpy_32_32( re, re ), im, im ); // 2*(q_cldfb+min_q_shift)-31 + + reference_power_fx[l] = Madd_32_16( reference_power_fx[l], sq_tmp_fx, 16384 /*0.5 in Q15*/ ); // 2*(q_cldfb+min_q_shift)-31 + move32(); + } + FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ ) + { + re = L_shl( RealBuffer_fx[k][0][l], min_q_shift2 ); // q_cldfb+min_q_shift + im = L_shl( ImagBuffer_fx[k][0][l], min_q_shift2 ); // q_cldfb+min_q_shift + + sq_tmp_fx = Madd_32_32( Mpy_32_32( re, re ), im, im ); // 2*(q_cldfb+min_q_shift)-31 + + reference_power_fx[l] = Madd_32_16( reference_power_fx[l], sq_tmp_fx, 16384 /*0.5 in Q15*/ ); // 2*(q_cldfb+min_q_shift)-31 + move32(); + } +#else FOR( l = 0; l < num_freq_bands; l++ ) { re = L_shl( RealBuffer_fx[k][0][l], min_q_shift ); // q_cldfb+min_q_shift @@ -2531,12 +3100,24 @@ void protoSignalComputation4_fx( reference_power_fx[l] = Madd_32_16( reference_power_fx[l], sq_tmp_fx, 16384 /*0.5 in Q15*/ ); // 2*(q_cldfb+min_q_shift)-31 move32(); } +#endif } +#ifdef FIX_867_CLDFB_NRG_SCALE + sq_tmp_q = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); + reference_power_q[0] = sq_tmp_q; + move16(); + sq_tmp_q = sub( add( add( q_cldfb, min_q_shift2 ), add( q_cldfb, min_q_shift2 ) ), 31 ); + reference_power_q[1] = sq_tmp_q; + move16(); + + min_q_shift = sub( s_min( q_shift, q_shift2 ), find_guarded_bits_fx( 2 ) ); +#else sq_tmp_q = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 ); *reference_power_q = sub( add( sq_tmp_q, Q15 ), 15 ); move16(); min_q_shift = sub( q_shift, find_guarded_bits_fx( 2 ) ); +#endif /*For decorrelated diffuseness*/ FOR( l = 0; l < num_outputs_diff; l++ ) @@ -2619,8 +3200,15 @@ void protoSignalComputation4_fx( *proto_direct_buffer_f_q = *proto_frame_f_q; move16(); +#ifdef FIX_867_CLDFB_NRG_SCALE + proto_power_smooth_q[0] = proto_power_smooth_fx_q; + proto_power_smooth_q[1] = proto_power_smooth_fx_q; + move16(); + move16(); +#else *proto_power_smooth_q = proto_power_smooth_fx_q; move16(); +#endif return; } @@ -3681,7 +4269,11 @@ static void ivas_masa_ext_dirac_render_sf_fx( &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_fx, &hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q, +#ifdef FIX_867_CLDFB_NRG_SCALE + reference_power_fix, DirAC_mem.reference_power_q, slot_idx, nchan_transport, +#else reference_power_fix, &DirAC_mem.reference_power_q, slot_idx, nchan_transport, +#endif hDirACRend->num_outputs_diff, hSpatParamRendCom->num_freq_bands, 0, q_cldfb ); @@ -3694,12 +4286,49 @@ static void ivas_masa_ext_dirac_render_sf_fx( protoSignalComputation2_fx( Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hDirACRend->proto_frame_f_fx, &hDirACRend->proto_frame_f_q, hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx, &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, +#ifdef FIX_867_CLDFB_NRG_SCALE + reference_power_fix, DirAC_mem.reference_power_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#else reference_power_fix, &DirAC_mem.reference_power_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, &hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#endif 0, slot_idx, hSpatParamRendCom->num_freq_bands, hDirACRend->masa_stereo_type_detect, q_cldfb ); proto_direct_buffer_f_temp_q[slot_idx] = hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q; move16(); +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ) + { + FOR( i = hSpatParamRendCom->num_freq_bands; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + Scale_sig32( reference_power_fix + i, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q + } + DirAC_mem.reference_power_smooth_q[0] = DirAC_mem.reference_power_q[0]; + move16(); + } + ELSE + { + Scale_sig32( reference_power_fix, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_smooth_q[0], DirAC_mem.reference_power_q[0] ) ); // DirAC_mem.reference_power_smooth_q + DirAC_mem.reference_power_q[0] = DirAC_mem.reference_power_smooth_q[0]; + move16(); + } + IF( LT_16( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ) + { + FOR( i = hSpatParamRendCom->num_freq_bands; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i, s_min( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q + } + DirAC_mem.reference_power_smooth_q[1] = DirAC_mem.reference_power_q[1]; + move16(); + } + ELSE + { + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF, s_min( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( DirAC_mem.reference_power_smooth_q[1], DirAC_mem.reference_power_q[1] ) ); // DirAC_mem.reference_power_smooth_q + DirAC_mem.reference_power_q[1] = DirAC_mem.reference_power_smooth_q[1]; + move16(); + } +#else IF( LT_16( DirAC_mem.reference_power_q, DirAC_mem.reference_power_smooth_q ) ) { Scale_sig32( reference_power_fix + hSpatParamRendCom->num_freq_bands, sub( DirAC_mem.reference_power_len, hSpatParamRendCom->num_freq_bands ), sub( DirAC_mem.reference_power_q, DirAC_mem.reference_power_smooth_q ) ); // DirAC_mem.reference_power_q @@ -3712,6 +4341,7 @@ static void ivas_masa_ext_dirac_render_sf_fx( DirAC_mem.reference_power_q = DirAC_mem.reference_power_smooth_q; move16(); } +#endif temp_proto_frame_q = sub( getScaleFactor32( hDirACRend->proto_frame_f_fx, hDirACRend->proto_frame_f_len ), 2 ); Scale_sig32( hDirACRend->proto_frame_f_fx, hDirACRend->proto_frame_f_len, temp_proto_frame_q ); // hDirACRend->proto_frame_f_q+temp_proto_frame_q hDirACRend->proto_frame_f_q = add( hDirACRend->proto_frame_f_q, temp_proto_frame_q ); @@ -3727,9 +4357,15 @@ static void ivas_masa_ext_dirac_render_sf_fx( &hDirACRend->proto_frame_f_q, hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx, &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, +#ifdef FIX_867_CLDFB_NRG_SCALE + reference_power_fix, DirAC_mem.reference_power_q, + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#else reference_power_fix, &DirAC_mem.reference_power_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, &hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#endif hDirACRend->hOutSetup.is_loudspeaker_setup, slot_idx, hSpatParamRendCom->num_freq_bands, @@ -3737,6 +4373,39 @@ static void ivas_masa_ext_dirac_render_sf_fx( proto_direct_buffer_f_temp_q[slot_idx] = hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q; move16(); +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ) + { + FOR( i = hSpatParamRendCom->num_freq_bands; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + Scale_sig32( reference_power_fix + i, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q + } + DirAC_mem.reference_power_smooth_q[0] = DirAC_mem.reference_power_q[0]; + move16(); + } + ELSE + { + Scale_sig32( reference_power_fix, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_smooth_q[0], DirAC_mem.reference_power_q[0] ) ); // DirAC_mem.reference_power_smooth_q + DirAC_mem.reference_power_q[0] = DirAC_mem.reference_power_smooth_q[0]; + move16(); + } + IF( LT_16( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ) + { + FOR( i = hSpatParamRendCom->num_freq_bands; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i, s_min( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q + } + DirAC_mem.reference_power_smooth_q[0] = DirAC_mem.reference_power_q[1]; + move16(); + } + ELSE + { + Scale_sig32( reference_power_fix, s_min( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( DirAC_mem.reference_power_smooth_q[1], DirAC_mem.reference_power_q[1] ) ); // DirAC_mem.reference_power_smooth_q + DirAC_mem.reference_power_q[1] = DirAC_mem.reference_power_smooth_q[1]; + move16(); + } + +#else IF( LT_16( DirAC_mem.reference_power_q, DirAC_mem.reference_power_smooth_q ) ) { Scale_sig32( reference_power_fix + hSpatParamRendCom->num_freq_bands, sub( DirAC_mem.reference_power_len, hSpatParamRendCom->num_freq_bands ), sub( DirAC_mem.reference_power_q, DirAC_mem.reference_power_smooth_q ) ); // DirAC_mem.reference_power_q @@ -3749,6 +4418,7 @@ static void ivas_masa_ext_dirac_render_sf_fx( DirAC_mem.reference_power_q = DirAC_mem.reference_power_smooth_q; move16(); } +#endif temp_proto_frame_q = sub( getScaleFactor32( hDirACRend->proto_frame_f_fx, hDirACRend->proto_frame_f_len ), 2 ); Scale_sig32( hDirACRend->proto_frame_f_fx, hDirACRend->proto_frame_f_len, temp_proto_frame_q ); // hDirACRend->proto_frame_f_q+temp_proto_frame_q hDirACRend->proto_frame_f_q = add( hDirACRend->proto_frame_f_q, temp_proto_frame_q ); @@ -3761,9 +4431,15 @@ static void ivas_masa_ext_dirac_render_sf_fx( &hDirACRend->proto_frame_f_q, hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx, &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, +#ifdef FIX_867_CLDFB_NRG_SCALE + reference_power_fix, DirAC_mem.reference_power_q, + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#else reference_power_fix, &DirAC_mem.reference_power_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, &hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, +#endif slot_idx, hDirACRend->num_protos_diff, hSpatParamRendCom->num_freq_bands, q_cldfb ); @@ -3771,6 +4447,38 @@ static void ivas_masa_ext_dirac_render_sf_fx( proto_direct_buffer_f_temp_q[slot_idx] = hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q; move16(); +#ifdef FIX_867_CLDFB_NRG_SCALE + IF( LT_16( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ) + { + FOR( i = hSpatParamRendCom->num_freq_bands; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + Scale_sig32( reference_power_fix + i, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q + } + DirAC_mem.reference_power_smooth_q[0] = DirAC_mem.reference_power_q[0]; + move16(); + } + ELSE + { + Scale_sig32( reference_power_fix, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_smooth_q[0], DirAC_mem.reference_power_q[0] ) ); // DirAC_mem.reference_power_smooth_q + DirAC_mem.reference_power_q[0] = DirAC_mem.reference_power_smooth_q[0]; + move16(); + } + IF( LT_16( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ) + { + FOR( i = hSpatParamRendCom->num_freq_bands; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i, s_min( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q + } + DirAC_mem.reference_power_smooth_q[1] = DirAC_mem.reference_power_q[1]; + move16(); + } + ELSE + { + Scale_sig32( reference_power_fix, s_min( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( DirAC_mem.reference_power_smooth_q[1], DirAC_mem.reference_power_q[1] ) ); // DirAC_mem.reference_power_smooth_q + DirAC_mem.reference_power_q[1] = DirAC_mem.reference_power_smooth_q[1]; + move16(); + } +#else IF( LT_16( DirAC_mem.reference_power_q, DirAC_mem.reference_power_smooth_q ) ) { Scale_sig32( reference_power_fix + hSpatParamRendCom->num_freq_bands, sub( DirAC_mem.reference_power_len, hSpatParamRendCom->num_freq_bands ), sub( DirAC_mem.reference_power_q, DirAC_mem.reference_power_smooth_q ) ); // DirAC_mem.reference_power_q @@ -3783,6 +4491,7 @@ static void ivas_masa_ext_dirac_render_sf_fx( DirAC_mem.reference_power_q = DirAC_mem.reference_power_smooth_q; move16(); } +#endif temp_proto_frame_q = sub( getScaleFactor32( hDirACRend->proto_frame_f_fx, hDirACRend->proto_frame_f_len ), 2 ); Scale_sig32( hDirACRend->proto_frame_f_fx, hDirACRend->proto_frame_f_len, temp_proto_frame_q ); // hDirACRend->proto_frame_f_q+temp_proto_frame_q @@ -3902,10 +4611,21 @@ static void ivas_masa_ext_dirac_render_sf_fx( IF( NE_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) { Scale_sig32( DirAC_mem.reference_power_fx, DirAC_mem.reference_power_len, -1 ); // DirAC_mem.reference_power_q-1 +#ifdef FIX_867_CLDFB_NRG_SCALE + DirAC_mem.reference_power_q[0] = sub( DirAC_mem.reference_power_q[0], 1 ); + DirAC_mem.reference_power_q[1] = sub( DirAC_mem.reference_power_q[1], 1 ); + move16(); + move16(); + DirAC_mem.reference_power_smooth_q[0] = DirAC_mem.reference_power_q[0]; + DirAC_mem.reference_power_smooth_q[1] = DirAC_mem.reference_power_q[1]; + move16(); + move16(); +#else DirAC_mem.reference_power_q = sub( DirAC_mem.reference_power_q, 1 ); move16(); DirAC_mem.reference_power_smooth_q = DirAC_mem.reference_power_q; move16(); +#endif v_add_fixed( reference_power_fix, reference_power_smooth_fx, reference_power_smooth_fx, hSpatParamRendCom->num_freq_bands, 0 ); // DirAC_mem.reference_power_smooth_q } } @@ -4016,10 +4736,19 @@ static void ivas_masa_ext_dirac_render_sf_fx( Word16 reference_power_temp_q = getScaleFactor32( DirAC_mem.reference_power_fx, DirAC_mem.reference_power_len ); scale_sig32( DirAC_mem.reference_power_fx, DirAC_mem.reference_power_len, reference_power_temp_q ); /*DirAC_mem.reference_power_q + reference_power_temp_q*/ +#ifdef FIX_867_CLDFB_NRG_SCALE + DirAC_mem.reference_power_q[0] = add( DirAC_mem.reference_power_q[0], reference_power_temp_q ); + DirAC_mem.reference_power_q[1] = add( DirAC_mem.reference_power_q[1], reference_power_temp_q ); + move16(); + DirAC_mem.reference_power_smooth_q[0] = add( DirAC_mem.reference_power_q[0], reference_power_temp_q ); + DirAC_mem.reference_power_smooth_q[1] = add( DirAC_mem.reference_power_q[1], reference_power_temp_q ); + move16(); +#else DirAC_mem.reference_power_q = add( DirAC_mem.reference_power_q, reference_power_temp_q ); move16(); DirAC_mem.reference_power_smooth_q = add( DirAC_mem.reference_power_q, reference_power_temp_q ); move16(); +#endif Word16 q_cy_auto_diff_smooth = getScaleFactor32( h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, h_dirac_output_synthesis_state->cy_auto_diff_smooth_len ); Scale_sig32( h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, h_dirac_output_synthesis_state->cy_auto_diff_smooth_len, q_cy_auto_diff_smooth ); // h_dirac_output_synthesis_state->q_cy_auto_diff_smooth+ q_cy_auto_diff_smooth @@ -4050,12 +4779,40 @@ static void ivas_masa_ext_dirac_render_sf_fx( move16(); } +#ifdef FIX_867_CLDFB_NRG_SCALE + FOR( i = 0; hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + i, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ); + move16(); + FOR( i = 0; hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + i, s_min( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ); + move16(); + + FOR( i = 0; hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + i, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ); + move16(); + FOR( i = 0; hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + i, s_min( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ); + move16(); +#else Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ); move16(); Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_len, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q ) hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ); move16(); +#endif Word16 proto_power_diff_smooth_prev_temp_q = getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_len ); Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_len, proto_power_diff_smooth_prev_temp_q ); // hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_q + proto_power_diff_smooth_prev_temp_q @@ -4078,6 +4835,27 @@ static void ivas_masa_ext_dirac_render_sf_fx( /*Buffer rescaling*/ +#ifdef FIX_867_CLDFB_NRG_SCALE + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + Scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, s_min( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ), hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + FOR( i = 0; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + Scale_sig32( DirAC_mem.reference_power_fx + i, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), DirAC_mem.reference_power_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + Scale_sig32( DirAC_mem.reference_power_fx + CLDFB_NO_CHANNELS_HALF + i, s_min( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ), DirAC_mem.reference_power_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) + } + hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ); + move16(); + hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ); + move16(); + DirAC_mem.reference_power_q[0] = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ); + move16(); + DirAC_mem.reference_power_q[1] = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ); + move16(); + DirAC_mem.reference_power_smooth_q[0] = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ); + move16(); + DirAC_mem.reference_power_smooth_q[1] = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ); + move16(); +#else Scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx, hSpatParamRendCom->num_freq_bands, sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ), hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) Scale_sig32( DirAC_mem.reference_power_fx, DirAC_mem.reference_power_len, sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ), DirAC_mem.reference_power_q ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ) @@ -4087,6 +4865,7 @@ static void ivas_masa_ext_dirac_render_sf_fx( move16(); DirAC_mem.reference_power_smooth_q = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q ); move16(); +#endif ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, @@ -4095,12 +4874,51 @@ static void ivas_masa_ext_dirac_render_sf_fx( hSpatParamRendCom->subframe_nbslots[subframe_idx], diffuseness_vector_fx, reference_power_smooth_fx, +#ifdef FIX_867_CLDFB_NRG_SCALE + DirAC_mem.reference_power_smooth_q, +#else &DirAC_mem.reference_power_smooth_q, +#endif ONE_IN_Q31, 0, &q_cldfb ); hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_q = hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q; move16(); +#ifdef FIX_867_CLDFB_NRG_SCALE + hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] = DirAC_mem.reference_power_smooth_q[0]; + hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] = DirAC_mem.reference_power_smooth_q[1]; + move16(); + IF( LT_16( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ) + { + FOR( i = hSpatParamRendCom->num_freq_bands; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + Scale_sig32( reference_power_fix + i, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q + } + DirAC_mem.reference_power_smooth_q[0] = DirAC_mem.reference_power_q[0]; + move16(); + } + ELSE + { + Scale_sig32( reference_power_fix, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_smooth_q[0], DirAC_mem.reference_power_q[0] ) ); // DirAC_mem.reference_power_smooth_q + DirAC_mem.reference_power_q[0] = DirAC_mem.reference_power_smooth_q[0]; + move16(); + } + IF( LT_16( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ) + { + FOR( i = hSpatParamRendCom->num_freq_bands; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) ) + { + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i, s_min( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q + } + DirAC_mem.reference_power_smooth_q[1] = DirAC_mem.reference_power_q[1]; + move16(); + } + ELSE + { + Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF, s_min( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( DirAC_mem.reference_power_smooth_q[1], DirAC_mem.reference_power_q[1] ) ); // DirAC_mem.reference_power_smooth_q + DirAC_mem.reference_power_q[1] = DirAC_mem.reference_power_smooth_q[1]; + move16(); + } +#else hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q = DirAC_mem.reference_power_smooth_q; move16(); IF( LT_16( DirAC_mem.reference_power_q, DirAC_mem.reference_power_smooth_q ) ) @@ -4115,6 +4933,7 @@ static void ivas_masa_ext_dirac_render_sf_fx( DirAC_mem.reference_power_q = DirAC_mem.reference_power_smooth_q; move16(); } +#endif } /*-----------------------------------------------------------------* diff --git a/lib_rend/ivas_prot_rend_fx.h b/lib_rend/ivas_prot_rend_fx.h index 695e05fdfed182e6f7f5c73eb6c0dc4c956a41df..983c814aa51db73321d46dfebcaa290ad2bce5f9 100644 --- a/lib_rend/ivas_prot_rend_fx.h +++ b/lib_rend/ivas_prot_rend_fx.h @@ -452,7 +452,11 @@ void ivas_dirac_dec_output_synthesis_close_fx( void ivas_dirac_dec_output_synthesis_process_slot_fx( const Word32 *reference_power, /* i : Estimated power */ +#ifdef FIX_867_CLDFB_NRG_SCALE + const Word16 *q_reference_power, /* i : Estimated power */ +#else const Word16 q_reference_power, /* i : Estimated power */ +#endif const Word32 *onset, /* i : onset filter */ const Word16 *azimuth, const Word16 *elevation, diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index a8f32514d16f632721c8ef92112982750e2ec96c..0515e403885d5857306fb3683826d9e1994ece83 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -228,8 +228,13 @@ typedef struct dirac_dec_stack_mem Word32 *cy_auto_diff_smooth_fx; Word32 *reference_power_fx; +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 reference_power_q[2]; + Word16 reference_power_smooth_q[2]; +#else Word16 reference_power_q; Word16 reference_power_smooth_q; +#endif Word16 reference_power_len; Word32 *onset_filter_fx; /* Q31 */ @@ -277,7 +282,11 @@ typedef struct dirac_output_synthesis_state_structure /* Temporal smoothing memories */ Word32 *reference_power_smooth_prev_fx; /* Q(reference_power_smooth_prev_q) */ +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 reference_power_smooth_prev_q[2]; +#else Word16 reference_power_smooth_prev_q; +#endif Word32 *direction_smoothness_prev_fx; /* Q31 */ /* only pointer to local buffers */ @@ -295,10 +304,18 @@ typedef struct dirac_output_synthesis_state_structure Word16 diff_dir_power_factor_len; Word32 *proto_power_smooth_fx; /* Smoothed power of the prototype signals. Size: num_freq_bands*num_channels. */ +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 proto_power_smooth_q[2]; +#else Word16 proto_power_smooth_q; +#endif Word16 proto_power_smooth_len; Word32 *proto_power_smooth_prev_fx; /* Smoothed power of the prototype signals of the previous synthesis block. Size: num_freq_bands*num_channels. */ +#ifdef FIX_867_CLDFB_NRG_SCALE + Word16 proto_power_smooth_prev_q[2]; +#else Word16 proto_power_smooth_prev_q; +#endif Word16 proto_power_smooth_prev_len; Word32 *proto_power_diff_smooth_fx; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 84e771106c16a6b7273b59a84756364bd6f5f9e7..7e526ca772b108eb521a17a36eb1abe75b4c7086 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -8306,8 +8306,15 @@ static void intermidiate_ext_dirac_render( IF( to_fix ) { +#ifdef FIX_867_CLDFB_NRG_SCALE + DirAC_mem.reference_power_smooth_q[0] = DirAC_mem.reference_power_q[0] = Q31; + DirAC_mem.reference_power_smooth_q[1] = DirAC_mem.reference_power_q[1] = Q31; + move16(); + move16(); +#else DirAC_mem.reference_power_smooth_q = DirAC_mem.reference_power_q = Q31; move16(); +#endif move16(); FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) { @@ -8436,14 +8443,65 @@ static void intermidiate_ext_dirac_render( IF( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx ) { +#ifdef FIX_867_CLDFB_NRG_SCALE + tmp = 0; + move16(); + FOR( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands ) ) + { + tmp = s_min( tmp, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + slot_idx, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ); + } + FOR( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands ) ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + slot_idx, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + tmp) */ + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], tmp ); + move16(); + tmp = 0; + move16(); + FOR( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands ) ) + { + tmp = s_min( tmp, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + slot_idx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); + } + FOR( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands ) ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + slot_idx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + tmp) */ + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], tmp ); + move16(); +#else tmp = L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, imult1616( hDirACRend->num_protos_dir, hSpatParamRendCom->num_freq_bands ) ); scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len, tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q + tmp) */ hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q = add( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, tmp ); move16(); +#endif +#ifdef FIX_867_CLDFB_NRG_SCALE + tmp = 0; + FOR( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands ) ) + { + tmp = s_min( tmp, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, s_min( CLDFB_NO_CHANNELS_HALF, hSpatParamRendCom->num_freq_bands ) ) ); + } + FOR( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands ) ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, s_min( CLDFB_NO_CHANNELS_HALF, hSpatParamRendCom->num_freq_bands ), tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q + tmp) */ + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] = add( tmp, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ); + move16(); + FOR( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands ) ) + { + tmp = s_min( tmp, L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) ); + } + FOR( slot_idx = 0; slot_idx < hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len; slot_idx = add( slot_idx, hSpatParamRendCom->num_freq_bands ) ) + { + scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q + tmp) */ + } + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] = add( tmp, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ); + move16(); +#else tmp = L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, imult1616( hDirACRend->num_protos_dir, hSpatParamRendCom->num_freq_bands ) ); scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_len, tmp ); /* Q(hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q + tmp) */ hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q = add( tmp, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q ); move16(); +#endif } tmp = L_norm_arr( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_len );