Commit 5f95f44e authored by Nicolas Roussin's avatar Nicolas Roussin
Browse files

Remove BE opt flags.

parent 24e8bdab
Loading
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -106,9 +106,6 @@

/* #################### Start BASOP optimization switches ############################ */

#define OPT_2181_MATRIX_TRANSP_1_MUL        /* Dolby: Issue 2181, optimize matrixTransp1Mul_fx. */
#define OPT_2182_MATRIX_SCALE_OPS           /* Dolby: Issue 2181, move matrix scale operations outside mul operations. */
#define OPT_2185_MATRIX_OUT_SCALING         /* Dolby: Issue 2185, optimize matrix-mul output-format. */
#define OPT_2239_IVAS_FILTER_PROCESS        /* Dolby: Issue 2239, optimize ivas_filter_process_fx. */
#define NONBE_OPT_2193_EIG2X2               /* Dolby: Issue 2193, optimize eig2x2_fx. */
#define BE_FIX_2240_COMPUTE_COV_MTC_FX_FAST /* FhG: Speeds up covariance calculation e.g. 60 WMOPS for encoding -mc 7_1_4 24400 48 */
+0 −199
Original line number Diff line number Diff line
@@ -118,17 +118,11 @@ static void ivas_masa_ext_rend_parambin_internal_fx( MASA_EXT_REND_HANDLE hMasaE

static void formulate2x2MixingMatrix_fx( Word32 Ein1_fx /*q_Ein*/, Word32 Ein2_fx /*q_Ein*/, Word16 q_Ein, Word32 CinRe_fx /*q_Cin*/, Word32 CinIm_fx /*q_Cin*/, Word16 q_Cin, Word32 Eout1_fx /*q_Eout*/, Word32 Eout2_fx /*q_Eout*/, Word16 q_Eout, Word32 CoutRe_fx /*q_Cout*/, Word32 CoutIm_fx /*q_Cout*/, Word16 q_Cout, Word32 Q_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*Q31*/, Word32 Mre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_M*/, Word32 Mim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_M*/, Word16 *q_M, const Word16 regularizationFactor_fx /*Q14*/ );

#ifdef OPT_2182_MATRIX_SCALE_OPS
static void matrixScale_fx( Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, Word32 Aim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, Word16 *q_A );
#endif

static void matrixMul_fx( Word32 Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, Word32 Aim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, Word16 *q_A, Word32 Bre[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word32 Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word16 *q_B, Word32 outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word32 outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word16 *q_out );

#ifdef OPT_2182_MATRIX_SCALE_OPS
static void matrixTransp2Mul_fx( Word32 Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, Word32 Aim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, Word16 *q_A, Word32 Bre[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word32 Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word16 *q_B, Word32 outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word32 outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word16 *q_out );
#else
static void matrixTransp2Mul_fx( Word32 Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, Word32 Aim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, Word16 *q_A, Word32 Bre[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word32 Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word16 *q_B, Word32 Ascale, Word32 Bscale, Word32 outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word32 outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word16 *q_out );
#endif


/*-------------------------------------------------------------------------
@@ -2236,24 +2230,14 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx(
        }

        /* Make matrix multiplication M*Cx*M' to determine resulting covariance matrix of processing input with M */
#ifdef OPT_2182_MATRIX_SCALE_OPS
        matrixScale_fx( Mre_fx, Mim_fx, &q_M );
        matrixScale_fx( CxRe_fx, CxIm_fx, &q_Cx );
#endif
        matrixMul_fx( Mre_fx, Mim_fx, &q_M, CxRe_fx, CxIm_fx, &q_Cx, tmpMtxRe_fx, tmpMtxIm_fx, &q_tmp );
#ifdef OPT_2182_MATRIX_SCALE_OPS
        matrixScale_fx( tmpMtxRe_fx, tmpMtxIm_fx, &q_tmp );
        matrixTransp2Mul_fx(
            tmpMtxRe_fx, tmpMtxIm_fx, &q_tmp,
            Mre_fx, Mim_fx, &q_M,
            resultMtxRe_fx, resultMtxIm_fx, &q_res );
#else
        matrixTransp2Mul_fx(
            tmpMtxRe_fx, tmpMtxIm_fx, &q_tmp, Mre_fx, Mim_fx, &q_M,
            1 /*int Ascale*/,
            0 /*int Bscale*/,
            resultMtxRe_fx, resultMtxIm_fx, &q_res );
#endif

        /* When below the frequency limit where decorrelation is applied, we inject the decorrelated
         * residual (or missing) signal component. The procedure is active when there are not enough independent
@@ -4202,10 +4186,7 @@ static void matrixDiagMul_fx(
    Word16 *q_Out )
{
    Word16 chA, chB;

#ifdef OPT_2185_MATRIX_OUT_SCALING
    Word32 not_zero = 0;
#endif

    FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
    {
@@ -4215,35 +4196,22 @@ static void matrixDiagMul_fx(
            imOut_fx[chA][chB] = Mpy_32_32( imIn_fx[chA][chB], D_fx[chB] );
            move32();
            move32();
#ifdef OPT_2185_MATRIX_OUT_SCALING
            not_zero = L_or( not_zero, reOut_fx[chA][chB] );
            not_zero = L_or( not_zero, imOut_fx[chA][chB] );
#endif
        }
    }

    *q_Out = sub( add( q_In, q_D ), 31 );
    move16();
#ifdef OPT_2185_MATRIX_OUT_SCALING
    if ( !not_zero )
    {
        *q_Out = Q31;
        move16();
    }
#else
    Word16 size = i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS );
    if ( L_and( is_zero_arr( reOut_fx[0], size ), is_zero_arr( imOut_fx[0], size ) ) )
    {
        *q_Out = Q31;
        move16();
    }
#endif


    return;
}

#ifdef OPT_2182_MATRIX_SCALE_OPS
static void matrixScale_fx(
    Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/
    Word32 Aim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/
@@ -4257,7 +4225,6 @@ static void matrixScale_fx(
    *q_A = add( *q_A, shift );
    move16();
}
#endif

static void matrixMul_fx(
    Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/
@@ -4270,29 +4237,8 @@ static void matrixMul_fx(
    Word32 outIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/
    Word16 *q_out )
{
#ifdef OPT_2182_MATRIX_SCALE_OPS
    Word16 chA, chB;
#else
    Word16 chA, chB;
    Word16 min_q_shift1, min_q_shift2;
    Word16 size = i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS );

    min_q_shift1 = sub( s_min( L_norm_arr( Are_fx[0], size ), L_norm_arr( Aim_fx[0], size ) ), 1 );
    min_q_shift2 = sub( s_min( L_norm_arr( Bre_fx[0], size ), L_norm_arr( Bim_fx[0], size ) ), 1 );

    scale_sig32( Are_fx[0], size, min_q_shift1 );
    scale_sig32( Aim_fx[0], size, min_q_shift1 );
    scale_sig32( Bre_fx[0], size, min_q_shift2 );
    scale_sig32( Bim_fx[0], size, min_q_shift2 );

    *q_A = add( *q_A, min_q_shift1 );
    *q_B = add( *q_B, min_q_shift2 );
    move16();
    move16();
#endif
#ifdef OPT_2185_MATRIX_OUT_SCALING
    Word32 not_zero = 0;
#endif

    FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
    {
@@ -4319,31 +4265,18 @@ static void matrixMul_fx(
                                             Are_fx[chA][1], Bim_fx[1][chB] );
            move32();
#endif /* #ifdef IVAS_ENH64_CADENCE_CHANGES */
#ifdef OPT_2185_MATRIX_OUT_SCALING
            not_zero = L_or( not_zero, outRe_fx[chA][chB] );
            not_zero = L_or( not_zero, outIm_fx[chA][chB] );
#endif
        }
    }

    *q_out = sub( add( *q_A, *q_B ), 31 );
    move16();
#ifdef OPT_2185_MATRIX_OUT_SCALING
    if ( !not_zero )
    {
        *q_out = Q31;
        move16();
    }
#else
#ifdef OPT_2182_MATRIX_SCALE_OPS
    Word16 size = BINAURAL_CHANNELS * BINAURAL_CHANNELS;
#endif
    if ( L_and( is_zero_arr( outRe_fx[0], size ), is_zero_arr( outIm_fx[0], size ) ) )
    {
        *q_out = Q31;
        move16();
    }
#endif

    return;
}
@@ -4363,25 +4296,16 @@ static void matrixTransp1Mul_fx(

    Word64 tmp_outRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
    Word64 tmp_outIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
#ifdef OPT_2181_MATRIX_TRANSP_1_MUL
    Word64 tmp64;
    Word16 common_lsh, q;
    q = add( add( q_A, q_B ), 1 );
    common_lsh = sub( 63, q );
    move16();
#else
    Word16 q_tmp_outRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
    Word16 q_tmp_outIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
    Word64 tmp64_1, tmp64_2;
    Word16 tmp16, q_common = 63;
    move16();
#endif

    FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
    {
        FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ )
        {
#ifdef OPT_2181_MATRIX_TRANSP_1_MUL
            tmp64 = W_mult_32_32( Are_fx[0][chA], Bre_fx[0][chB] );
            tmp64 = W_mac_32_32( tmp64, Are_fx[1][chA], Bre_fx[1][chB] );
            tmp64 = W_mac_32_32( tmp64, Aim_fx[0][chA], Bim_fx[0][chB] );
@@ -4395,82 +4319,32 @@ static void matrixTransp1Mul_fx(
            tmp_outIm_fx[chA][chB] = W_mac_32_32( tmp64, Are_fx[1][chA], Bim_fx[1][chB] );
            move64();
            common_lsh = s_min( common_lsh, W_norm( tmp_outIm_fx[chA][chB] ) );
#else
            tmp64_1 = W_mac_32_32( W_mult_32_32( Are_fx[0][chA], Bre_fx[0][chB] ), Are_fx[1][chA], Bre_fx[1][chB] ); // Q: add( add( q_A, q_B ), 1 )
            tmp64_2 = W_mac_32_32( W_mult_32_32( Aim_fx[0][chA], Bim_fx[0][chB] ), Aim_fx[1][chA], Bim_fx[1][chB] ); // Q: add( add( q_A, q_B ), 1 )
            tmp_outRe_fx[chA][chB] = W_add( tmp64_1, tmp64_2 );                                                      // Q: add( add( q_A, q_B ), 1 )
            move64();
            tmp16 = W_norm( tmp_outRe_fx[chA][chB] );
            tmp_outRe_fx[chA][chB] = W_shl( tmp_outRe_fx[chA][chB], tmp16 ); // Q:add( tmp16, add( add( q_A, q_B ), 1 ) )
            move64();
            q_tmp_outRe_fx[chA][chB] = add( tmp16, add( add( q_A, q_B ), 1 ) );
            move16();
            q_common = s_min( q_tmp_outRe_fx[chA][chB], q_common );


            tmp64_1 = W_mac_32_32( W_mult_32_32( Are_fx[0][chA], Bim_fx[0][chB] ), Are_fx[1][chA], Bim_fx[1][chB] ); // Q: add( add( q_A, q_B ), 1 )
            tmp64_2 = W_mac_32_32( W_mult_32_32( Aim_fx[0][chA], Bre_fx[0][chB] ), Aim_fx[1][chA], Bre_fx[1][chB] ); // Q: add( add( q_A, q_B ), 1 )
            tmp_outIm_fx[chA][chB] = W_sub( tmp64_1, tmp64_2 );                                                      // Q: add( add( q_A, q_B ), 1 )
            move64();
            tmp16 = W_norm( tmp_outIm_fx[chA][chB] );
            tmp_outIm_fx[chA][chB] = W_shl( tmp_outIm_fx[chA][chB], tmp16 ); // Q:add( tmp16, add( add( q_A, q_B ), 1 ) )
            move64();
            q_tmp_outIm_fx[chA][chB] = add( tmp16, add( add( q_A, q_B ), 1 ) );
            move16();
            q_common = s_min( q_tmp_outIm_fx[chA][chB], q_common );
#endif
        }
    }
#ifdef OPT_2185_MATRIX_OUT_SCALING
    Word32 not_zero = 0;
#endif
    FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
    {
        FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ )
        {
#ifdef OPT_2181_MATRIX_TRANSP_1_MUL
            outRe_fx[chA][chB] = W_extract_h( W_shl( tmp_outRe_fx[chA][chB], common_lsh ) );
            move32();
            outIm_fx[chA][chB] = W_extract_h( W_shl( tmp_outIm_fx[chA][chB], common_lsh ) );
            move32();
#else
            outRe_fx[chA][chB] = W_extract_h( W_shl( tmp_outRe_fx[chA][chB], s_max( -63, sub( q_common, q_tmp_outRe_fx[chA][chB] ) ) ) );
            move32();
            outIm_fx[chA][chB] = W_extract_h( W_shl( tmp_outIm_fx[chA][chB], s_max( -63, sub( q_common, q_tmp_outIm_fx[chA][chB] ) ) ) );
            move32();
#endif
#ifdef OPT_2185_MATRIX_OUT_SCALING
            not_zero = L_or( not_zero, outRe_fx[chA][chB] );
            not_zero = L_or( not_zero, outIm_fx[chA][chB] );
#endif
        }
    }
#ifdef OPT_2181_MATRIX_TRANSP_1_MUL
    *q_out = sub( add( q, common_lsh ), 32 );
    move16();
#else
    *q_out = sub( q_common, 32 );
    move16();
#endif
#ifdef OPT_2185_MATRIX_OUT_SCALING
    if ( !not_zero )
    {
        *q_out = Q31;
        move16();
    }
#else
    Word16 size = i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS );
    if ( L_and( is_zero_arr( outRe_fx[0], size ), is_zero_arr( outIm_fx[0], size ) ) )
    {
        *q_out = Q31;
        move16();
    }
#endif

    return;
}

#ifdef OPT_2182_MATRIX_SCALE_OPS
static void matrixTransp2Mul_fx(
    Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/
    Word32 Aim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/
@@ -4481,50 +4355,10 @@ static void matrixTransp2Mul_fx(
    Word32 outRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/
    Word32 outIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/
    Word16 *q_out )
#else
static void matrixTransp2Mul_fx(
    Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/
    Word32 Aim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/
    Word16 *q_A,
    Word32 Bre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_B*/
    Word32 Bim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_B*/
    Word16 *q_B,
    Word32 Ascale,
    Word32 Bscale,
    Word32 outRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/
    Word32 outIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/
    Word16 *q_out )
#endif
{
#ifdef OPT_2182_MATRIX_SCALE_OPS
    Word16 chA, chB;
    // Word16 size = BINAURAL_CHANNELS * BINAURAL_CHANNELS;
#else
    Word16 chA, chB;
    Word16 min_q_shift;
    Word16 size = BINAURAL_CHANNELS * BINAURAL_CHANNELS;

    IF( Ascale == 1 )
    {
        min_q_shift = sub( s_min( L_norm_arr( Are_fx[0], size ), L_norm_arr( Aim_fx[0], size ) ), 1 );
        scale_sig32( Are_fx[0], size, min_q_shift );
        scale_sig32( Aim_fx[0], size, min_q_shift );
        *q_A = add( *q_A, min_q_shift );
        move16();
    }

    IF( Bscale == 1 )
    {
        min_q_shift = sub( s_min( L_norm_arr( Bre_fx[0], size ), L_norm_arr( Bim_fx[0], size ) ), 1 );
        scale_sig32( Bre_fx[0], size, min_q_shift );
        scale_sig32( Bim_fx[0], size, min_q_shift );
        *q_B = add( *q_B, min_q_shift );
        move16();
    }
#endif
#ifdef OPT_2185_MATRIX_OUT_SCALING
    Word32 not_zero = 0;
#endif
    FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
    {
        FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ )
@@ -4550,31 +4384,18 @@ static void matrixTransp2Mul_fx(
                                             Are_fx[chA][1], Bim_fx[chB][1] );
            move32();
#endif /* #ifdef IVAS_ENH64_CADENCE_CHANGES */
#ifdef OPT_2185_MATRIX_OUT_SCALING
            not_zero = L_or( not_zero, outRe_fx[chA][chB] );
            not_zero = L_or( not_zero, outIm_fx[chA][chB] );
#endif
        }
    }

    *q_out = sub( add( *q_A, *q_B ), 31 );
    move16();
#ifdef OPT_2185_MATRIX_OUT_SCALING
    if ( !not_zero )
    {
        *q_out = Q31;
        move16();
    }
#else
#ifdef OPT_2182_MATRIX_SCALE_OPS
    Word16 size = BINAURAL_CHANNELS * BINAURAL_CHANNELS;
#endif
    if ( L_and( is_zero_arr( outRe_fx[0], size ), is_zero_arr( outIm_fx[0], size ) ) )
    {
        *q_out = Q31;
        move16();
    }
#endif

    return;
}
@@ -5077,10 +4898,8 @@ static void formulate2x2MixingMatrix_fx(
    q_temp = sub( add( q_ky, q_GhatQ ), 31 );

    /* A = Ky' * G_hat * Q * Kx (see publication) */
#ifdef OPT_2182_MATRIX_SCALE_OPS
    matrixScale_fx( tmpRe_fx, tmpIm_fx, &q_temp );
    matrixScale_fx( Kxre_fx, Kxim_fx, &q_Kx );
#endif
    matrixMul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Kxre_fx, Kxim_fx, &q_Kx, Are_fx, Aim_fx, &q_A );

    /* Find nearest orthonormal matrix P to A = Ky' * G_hat * Q * Kx
@@ -5138,10 +4957,8 @@ static void formulate2x2MixingMatrix_fx(
    div_fx[0] = L_min( div_fx[0], thresh );                     // q_div
    div_fx[1] = L_min( div_fx[1], thresh );                     // q_div

#ifdef OPT_2182_MATRIX_SCALE_OPS
    matrixScale_fx( Are_fx, Aim_fx, &q_A );
    matrixScale_fx( Ure_fx, Uim_fx, &q_U );
#endif
    matrixMul_fx( Are_fx, Aim_fx, &q_A, Ure_fx, Uim_fx, &q_U, tmpRe_fx, tmpIm_fx, &q_temp );

    exp = L_norm_arr( div_fx, BINAURAL_CHANNELS );
@@ -5205,17 +5022,10 @@ static void formulate2x2MixingMatrix_fx(
        }
    }

#ifdef OPT_2182_MATRIX_SCALE_OPS
    matrixTransp2Mul_fx(
        tmpRe_fx, tmpIm_fx, &q_temp,
        Ure_fx, Uim_fx, &q_U,
        Pre_fx, Pim_fx, &q_P ); /* Nearest orthonormal matrix P to matrix A formulated */
#else
    matrixTransp2Mul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Ure_fx, Uim_fx, &q_U,
                         0 /*int Ascale*/,
                         0 /*int Bscale*/,
                         Pre_fx, Pim_fx, &q_P ); /* Nearest orthonormal matrix P to matrix A formulated */
#endif

    /* These are the final formulas of the JAES publication M = Ky P Kx^(-1) */
#if ( BINAURAL_CHANNELS != 2 )
@@ -5346,23 +5156,14 @@ static void formulate2x2MixingMatrix_fx(
        }
    }

#ifdef OPT_2182_MATRIX_SCALE_OPS
    matrixScale_fx( KyRe_fx, KyIm_fx, &q_ky );
    matrixScale_fx( Pre_fx, Pim_fx, &q_P );
#endif
    matrixMul_fx( KyRe_fx, KyIm_fx, &q_ky, Pre_fx, Pim_fx, &q_P, tmpRe_fx, tmpIm_fx, &q_temp );
#ifdef OPT_2182_MATRIX_SCALE_OPS
    matrixScale_fx( tmpRe_fx, tmpIm_fx, &q_temp );
    matrixTransp2Mul_fx(
        tmpRe_fx, tmpIm_fx, &q_temp,
        Uxre_fx, Uxim_fx, &q_Ux,
        Mre_fx, Mim_fx, q_M );
#else
    matrixTransp2Mul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Uxre_fx, Uxim_fx, &q_Ux,
                         1 /*int Ascale*/,
                         0 /*int Bscale*/,
                         Mre_fx, Mim_fx, q_M );
#endif

    return;
}