Commit a11173eb authored by Tapani Pihlajakuja's avatar Tapani Pihlajakuja
Browse files

Fix BASOP issue 2442: Improve MASA2 to MONO and Ambi rendering by fixing bugs,...

Fix BASOP issue 2442: Improve MASA2 to MONO and Ambi rendering by fixing bugs, adding accuracy, and limiting low signal power diffuse synthesis gains.
parent 06686cc2
Loading
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -133,6 +133,7 @@
#define FIX_FLOAT_1578_OMASA_REND_SPIKES                /* Nokia: Float issue 1578: Fix spikes and collapsed perception in OMASA/MASA rendering to FOA/HOA */
#define FIX_1521_SBA_LOUDNESS_STEREO                    /* FhG: issue 1521: Fix loudness for SBA to stereo rendering */
#define FIX_1559                                        /* Eri/FhG: fix for Issue 1559 in FD CNG with bitrate/bw switching */
#define FIX_BASOP_2442_MASA2TC_TO_MONO_AND_AMBI         /* Nokia: BASOP issue 2442: Aligns float with identical diffuse gain limitation to minimize diff */

/* ##################### End NON-BE switches ########################### */

+99 −0
Original line number Diff line number Diff line
@@ -56,6 +56,11 @@
#define POINT_3679_Q31 790059234 /*.3679 q31*/
#define POINT_1175_Q31 252329329 /*.1175 q31*/

#ifdef FIX_BASOP_2442_MASA2TC_TO_MONO_AND_AMBI
#define DIRAC_SMALL_DIFF_POW_LIM       65536
#define DIRAC_SMALL_DIFF_POW_MAX_GAIN  2
#endif

/*-------------------------------------------------------------------------
 * Local function prototypes
 *------------------------------------------------------------------------*/
@@ -2001,12 +2006,32 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx(
        masa_stereo_type_detect->target_power_y_smooth_fx = L_shl( masa_stereo_type_detect->target_power_y_smooth_fx,
                                                                   sub( q_com, masa_stereo_type_detect->q_target_power_y_smooth ) );
        move32();
#ifdef FIX_BASOP_2442_MASA2TC_TO_MONO_AND_AMBI

        W_temp = W_add( W_mult0_32_32( a, target_power_y ), W_mult0_32_32( b, masa_stereo_type_detect->target_power_y_smooth_fx ) ); // Q31 + q_com
        IF( W_temp )
        {
            exp = W_norm( W_temp );
            masa_stereo_type_detect->target_power_y_smooth_fx = W_extract_h( W_shl( W_temp, exp ) ); // Q31 + q_com + exp - 32
            move32();
            masa_stereo_type_detect->q_target_power_y_smooth = sub( add( q_com, exp ), 1 );
            move16();
        }
        ELSE
        {
            masa_stereo_type_detect->target_power_y_smooth_fx = 0; // Q31
            move32();
            masa_stereo_type_detect->q_target_power_y_smooth = Q31;
            move16();
        }
#else
        masa_stereo_type_detect->target_power_y_smooth_fx =
            L_add( Mpy_32_32( a, target_power_y ),
                   Mpy_32_32( b, masa_stereo_type_detect->target_power_y_smooth_fx ) ); //(Q31, q_com) -> q_com
        move32();
        masa_stereo_type_detect->q_target_power_y_smooth = q_com;
        move16();
#endif

        IF( NE_16( masa_stereo_type_detect->q_subtract_power_y, masa_stereo_type_detect->q_subtract_power_y_smooth ) )
        {
@@ -2046,7 +2071,11 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx(
        {
            subtract_target_ratio = L_sub( BASOP_Util_Log2( masa_stereo_type_detect->subtract_power_y_smooth_fx ),
                                           BASOP_Util_Log2( masa_stereo_type_detect->target_power_y_smooth_fx ) ); // Q25
#ifdef FIX_BASOP_2442_MASA2TC_TO_MONO_AND_AMBI
            exp = sub( masa_stereo_type_detect->q_subtract_power_y_smooth, masa_stereo_type_detect->q_target_power_y_smooth );
#else
            exp = sub( masa_stereo_type_detect->q_subtract_power_y_smooth, q_com );
#endif
            L_tmp = Mpy_32_32( L_sub( subtract_target_ratio, L_shl( exp, 25 ) ), LOG10_2_Q31 ); // Q25
        }
        ELSE
@@ -2272,6 +2301,24 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx(
    Word32 cmp = W_shl_sat_l( DIRAC_GAIN_LIMIT_Q26, sub( h_dirac_output_synthesis_state->gains_dir_prev_q, 26 ) );
    Word32 cmp2 = W_extract_h( W_shl( W_mult_32_32( DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state->gains_diff_prev_q ) ), Q5 ) );

#ifdef FIX_BASOP_2442_MASA2TC_TO_MONO_AND_AMBI
    Word32 diff_gain_limit = L_shl( DIRAC_SMALL_DIFF_POW_MAX_GAIN, h_dirac_output_synthesis_state->gains_diff_prev_q );
    Word32 power_diff_small_lim;
    IF( GT_16( h_dirac_output_synthesis_state->proto_power_diff_smooth_q, norm_l( DIRAC_SMALL_DIFF_POW_LIM ) ) )
    {
        power_diff_small_lim = MAX_32; /* All bands have low very low signal energy */
    }
    ELSE IF( LT_16( h_dirac_output_synthesis_state->proto_power_diff_smooth_q, -31 ) )
    {
        power_diff_small_lim = 0; /* All bands have high enough signal energy */
    }
    ELSE
    {
        power_diff_small_lim = L_shl( DIRAC_SMALL_DIFF_POW_LIM, h_dirac_output_synthesis_state->proto_power_diff_smooth_q );
    }

#endif

    FOR( k = 0; k < nchan_out_woLFE; k++ )
    {
        Word32 power_smooth_temp;
@@ -2333,6 +2380,14 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx(
                                                     Mpy_32_32( g2, ( *( p_cy_auto_diff_smooth_prev ) ) ) ); // (Q31, q_cy_auto_diff_smooth_prev) -> q_cy_auto_diff_smooth_prev
            move32();

#ifdef FIX_BASOP_2442_MASA2TC_TO_MONO_AND_AMBI
            IF ( LT_32(*( p_power_diff_smooth_prev ), power_diff_small_lim) )
            {
                cmp2 = diff_gain_limit;
                move32();
            }
#endif

            exp = 0;
            move16();
            L_tmp = BASOP_Util_Divide3232_Scale_newton( *( p_cy_auto_diff_smooth_prev++ ), ( *( p_power_diff_smooth_prev++ ) ), &exp ); // (Q31 - exp) + (q_a - q_b)
@@ -2370,8 +2425,16 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx(
            *( p_cy_auto_dir_smooth_prev++ ) = L_shr_r( L_tmp, q_tmp ); // q_cy_auto_dir_smooth_prev_local

            move32();
#ifdef FIX_BASOP_2442_MASA2TC_TO_MONO_AND_AMBI

            W_temp = W_mac_32_32( W_mult_32_32( g1, ( *( p_cy_cross_dir_smooth ) ) ), g2, ( *( p_cy_cross_dir_smooth_prev ) ) );
            q_tmp = W_norm( W_temp );
            L_tmp = W_extract_h( W_shl( W_temp, q_tmp ) );
            *( p_cy_cross_dir_smooth_prev ) = L_shr_r( L_tmp, q_tmp ); // q_cy_cross_dir_smooth_prev
#else
            *( p_cy_cross_dir_smooth_prev ) = Madd_32_32( Mpy_32_32( g1, ( *( p_cy_cross_dir_smooth ) ) ),
                                                          g2, ( *( p_cy_cross_dir_smooth_prev ) ) ); // (Q31, q_cy_cross_dir_smooth_prev) -> q_cy_cross_dir_smooth_prev
#endif
            move32();
            test();
            if ( *( p_cy_cross_dir_smooth_prev ) == 0 && ( *( p_cy_cross_dir_smooth ) != 0 ) )
@@ -2826,8 +2889,13 @@ void ivas_dirac_dec_compute_directional_responses_fx(

                        Word16 max_exp = MIN16B;
                        move16();
#ifdef FIX_BASOP_2442_MASA2TC_TO_MONO_AND_AMBI
                        maximum_fx( exp_arr, num_channels_dir, &max_exp );
                        FOR( l = 0; l < num_channels_dir; l++ )
#else
                        maximum_fx( exp_arr, MAX_OUTPUT_CHANNELS, &max_exp );
                        FOR( l = 0; l < MAX_OUTPUT_CHANNELS; l++ )
#endif
                        {
                            direct_response_hoa_fx[l] = L_shr( direct_response_hoa_fx[l], sub( max_exp, exp_arr[l] ) ); /*Q(31-exp_arr[l])->Q(31-max_exp)*/
                            move32();
@@ -2965,8 +3033,13 @@ void ivas_dirac_dec_compute_directional_responses_fx(
                        }
                        Word16 max_exp = MIN_16;
                        move16();
#ifdef FIX_BASOP_2442_MASA2TC_TO_MONO_AND_AMBI
                        maximum_fx( exp_arr, num_channels_dir, &max_exp );
                        FOR( l = 0; l < num_channels_dir; l++ )
#else
                        maximum_fx( exp_arr, MAX_OUTPUT_CHANNELS, &max_exp );
                        FOR( l = 0; l < MAX_OUTPUT_CHANNELS; l++ )
#endif
                        {
                            direct_response_hoa_fx[l] = L_shr( direct_response_hoa_fx[l], sub( max_exp, exp_arr[l] ) ); /*q(31-exp_arr[l])->q(31-max_exp)*/
                            move32();
@@ -2978,7 +3051,11 @@ void ivas_dirac_dec_compute_directional_responses_fx(

                    Q_direct_response_hoa = sub( Q31, exp_direct_response_hoa );

#ifdef FIX_BASOP_2442_MASA2TC_TO_MONO_AND_AMBI
                    Scale_sig32( direct_response_hoa_fx, num_channels_dir, sub( Q29, Q_direct_response_hoa ) ); /*Q_direct_response_hoa->q29*/
#else
                    Scale_sig32( direct_response_hoa_fx, MAX_OUTPUT_CHANNELS, sub( Q29, Q_direct_response_hoa ) ); /*Q_direct_response_hoa->q29*/
#endif
                    direct_response_q = Q29;
                    move16();

@@ -3080,9 +3157,14 @@ void ivas_dirac_dec_compute_directional_responses_fx(
                        move16();
                    }

#ifdef FIX_BASOP_2442_MASA2TC_TO_MONO_AND_AMBI
                    maximum_fx( exp_table, num_channels_dir, &exp_max );
                    FOR( i = 0; i < num_channels_dir; i++ )
#else
                    maximum_fx( exp_table, MAX_OUTPUT_CHANNELS, &exp_max );

                    FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ )
#endif
                    {
                        direct_response_ls_fx[i] = L_shr( direct_response_ls_fx[i], sub( exp_max, exp_table[i] ) ); /*(q(31-exp_table[i])->q(31-exp_max))*/
                        move32();
@@ -3249,8 +3331,13 @@ void ivas_dirac_dec_compute_directional_responses_fx(

                    max_exp = MIN16B; /*Q0*/
                    move16();
#ifdef FIX_BASOP_2442_MASA2TC_TO_MONO_AND_AMBI
                    maximum_fx( exp_arr, num_channels_dir, &max_exp );
                    FOR( l = 0; l < num_channels_dir; l++ )
#else
                    maximum_fx( exp_arr, MAX_OUTPUT_CHANNELS, &max_exp );
                    FOR( l = 0; l < MAX_OUTPUT_CHANNELS; l++ )
#endif
                    {
                        direct_response_ls_fx[l] = L_shr( direct_response_ls_fx[l], sub( max_exp, exp_arr[l] ) ); /*Q(31-exp_arr[l])->Q(31-max_exp)*/
                        move32();
@@ -3264,7 +3351,11 @@ void ivas_dirac_dec_compute_directional_responses_fx(
                normalizePanningGains_fx( direct_response_ls_fx, &Q_direct_response_ls, num_channels_dir );
                exp_direct_response_ls = sub( 31, Q_direct_response_ls );

#ifdef FIX_BASOP_2442_MASA2TC_TO_MONO_AND_AMBI
                Scale_sig32( direct_response_ls_fx, num_channels_dir, sub( Q29, Q_direct_response_ls ) ); /*Q_direct_response_ls->Q29*/
#else
                Scale_sig32( direct_response_ls_fx, MAX_OUTPUT_CHANNELS, sub( Q29, Q_direct_response_ls ) ); /*Q_direct_response_ls->Q29*/
#endif
                direct_response_q = Q29;
                move16();

@@ -3991,11 +4082,19 @@ static void spreadCoherencePanningHoa_fx(
        }
        Word16 max_val = MIN_16;
        move16();
#ifdef FIX_BASOP_2442_MASA2TC_TO_MONO_AND_AMBI
        FOR( i = 0; i < num_channels_dir; i++ )
#else
        FOR( i = 0; i < 16; i++ )
#endif
        {
            max_val = s_max( max_val, exp_arr[i] );
        }
#ifdef FIX_BASOP_2442_MASA2TC_TO_MONO_AND_AMBI
        FOR( i = 0; i < num_channels_dir; i++ )
#else
        FOR( i = 0; i < 16; i++ )
#endif
        {
            direct_response_fx[i] = L_shr( direct_response_fx[i], sub( max_val, exp_arr[i] ) ); // Q(31-exp_arr[i])->q(31-max_val)
            move32();
+17 −0
Original line number Diff line number Diff line
@@ -2690,6 +2690,22 @@ void protoSignalComputation2_fx(
            }
        }

#ifdef FIX_BASOP_2442_MASA2TC_TO_MONO_AND_AMBI
        stereo_type_detect->left_bb_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, left_bb_power_fx ), sub( 31, q_Left_Right_power ), Mpy_32_32( b_fx, stereo_type_detect->left_bb_power_fx ), sub( 31, stereo_type_detect->q_left_bb_power ), &stereo_type_detect->q_left_bb_power );
        move32();
        stereo_type_detect->q_left_bb_power = sub( 31, stereo_type_detect->q_left_bb_power );
        move16();

        stereo_type_detect->right_bb_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, right_bb_power_fx ), sub( 31, q_Left_Right_power ), Mpy_32_32( b_fx, stereo_type_detect->right_bb_power_fx ), sub( 31, stereo_type_detect->q_right_bb_power ), &stereo_type_detect->q_right_bb_power );
        move32();
        stereo_type_detect->q_right_bb_power = sub( 31, stereo_type_detect->q_right_bb_power );
        move16();

        stereo_type_detect->total_bb_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, total_bb_power_fx ), sub( 31, q_Left_Right_power ), Mpy_32_32( b_fx, stereo_type_detect->total_bb_power_fx ), sub( 31, stereo_type_detect->q_total_bb_power ), &stereo_type_detect->q_total_bb_power );
        move32();
        stereo_type_detect->q_total_bb_power = sub( 31, stereo_type_detect->q_total_bb_power );
        move16();
#else
        temp = Mpy_32_32( a_fx, left_bb_power_fx ); // q_Left_Right_power
        IF( LT_16( q_Left_Right_power, stereo_type_detect->q_left_bb_power ) )
        {
@@ -2731,6 +2747,7 @@ void protoSignalComputation2_fx(
            stereo_type_detect->total_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power, stereo_type_detect->q_total_bb_power ) ), b_fx, stereo_type_detect->total_bb_power_fx ); // stereo_type_detect->q_total_bb_power
            move32();
        }
#endif

        IF( LT_16( stereo_type_detect->q_left_bb_power, stereo_type_detect->q_right_bb_power ) )
        {
+44 −0
Original line number Diff line number Diff line
@@ -9031,9 +9031,31 @@ static void copyMasaMetadataToDiracRenderer_fx(
        {
            FOR( bin = MASA_band_grouping_24[band]; bin < MASA_band_grouping_24[band + 1] && bin < maxBin; bin++ )
            {
#ifdef FIX_BASOP_2442_MASA2TC_TO_MONO_AND_AMBI
                IF( meta->directional_meta[0].azimuth_fx[sf][band] < 0 )
                {
                    hSpatParamRendCom->azimuth[meta_write_index][bin] = negate( extract_l( L_shr( L_negate( meta->directional_meta[0].azimuth_fx[sf][band] ), Q22 ) ) ); /* Q22 - Q22 = Q0 */
                }
                ELSE
                {
                    hSpatParamRendCom->azimuth[meta_write_index][bin] = extract_l( L_shr( meta->directional_meta[0].azimuth_fx[sf][band], Q22 ) );
                }
#else
                hSpatParamRendCom->azimuth[meta_write_index][bin] = extract_l( L_shr( meta->directional_meta[0].azimuth_fx[sf][band], Q22 ) ); /* Q22 - Q22 = Q0 */
#endif
                move16();
#ifdef FIX_BASOP_2442_MASA2TC_TO_MONO_AND_AMBI
                IF( meta->directional_meta[0].elevation_fx[sf][band] < 0 )
                {
                    hSpatParamRendCom->elevation[meta_write_index][bin] = negate( extract_l( L_shr( L_negate( meta->directional_meta[0].elevation_fx[sf][band] ), Q22 ) ) ); /* Q22 - Q22 = Q0 */
                }
                ELSE
                {
                    hSpatParamRendCom->elevation[meta_write_index][bin] = extract_l( L_shr( meta->directional_meta[0].elevation_fx[sf][band], Q22 ) );
                }
#else
                hSpatParamRendCom->elevation[meta_write_index][bin] = extract_l( L_shr( meta->directional_meta[0].elevation_fx[sf][band], Q22 ) ); /* Q22 - Q22 = Q0 */
#endif
                move16();
                hSpatParamRendCom->energy_ratio1_fx[meta_write_index][bin] = meta->directional_meta[0].energy_ratio_fx[sf][band];
                move32();
@@ -9046,9 +9068,31 @@ static void copyMasaMetadataToDiracRenderer_fx(

                IF( EQ_16( hSpatParamRendCom->numSimultaneousDirections, 2 ) )
                {
#ifdef FIX_BASOP_2442_MASA2TC_TO_MONO_AND_AMBI
                    IF( meta->directional_meta[1].azimuth_fx[sf][band] < 0 )
                    {
                        hSpatParamRendCom->azimuth2[meta_write_index][bin] = negate( extract_l( L_shr( L_negate( meta->directional_meta[1].azimuth_fx[sf][band] ), Q22 ) ) ); /* Q22 - Q22 = Q0 */
                    }
                    ELSE
                    {
                        hSpatParamRendCom->azimuth2[meta_write_index][bin] = extract_l( L_shr( meta->directional_meta[1].azimuth_fx[sf][band], Q22 ) );
                    }
#else
                    hSpatParamRendCom->azimuth2[meta_write_index][bin] = extract_l( L_shr( meta->directional_meta[1].azimuth_fx[sf][band], Q22 ) ); /* Q22 - Q22 = Q0 */
#endif
                    move16();
#ifdef FIX_BASOP_2442_MASA2TC_TO_MONO_AND_AMBI
                    IF( meta->directional_meta[1].elevation_fx[sf][band] < 0 )
                    {
                        hSpatParamRendCom->elevation2[meta_write_index][bin] = negate( extract_l( L_shr( L_negate( meta->directional_meta[1].elevation_fx[sf][band] ), Q22 ) ) ); /* Q22 - Q22 = Q0 */
                    }
                    ELSE
                    {
                        hSpatParamRendCom->elevation2[meta_write_index][bin] = extract_l( L_shr( meta->directional_meta[1].elevation_fx[sf][band], Q22 ) );
                    }
#else
                    hSpatParamRendCom->elevation2[meta_write_index][bin] = extract_l( L_shr( meta->directional_meta[1].elevation_fx[sf][band], Q22 ) ); /* Q22 - Q22 = Q0 */
#endif
                    move16();
                    hSpatParamRendCom->energy_ratio2_fx[meta_write_index][bin] = meta->directional_meta[1].energy_ratio_fx[sf][band];
                    move32();