Commit 387d70f2 authored by Sandesh Venkatesh's avatar Sandesh Venkatesh
Browse files

Merge branch '3gpp_issue_964_fix' into 'main'

Fix for 3GPP issue 964: ParamISM: High MLD for ParamISM, 32 kbps, high frequency content missing [allow regression]

See merge request !746
parents 0076ecbe 534b184c
Loading
Loading
Loading
Loading
Loading
+65 −112
Original line number Diff line number Diff line
@@ -1231,8 +1231,7 @@ static void ivas_dirac_dec_binaural_internal_fx(
        st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp = sub( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp, shift );
        move16();
    }
    Word16 q_cldfb[6][CLDFB_SLOTS_PER_SUBFRAME] = { 0 };
    move16();
    Word16 q_cldfb[6][CLDFB_SLOTS_PER_SUBFRAME];
    FOR( Word16 ind = 0; ind < 6; ind++ )
    {
        FOR( Word16 ind2 = 0; ind2 < 4; ind2++ )
@@ -1533,36 +1532,9 @@ static void ivas_dirac_dec_binaural_internal_fx(
        }
    }

    Word16 shift = 31;
    move16();
    Word32 Cldfb_RealBuffer_inTmp_fx[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Cldfb_ImagBuffer_inTmp_fx[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
    FOR( i = 0; i < 2; i++ )
    {
        FOR( j = 0; j < 4; j++ )
        {
            shift = s_min( shift, getScaleFactor32( Cldfb_RealBuffer_in_fx[i][j], CLDFB_NO_CHANNELS_MAX ) );
            shift = s_min( shift, getScaleFactor32( Cldfb_ImagBuffer_in_fx[i][j], CLDFB_NO_CHANNELS_MAX ) );
        }
    }

    Word16 q = add( q_inp, shift );

    FOR( i = 0; i < 2; i++ )
    {
        FOR( j = 0; j < 4; j++ )
        {
            FOR( Word16 k = 0; k < 60; k++ )
            {
                Cldfb_RealBuffer_inTmp_fx[i][j][k] = L_shl( Cldfb_RealBuffer_in_fx[i][j][k], shift ); // q
                Cldfb_ImagBuffer_inTmp_fx[i][j][k] = L_shl( Cldfb_ImagBuffer_in_fx[i][j][k], shift ); // q
                move32();
                move32();
            }
        }
    }

    ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_inTmp_fx, Cldfb_ImagBuffer_inTmp_fx, Rmat_fx, subframe,
                                                                               hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, st_ivas->hMasaIsmData, q );
    test();
    ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, Rmat_fx, subframe,
                                                                               hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, st_ivas->hMasaIsmData, q_inp );

    IF( EQ_32( config_data.ivas_format, ISM_FORMAT ) )
    {
@@ -2282,7 +2254,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric
    UWord8 applyLowBitRateEQ;
    Word16 dirac_read_idx;
    Word32 subFrameTotalEne_fx[CLDFB_NO_CHANNELS_MAX];
    Word16 q_subFrameTotalEne;
    Word16 subFrameTotalEne_e[CLDFB_NO_CHANNELS_MAX];
    PARAMBIN_HRTF_GAIN_CACHE gainCache[MAX_GAIN_CACHE_SIZE];
    IVAS_FORMAT ivas_format;
    MC_MODE mc_mode;
@@ -2290,6 +2262,9 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric
    Word16 nchan_transport;
    Word16 gainCacheBaseIndex;
    Word16 q_earlyPartEneCorrection;
    Word16 exp, exp1;
    Word64 temp64;
    Word32 temp;

    separateCenterChannelRendering = hConfig->separateCenterChannelRendering;
    move16();
@@ -2334,6 +2309,8 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric

    set32_fx( frameMeanDiffusenessEneWeight_fx, 0, CLDFB_NO_CHANNELS_MAX );

    set16_fx( subFrameTotalEne_e, 0, CLDFB_NO_CHANNELS_MAX );

    FOR( idx = 0; idx < MAX_GAIN_CACHE_SIZE; idx++ )
    {
        gainCache[idx].azi = -1000; /* Use -1000 as value for uninitialized cache. */
@@ -2372,44 +2349,43 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric
    dirac_read_idx = hSpatParamRendCom->render_to_md_map[subframe];
    move16();

    exp = sub( 63, shl( q, 1 ) ); // exp for the energy (inRe_fx * inRe_fx + inIm_fx * inIm_fx) computed below

    /* Calculate input covariance matrix */
    FOR( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ )
    {
        FOR( bin = 0; bin < nBins; bin++ )
        {
            hDiracDecBin->ChCrossRe_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossRe_fx[bin], hDiracDecBin->ChCrossRe_e[bin],
                                                                        L_add( L_shr( Mpy_32_32( inRe_fx[0][slot][bin], inRe_fx[1][slot][bin] ), 1 ), L_shr( Mpy_32_32( inIm_fx[0][slot][bin], inIm_fx[1][slot][bin] ), 1 ) ), sub( 63, shl( q, 1 ) ), &hDiracDecBin->ChCrossRe_e[bin] );
            hDiracDecBin->ChCrossIm_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossIm_fx[bin], hDiracDecBin->ChCrossIm_e[bin],
                                                                        L_sub( L_shr( Mpy_32_32( inRe_fx[0][slot][bin], inIm_fx[1][slot][bin] ), 1 ), L_shr( Mpy_32_32( inIm_fx[0][slot][bin], inRe_fx[1][slot][bin] ), 1 ) ), sub( 63, shl( q, 1 ) ), &hDiracDecBin->ChCrossIm_e[bin] );

            inRe_fx[0][slot][bin] = L_shr( inRe_fx[0][slot][bin], 2 );
            inRe_fx[1][slot][bin] = L_shr( inRe_fx[1][slot][bin], 2 );
            inIm_fx[0][slot][bin] = L_shr( inIm_fx[0][slot][bin], 2 );
            inIm_fx[1][slot][bin] = L_shr( inIm_fx[1][slot][bin], 2 );

            move32();
            move32();
            move32();
            move32();
            move32();
            move32();
            FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
            {
                Word32 instEne_fx;
                temp64 = W_mult0_32_32( inRe_fx[ch][slot][bin], inRe_fx[ch][slot][bin] );                  // 2q
                temp64 = W_add( temp64, W_mult0_32_32( inIm_fx[ch][slot][bin], inIm_fx[ch][slot][bin] ) ); // 2q
                exp1 = W_norm( temp64 );
                instEne_fx = W_extract_h( W_shl( temp64, exp1 ) ); // 2q - 32 + exp1
                /* exp of instEne_fx = 31 - (2q -32 + exp1) = 63 - 2q - exp1 = exp - exp1*/

                instEne_fx = Mpy_32_32( inRe_fx[ch][slot][bin], inRe_fx[ch][slot][bin] );                      // 2q - 31
                instEne_fx = L_add( instEne_fx, Mpy_32_32( inIm_fx[ch][slot][bin], inIm_fx[ch][slot][bin] ) ); // 2q - 31
                hDiracDecBin->ChEne_fx[ch][bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEne_fx[ch][bin], hDiracDecBin->ChEne_e[ch][bin], instEne_fx, sub( 66, shl( q, 1 ) ), &hDiracDecBin->ChEne_e[ch][bin] );
                subFrameTotalEne_fx[bin] = L_add( subFrameTotalEne_fx[bin], L_shr( instEne_fx, 1 ) ); // 2q - 32
                hDiracDecBin->ChEne_fx[ch][bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEne_fx[ch][bin], hDiracDecBin->ChEne_e[ch][bin], instEne_fx, sub( exp, exp1 ), &hDiracDecBin->ChEne_e[ch][bin] );
                subFrameTotalEne_fx[bin] = BASOP_Util_Add_Mant32Exp( subFrameTotalEne_fx[bin], subFrameTotalEne_e[bin], instEne_fx, sub( exp, exp1 ), &subFrameTotalEne_e[bin] );
                move32();
                move32();
            }
            temp64 = W_mult0_32_32( inRe_fx[0][slot][bin], inRe_fx[1][slot][bin] );                  // 2q
            temp64 = W_add( temp64, W_mult0_32_32( inIm_fx[0][slot][bin], inIm_fx[1][slot][bin] ) ); // 2q
            exp1 = W_norm( temp64 );
            temp = W_extract_h( W_shl( temp64, exp1 ) ); // // 2q - 32 + exp1
            hDiracDecBin->ChCrossRe_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossRe_fx[bin], hDiracDecBin->ChCrossRe_e[bin], temp, sub( exp, exp1 ), &hDiracDecBin->ChCrossRe_e[bin] );
            move32();

            temp64 = W_mult0_32_32( inRe_fx[0][slot][bin], inIm_fx[1][slot][bin] );                  // 2q
            temp64 = W_sub( temp64, W_mult0_32_32( inIm_fx[0][slot][bin], inRe_fx[1][slot][bin] ) ); // 2q
            exp1 = W_norm( temp64 );
            temp = W_extract_h( W_shl( temp64, exp1 ) ); // // 2q - 32 + exp1
            hDiracDecBin->ChCrossIm_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossIm_fx[bin], hDiracDecBin->ChCrossIm_e[bin], temp, sub( exp, exp1 ), &hDiracDecBin->ChCrossIm_e[bin] );
            move32();
        }
    }

    q = sub( q, 2 );
    q_subFrameTotalEne = sub( shl( q, 1 ), 32 );

    /* Apply EQ at low bit rates */
    IF( applyLowBitRateEQ != 0 )
    {
@@ -2417,12 +2393,12 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric

        FOR( bin = LOW_BIT_RATE_BINAURAL_EQ_OFFSET; bin < lastEqBin; bin++ )
        {
            subFrameTotalEne_fx[bin] = Mpy_32_32( subFrameTotalEne_fx[bin], lowBitRateEQ_fx[bin] ); // 2q -32
            subFrameTotalEne_fx[bin] = Mpy_32_32( subFrameTotalEne_fx[bin], lowBitRateEQ_fx[bin] ); // exp = subFrameTotalEne_e[bin]
            move32();
        }
        FOR( ; bin < nBins; bin++ )
        {
            subFrameTotalEne_fx[bin] = Mpy_32_32( subFrameTotalEne_fx[bin], lowBitRateEQ_fx[lastEqBin] ); // 2q -32
            subFrameTotalEne_fx[bin] = Mpy_32_32( subFrameTotalEne_fx[bin], lowBitRateEQ_fx[lastEqBin] ); // exp = subFrameTotalEne_e[bin]
            move32();
        }
    }
@@ -2433,22 +2409,33 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric
    {
        Word32 tempRe, tempIm;
        Word32 subFrameSumEne_fx[CLDFB_NO_CHANNELS_MAX];
        Word16 subFrameSumEne_e[CLDFB_NO_CHANNELS_MAX];

        set32_fx( subFrameSumEne_fx, 0, CLDFB_NO_CHANNELS_MAX );
        set16_fx( subFrameSumEne_e, 0, CLDFB_NO_CHANNELS_MAX );
        FOR( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ )
        {
            FOR( bin = 0; bin < nBins; bin++ )
            {
                tempRe = L_add( inRe_fx[0][slot][bin], inRe_fx[1][slot][bin] );                     // q
                tempIm = L_add( inIm_fx[0][slot][bin], inIm_fx[1][slot][bin] );                     // q
                subFrameSumEne_fx[bin] = L_add( subFrameSumEne_fx[bin], L_add( L_shr( Mpy_32_32( tempRe, tempRe ), 1 ), L_shr( Mpy_32_32( tempIm, tempIm ), 1 ) ) ); // 2q -32
                temp64 = W_add( W_mult0_32_32( tempRe, tempRe ), W_mult0_32_32( tempIm, tempIm ) ); // 2q
                exp1 = W_norm( temp64 );
                temp64 = W_shl( temp64, exp1 ); // 2q + exp1
                subFrameSumEne_fx[bin] = BASOP_Util_Add_Mant32Exp( subFrameSumEne_fx[bin], subFrameTotalEne_e[bin], W_extract_h( temp64 ), sub( exp /* 63 - 2q */, exp1 ) /*31 - (2q + exp1 - 32)*/, &subFrameTotalEne_e[bin] );
                move32();
            }
        }
        FOR( bin = 0; bin < nBins; bin++ )
        {
            subFrameTotalEne_fx[bin] = L_max( subFrameTotalEne_fx[bin], subFrameSumEne_fx[bin] ); // 2q -32
            temp = L_shl_sat( subFrameTotalEne_fx[bin], sub( subFrameTotalEne_e[bin], subFrameSumEne_e[bin] ) ); // subFrameSumEne_e[bin]
            IF( GT_32( subFrameSumEne_fx[bin], temp ) )
            {
                subFrameTotalEne_fx[bin] = subFrameSumEne_fx[bin];
                move32();
                subFrameTotalEne_e[bin] = subFrameSumEne_e[bin];
                move16();
            }
        }
    }

@@ -2475,7 +2462,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric
         * the early spectrum of the BRIR data, using the spectral correction data in
         * hBinaural->earlyPartEneCorrection[bin], based on the BRIR set. */
        meanEnePerCh_fx = Mpy_32_32( hDiracDecBin->earlyPartEneCorrection_fx[bin], subFrameTotalEne_fx[bin] ); // Q( q_meanEnePerCh )
        q_meanEnePerCh = sub( add( q_earlyPartEneCorrection, q_subFrameTotalEne ), 30 );
        q_meanEnePerCh = add( sub( q_earlyPartEneCorrection, subFrameTotalEne_e[bin] ), 1 );                   // q_earlyPartEneCorrection + 31 - subFrameTotalEne_e[bin] - 31 + Q1(0.5f)
        /* Determine direct part target covariance matrix (for 1 or 2 directions) */
        FOR( dirIndex = 0; dirIndex < hSpatParamRendCom->numSimultaneousDirections; dirIndex++ )
        {
@@ -2808,7 +2795,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric
            test();
            IF( ( EQ_32( ivas_format, SBA_FORMAT ) || EQ_32( ivas_format, SBA_ISM_FORMAT ) ) && LT_16( bin, BINAURAL_COHERENCE_DIFFERENCE_BINS ) )
            {
                Word32 diffuseFieldCoherence_fx, temp;
                Word32 diffuseFieldCoherence_fx;
                Word16 tmp_exp;
                temp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( hDiracDecBin->hDiffuseDist->diffuseRatioX_fx[bin], hDiracDecBin->diffuseFieldCoherenceX_fx[bin] ), 0, Mpy_32_32( hDiracDecBin->hDiffuseDist->diffuseRatioY_fx[bin], hDiracDecBin->diffuseFieldCoherenceY_fx[bin] ), 0, &tmp_exp );
                diffuseFieldCoherence_fx = BASOP_Util_Add_Mant32Exp( temp, tmp_exp, Mpy_32_32( hDiracDecBin->hDiffuseDist->diffuseRatioZ_fx[bin], hDiracDecBin->diffuseFieldCoherenceZ_fx[bin] ), 0, &tmp_exp );
@@ -2823,21 +2810,14 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric
        }

        /* Store parameters for formulating average diffuseness over frame */
        hDiracDecBin->frameMeanDiffuseness_fx[bin] = L_add( hDiracDecBin->frameMeanDiffuseness_fx[bin], L_shl( diffEneValForDecorrelationReduction_fx, sub( q_meanEnePerCh, q_diffEneValForDecorrelationReduction ) ) ); // Q(q_meanEnePerCh)
        Word32 frameMeanDiffuseness = BASOP_Util_Add_Mant32Exp( hDiracDecBin->frameMeanDiffuseness_fx[bin], 2 /*Q29*/, diffEneValForDecorrelationReduction_fx, sub( 31, q_diffEneValForDecorrelationReduction ), &exp1 ); // exp = exp1
        frameMeanDiffusenessEneWeight_fx[bin] = L_add( frameMeanDiffusenessEneWeight_fx[bin], meanEnePerCh_fx );
        move32();
        move32();
    }

        /* Formulate average diffuseness over frame */
    Word16 e;
    FOR( bin = 0; bin < nBins; bin++ )
    {
        e = 0;
        move16();
        hDiracDecBin->frameMeanDiffuseness_fx[bin] = BASOP_Util_Divide3232_Scale( hDiracDecBin->frameMeanDiffuseness_fx[bin], L_max( EPSILLON_FX, frameMeanDiffusenessEneWeight_fx[bin] ), &e );
        hDiracDecBin->frameMeanDiffuseness_fx[bin] = L_shl( hDiracDecBin->frameMeanDiffuseness_fx[bin], add( 14, e ) ); // Q29
        move32();
        frameMeanDiffuseness = BASOP_Util_Divide3232_Scale_cadence( frameMeanDiffuseness, L_max( EPSILLON_FX, frameMeanDiffusenessEneWeight_fx[bin] ), &exp ); // exp = exp + 31 - q_meanEnePerCh - exp1
        exp = sub( exp, sub( sub( 31, q_meanEnePerCh ), exp1 ) );
        hDiracDecBin->frameMeanDiffuseness_fx[bin] = L_shl( frameMeanDiffuseness, sub( exp, 2 ) ); // Q29
        move32();
    }

@@ -2867,16 +2847,16 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric
        move16();
        den = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEnePrev_fx[0][bin], hDiracDecBin->ChEnePrev_e[0][bin], hDiracDecBin->ChEnePrev_fx[1][bin], hDiracDecBin->ChEnePrev_e[1][bin], &den_e );
        den = L_max( 1, den );
        IIReneLimiter_fx = BASOP_Util_Divide3232_Scale_cadence( num, den, &e );
        e = add( sub( num_e, den_e ), add( 5, e ) );
        IF( L_shr_sat( IIReneLimiter_fx, sub( 31, e ) ) > 0 )
        IIReneLimiter_fx = BASOP_Util_Divide3232_Scale_cadence( num, den, &exp );
        exp = add( sub( num_e, den_e ), add( 5, exp ) );
        IF( L_shr_sat( IIReneLimiter_fx, sub( 31, exp ) ) > 0 )
        {
            IIReneLimiter_fx = ONE_IN_Q31; /*Q31*/
            move32();
        }
        ELSE
        {
            IIReneLimiter_fx = L_shl( IIReneLimiter_fx, e ); /*Q31*/
            IIReneLimiter_fx = L_shl( IIReneLimiter_fx, exp ); /*Q31*/
        }

        hDiracDecBin->ChCrossRe_fx[bin] = Mpy_32_32( hDiracDecBin->ChCrossRe_fx[bin], qualityBasedSmFactor_fx );
@@ -7969,36 +7949,9 @@ static void ivas_masa_ext_rend_parambin_internal_fx(
        }
    }

    Word16 shift = 31;
    move16();
    Word32 Cldfb_RealBuffer_inTmp_fx[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Cldfb_ImagBuffer_inTmp_fx[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
    FOR( i = 0; i < 2; i++ )
    {
        FOR( j = 0; j < 4; j++ )
        {
            shift = s_min( shift, getScaleFactor32( Cldfb_RealBuffer_in_fx[i][j], CLDFB_NO_CHANNELS_MAX ) );
            shift = s_min( shift, getScaleFactor32( Cldfb_ImagBuffer_in_fx[i][j], CLDFB_NO_CHANNELS_MAX ) );
        }
    }

    Word16 q = add( q_inp, shift );

    FOR( i = 0; i < 2; i++ )
    {
        FOR( j = 0; j < 4; j++ )
        {
            FOR( Word16 k = 0; k < 60; k++ )
            {
                Cldfb_RealBuffer_inTmp_fx[i][j][k] = L_shl( Cldfb_RealBuffer_in_fx[i][j][k], shift ); // q
                Cldfb_ImagBuffer_inTmp_fx[i][j][k] = L_shl( Cldfb_ImagBuffer_in_fx[i][j][k], shift ); // q
                move32();
                move32();
            }
        }
    }

    ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_inTmp_fx, Cldfb_ImagBuffer_inTmp_fx, Rmat_fx, subframe,
                                                                               hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, NULL, q );
    test();
    ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, Rmat_fx, subframe,
                                                                               hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, NULL, q_inp );

    /* Always using CLDFB decorrelation in MASA EXT renderer */
    max_band_decorr = hDiracDecBin->h_freq_domain_decorr_ap_params->max_band_decorr;