diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 0f30198f30285cb5a3123d9c8efc78183fc4a4bd..826fbb1ae32a69f35d9ff55efc838849fb68cc89 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -4153,6 +4153,21 @@ Word16 matrix_product_fx( const Word16 transpY, /* i : flag indicating the transposition of the right hand matrix prior to the multiplication */ Word32 *Z_fx /* o : resulting matrix after the matrix multiplication */ ); + +void mat2svdMat_fx( + const Word32 *mat, /* i : matrix as column ordered vector */ + Word32 svdMat[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS], /* o : matrix as two-dimensional arry */ + const Word16 nRows, /* i : number of rows of the matrix */ + const Word16 mCols, /* i : number of columns of the matrix */ + const Word16 transpose /* i : flag indication transposition */ +); + +void svdMat2mat_fx( + Word32 svdMat[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS], /* i : matrix as two-dimensional arry */ + Word32 *mat, /* o : matrix as column ordered vector */ + const Word16 nRows, /* i : number of rows of the matrix */ + const Word16 mCols /* i : number of columns of the matrix */ +); #endif void mat2svdMat( diff --git a/lib_com/prot.h b/lib_com/prot.h index ac5462f53f53c5a81aeeb29fc34403b7eaff17d0..81b68fbeb83ec31fb34dae75c5d9cc46e3ec1306 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -190,6 +190,11 @@ void set_f( const int16_t N /* i : Lenght of the vector */ ); +void set_zero_fx( + Word32 *vec, /* o : input vector */ + const Word16 lvec /* i : length of the vector */ +); + void set_zero( float *vec, /* o : input vector */ const int16_t lvec /* i : length of the vector */ diff --git a/lib_com/tools.c b/lib_com/tools.c index 6fe347f61ded16c40a3230e919f997751bf5260b..ae1bf97afcecab30d6cab317cf715555a748fa01 100644 --- a/lib_com/tools.c +++ b/lib_com/tools.c @@ -270,8 +270,28 @@ void set_f( return; } +#ifdef IVAS_FLOAT_FIXED +/*---------------------------------------------------------------------* + * set_zero() + * + * Set a vector vec[] of dimension lvec to zero + *---------------------------------------------------------------------*/ + +void set_zero_fx( + Word32 *vec, /* o : input vector */ + const Word16 lvec /* i : length of the vector */ +) +{ + Word16 i; + FOR ( i = 0; i < lvec; i++ ) + { + *vec++ = 0; + } + return; +} +#endif /*---------------------------------------------------------------------* * set_zero() * @@ -1146,7 +1166,6 @@ void v_multc_fixed_16( return; } - /*-------------------------------------------------------------------* * squant() * diff --git a/lib_dec/ivas_dirac_output_synthesis_cov.c b/lib_dec/ivas_dirac_output_synthesis_cov.c index ea027c0b991561c0f83c88c742df5dc97c778a58..164b6225a9627956b3ed33a6a93bbb2aadc4ab35 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov.c @@ -563,7 +563,21 @@ int16_t computeMixingMatrices( float mat_mult_buffer1[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; float mat_mult_buffer2[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; float mat_mult_buffer3[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; - +#ifdef IVAS_FLOAT_FIXED + Word32 svd_in_buffer_fx[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; + Word32 mat_mult_buffer1_fx[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; + Word32 mat_mult_buffer2_fx[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; + Word32 Cx_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; + Word32 Cy_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; + Word32 svd_u_buffer_fx[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; + Word32 svd_v_buffer_fx[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; + + Word16 mat_mult_buffer1_fx_e; + Word16 Cx_fx_e; + Word16 Cy_fx_e; + Word16 svd_u_buffer_fx_e[MAX_OUTPUT_CHANNELS]; + Word16 svd_v_buffer_fx_e[MAX_OUTPUT_CHANNELS]; +#endif push_wmops( "dirac_cov_mix_mat" ); set_zero( svd_s_buffer, MAX_OUTPUT_CHANNELS ); @@ -579,8 +593,16 @@ int16_t computeMixingMatrices( *-----------------------------------------------------------------*/ /* Processing the SVD */ +#ifdef IVAS_FLOAT_FIXED + f2me_buf( Cy, Cy_fx, &Cy_fx_e, lengthCy * lengthCy ); + mat2svdMat_fx( Cy_fx, svd_in_buffer_fx, lengthCy, lengthCy, 0 ); + FOR ( Word32 g = 0; g < lengthCy; g++ ) + { + me2f_buf( ( svd_in_buffer_fx[g] ), Cy_fx_e, ( svd_in_buffer[g] ), lengthCy ); + } +#else mat2svdMat( Cy, svd_in_buffer, lengthCy, lengthCy, 0 ); - +#endif svd( svd_in_buffer, svd_u_buffer, svd_s_buffer, svd_v_buffer, lengthCy, lengthCy ); /* Computing Ky */ @@ -597,7 +619,17 @@ int16_t computeMixingMatrices( *-----------------------------------------------------------------*/ /* Processing the SVD */ + +#ifdef IVAS_FLOAT_FIXED + f2me_buf( Cx, Cx_fx, &Cx_fx_e, lengthCx * lengthCx ); + mat2svdMat_fx( Cx_fx, svd_in_buffer_fx, lengthCx, lengthCx, 0 ); + FOR ( Word32 g = 0; g < lengthCx; g++ ) + { + me2f_buf( ( svd_in_buffer_fx[g] ), Cx_fx_e, ( svd_in_buffer[g] ), lengthCx ); + } +#else mat2svdMat( Cx, svd_in_buffer, lengthCx, lengthCx, 0 ); +#endif svd( svd_in_buffer, svd_u_buffer, svd_s_buffer, svd_v_buffer, lengthCx, lengthCx ); @@ -718,8 +750,6 @@ int16_t computeMixingMatrices( /* Computing the input matrix Kx'*Q'*G_hat'*Ky */ matrix_product( Kx, lengthCx, lengthCx, 1, Q, lengthCy, lengthCx, 1, mat_mult_buffer1 ); #ifdef IVAS_FLOAT_FIXED - Word32 mat_mult_buffer1_fx[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; - Word32 mat_mult_buffer2_fx[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; Word32 G_hat_fx[MAX_OUTPUT_CHANNELS]; Word16 mat_mult_buffer1_e, mat_mult_buffer2_e, G_hat_e; @@ -736,7 +766,16 @@ int16_t computeMixingMatrices( if ( lengthCx < lengthCy ) { +#ifdef IVAS_FLOAT_FIXED + f2me_buf( mat_mult_buffer1, mat_mult_buffer1_fx, &mat_mult_buffer1_fx_e, lengthCx * lengthCy ); + mat2svdMat_fx( mat_mult_buffer1_fx, svd_in_buffer_fx, lengthCx, lengthCy, 1 ); + FOR ( Word32 g = 0; g < lengthCy; g++ ) + { + me2f_buf( ( svd_in_buffer_fx[g] ), mat_mult_buffer1_fx_e, ( svd_in_buffer[g] ), lengthCx ); + } +#else mat2svdMat( mat_mult_buffer1, svd_in_buffer, lengthCx, lengthCy, 1 ); +#endif nL = lengthCy; nC = lengthCx; @@ -745,7 +784,17 @@ int16_t computeMixingMatrices( } else { +#ifdef IVAS_FLOAT_FIXED + f2me_buf( mat_mult_buffer1, mat_mult_buffer1_fx, &mat_mult_buffer1_fx_e, lengthCx * lengthCy ); + mat2svdMat_fx( mat_mult_buffer1_fx, svd_in_buffer_fx, lengthCx, lengthCy, 0 ); + FOR ( Word32 g = 0; g < lengthCx; g++ ) + { + me2f_buf( ( svd_in_buffer_fx[g] ), mat_mult_buffer1_fx_e, ( svd_in_buffer[g] ), lengthCy ); + } +#else mat2svdMat( mat_mult_buffer1, svd_in_buffer, lengthCx, lengthCy, 0 ); +#endif + nL = lengthCx; nC = lengthCy; @@ -758,8 +807,53 @@ int16_t computeMixingMatrices( /* can be skipped: lambda is always column-truncated identity matrix, so this operation just truncates V to num_input_channel columns */ +#ifdef IVAS_FLOAT_FIXED + Word16 min_q = -1; + FOR ( Word32 g = 0; g < lengthCy; g++ ) + { + f2me_buf( svd_v_buffer[g], svd_v_buffer_fx[g], &svd_v_buffer_fx_e[g], lengthCx ); + IF ( svd_v_buffer_fx_e[g] > min_q) + { + min_q = svd_v_buffer_fx_e[g]; + } + } + + FOR ( Word32 g = 0; g < lengthCy; g++ ) + { + FOR ( Word32 h = 0; h < lengthCx; h++ ) + { + svd_v_buffer_fx[g][h] = L_shr( svd_v_buffer_fx[g][h], min_q - svd_v_buffer_fx_e[g] ); + } + } + svd_v_buffer_fx_e[0] = min_q; + + min_q = -1; + FOR ( Word32 g = 0; g < lengthCx; g++ ) + { + f2me_buf( svd_u_buffer[g], svd_u_buffer_fx[g], &svd_u_buffer_fx_e[g], lengthCx ); + IF ( svd_u_buffer_fx_e[g] > min_q ) + { + min_q = svd_u_buffer_fx_e[g]; + } + } + + FOR ( Word32 g = 0; g < lengthCx; g++ ) + { + FOR ( Word32 h = 0; h < lengthCx; h++ ) + { + svd_u_buffer_fx[g][h] = L_shr( svd_u_buffer_fx[g][h], min_q - svd_u_buffer_fx_e[g] ); + } + } + svd_u_buffer_fx_e[0] = min_q; + svdMat2mat_fx( svd_v_buffer_fx, mat_mult_buffer1_fx, lengthCy, lengthCx ); + svdMat2mat_fx( svd_u_buffer_fx, mat_mult_buffer2_fx, lengthCx, lengthCx ); + + me2f_buf( mat_mult_buffer1_fx, svd_v_buffer_fx_e[0], mat_mult_buffer1, lengthCy * lengthCx ); + me2f_buf( mat_mult_buffer2_fx, svd_u_buffer_fx_e[0], mat_mult_buffer2, lengthCx * lengthCx ); +#else svdMat2mat( svd_v_buffer, mat_mult_buffer1, lengthCy, lengthCx ); svdMat2mat( svd_u_buffer, mat_mult_buffer2, lengthCx, lengthCx ); +#endif matrix_product( mat_mult_buffer1, lengthCy, lengthCx, 0, mat_mult_buffer2, lengthCx, lengthCx, 1, @@ -881,7 +975,18 @@ int16_t computeMixingMatricesResidual( float mat_mult_buffer1[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; float mat_mult_buffer2[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; float mat_mult_buffer3[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; - +#ifdef IVAS_FLOAT_FIXED + Word32 svd_in_buffer_fx[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; + Word32 mat_mult_buffer2_fx[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; + Word32 Cy_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; + Word32 svd_u_buffer_fx[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; + Word32 svd_v_buffer_fx[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; + + Word16 mat_mult_buffer1_fx_e; + Word16 Cy_fx_e; + Word16 svd_u_buffer_fx_e[MAX_OUTPUT_CHANNELS]; + Word16 svd_v_buffer_fx_e[MAX_OUTPUT_CHANNELS]; +#endif push_wmops( "dirac_cov_mix_mat_r" ); #ifdef IVAS_FLOAT_FIXED @@ -900,7 +1005,18 @@ int16_t computeMixingMatricesResidual( /* Processing the SVD */ /* linear array to svd buffer */ +#ifdef IVAS_FLOAT_FIXED + f2me_buf( Cy, Cy_fx, &Cy_fx_e, lengthCy * lengthCy ); + mat2svdMat_fx( Cy_fx, svd_in_buffer_fx, lengthCy, lengthCy, 0 ); + + FOR ( Word32 g = 0; g < lengthCy; g++ ) + { + me2f_buf( ( svd_in_buffer_fx[g] ), Cy_fx_e, ( svd_in_buffer[g] ), lengthCy ); + } +#else mat2svdMat( Cy, svd_in_buffer, lengthCy, lengthCy, 0 ); +#endif + svd( svd_in_buffer, svd_u_buffer, svd_s_buffer, svd_v_buffer, lengthCy, lengthCy ); @@ -993,14 +1109,71 @@ int16_t computeMixingMatricesResidual( } } +#ifdef IVAS_FLOAT_FIXED + f2me_buf( mat_mult_buffer1, mat_mult_buffer1_fx, &mat_mult_buffer1_fx_e, lengthCx * lengthCy ); + mat2svdMat_fx( mat_mult_buffer1_fx, svd_in_buffer_fx, lengthCx, lengthCy, 0 ); + + FOR ( Word32 g = 0; g < lengthCx; g++ ) + { + me2f_buf( ( svd_in_buffer_fx[g] ), mat_mult_buffer1_fx_e, ( svd_in_buffer[g] ), lengthCy ); + } +#else mat2svdMat( mat_mult_buffer1, svd_in_buffer, lengthCx, lengthCy, 0 ); +#endif + svd( svd_in_buffer, svd_u_buffer, svd_s_buffer, svd_v_buffer, lengthCx, lengthCy ); /* Actually Processing P */ + +#ifdef IVAS_FLOAT_FIXED + Word16 min_q = -1; + FOR ( Word32 g = 0; g < lengthCy; g++ ) + { + f2me_buf( svd_v_buffer[g], svd_v_buffer_fx[g], &svd_v_buffer_fx_e[g], lengthCx ); + IF ( svd_v_buffer_fx_e[g] > min_q ) + { + min_q = svd_v_buffer_fx_e[g]; + } + } + + FOR ( Word32 g = 0; g < lengthCy; g++ ) + { + FOR ( Word32 h = 0; h < lengthCx; h++ ) + { + svd_v_buffer_fx[g][h] = L_shr( svd_v_buffer_fx[g][h], min_q - svd_v_buffer_fx_e[g] ); + } + } + svd_v_buffer_fx_e[0] = min_q; + + min_q = -1; + FOR ( Word32 g = 0; g < lengthCx; g++ ) + { + f2me_buf( svd_u_buffer[g], svd_u_buffer_fx[g], &svd_u_buffer_fx_e[g], lengthCx ); + IF ( svd_u_buffer_fx_e[g] > min_q ) + { + min_q = svd_u_buffer_fx_e[g]; + } + } + + FOR ( Word32 g = 0; g < lengthCx; g++ ) + { + FOR ( Word32 h = 0; h < lengthCx; h++ ) + { + svd_u_buffer_fx[g][h] = L_shr( svd_u_buffer_fx[g][h], min_q - svd_u_buffer_fx_e[g] ); + } + } + svd_u_buffer_fx_e[0] = min_q; + + svdMat2mat_fx( svd_v_buffer_fx, mat_mult_buffer1_fx, lengthCy, lengthCx ); + svdMat2mat_fx( svd_u_buffer_fx, mat_mult_buffer2_fx, lengthCx, lengthCx ); + + me2f_buf( mat_mult_buffer1_fx, svd_v_buffer_fx_e[0], mat_mult_buffer1, lengthCy * lengthCx ); + me2f_buf( mat_mult_buffer2_fx, svd_u_buffer_fx_e[0], mat_mult_buffer2, lengthCx * lengthCx ); +#else svdMat2mat( svd_v_buffer, mat_mult_buffer1, lengthCy, lengthCx ); svdMat2mat( svd_u_buffer, mat_mult_buffer2, lengthCx, lengthCx ); - +#endif matrix_product( mat_mult_buffer1, lengthCy, lengthCx, 0, mat_mult_buffer2, lengthCx, lengthCx, 1, mat_mult_buffer3 ); @@ -1156,8 +1329,15 @@ int16_t computeMixingMatricesISM( Word32 mat_mult_buffer3_fx[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; Word32 Kx_fx[MAX_TRANSPORT_CHANNELS]; Word16 responses_e, ener_e, Ky_e, Q_e, Cx_diag_e, Q_Cx_e, mat_mult_buffer1_e, G_hat_e, mat_mult_buffer2_e, Kx_reg_inv_e, mixing_matrix_e, adj_e, mat_mult_buffer3_e, Kx_e; -#endif + Word32 svd_in_buffer_fx[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; + Word32 svd_u_buffer_fx[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; + Word32 svd_v_buffer_fx[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; + + Word16 mat_mult_buffer1_fx_e; + Word16 svd_u_buffer_fx_e[MAX_OUTPUT_CHANNELS]; + Word16 svd_v_buffer_fx_e[MAX_OUTPUT_CHANNELS]; +#endif push_wmops( "dirac_cov_mix_mat" ); out = EXIT_SUCCESS; @@ -1293,14 +1473,37 @@ int16_t computeMixingMatricesISM( if ( lengthCx < num_responses ) { + +#ifdef IVAS_FLOAT_FIXED + f2me_buf( mat_mult_buffer1, mat_mult_buffer1_fx, &mat_mult_buffer1_fx_e, lengthCx * num_responses ); + mat2svdMat_fx( mat_mult_buffer1_fx, svd_in_buffer_fx, lengthCx, num_responses, 1 ); + + FOR ( Word32 g = 0; g < num_responses; g++ ) + { + me2f_buf( ( svd_in_buffer_fx[g] ), mat_mult_buffer1_fx_e, ( svd_in_buffer[g] ), lengthCx ); + } +#else mat2svdMat( mat_mult_buffer1, svd_in_buffer, lengthCx, num_responses, 1 ); +#endif + nL = num_responses; nC = lengthCx; svd( svd_in_buffer, svd_v_buffer, svd_s_buffer, svd_u_buffer, nL, nC ); } else { +#ifdef IVAS_FLOAT_FIXED + f2me_buf( mat_mult_buffer1, mat_mult_buffer1_fx, &mat_mult_buffer1_fx_e, lengthCx * num_responses ); + mat2svdMat_fx( mat_mult_buffer1_fx, svd_in_buffer_fx, lengthCx, num_responses, 0 ); + + FOR ( Word32 g = 0; g < lengthCx; g++ ) + { + me2f_buf( ( svd_in_buffer_fx[g] ), mat_mult_buffer1_fx_e, ( svd_in_buffer[g] ), num_responses ); + } +#else mat2svdMat( mat_mult_buffer1, svd_in_buffer, lengthCx, num_responses, 0 ); +#endif + nL = lengthCx; nC = num_responses; svd( svd_in_buffer, svd_u_buffer, svd_s_buffer, svd_v_buffer, nL, nC ); @@ -1309,9 +1512,53 @@ int16_t computeMixingMatricesISM( /* Actually Processing P */ /* can be skipped: lambda is always column-truncated identity matrix, so this operation just truncates V to num_input_channel columns */ +#ifdef IVAS_FLOAT_FIXED + Word16 min_q = -1; + FOR ( Word32 g = 0; g < num_responses; g++ ) + { + f2me_buf( svd_v_buffer[g], svd_v_buffer_fx[g], &svd_v_buffer_fx_e[g], lengthCx ); + IF ( svd_v_buffer_fx_e[g] > min_q ) + { + min_q = svd_v_buffer_fx_e[g]; + } + } + + FOR ( Word32 g = 0; g < num_responses; g++ ) + { + FOR ( Word32 h = 0; h < lengthCx; h++ ) + { + svd_v_buffer_fx[g][h] = L_shr( svd_v_buffer_fx[g][h], min_q - svd_v_buffer_fx_e[g] ); + } + } + svd_v_buffer_fx_e[0] = min_q; + + min_q = -1; + FOR ( Word32 g = 0; g < lengthCx; g++ ) + { + f2me_buf( svd_u_buffer[g], svd_u_buffer_fx[g], &svd_u_buffer_fx_e[g], lengthCx ); + IF ( svd_u_buffer_fx_e[g] > min_q ) + { + min_q = svd_u_buffer_fx_e[g]; + } + } + + FOR ( Word32 g = 0; g < lengthCx; g++ ) + { + FOR ( Word32 h = 0; h < lengthCx; h++ ) + { + svd_u_buffer_fx[g][h] = L_shr( svd_u_buffer_fx[g][h], min_q - svd_u_buffer_fx_e[g] ); + } + } + svd_u_buffer_fx_e[0] = min_q; + svdMat2mat_fx( svd_v_buffer_fx, mat_mult_buffer1_fx, num_responses, lengthCx ); + svdMat2mat_fx( svd_u_buffer_fx, mat_mult_buffer2_fx, lengthCx, lengthCx ); + + me2f_buf( mat_mult_buffer1_fx, svd_v_buffer_fx_e[0], mat_mult_buffer1, num_responses * lengthCx ); + me2f_buf( mat_mult_buffer2_fx, svd_u_buffer_fx_e[0], mat_mult_buffer2, lengthCx * lengthCx ); +#else svdMat2mat( svd_v_buffer, mat_mult_buffer1, num_responses, lengthCx ); svdMat2mat( svd_u_buffer, mat_mult_buffer2, lengthCx, lengthCx ); - +#endif matrix_product( mat_mult_buffer1, num_responses, lengthCx, 0, mat_mult_buffer2, lengthCx, lengthCx, 1, mat_mult_buffer3 ); /************************ Formulate M **********************/ diff --git a/lib_dec/ivas_svd_dec.c b/lib_dec/ivas_svd_dec.c index d294af20e87765c7c49353c1089a930bcae2e327..eb1f7e16bc0de9a0ed3a5a3b3dafaaa798c2e315 100644 --- a/lib_dec/ivas_svd_dec.c +++ b/lib_dec/ivas_svd_dec.c @@ -79,6 +79,88 @@ static void flushToZeroArray( float arr[MAX_OUTPUT_CHANNELS], const int16_t leng static void flushToZeroMat( float mat[][MAX_OUTPUT_CHANNELS], const int16_t m, const int16_t n ); +#ifdef IVAS_FLOAT_FIXED +/*------------------------------------------------------------------------- + * mat2svdMat() + * + * external matrix format to internal + *-------------------------------------------------------------------------*/ + +void mat2svdMat_fx( + const Word32 *mat, /* i : matrix as column ordered vector */ + Word32 svdMat[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS], /* o : matrix as two-dimensional arry */ + const Word16 nRows, /* i : number of rows of the matrix */ + const Word16 mCols, /* i : number of columns of the matrix */ + const Word16 transpose /* i : flag indication transposition */ +) +{ + Word16 i, j; + + IF ( transpose ) + { + FOR ( i = 0; i < mCols; i++ ) + { + FOR ( j = 0; j < nRows; j++ ) + { + svdMat[i][j] = mat[j + nRows * i]; + } + + set_zero_fx( &svdMat[i][mCols], MAX_OUTPUT_CHANNELS - nRows ); + } + + FOR ( ; i < MAX_OUTPUT_CHANNELS; i++ ) + { + set_zero_fx( svdMat[i], MAX_OUTPUT_CHANNELS ); + } + } + ELSE + { + FOR ( i = 0; i < nRows; i++ ) + { + FOR ( j = 0; j < mCols; j++ ) + { + svdMat[i][j] = mat[i + nRows * j]; + } + + set_zero_fx( &svdMat[i][mCols], MAX_OUTPUT_CHANNELS - mCols ); + } + + FOR ( ; i < MAX_OUTPUT_CHANNELS; i++ ) + { + set_zero_fx( svdMat[i], MAX_OUTPUT_CHANNELS ); + } + } + + return; +} + + +/*---------------------------------------------------------------------* + * svdMat2mat() + * + * transfer a matrix from a two dimensional array to a column wise ordered vector + *---------------------------------------------------------------------*/ + +void svdMat2mat_fx( + Word32 svdMat[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS], /* i : matrix as two-dimensional arry */ + Word32 *mat, /* o : matrix as column ordered vector */ + const Word16 nRows, /* i : number of rows of the matrix */ + const Word16 mCols /* i : number of columns of the matrix */ +) +{ + Word16 i, j; + + FOR ( i = 0; i < nRows; i++ ) + { + FOR ( j = 0; j < mCols; j++ ) + { + mat[i + nRows * j] = svdMat[i][j]; + } + } + + return; +} +#endif /*------------------------------------------------------------------------- * mat2svdMat()