Commit 585c5dcc authored by Sandesh Venkatesh's avatar Sandesh Venkatesh
Browse files

Converted few common functions to fixed point.

Converted cmplx_matrix_square, matrix_diag_product,
diag_matrix_product and matrix_product_diag to
fixed point.
parent 1a13687f
Loading
Loading
Loading
Loading
Loading
+47 −0
Original line number Diff line number Diff line
@@ -942,4 +942,51 @@ void ivas_decision_matrix_dec_fx(
    const Word16 nchan_out       /* i  : Number of output channels           */
);

void cmplx_matrix_square_fx(
    const Word32 *realX, /* i  : real part of the matrix                                                     */
    const Word32 *imagX, /* i  : imaginary part of the matrix                                                */
    const Word16 mRows,  /* i  : number of rows of the matrix                                                */
    const Word16 nCols,  /* i  : number of columns of the matrix                                             */
    Word32 *realZ,       /* o  : real part of the resulting matrix                                           */
    Word32 *imagZ,       /* o  : imaginary part of the resulting matrix                                      */
    Word16 input_exp,
    Word16 *output_exp );

Word16 matrix_diag_product_fx(
    const Word32 *X, /* i  : left hand matrix                                                                       */
    Word16 X_e,
    const Word16 rowsX,   /* i  : number of rows of the left hand matrix                                                 */
    const Word16 colsX,   /* i  : number of columns of the left hand matrix                                              */
    const Word16 transpX, /* i  : flag indicating the transposition of the left hand matrix prior to the multiplication  */
    const Word32 *Y,      /* i  : right hand diagonal matrix as vector containing the diagonal elements                  */
    Word16 Y_e,
    const Word16 entriesY, /* i  : number of entries in the diagonal                                                      */
    Word32 *Z,             /* o  : resulting matrix after the matrix multiplication                                       */
    Word16 *Z_e );

Word16 diag_matrix_product_fx(
    const Word32 *Y, /* i  : left hand diagonal matrix as vector containing the diagonal elements                   */
    Word16 Y_e,
    const Word16 entriesY, /* i  : length of the diagonal of the left hand matrix                                         */
    const Word32 *X,       /* i  : right hand matrix                                                                      */
    Word16 X_e,
    const Word16 rowsX,   /* i  : number of rows of the right hand matrix                                                */
    const Word16 colsX,   /* i  : number of columns of the right hand matrix                                             */
    const Word16 transpX, /* i  : flag indicating the transposition of the right hand matrix prior to the multiplication */
    Word32 *Z,            /* o  : resulting matrix after the matrix multiplication                                       */
    Word16 *Z_e );

Word16 matrix_product_diag_fx(
    const Word32 *X, /* i  : left hand matrix                                                                       */
    Word16 X_e,
    const Word16 rowsX,   /* i  : number of rows of the left hand matrix                                                 */
    const Word16 colsX,   /* i  : number of columns of the left hand matrix                                              */
    const Word16 transpX, /* i  : flag indicating the transposition of the left hand matrix prior to the multiplication  */
    const Word32 *Y,      /* i  : right hand matrix                                                                      */
    Word16 Y_e,
    const Word16 rowsY,   /* i  : number of rows of the right hand matrix                                                */
    const Word16 colsY,   /* i  : number of columns of the right hand matrix                                             */
    const Word16 transpY, /* i  : flag indicating the transposition of the right hand matrix prior to the multiplication */
    Word32 *Z,            /* o  : resulting matrix after the matrix multiplication                                       */
    Word16 *Z_e );
#endif
+273 −0
Original line number Diff line number Diff line
@@ -860,6 +860,62 @@ int16_t matrix_diag_product(
    return EXIT_SUCCESS;
}

#ifdef IVAS_FLOAT_FIXED
Word16 matrix_diag_product_fx(
    const Word32 *X, /* i  : left hand matrix                                                                       */
    Word16 X_e,
    const Word16 rowsX,   /* i  : number of rows of the left hand matrix                                                 */
    const Word16 colsX,   /* i  : number of columns of the left hand matrix                                              */
    const Word16 transpX, /* i  : flag indicating the transposition of the left hand matrix prior to the multiplication  */
    const Word32 *Y,      /* i  : right hand diagonal matrix as vector containing the diagonal elements                  */
    Word16 Y_e,
    const Word16 entriesY, /* i  : number of entries in the diagonal                                                      */
    Word32 *Z,             /* o  : resulting matrix after the matrix multiplication                                       */
    Word16 *Z_e )
{
    Word16 i, j;
    Word32 *Zp = Z;

    /* Processing */
    IF( EQ_16(transpX, 1 )) /* We use X transpose */
    {
        IF( NE_16(rowsX, entriesY ))
        {
            return EXIT_FAILURE;
        }
        FOR( j = 0; j < entriesY; ++j )
        {
            FOR( i = 0; i < colsX; ++i )
            {
                *( Zp ) = Mpy_32_32( X[j + i * rowsX], Y[j] );
                Zp++;
            }
        }
    }
    ELSE /* Regular case */
    {
        IF(NE_16(colsX, entriesY ))
        {
            return EXIT_FAILURE;
        }

        FOR( j = 0; j < entriesY; ++j )
        {
            FOR( i = 0; i < rowsX; ++i )
            {
                *( Zp ) = Mpy_32_32( *( X ), Y[j] );
                Zp++;
                X++;
            }
        }
    }

    *Z_e = add( X_e, Y_e );

    return EXIT_SUCCESS;
}
#endif

/*---------------------------------------------------------------------*
 * diag_matrix_product()
 *
@@ -913,6 +969,61 @@ int16_t diag_matrix_product(
    return EXIT_SUCCESS;
}

#ifdef IVAS_FLOAT_FIXED
Word16 diag_matrix_product_fx(
    const Word32 *Y, /* i  : left hand diagonal matrix as vector containing the diagonal elements                   */
    Word16 Y_e,
    const Word16 entriesY, /* i  : length of the diagonal of the left hand matrix                                         */
    const Word32 *X,       /* i  : right hand matrix                                                                      */
    Word16 X_e,
    const Word16 rowsX,   /* i  : number of rows of the right hand matrix                                                */
    const Word16 colsX,   /* i  : number of columns of the right hand matrix                                             */
    const Word16 transpX, /* i  : flag indicating the transposition of the right hand matrix prior to the multiplication */
    Word32 *Z,            /* o  : resulting matrix after the matrix multiplication                                       */
    Word16 *Z_e )
{
    Word16 i, j;
    Word32 *Zp = Z;

    /* Processing */
    IF( EQ_16( transpX, 1 ) ) /* We use X transpose */
    {
        IF( NE_16( colsX, entriesY ) )
        {
            return EXIT_FAILURE;
        }
        FOR( i = 0; i < rowsX; ++i )
        {
            FOR( j = 0; j < entriesY; ++j )
            {
                *( Zp ) = Mpy_32_32( X[i + j * rowsX], Y[j] );
                Zp++;
            }
        }
    }
    ELSE /* Regular case */
    {
        IF( NE_16( rowsX, entriesY ) )
        {
            return EXIT_FAILURE;
        }
        FOR( i = 0; i < colsX; ++i )
        {
            FOR( j = 0; j < entriesY; ++j )
            {
                *( Zp ) = Mpy_32_32( *( X ), Y[j] );
                Zp++;
                X++;
            }
        }
    }

    *Z_e = add(Y_e, X_e);

    return EXIT_SUCCESS;
}
#endif


/*---------------------------------------------------------------------*
 * matrix_product_diag()
@@ -1010,6 +1121,103 @@ int16_t matrix_product_diag(
    return EXIT_SUCCESS;
}

#ifdef IVAS_FLOAT_FIXED
Word16 matrix_product_diag_fx(
    const Word32 *X, /* i  : left hand matrix                                                                       */
    Word16 X_e,
    const Word16 rowsX,   /* i  : number of rows of the left hand matrix                                                 */
    const Word16 colsX,   /* i  : number of columns of the left hand matrix                                              */
    const Word16 transpX, /* i  : flag indicating the transposition of the left hand matrix prior to the multiplication  */
    const Word32 *Y,      /* i  : right hand matrix                                                                      */
    Word16 Y_e,
    const Word16 rowsY,   /* i  : number of rows of the right hand matrix                                                */
    const Word16 colsY,   /* i  : number of columns of the right hand matrix                                             */
    const Word16 transpY, /* i  : flag indicating the transposition of the right hand matrix prior to the multiplication */
    Word32 *Z,            /* o  : resulting matrix after the matrix multiplication                                       */
    Word16 *Z_e )
{
    Word16 j, k;
    Word32 *Zp = Z;

    /* Processing */
    test();
    test();
    test();
    IF( EQ_16( transpX, 1 ) && EQ_16( transpY, 0 ) ) /* We use X transpose */
    {
        IF( NE_16( rowsX, rowsY ) )
        {
            return EXIT_FAILURE;
        }

        FOR( j = 0; j < colsY; ++j )
        {
            ( *Zp ) = 0;
            FOR( k = 0; k < rowsX; ++k )
            {
                ( *Zp ) = L_add( ( *Zp ), Mpy_32_32( X[k + j * rowsX], Y[k + j * rowsY] ) );
            }
            Zp++;
        }
    }
    ELSE IF( EQ_16( transpX, 0 ) && EQ_16( transpY, 1 ) ) /* We use Y transpose */
    {
        IF( NE_16( colsX, colsY ) )
        {
            return EXIT_FAILURE;
        }
        FOR( j = 0; j < rowsY; ++j )
        {
            ( *Zp ) = 0;
            FOR( k = 0; k < colsX; ++k )
            {
                ( *Zp ) = L_add( ( *Zp ), Mpy_32_32( X[j + k * rowsX], Y[j + k * rowsY] ) );
            }
            Zp++;
        }
    }
    ELSE IF( EQ_16( transpX, 1 ) && EQ_16( transpY, 1 ) ) /* We use both transpose */
    {
        IF( NE_16( rowsX, colsY ) )
        {
            return EXIT_FAILURE;
        }

        FOR( j = 0; j < rowsY; ++j )
        {

            ( *Zp ) = 0;
            FOR( k = 0; k < colsX; ++k )
            {
                ( *Zp ) = L_add( ( *Zp ), Mpy_32_32( X[k + j * rowsX], Y[j + k * rowsY] ) );
            }

            Zp++;
        }
    }
    ELSE /* Regular case */
    {
        IF( NE_16( colsX, rowsY ) )
        {
            return EXIT_FAILURE;
        }

        FOR( j = 0; j < colsY; ++j )
        {
            ( *Zp ) = 0;
            FOR( k = 0; k < colsX; ++k )
            {
                ( *Zp ) = L_add( ( *Zp ), Mpy_32_32( X[j + k * rowsX], Y[k + j * rowsY] ) );
            }
            Zp++;
        }
    }

    *Z_e = add( X_e, Y_e );

    return EXIT_SUCCESS;
}
#endif

/*---------------------------------------------------------------------*
 * cmplx_matrix_square()
@@ -1018,6 +1226,71 @@ int16_t matrix_product_diag(
 *---------------------------------------------------------------------*/

/*! r: success or failure */
#ifdef IVAS_FLOAT_FIXED
void cmplx_matrix_square_fx(
    const Word32 *realX, /* i  : real part of the matrix                                                     */
    const Word32 *imagX, /* i  : imaginary part of the matrix                                                */
    const Word16 mRows,  /* i  : number of rows of the matrix                                                */
    const Word16 nCols,  /* i  : number of columns of the matrix                                             */
    Word32 *realZ,       /* o  : real part of the resulting matrix                                           */
    Word32 *imagZ,       /* o  : imaginary part of the resulting matrix                                      */
    Word16 input_exp,
    Word16 *output_exp )
{
    Word16 i, j, k;
    Word32 *realZp, *imagZp;
    const Word32 *p_real1, *p_real2, *p_imag1, *p_imag2;

    /* resulting matrix is hermitean, we only need to calc the upper triangle */
    /* we assume transposition needed */

    /* column*column = column/column */
    FOR( i = 0; i < nCols; i++ )
    {
        FOR( j = i; j < nCols; j++ )
        {
            p_real1 = realX + i * mRows;
            p_imag1 = imagX + i * mRows;
            p_real2 = realX + j * mRows;
            p_imag2 = imagX + j * mRows;
            realZp = realZ + ( i + nCols * j );
            imagZp = imagZ + ( i + nCols * j );
            *( realZp ) = 0;
            move32();
            *( imagZp ) = 0;
            move32();

            FOR( k = 0; k < mRows; k++ )
            {
                *( imagZp ) = L_add( *( imagZp ), L_sub( Mpy_32_32( *( p_real1 ), *( p_imag2 ) ), Mpy_32_32( *( p_real2 ), *( p_imag1 ) ) ) );
                *( realZp ) = L_add( *( realZp ), L_add( Mpy_32_32( *( p_real1 ), *( p_real2 ) ), Mpy_32_32( *( p_imag1 ), *( p_imag2 ) ) ) );
                p_real1++;
                p_real2++;
                p_imag1++;
                p_imag2++;
            }
        }
    }

    /* fill lower triangle */
    FOR( i = 1; i < nCols; i++ )
    {
        FOR( j = 0; j < i; j++ )
        {
            realZ[i + nCols * j] = realZ[j + nCols * i];
            move32();
            imagZ[i + nCols * j] = imagZ[j + nCols * i];
            move32();
        }
    }

    *output_exp = shl( input_exp, 1 );
    move16();

    return;
}
#endif

void cmplx_matrix_square(
    const float *realX,  /* i  : real part of the matrix                                                     */
    const float *imagX,  /* i  : imaginary part of the matrix                                                */
+269 −1

File changed.

Preview size limit exceeded, changes collapsed.

+22 −0
Original line number Diff line number Diff line
@@ -210,6 +210,11 @@ static void ivas_param_ism_compute_mixing_matrix(
    float *proto_matrix;
    float response_matrix[PARAM_ISM_MAX_CHAN * MAX_NUM_OBJECTS];
    int16_t num_wave;
#ifdef IVAS_FLOAT_FIXED
    Word32 dir_res_ptr_fx[PARAM_ISM_MAX_CHAN];
    Word32 cy_diag_tmp_fx[PARAM_ISM_MAX_CHAN];
    Word16 dir_res_ptr_e, cy_diag_tmp_e;
#endif

    proto_matrix = hParamIsmDec->hParamIsmRendering->proto_matrix;

@@ -248,7 +253,24 @@ static void ivas_param_ism_compute_mixing_matrix(
            }
            mvr2r( dir_res_ptr, response_matrix + w * nchan_out_woLFE, nchan_out_woLFE );
            /* we only need the diagonal of Cy*/
#ifdef IVAS_FLOAT_FIXED
            f2me_buf( dir_res_ptr, dir_res_ptr_fx, &dir_res_ptr_e, nchan_out_woLFE );

            Word16 guard_bits = 1;

            for ( i = 0; i < nchan_out_woLFE; ++i )
            {
                dir_res_ptr_fx[i] = L_shr( dir_res_ptr_fx[i], guard_bits );
            }

            dir_res_ptr_e += guard_bits;

            matrix_product_diag_fx( dir_res_ptr_fx, dir_res_ptr_e, nchan_out_woLFE, 1, 0, dir_res_ptr_fx, dir_res_ptr_e, 1, nchan_out_woLFE, 0, cy_diag_tmp_fx, &cy_diag_tmp_e );

            me2f_buf( cy_diag_tmp_fx, cy_diag_tmp_e, cy_diag_tmp[w], nchan_out_woLFE );
#else
            matrix_product_diag( dir_res_ptr, nchan_out_woLFE, 1, 0, dir_res_ptr, 1, nchan_out_woLFE, 0, cy_diag_tmp[w] );
#endif
        }

        for ( bin_idx = brange[0]; bin_idx < brange[1]; bin_idx++ )
+100 −0
Original line number Diff line number Diff line
@@ -2424,7 +2424,44 @@ static void ivas_param_mc_get_mixing_matrices(

        matrix_product( proto_matrix_ptr, nY_band, nX, 0, Cx, nX, nX, 0, mat_mult_buffer1 );

#ifdef IVAS_FLOAT_FIXED
        Word32 mat_mult_buffer1_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS];
        Word32 proto_matrix_ptr_fx[PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS];
        Word32 Cproto_diag_fx[MAX_CICP_CHANNELS];
        Word16 mat_mult_buffer1_e, proto_matrix_ptr_e, Cproto_diag_e;

        Word16 guard_bits = find_guarded_bits_fx( nY_band + 1 );

        f2me_buf( mat_mult_buffer1, mat_mult_buffer1_fx, &mat_mult_buffer1_e, nY_band * nX );
        f2me_buf( proto_matrix_ptr, proto_matrix_ptr_fx, &proto_matrix_ptr_e, nY_band * nX );

        for ( i = 0; i < nY_band * nX; ++i )
        {
            if ( mat_mult_buffer1_e > proto_matrix_ptr_e )
            {
                proto_matrix_ptr_fx[i] = L_shr( proto_matrix_ptr_fx[i], guard_bits );
            }
            else
            {
                mat_mult_buffer1_fx[i] = L_shr( mat_mult_buffer1_fx[i], guard_bits );
            }
        }

        if ( mat_mult_buffer1_e > proto_matrix_ptr_e )
        {
            proto_matrix_ptr_e += guard_bits;
        }
        else
        {
            mat_mult_buffer1_e += guard_bits;
        }

        matrix_product_diag_fx(mat_mult_buffer1_fx, mat_mult_buffer1_e, nY_band, nX, 0, proto_matrix_ptr_fx, proto_matrix_ptr_e, nY_band, nX, 1, Cproto_diag_fx,&Cproto_diag_e);

        me2f_buf(Cproto_diag_fx, Cproto_diag_e, Cproto_diag, nY_band);
#else
        matrix_product_diag( mat_mult_buffer1, nY_band, nX, 0, proto_matrix_ptr, nY_band, nX, 1, Cproto_diag );
#endif

        /* make sure we have no negative entries in Cproto_diag due to rounding errors */
        for ( ch_idx1 = 0; ch_idx1 < nY_band; ch_idx1++ )
@@ -2487,7 +2524,21 @@ static void ivas_param_mc_get_mixing_matrices(
                Cy_diag[i] = sqrtf( Cy_diag[i] / ( Cproto_diag[i] + EPSILON ) );
            }

#ifdef IVAS_FLOAT_FIXED
            Word32 Cy_diag_fx[MAX_OUTPUT_CHANNELS];
            Word32 proto_matrix_ptr_fx[PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS];
            Word32 mixing_matrix_local_fx[MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS];
            Word16 Cy_diag_e, proto_matrix_ptr_e, mixing_matrix_local_e;

            f2me_buf( Cy_diag, Cy_diag_fx, &Cy_diag_e, nY_band );
            f2me_buf( proto_matrix_ptr, proto_matrix_ptr_fx, &proto_matrix_ptr_e, nY_band * nX );

            diag_matrix_product_fx( Cy_diag_fx, Cy_diag_e, nY_band, proto_matrix_ptr_fx, proto_matrix_ptr_e, nY_band, nX, 0, mixing_matrix_local_fx, &mixing_matrix_local_e );

            me2f_buf( mixing_matrix_local_fx, mixing_matrix_local_e, mixing_matrix_local, nY_band * nX );
#else
            diag_matrix_product( Cy_diag, nY_band, proto_matrix_ptr, nY_band, nX, 0, mixing_matrix_local );
#endif
        }
        if ( remove_lfe )
        {
@@ -2547,6 +2598,14 @@ static void ivas_param_mc_get_mono_stereo_mixing_matrices(
    int16_t nY_band;
    float proto_matrix[PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS];
    uint16_t i;
#ifdef IVAS_FLOAT_FIXED
    Word32 Cy_diag_fx[MAX_OUTPUT_CHANNELS];
    Word32 proto_matrix_fx[PARAM_MC_MAX_TRANSPORT_CHANS * MAX_CICP_CHANNELS];
    Word32 mixing_matrix_woLFE_fx[MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS];
    Word32 mat_mult_buffer1_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS];
    Word32 Cproto_diag_fx[MAX_CICP_CHANNELS];
    Word16 Cy_diag_e, proto_matrix_e, mixing_matrix_woLFE_e, mat_mult_buffer1_e, Cproto_diag_e;
#endif

    set_zero( Cproto, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS );
    set_zero( mat_mult_buffer1, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS );
@@ -2618,7 +2677,39 @@ static void ivas_param_mc_get_mono_stereo_mixing_matrices(

        matrix_product( proto_matrix, nY_band, nX, 0, Cx, nX, nX, 0, mat_mult_buffer1 );

#ifdef IVAS_FLOAT_FIXED
        Word16 guard_bits = find_guarded_bits_fx( nY_band + 1 );

        f2me_buf( mat_mult_buffer1, mat_mult_buffer1_fx, &mat_mult_buffer1_e, nY_band * nX );
        f2me_buf( proto_matrix, proto_matrix_fx, &proto_matrix_e, nY_band * nX );

        for ( i = 0; i < nY_band * nX; ++i )
        {
            if ( mat_mult_buffer1_e > proto_matrix_e )
            {
                proto_matrix_fx[i] = L_shr( proto_matrix_fx[i], guard_bits );
            }
            else
            {
                mat_mult_buffer1_fx[i] = L_shr( mat_mult_buffer1_fx[i], guard_bits );
            }
        }

        if ( mat_mult_buffer1_e > proto_matrix_e )
        {
            proto_matrix_e += guard_bits;
        }
        else
        {
            mat_mult_buffer1_e += guard_bits;
        }

        matrix_product_diag_fx( mat_mult_buffer1_fx, mat_mult_buffer1_e, nY_band, nX, 0, proto_matrix_fx, proto_matrix_e, nY_band, nX, 1, Cproto_diag_fx, &Cproto_diag_e );

        me2f_buf( Cproto_diag_fx, Cproto_diag_e, Cproto_diag, nY_band );
#else
        matrix_product_diag( mat_mult_buffer1, nY_band, nX, 0, proto_matrix, nY_band, nX, 1, Cproto_diag );
#endif

        /* Computing the mixing matrices */
        for ( i = 0; i < nY_band; i++ )
@@ -2627,7 +2718,16 @@ static void ivas_param_mc_get_mono_stereo_mixing_matrices(
            Cy_diag[i] = sqrtf( Cy_diag[i] / ( Cproto_diag[i] + EPSILON ) );
        }

#ifdef IVAS_FLOAT_FIXED
        f2me_buf( Cy_diag, Cy_diag_fx, &Cy_diag_e, nY_band );
        f2me_buf( proto_matrix, proto_matrix_fx, &proto_matrix_e, nY_band * nX );

        diag_matrix_product_fx( Cy_diag_fx, Cy_diag_e, nY_band, proto_matrix_fx, proto_matrix_e, nY_band, nX, 0, mixing_matrix_woLFE_fx, &mixing_matrix_woLFE_e );

        me2f_buf( mixing_matrix_woLFE_fx, mixing_matrix_woLFE_e, mixing_matrix_woLFE, nY_band * nX );
#else
        diag_matrix_product( Cy_diag, nY_band, proto_matrix, nY_band, nX, 0, mixing_matrix_woLFE );
#endif

        mvr2r( mixing_matrix_woLFE, mixing_matrix[param_band_idx], nY_cov * nX );
        if ( hParamMC->band_grouping[param_band_idx] < hParamMC->h_output_synthesis_params.max_band_decorr )
Loading