Loading lib_com/basop32.c +8 −0 Original line number Diff line number Diff line Loading @@ -3577,12 +3577,20 @@ Word16 div_l( Word32 L_num, Word16 den ) if ( den == (Word16) 0 ) { #ifdef IVAS_FLOAT_FIXED /* NOTE: This is just for temporary usage for identifying crashes */ assert( 0 ); #endif // IVAS_FLOAT_FIXED /* printf("Division by 0 in div_l, Fatal error in "); printStack(); */ exit( -1 ); } if ( ( L_num < (Word32) 0 ) || ( den < (Word16) 0 ) ) { #ifdef IVAS_FLOAT_FIXED /* NOTE: This is just for temporary usage for identifying crashes */ assert( 0 ); #endif // IVAS_FLOAT_FIXED /* printf("Division Error in div_l, Fatal error in "); printStack(); */ exit( -1 ); } Loading lib_com/common_api_types.h +1 −0 Original line number Diff line number Diff line Loading @@ -255,4 +255,5 @@ typedef struct _IVAS_RENDER_CONFIG #endif } IVAS_RENDER_CONFIG_DATA, *IVAS_RENDER_CONFIG_HANDLE; #endif /* COMMON_API_TYPES_H */ lib_com/ivas_prot.h +11 −0 Original line number Diff line number Diff line Loading @@ -4924,6 +4924,17 @@ Word16 computeMixingMatricesResidual_fx( ); #endif /*! r: error or success */ Word16 svd_fx( Word32 InputMatrix[][MAX_OUTPUT_CHANNELS], /* i : matrix to be decomposed (M) */ Word16 InputMatrix_e, float singularVectors_Left[][MAX_OUTPUT_CHANNELS], /* o : left singular vectors (U) */ float singularValues[MAX_OUTPUT_CHANNELS], /* o : singular values vector (S) */ float singularVectors_Right[][MAX_OUTPUT_CHANNELS], /* o : right singular vectors (V) */ const Word16 nChannelsL, /* i : number of rows in the matrix to be decomposed */ const Word16 nChannelsC /* i : number of columns in the matrix to be decomposed */ ); /*! r: error or success */ int16_t svd( float InputMatrix[][MAX_OUTPUT_CHANNELS], /* i : matrix to be decomposed (M) */ Loading lib_dec/ivas_dirac_output_synthesis_cov.c +201 −24 Original line number Diff line number Diff line Loading @@ -1645,12 +1645,12 @@ Word16 computeMixingMatrices_fx( /* Processing the SVD */ mat2svdMat_fx( Cy_fx, svd_in_buffer_fx, lengthCy, lengthCy, 0 ); FOR ( Word32 g = 0; g < lengthCy; g++ ) /*FOR ( Word32 g = 0; g < lengthCy; g++ ) { me2f_buf( ( svd_in_buffer_fx[g] ), Cy_fx_e, ( svd_in_buffer[g] ), lengthCy ); } }*/ svd( svd_in_buffer, svd_u_buffer, svd_s_buffer, svd_v_buffer, lengthCy, lengthCy ); svd_fx(svd_in_buffer_fx, Cy_fx_e, svd_u_buffer, svd_s_buffer, svd_v_buffer, lengthCy, lengthCy ); f2me_buf(svd_s_buffer, svd_s_buffer_fx, &svd_s_buffer_fx_e, lengthCy); FOR(Word32 g = 0; g < lengthCy; g++) Loading Loading @@ -1695,13 +1695,13 @@ Word16 computeMixingMatrices_fx( /* Processing the SVD */ mat2svdMat_fx( Cx_fx, svd_in_buffer_fx, lengthCx, lengthCx, 0 ); FOR ( Word32 g = 0; g < lengthCx; g++ ) /*FOR ( Word32 g = 0; g < lengthCx; g++ ) { me2f_buf( ( svd_in_buffer_fx[g] ), Cx_fx_e, ( svd_in_buffer[g] ), lengthCx ); } }*/ svd( svd_in_buffer, svd_u_buffer, svd_s_buffer, svd_v_buffer, lengthCx, lengthCx ); svd_fx( svd_in_buffer_fx, Cx_fx_e, svd_u_buffer, svd_s_buffer, svd_v_buffer, lengthCx, lengthCx ); f2me_buf(svd_s_buffer, svd_s_buffer_fx, &svd_s_buffer_fx_e, lengthCx); FOR(Word32 g = 0; g < lengthCy; g++) { Loading Loading @@ -1937,17 +1937,17 @@ Word16 computeMixingMatrices_fx( mat2svdMat_fx( mat_mult_buffer1_fx, svd_in_buffer_fx, lengthCx, lengthCy, 1 ); #ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED FOR ( Word32 g = 0; g < lengthCy; g++ ) /*FOR ( Word32 g = 0; g < lengthCy; g++ ) { me2f_buf( ( svd_in_buffer_fx[g] ), mat_mult_buffer1_e, ( svd_in_buffer[g] ), lengthCx ); } }*/ nL = lengthCy; move16(); nC = lengthCx; move16(); svd( svd_in_buffer, svd_v_buffer, svd_s_buffer, svd_u_buffer, nL, nC ); svd_fx(svd_in_buffer_fx, mat_mult_buffer1_e, svd_v_buffer, svd_s_buffer, svd_u_buffer, nL, nC ); #endif } ELSE Loading @@ -1965,7 +1965,7 @@ Word16 computeMixingMatrices_fx( nC = lengthCy; move16(); svd( svd_in_buffer, svd_u_buffer, svd_s_buffer, svd_v_buffer, nL, nC ); svd_fx( svd_in_buffer_fx, mat_mult_buffer1_e, svd_u_buffer, svd_s_buffer, svd_v_buffer, nL, nC ); #endif } Loading Loading @@ -2395,7 +2395,7 @@ Word16 computeMixingMatricesResidual_fx( Word16 lengthCy = extract_l(num_outputs); #ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED float svd_in_buffer[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; //float svd_in_buffer[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; float svd_u_buffer[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; float svd_s_buffer[MAX_OUTPUT_CHANNELS]; float svd_v_buffer[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; Loading Loading @@ -2460,12 +2460,12 @@ Word16 computeMixingMatricesResidual_fx( mat2svdMat_fx( Cy_fx, svd_in_buffer_fx, lengthCy, lengthCy, 0 ); #ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED FOR ( Word32 g = 0; g < lengthCy; g++ ) /*FOR ( Word32 g = 0; g < lengthCy; g++ ) { me2f_buf( ( svd_in_buffer_fx[g] ), Cy_fx_e, ( svd_in_buffer[g] ), lengthCy ); } }*/ svd(svd_in_buffer, svd_u_buffer, svd_s_buffer, svd_v_buffer, lengthCy, lengthCy); svd_fx( svd_in_buffer_fx, Cy_fx_e, svd_u_buffer, svd_s_buffer, svd_v_buffer, lengthCy, lengthCy ); f2me_buf(svd_s_buffer, svd_s_buffer_fx, &svd_s_buffer_fx_e, lengthCy); FOR(Word32 g = 0; g < lengthCy; g++) { Loading Loading @@ -2677,13 +2677,13 @@ Word16 computeMixingMatricesResidual_fx( mat2svdMat_fx( mat_mult_buffer1_fx, svd_in_buffer_fx, lengthCx, lengthCy, 0 ); FOR ( Word32 g = 0; g < lengthCx; g++ ) /*FOR ( Word32 g = 0; g < lengthCx; g++ ) { me2f_buf( ( svd_in_buffer_fx[g] ), mat_mult_buffer1_e, ( svd_in_buffer[g] ), lengthCy ); } }*/ #ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED svd( svd_in_buffer, svd_u_buffer, svd_s_buffer, svd_v_buffer, lengthCx, lengthCy ); svd_fx( svd_in_buffer_fx, mat_mult_buffer1_e, svd_u_buffer, svd_s_buffer, svd_v_buffer, lengthCx, lengthCy ); /* Actually Processing P */ Word16 min_q = -1; Loading Loading @@ -2866,7 +2866,7 @@ Word16 computeMixingMatricesResidual_fx( * * *-------------------------------------------------------------------*/ #ifdef IVAS_FLOAT_FIXED int16_t computeMixingMatricesISM( const int16_t num_inputs, const int16_t num_responses, Loading Loading @@ -3066,17 +3066,17 @@ int16_t computeMixingMatricesISM( 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++ ) /*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 ); svd_fx( svd_in_buffer_fx, mat_mult_buffer1_fx_e, svd_v_buffer, svd_s_buffer, svd_u_buffer, nL, nC ); } else { Loading @@ -3084,17 +3084,17 @@ int16_t computeMixingMatricesISM( 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++ ) /*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 ); svd_fx(svd_in_buffer_fx, mat_mult_buffer1_fx_e, svd_u_buffer, svd_s_buffer, svd_v_buffer, nL, nC ); } /* Actually Processing P */ Loading Loading @@ -3219,3 +3219,180 @@ int16_t computeMixingMatricesISM( return out; } #else int16_t computeMixingMatricesISM( const int16_t num_inputs, const int16_t num_responses, const int16_t num_outputs, const float *responses, const float *ener, const float *Cx_diag, const float *Cy_diag, const float *Q, const int16_t energy_compensation_flag, const float reg_Sx, const float reg_ghat, float *mixing_matrix ) { int16_t i, out; int16_t lengthCx, lengthCy; float *Cy_tilde_p; float *adj; float limit; float svd_in_buffer[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; float svd_u_buffer[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; float svd_s_buffer[MAX_OUTPUT_CHANNELS]; float svd_v_buffer[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; float Kx[MAX_TRANSPORT_CHANNELS]; float Ky[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; float Kx_reg_inv[MAX_TRANSPORT_CHANNELS]; float Q_Cx[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; float Cy_hat_diag[MAX_OUTPUT_CHANNELS]; float G_hat[MAX_OUTPUT_CHANNELS]; 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]; int16_t nL, nC; push_wmops( "dirac_cov_mix_mat" ); out = EXIT_SUCCESS; lengthCx = num_inputs; lengthCy = num_outputs; set_zero( svd_s_buffer, MAX_OUTPUT_CHANNELS ); for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) { set_zero( svd_in_buffer[i], MAX_OUTPUT_CHANNELS ); set_zero( svd_u_buffer[i], MAX_OUTPUT_CHANNELS ); set_zero( svd_v_buffer[i], MAX_OUTPUT_CHANNELS ); } /* Decomposition of Cy = Ky*Ky' */ /* Ky = responses*diag(ener) */ matrix_diag_product( responses, lengthCy, num_responses, 0, ener, num_responses, Ky ); /* Decomposition of Cx -> Computing Kx */ v_sqrt( Cx_diag, Kx, lengthCx ); /* Regularization of Sx */ maximum( Kx, lengthCx, &limit ); limit = limit * reg_Sx + EPSILON; for ( i = 0; i < lengthCx; ++i ) { svd_s_buffer[i] = ( ( Kx[i] > limit ) ? Kx[i] : limit ); } limit = 0.0f; /* regularized Kx-1 */ for ( i = 0; i < lengthCx; ++i ) { float reg_fac = ( 1.0f / svd_s_buffer[i] ); Kx_reg_inv[i] = reg_fac; } /************************ normalization matrix G hat **********************/ /* Computing Q*Cx*Q' */ matrix_diag_product( Q, lengthCy, lengthCx, 0, Cx_diag, lengthCx, Q_Cx ); matrix_product_diag( Q_Cx, lengthCy, lengthCx, 0, Q, lengthCy, lengthCx, 1, Cy_hat_diag ); /* Computing Cy_hat_diag */ for ( i = 0; i < lengthCy; ++i ) { if ( Cy_hat_diag[i] > limit ) { limit = Cy_hat_diag[i]; } } limit = limit * reg_ghat + EPSILON; /* Computing G_hat */ for ( i = 0; i < lengthCy; ++i ) { if ( limit > Cy_hat_diag[i] ) /* Computing Cy_hat_diag = max(Cy_hat_diag,limit) */ { Cy_hat_diag[i] = limit; } G_hat[i] = sqrtf( Cy_diag[i] / Cy_hat_diag[i] ); } /************************ Formulate optimal P **********************/ /* Computing the input matrix Kx'*Q'*G_hat'*Ky */ diag_matrix_product( Kx, lengthCx, Q, lengthCy, lengthCx, 1, mat_mult_buffer1 ); matrix_diag_product( mat_mult_buffer1, lengthCx, lengthCy, 0, G_hat, lengthCy, mat_mult_buffer2 ); matrix_product( mat_mult_buffer2, lengthCx, lengthCy, 0, Ky, lengthCy, num_responses, 0, mat_mult_buffer1 ); if ( lengthCx < num_responses ) { mat2svdMat( mat_mult_buffer1, svd_in_buffer, lengthCx, num_responses, 1 ); nL = num_responses; nC = lengthCx; svd( svd_in_buffer, svd_v_buffer, svd_s_buffer, svd_u_buffer, nL, nC ); } else { mat2svdMat( mat_mult_buffer1, svd_in_buffer, lengthCx, num_responses, 0 ); nL = lengthCx; nC = num_responses; svd( svd_in_buffer, svd_u_buffer, svd_s_buffer, svd_v_buffer, nL, nC ); } /* Actually Processing P */ /* can be skipped: lambda is always column-truncated identity matrix, so this operation just truncates V to num_input_channel columns */ svdMat2mat( svd_v_buffer, mat_mult_buffer1, num_responses, lengthCx ); svdMat2mat( svd_u_buffer, mat_mult_buffer2, lengthCx, lengthCx ); matrix_product( mat_mult_buffer1, num_responses, lengthCx, 0, mat_mult_buffer2, lengthCx, lengthCx, 1, mat_mult_buffer3 ); /************************ Formulate M **********************/ matrix_product( Ky, lengthCy, num_responses, 0, mat_mult_buffer3, num_responses, lengthCx, 0, mat_mult_buffer1 ); matrix_diag_product( mat_mult_buffer1, lengthCy, lengthCx, 0, Kx_reg_inv, lengthCx, mixing_matrix ); /*********************** Energy Compensation ****************/ /* Compute Cy_tilde = M*Cx*M' */ matrix_diag_product( mixing_matrix, lengthCy, lengthCx, 0, Cx_diag, lengthCx, mat_mult_buffer1 ); matrix_product( mat_mult_buffer1, lengthCy, lengthCx, 0, mixing_matrix, lengthCy, lengthCx, 1, mat_mult_buffer2 ); if ( energy_compensation_flag == 1 ) { adj = svd_s_buffer; Cy_tilde_p = mat_mult_buffer2; for ( i = 0; i < lengthCy; ++i ) { /* Avoid correction for very small energies, main diagonal elements of Cy_tilde_p may be negative */ if ( Cy_tilde_p[i + i * lengthCy] < 0.0f ) { adj[i] = 1.0f; } else { adj[i] = sqrtf( Cy_diag[i] / ( Cy_tilde_p[i + i * lengthCy] + EPSILON ) ); } if ( adj[i] > 4.0f ) { adj[i] = 4.0f; } } diag_matrix_product( adj, lengthCy, mixing_matrix, lengthCy, lengthCx, 0, mat_mult_buffer3 ); mvr2r( mat_mult_buffer3, mixing_matrix, lengthCy * lengthCx ); } pop_wmops(); return out; } #endif No newline at end of file lib_dec/ivas_svd_dec.c +341 −0 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
lib_com/basop32.c +8 −0 Original line number Diff line number Diff line Loading @@ -3577,12 +3577,20 @@ Word16 div_l( Word32 L_num, Word16 den ) if ( den == (Word16) 0 ) { #ifdef IVAS_FLOAT_FIXED /* NOTE: This is just for temporary usage for identifying crashes */ assert( 0 ); #endif // IVAS_FLOAT_FIXED /* printf("Division by 0 in div_l, Fatal error in "); printStack(); */ exit( -1 ); } if ( ( L_num < (Word32) 0 ) || ( den < (Word16) 0 ) ) { #ifdef IVAS_FLOAT_FIXED /* NOTE: This is just for temporary usage for identifying crashes */ assert( 0 ); #endif // IVAS_FLOAT_FIXED /* printf("Division Error in div_l, Fatal error in "); printStack(); */ exit( -1 ); } Loading
lib_com/common_api_types.h +1 −0 Original line number Diff line number Diff line Loading @@ -255,4 +255,5 @@ typedef struct _IVAS_RENDER_CONFIG #endif } IVAS_RENDER_CONFIG_DATA, *IVAS_RENDER_CONFIG_HANDLE; #endif /* COMMON_API_TYPES_H */
lib_com/ivas_prot.h +11 −0 Original line number Diff line number Diff line Loading @@ -4924,6 +4924,17 @@ Word16 computeMixingMatricesResidual_fx( ); #endif /*! r: error or success */ Word16 svd_fx( Word32 InputMatrix[][MAX_OUTPUT_CHANNELS], /* i : matrix to be decomposed (M) */ Word16 InputMatrix_e, float singularVectors_Left[][MAX_OUTPUT_CHANNELS], /* o : left singular vectors (U) */ float singularValues[MAX_OUTPUT_CHANNELS], /* o : singular values vector (S) */ float singularVectors_Right[][MAX_OUTPUT_CHANNELS], /* o : right singular vectors (V) */ const Word16 nChannelsL, /* i : number of rows in the matrix to be decomposed */ const Word16 nChannelsC /* i : number of columns in the matrix to be decomposed */ ); /*! r: error or success */ int16_t svd( float InputMatrix[][MAX_OUTPUT_CHANNELS], /* i : matrix to be decomposed (M) */ Loading
lib_dec/ivas_dirac_output_synthesis_cov.c +201 −24 Original line number Diff line number Diff line Loading @@ -1645,12 +1645,12 @@ Word16 computeMixingMatrices_fx( /* Processing the SVD */ mat2svdMat_fx( Cy_fx, svd_in_buffer_fx, lengthCy, lengthCy, 0 ); FOR ( Word32 g = 0; g < lengthCy; g++ ) /*FOR ( Word32 g = 0; g < lengthCy; g++ ) { me2f_buf( ( svd_in_buffer_fx[g] ), Cy_fx_e, ( svd_in_buffer[g] ), lengthCy ); } }*/ svd( svd_in_buffer, svd_u_buffer, svd_s_buffer, svd_v_buffer, lengthCy, lengthCy ); svd_fx(svd_in_buffer_fx, Cy_fx_e, svd_u_buffer, svd_s_buffer, svd_v_buffer, lengthCy, lengthCy ); f2me_buf(svd_s_buffer, svd_s_buffer_fx, &svd_s_buffer_fx_e, lengthCy); FOR(Word32 g = 0; g < lengthCy; g++) Loading Loading @@ -1695,13 +1695,13 @@ Word16 computeMixingMatrices_fx( /* Processing the SVD */ mat2svdMat_fx( Cx_fx, svd_in_buffer_fx, lengthCx, lengthCx, 0 ); FOR ( Word32 g = 0; g < lengthCx; g++ ) /*FOR ( Word32 g = 0; g < lengthCx; g++ ) { me2f_buf( ( svd_in_buffer_fx[g] ), Cx_fx_e, ( svd_in_buffer[g] ), lengthCx ); } }*/ svd( svd_in_buffer, svd_u_buffer, svd_s_buffer, svd_v_buffer, lengthCx, lengthCx ); svd_fx( svd_in_buffer_fx, Cx_fx_e, svd_u_buffer, svd_s_buffer, svd_v_buffer, lengthCx, lengthCx ); f2me_buf(svd_s_buffer, svd_s_buffer_fx, &svd_s_buffer_fx_e, lengthCx); FOR(Word32 g = 0; g < lengthCy; g++) { Loading Loading @@ -1937,17 +1937,17 @@ Word16 computeMixingMatrices_fx( mat2svdMat_fx( mat_mult_buffer1_fx, svd_in_buffer_fx, lengthCx, lengthCy, 1 ); #ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED FOR ( Word32 g = 0; g < lengthCy; g++ ) /*FOR ( Word32 g = 0; g < lengthCy; g++ ) { me2f_buf( ( svd_in_buffer_fx[g] ), mat_mult_buffer1_e, ( svd_in_buffer[g] ), lengthCx ); } }*/ nL = lengthCy; move16(); nC = lengthCx; move16(); svd( svd_in_buffer, svd_v_buffer, svd_s_buffer, svd_u_buffer, nL, nC ); svd_fx(svd_in_buffer_fx, mat_mult_buffer1_e, svd_v_buffer, svd_s_buffer, svd_u_buffer, nL, nC ); #endif } ELSE Loading @@ -1965,7 +1965,7 @@ Word16 computeMixingMatrices_fx( nC = lengthCy; move16(); svd( svd_in_buffer, svd_u_buffer, svd_s_buffer, svd_v_buffer, nL, nC ); svd_fx( svd_in_buffer_fx, mat_mult_buffer1_e, svd_u_buffer, svd_s_buffer, svd_v_buffer, nL, nC ); #endif } Loading Loading @@ -2395,7 +2395,7 @@ Word16 computeMixingMatricesResidual_fx( Word16 lengthCy = extract_l(num_outputs); #ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED float svd_in_buffer[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; //float svd_in_buffer[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; float svd_u_buffer[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; float svd_s_buffer[MAX_OUTPUT_CHANNELS]; float svd_v_buffer[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; Loading Loading @@ -2460,12 +2460,12 @@ Word16 computeMixingMatricesResidual_fx( mat2svdMat_fx( Cy_fx, svd_in_buffer_fx, lengthCy, lengthCy, 0 ); #ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED FOR ( Word32 g = 0; g < lengthCy; g++ ) /*FOR ( Word32 g = 0; g < lengthCy; g++ ) { me2f_buf( ( svd_in_buffer_fx[g] ), Cy_fx_e, ( svd_in_buffer[g] ), lengthCy ); } }*/ svd(svd_in_buffer, svd_u_buffer, svd_s_buffer, svd_v_buffer, lengthCy, lengthCy); svd_fx( svd_in_buffer_fx, Cy_fx_e, svd_u_buffer, svd_s_buffer, svd_v_buffer, lengthCy, lengthCy ); f2me_buf(svd_s_buffer, svd_s_buffer_fx, &svd_s_buffer_fx_e, lengthCy); FOR(Word32 g = 0; g < lengthCy; g++) { Loading Loading @@ -2677,13 +2677,13 @@ Word16 computeMixingMatricesResidual_fx( mat2svdMat_fx( mat_mult_buffer1_fx, svd_in_buffer_fx, lengthCx, lengthCy, 0 ); FOR ( Word32 g = 0; g < lengthCx; g++ ) /*FOR ( Word32 g = 0; g < lengthCx; g++ ) { me2f_buf( ( svd_in_buffer_fx[g] ), mat_mult_buffer1_e, ( svd_in_buffer[g] ), lengthCy ); } }*/ #ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED svd( svd_in_buffer, svd_u_buffer, svd_s_buffer, svd_v_buffer, lengthCx, lengthCy ); svd_fx( svd_in_buffer_fx, mat_mult_buffer1_e, svd_u_buffer, svd_s_buffer, svd_v_buffer, lengthCx, lengthCy ); /* Actually Processing P */ Word16 min_q = -1; Loading Loading @@ -2866,7 +2866,7 @@ Word16 computeMixingMatricesResidual_fx( * * *-------------------------------------------------------------------*/ #ifdef IVAS_FLOAT_FIXED int16_t computeMixingMatricesISM( const int16_t num_inputs, const int16_t num_responses, Loading Loading @@ -3066,17 +3066,17 @@ int16_t computeMixingMatricesISM( 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++ ) /*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 ); svd_fx( svd_in_buffer_fx, mat_mult_buffer1_fx_e, svd_v_buffer, svd_s_buffer, svd_u_buffer, nL, nC ); } else { Loading @@ -3084,17 +3084,17 @@ int16_t computeMixingMatricesISM( 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++ ) /*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 ); svd_fx(svd_in_buffer_fx, mat_mult_buffer1_fx_e, svd_u_buffer, svd_s_buffer, svd_v_buffer, nL, nC ); } /* Actually Processing P */ Loading Loading @@ -3219,3 +3219,180 @@ int16_t computeMixingMatricesISM( return out; } #else int16_t computeMixingMatricesISM( const int16_t num_inputs, const int16_t num_responses, const int16_t num_outputs, const float *responses, const float *ener, const float *Cx_diag, const float *Cy_diag, const float *Q, const int16_t energy_compensation_flag, const float reg_Sx, const float reg_ghat, float *mixing_matrix ) { int16_t i, out; int16_t lengthCx, lengthCy; float *Cy_tilde_p; float *adj; float limit; float svd_in_buffer[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; float svd_u_buffer[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; float svd_s_buffer[MAX_OUTPUT_CHANNELS]; float svd_v_buffer[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; float Kx[MAX_TRANSPORT_CHANNELS]; float Ky[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; float Kx_reg_inv[MAX_TRANSPORT_CHANNELS]; float Q_Cx[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; float Cy_hat_diag[MAX_OUTPUT_CHANNELS]; float G_hat[MAX_OUTPUT_CHANNELS]; 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]; int16_t nL, nC; push_wmops( "dirac_cov_mix_mat" ); out = EXIT_SUCCESS; lengthCx = num_inputs; lengthCy = num_outputs; set_zero( svd_s_buffer, MAX_OUTPUT_CHANNELS ); for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) { set_zero( svd_in_buffer[i], MAX_OUTPUT_CHANNELS ); set_zero( svd_u_buffer[i], MAX_OUTPUT_CHANNELS ); set_zero( svd_v_buffer[i], MAX_OUTPUT_CHANNELS ); } /* Decomposition of Cy = Ky*Ky' */ /* Ky = responses*diag(ener) */ matrix_diag_product( responses, lengthCy, num_responses, 0, ener, num_responses, Ky ); /* Decomposition of Cx -> Computing Kx */ v_sqrt( Cx_diag, Kx, lengthCx ); /* Regularization of Sx */ maximum( Kx, lengthCx, &limit ); limit = limit * reg_Sx + EPSILON; for ( i = 0; i < lengthCx; ++i ) { svd_s_buffer[i] = ( ( Kx[i] > limit ) ? Kx[i] : limit ); } limit = 0.0f; /* regularized Kx-1 */ for ( i = 0; i < lengthCx; ++i ) { float reg_fac = ( 1.0f / svd_s_buffer[i] ); Kx_reg_inv[i] = reg_fac; } /************************ normalization matrix G hat **********************/ /* Computing Q*Cx*Q' */ matrix_diag_product( Q, lengthCy, lengthCx, 0, Cx_diag, lengthCx, Q_Cx ); matrix_product_diag( Q_Cx, lengthCy, lengthCx, 0, Q, lengthCy, lengthCx, 1, Cy_hat_diag ); /* Computing Cy_hat_diag */ for ( i = 0; i < lengthCy; ++i ) { if ( Cy_hat_diag[i] > limit ) { limit = Cy_hat_diag[i]; } } limit = limit * reg_ghat + EPSILON; /* Computing G_hat */ for ( i = 0; i < lengthCy; ++i ) { if ( limit > Cy_hat_diag[i] ) /* Computing Cy_hat_diag = max(Cy_hat_diag,limit) */ { Cy_hat_diag[i] = limit; } G_hat[i] = sqrtf( Cy_diag[i] / Cy_hat_diag[i] ); } /************************ Formulate optimal P **********************/ /* Computing the input matrix Kx'*Q'*G_hat'*Ky */ diag_matrix_product( Kx, lengthCx, Q, lengthCy, lengthCx, 1, mat_mult_buffer1 ); matrix_diag_product( mat_mult_buffer1, lengthCx, lengthCy, 0, G_hat, lengthCy, mat_mult_buffer2 ); matrix_product( mat_mult_buffer2, lengthCx, lengthCy, 0, Ky, lengthCy, num_responses, 0, mat_mult_buffer1 ); if ( lengthCx < num_responses ) { mat2svdMat( mat_mult_buffer1, svd_in_buffer, lengthCx, num_responses, 1 ); nL = num_responses; nC = lengthCx; svd( svd_in_buffer, svd_v_buffer, svd_s_buffer, svd_u_buffer, nL, nC ); } else { mat2svdMat( mat_mult_buffer1, svd_in_buffer, lengthCx, num_responses, 0 ); nL = lengthCx; nC = num_responses; svd( svd_in_buffer, svd_u_buffer, svd_s_buffer, svd_v_buffer, nL, nC ); } /* Actually Processing P */ /* can be skipped: lambda is always column-truncated identity matrix, so this operation just truncates V to num_input_channel columns */ svdMat2mat( svd_v_buffer, mat_mult_buffer1, num_responses, lengthCx ); svdMat2mat( svd_u_buffer, mat_mult_buffer2, lengthCx, lengthCx ); matrix_product( mat_mult_buffer1, num_responses, lengthCx, 0, mat_mult_buffer2, lengthCx, lengthCx, 1, mat_mult_buffer3 ); /************************ Formulate M **********************/ matrix_product( Ky, lengthCy, num_responses, 0, mat_mult_buffer3, num_responses, lengthCx, 0, mat_mult_buffer1 ); matrix_diag_product( mat_mult_buffer1, lengthCy, lengthCx, 0, Kx_reg_inv, lengthCx, mixing_matrix ); /*********************** Energy Compensation ****************/ /* Compute Cy_tilde = M*Cx*M' */ matrix_diag_product( mixing_matrix, lengthCy, lengthCx, 0, Cx_diag, lengthCx, mat_mult_buffer1 ); matrix_product( mat_mult_buffer1, lengthCy, lengthCx, 0, mixing_matrix, lengthCy, lengthCx, 1, mat_mult_buffer2 ); if ( energy_compensation_flag == 1 ) { adj = svd_s_buffer; Cy_tilde_p = mat_mult_buffer2; for ( i = 0; i < lengthCy; ++i ) { /* Avoid correction for very small energies, main diagonal elements of Cy_tilde_p may be negative */ if ( Cy_tilde_p[i + i * lengthCy] < 0.0f ) { adj[i] = 1.0f; } else { adj[i] = sqrtf( Cy_diag[i] / ( Cy_tilde_p[i + i * lengthCy] + EPSILON ) ); } if ( adj[i] > 4.0f ) { adj[i] = 4.0f; } } diag_matrix_product( adj, lengthCy, mixing_matrix, lengthCy, lengthCx, 0, mat_mult_buffer3 ); mvr2r( mat_mult_buffer3, mixing_matrix, lengthCy * lengthCx ); } pop_wmops(); return out; } #endif No newline at end of file
lib_dec/ivas_svd_dec.c +341 −0 File changed.Preview size limit exceeded, changes collapsed. Show changes