From f05128c5f00c0dd1a17f712ba2c6c8ccd1bfb0df Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 23 Feb 2024 17:55:45 +0530 Subject: [PATCH] Converted renderSbaToMASA function --- lib_com/ivas_dirac_com.c | 178 +++++++++++++++++ lib_com/ivas_prot.h | 26 ++- lib_rend/ivas_dirac_ana.c | 392 ++++++++++++++++++++++++++++++++++++- lib_rend/ivas_mcmasa_ana.c | 92 ++++++++- lib_rend/ivas_omasa_ana.c | 88 ++++++++- lib_rend/ivas_prot_rend.h | 46 ++++- lib_rend/ivas_stat_rend.h | 30 ++- lib_rend/lib_rend.c | 47 ++++- lib_rend/lib_rend.h | 1 - 9 files changed, 877 insertions(+), 23 deletions(-) diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index 00aa9a078..2f6077ccf 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -881,6 +881,96 @@ ivas_error ivas_dirac_sba_config( return error; } + +#ifdef IVAS_FLOAT_FIXED +/*------------------------------------------------------------------------- + * computeDirectionVectors() + * + * + *------------------------------------------------------------------------*/ + +void computeDirectionVectors_fx( + Word32 *intensity_real_x, + Word32 *intensity_real_y, + Word32 *intensity_real_z, + const Word16 enc_param_start_band, + const Word16 num_frequency_bands, + Word32 *direction_vector_x, + Word32 *direction_vector_y, + Word32 *direction_vector_z, + Word16 *i_q /*input/output Q*/ +) +{ + Word16 i; + Word32 intensityNorm; + + Word16 sq = 31 - ( 2 * ( *i_q ) - 31 ); + Word16 sq1 = ( 2 * ( *i_q ) - 31 ); + Word16 exp = sq; + Word16 local_i_q = sq1; + Word16 min_factor = 30; + Word32 *init_x = intensity_real_x; + Word32 *init_y = intensity_real_y; + Word32 *init_z = intensity_real_z; + // First loop to determine the Q for the direction vector + for ( i = enc_param_start_band; i < enc_param_start_band + num_frequency_bands; ++i ) + { + intensityNorm = L_add( L_add( Mpy_32_32_r( *( intensity_real_x ), *( intensity_real_x ) ), + Mpy_32_32_r( *( intensity_real_y ), *( intensity_real_y ) ) ), + Mpy_32_32_r( *( intensity_real_z ), *( intensity_real_z ) ) ); /*Q (2*i_q - 31) */ + exp = sq; + if ( intensityNorm <= EPSILON_FX ) + { + intensity_real_x++; + intensity_real_y++; + intensity_real_z++; + } + else + { + intensityNorm = ISqrt32( intensityNorm, &exp ); // Q31-exp + intensity_real_x++; // i_q + Q31-exp -31 = i_q -exp + intensity_real_y++; // i_q + Q31-exp -31 = i_q -exp + intensity_real_z++; // i_q + Q31-exp-31 = i_q -exo + local_i_q = *i_q - exp; + min_factor = min( min_factor, local_i_q ); + } + } + intensity_real_x = init_x; + intensity_real_y = init_y; + intensity_real_z = init_z; + // Actual processing loop for the direction vector + for ( i = enc_param_start_band; i < enc_param_start_band + num_frequency_bands; ++i ) + { + intensityNorm = L_add( L_add( Mpy_32_32_r( *( intensity_real_x ), *( intensity_real_x ) ), + Mpy_32_32_r( *( intensity_real_y ), *( intensity_real_y ) ) ), + Mpy_32_32_r( *( intensity_real_z ), *( intensity_real_z ) ) ); /*Q (2*i_q - 31) */ + exp = sq; + if ( intensityNorm <= EPSILON_FX ) + { + intensityNorm = L_shl( 1, min_factor ); + *( direction_vector_x++ ) = L_shl( 1, min_factor ); + *( direction_vector_y++ ) = 0; + *( direction_vector_z++ ) = 0; + intensity_real_x++; + intensity_real_y++; + intensity_real_z++; + } + else + { + intensityNorm = ISqrt32( intensityNorm, &exp ); // Q31-exp + Word32 temp = L_shr( Mpy_32_32( *( intensity_real_x++ ), intensityNorm ), ( *i_q - exp - min_factor ) ); + *( direction_vector_x++ ) = temp; // i_q + Q31-exp -31 = i_q -exp + temp = L_shr( Mpy_32_32( *( intensity_real_y++ ), intensityNorm ), ( *i_q - exp - min_factor ) ); + *( direction_vector_y++ ) = temp; // i_q + Q31-exp -31 = i_q -exp + temp = L_shr( Mpy_32_32( *( intensity_real_z++ ), intensityNorm ), ( *i_q - exp - min_factor ) ); + *( direction_vector_z++ ) = temp; // i_q + Q31-exp-31 = i_q -exp + } + } + *i_q = min_factor; + return; +} +#endif + /*------------------------------------------------------------------------- * computeDirectionVectors() * @@ -927,7 +1017,95 @@ void computeDirectionVectors( return; } +#ifdef IVAS_FLOAT_FIXED +/*------------------------------------------------------------------------- + * computeDiffuseness() + * + * + *------------------------------------------------------------------------*/ + +void computeDiffuseness_fx( + Word32 *buffer_intensity[DIRAC_NUM_DIMS][DIRAC_NO_COL_AVG_DIFF], + const Word32 *buffer_energy, + const Word16 num_freq_bands, + Word32 *diffuseness, + Word16 q_factor_intensity, + Word16 q_factor_energy, + Word16 *out_exp /*Ouput Q*/ +) +{ + Word32 intensity_slow[DIRAC_NUM_DIMS * CLDFB_NO_CHANNELS_MAX]; + Word32 intensity_slow_abs[CLDFB_NO_CHANNELS_MAX]; + Word32 energy_slow[CLDFB_NO_CHANNELS_MAX]; + Word16 i, j, k; + Word32 tmp = 0, tmp_1; + Word32 *p_tmp; + const Word32 *p_tmp_c; + + /* Compute Intensity slow and energy slow */ + + set_val_Word32( intensity_slow, 0, DIRAC_NUM_DIMS * CLDFB_NO_CHANNELS_MAX ); + set_val_Word32( intensity_slow_abs, 0, CLDFB_NO_CHANNELS_MAX ); + set_val_Word32( energy_slow, 0, CLDFB_NO_CHANNELS_MAX ); + + for ( i = 0; i < DIRAC_NO_COL_AVG_DIFF; ++i ) + { + /* Energy slow */ + p_tmp_c = buffer_energy + i * num_freq_bands; + for ( k = 0; k < num_freq_bands; k++ ) + { + energy_slow[k] = L_add( *( p_tmp_c++ ), energy_slow[k] ); // Q(q_factor_energy) + } + + /* Intensity slow */ + for ( j = 0; j < DIRAC_NUM_DIMS; ++j ) + { + p_tmp = buffer_intensity[j][i]; + + for ( k = 0; k < num_freq_bands; k++ ) + { + intensity_slow[j * num_freq_bands + k] = L_add( *( p_tmp++ ), intensity_slow[j * num_freq_bands + k] ); + } + } + } + + /* intensity_slow.^2 + intensity_slow_abs*/ + for ( j = 0; j < DIRAC_NUM_DIMS; ++j ) + { + p_tmp = intensity_slow + j * num_freq_bands; + + for ( k = 0; k < num_freq_bands; k++ ) + { + *( p_tmp ) = Mpy_32_32( *p_tmp, *( p_tmp ) ); // Q( 2*(q_factor_intensity + scale_fact - 1) -31 ) + intensity_slow_abs[k] = L_add( *( p_tmp++ ), intensity_slow_abs[k] ); + } + } + Word16 init_exp = 31 - (( 2 * ( q_factor_intensity ) ) - 31),exp; + + Word16 exp1 = 0, exp2; + /* Compute Diffuseness */ + p_tmp = intensity_slow_abs; + for ( i = 0; i < num_freq_bands; ++i ) + { + exp = init_exp; + Word32 temp = *( p_tmp++ ); + tmp_1 = Sqrt32( temp, &exp ); + tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( tmp_1, L_add( energy_slow[i],1 ), &exp1 ) ); + exp2 = 31 - exp1 + (31- exp - q_factor_energy ); + if ( exp2 > 30 ) + { + tmp = L_shr( tmp, ( exp2 - 30 ) ); + exp2 -= ( exp2 - 30 ); + } + tmp = L_sub( L_shl( 1, exp2 ), tmp ); + diffuseness[i] = ( ( tmp < L_shl( 1, exp2 ) ) ? ( ( tmp < 0 ) ? 0 : tmp ) : L_shl( 1, exp2 ) ); + out_exp[i] = exp2; + + } + return; +} +#endif /*------------------------------------------------------------------------- * computeDiffuseness() diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index c10546a53..42c717020 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -3962,7 +3962,19 @@ void computeDiffuseness_mdft( const uint16_t no_col_avg_diff, float *diffuseness ); - +#ifdef IVAS_FLOAT_FIXED +void computeDirectionVectors_fx( + Word32 *intensity_real_x, + Word32 *intensity_real_y, + Word32 *intensity_real_z, + const Word16 enc_param_start_band, + const Word16 num_frequency_bands, + Word32 *direction_vector_x, + Word32 *direction_vector_y, + Word32 *direction_vector_z , + Word16 *q_factor +); +#endif void computeDirectionVectors( float *intensity_real_x, float *intensity_real_y, @@ -3981,7 +3993,19 @@ void computeDiffuseness( float *diffuseness ); +#ifdef IVAS_FLOAT_FIXED + +void computeDiffuseness_fx( + Word32 *buffer_intensity[DIRAC_NUM_DIMS][DIRAC_NO_COL_AVG_DIFF], + const Word32 *buffer_energy, + const Word16 num_freq_bands, + Word32 *diffuseness , + Word16 q_factor_intensity, + Word16 q_factor_energy, + Word16 *out_exp +); +#endif void ivas_dirac_dec_get_response( const int16_t azimuth, const int16_t elevation, diff --git a/lib_rend/ivas_dirac_ana.c b/lib_rend/ivas_dirac_ana.c index 6156e94d6..40470f0a5 100644 --- a/lib_rend/ivas_dirac_ana.c +++ b/lib_rend/ivas_dirac_ana.c @@ -39,17 +39,23 @@ #include "ivas_stat_rend.h" #include "ivas_rom_com.h" #include "wmc_auto.h" - +#include "prot_fx2.h" +#include "prot_fx1.h" /*------------------------------------------------------------------------- * Local function prototypes *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void ivas_dirac_param_est_ana( DIRAC_ANA_HANDLE hDirAC, Word32 data_f[][L_FRAME48k], Word32 elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], Word32 azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], Word32 energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], Word32 spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], Word32 surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], const Word16 input_frame ); +static void ivas_dirac_dmx_fx( Word32 data_in_fx[][L_FRAME48k], const Word16 input_frame, const Word16 nchan_transport ); +#else static void ivas_dirac_param_est_ana( DIRAC_ANA_HANDLE hDirAC, float data_f[][L_FRAME48k], float elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], const int16_t input_frame ); - +#endif static void ivas_dirac_dmx( float data_in_f[][L_FRAME48k], const int16_t input_frame, const int16_t nchan_transport ); + /*--------------------------------------------------------------------------* * ivas_dirac_ana_open() * @@ -123,7 +129,24 @@ ivas_error ivas_dirac_ana_open( set_zero( hDirAC->direction_vector_m[i][j], MASA_FREQUENCY_BANDS ); } } +#ifdef IVAS_FLOAT_FIXED + for ( i = 0; i < DIRAC_NUM_DIMS; i++ ) + { + if ( ( hDirAC->direction_vector_m_fx[i] = (Word32 **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) ); + } + for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + if ( ( hDirAC->direction_vector_m_fx[i][j] = (Word32 *) malloc( MASA_FREQUENCY_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) ); + } + set_val_Word32( hDirAC->direction_vector_m_fx[i][j], 0, MASA_FREQUENCY_BANDS ); + } + } +#endif for ( i = 0; i < DIRAC_NUM_DIMS; i++ ) { for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ ) @@ -135,7 +158,20 @@ ivas_error ivas_dirac_ana_open( set_zero( hDirAC->buffer_intensity_real[i][j], MASA_FREQUENCY_BANDS ); } } - +#ifdef IVAS_FLOAT_FIXED + for ( i = 0; i < DIRAC_NUM_DIMS; i++ ) + { + for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ ) + { + if ( ( hDirAC->buffer_intensity_real_fx[i][j] = (Word32 *) malloc( MASA_FREQUENCY_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) ); + } + set_val_Word32( hDirAC->buffer_intensity_real_fx[i][j], 0, MASA_FREQUENCY_BANDS ); + } + } + set_val_Word32( hDirAC->buffer_energy_fx, 0, DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS ); +#endif set_zero( hDirAC->buffer_energy, DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS ); hDirAC->index_buffer_intensity = 0; @@ -186,13 +222,27 @@ void ivas_dirac_ana_close( free( ( *hDirAC )->direction_vector_m[i][j] ); ( *hDirAC )->direction_vector_m[i][j] = NULL; } - +#ifdef IVAS_FLOAT_FIXED + for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + free( ( *hDirAC )->direction_vector_m_fx[i][j] ); + ( *hDirAC )->direction_vector_m_fx[i][j] = NULL; + } +#endif for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ ) { free( ( *hDirAC )->buffer_intensity_real[i][j] ); ( *hDirAC )->buffer_intensity_real[i][j] = NULL; } - +#ifdef IVAS_FLOAT_FIXED + for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ ) + { + free( ( *hDirAC )->buffer_intensity_real_fx[i][j] ); + ( *hDirAC )->buffer_intensity_real_fx[i][j] = NULL; + } + free( ( *hDirAC )->direction_vector_m_fx[i] ); + ( *hDirAC )->direction_vector_m_fx[i] = NULL; +#endif free( ( *hDirAC )->direction_vector_m[i] ); ( *hDirAC )->direction_vector_m[i] = NULL; } @@ -207,8 +257,39 @@ void ivas_dirac_ana_close( return; } +#ifdef IVAS_FLOAT_FIXED +/*--------------------------------------------------------------------------* + * ivas_dirac_ana() + * + * DIRAC analysis function + *--------------------------------------------------------------------------*/ + +void ivas_dirac_ana( + DIRAC_ANA_HANDLE hDirAC, /* i/o: DIRAC analysis handle */ + Word32 data_fx[][L_FRAME48k], /* i/o: Input / transport audio signals */ + const Word16 input_frame, /* i : Input frame size */ + const Word16 nchan_transport /* i : Number of transport channels */ +) +{ + Word32 elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word32 azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word32 energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word32 spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word32 surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word16 energyRatio_q, surroundingCoherence_q = 0, spreadCoherence_q = 0; + /* Estimate MASA parameters from the SBA signals */ + ivas_dirac_param_est_ana( hDirAC, data_fx, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence, input_frame ); + energyRatio_q = 30; + /* Create MASA metadata buffer from the estimated values */ + ivas_create_masa_out_meta_fx( hDirAC->hMasaOut, hDirAC->sph_grid16, nchan_transport, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence, energyRatio_q, spreadCoherence_q, surroundingCoherence_q ); + /* Downmix */ + ivas_dirac_dmx_fx( data_fx, input_frame, nchan_transport );//output Q of data_fx is same as that of input + + return; +} +#else /*--------------------------------------------------------------------------* * ivas_dirac_ana() * @@ -241,7 +322,281 @@ void ivas_dirac_ana( return; } +#endif +#ifdef IVAS_FLOAT_FIXED +/*--------------------------------------------------------------------------* + * Local functions + *--------------------------------------------------------------------------*/ + +/* Estimate MASA parameters from the SBA signals */ +static void ivas_dirac_param_est_ana( + DIRAC_ANA_HANDLE hDirAC, + Word32 data_fx[][L_FRAME48k], + Word32 elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], + Word32 azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], + Word32 energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], + Word32 spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], + Word32 surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], + const Word16 input_frame ) +{ + Word32 reference_power_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + Word16 ts, i, d, j; + Word16 num_freq_bands, index; + Word32 dir_v[DIRAC_NUM_DIMS]; + Word32 dir_q; + Word16 l_ts; + Word32 Foa_RealBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX]; + Word32 Foa_ImagBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX]; + Word32 intensity_real_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; + Word32 direction_vector_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; + Word16 diffuseness_vector_exp[MASA_FREQUENCY_BANDS]; + Word32 diffuseness_vector_fx[MASA_FREQUENCY_BANDS]; + Word32 diffuseness_m_fx[MASA_FREQUENCY_BANDS]; + + Word16 band_m_idx, block_m_idx; + Word32 renormalization_factor_diff_fx[MASA_FREQUENCY_BANDS]; + Word32 norm_tmp_fx; + Word16 mrange[2]; + Word16 brange[2]; + Word16 numAnalysisChannels; + Word16 io_q; + Word16 scale_fact, scale_fact2; + Word16 q_factor_intensity, q_factor_intensity_old = 0; + Word16 q_factor_energy = 0, q_factor_energy_old = 0; + Word16 exp = 0, exp_div = 0; + Word16 exp2; + num_freq_bands = hDirAC->nbands; + Word16 tmp_e; + Word16 tmp = BASOP_Util_Divide3216_Scale( input_frame, CLDFB_NO_COL_MAX, &tmp_e ); + tmp = shr( tmp, negate( add( 1, tmp_e ) ) ); + l_ts = tmp; + numAnalysisChannels = FOA_CHANNELS; + /* do processing over all CLDFB time slots */ + FOR ( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ ) + { + mrange[0] = hDirAC->block_grouping[block_m_idx]; + mrange[1] = hDirAC->block_grouping[block_m_idx + 1]; + + FOR ( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ ) + { + hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx] = 0; + hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx] = 0; + hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] = 0; + } + + /* Need to initialize renormalization_factors, and variables to be normalized */ + set_val_Word32( renormalization_factor_diff_fx, 0, hDirAC->nbands ); + set_val_Word32( diffuseness_m_fx, 0, hDirAC->nbands ); + set_val_Word32( hDirAC->energy_fx[block_m_idx], 0, MASA_FREQUENCY_BANDS ); + set_val_Word32( hDirAC->energy_fx[block_m_idx], 0, MASA_FREQUENCY_BANDS ); + + FOR ( ts = mrange[0]; ts < mrange[1]; ts++ ) + { + FOR ( i = 0; i < numAnalysisChannels; i++ ) + { + io_q = Q7;// Input Q of data_fx + cldfbAnalysis_ts_fx_fixed_q( &( data_fx[i][l_ts * ts] ), Foa_RealBuffer_fx[i], Foa_ImagBuffer_fx[i], l_ts, hDirAC->cldfbAnaEnc[i], &io_q ); + } + scale_fact = getScaleFactor32( (const Word32 *) Foa_RealBuffer_fx, FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX ); + scale_fact = min( getScaleFactor32( (const Word32 *) Foa_ImagBuffer_fx, FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX ), scale_fact ); + FOR ( i = 0; i < DIRAC_NUM_DIMS; i++ ) + { + FOR ( j = 0; j < MASA_FREQUENCY_BANDS; j++ ) + { + Foa_RealBuffer_fx[i][j] = L_shl( Foa_RealBuffer_fx[i][j], ( scale_fact - Q3 ) ); // Q( scale_fact + Q1 ) + Foa_ImagBuffer_fx[i][j] = L_shl( Foa_ImagBuffer_fx[i][j], ( scale_fact - Q3 ) ); // Q( scale_fact + Q1 ) + } + } + /* Compute omni energy for metadata processing */ + FOR ( band_m_idx = 0; band_m_idx < num_freq_bands; band_m_idx++ ) + { + brange[0] = hDirAC->band_grouping[band_m_idx]; + brange[1] = hDirAC->band_grouping[band_m_idx + 1]; + FOR ( j = brange[0]; j < brange[1]; j++ ) + { + hDirAC->energy_fx[block_m_idx][band_m_idx] = ( L_add( hDirAC->energy_fx[block_m_idx][band_m_idx], L_add( Mpy_32_32( Foa_RealBuffer_fx[0][j], Foa_RealBuffer_fx[0][j] ), Mpy_32_32( Foa_ImagBuffer_fx[0][j], Foa_ImagBuffer_fx[0][j] ) ) ) ); // 2*( scale_fact + Q1 )-31 + } + } + /* Direction estimation */ + computeIntensityVector_ana_fx( hDirAC->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx ); // 2 * ( scale_fact + Q1 ) - 31 + exp = ( 2 * ( scale_fact - Q1 ) - 31 ); + + computeDirectionVectors_fx( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], &exp ); + + /* Power estimation for diffuseness */ + computeReferencePower_ana_fx( hDirAC->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, reference_power_fx[ts], num_freq_bands ); //( 2 * ( scale_fact - Q1 ) - 31 - 1 ); // computeReferencePower_ana( hDirAC->band_grouping, Foa_RealBuffer, Foa_ImagBuffer, reference_power[ts], num_freq_bands ); + exp2 = ( 2 * ( scale_fact ) - 31 ); + /* Fill buffers of length "averaging_length" time slots for intensity and energy */ + hDirAC->index_buffer_intensity = ( hDirAC->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ) + 1; /* averaging_length = 32 */ + index = hDirAC->index_buffer_intensity; + Word16 guard_bits = find_guarded_bits_fx( DIRAC_NO_COL_AVG_DIFF ); + scale_fact2 = getScaleFactor32( (const Word32 *) intensity_real_fx, DIRAC_NUM_DIMS * MASA_FREQUENCY_BANDS ); + IF ( guard_bits > scale_fact2 ) + { + FOR ( i = 0; i < DIRAC_NUM_DIMS; i++ ) + { + FOR ( j = 0; j < MASA_FREQUENCY_BANDS; j++ ) + { + intensity_real_fx[i][j] = L_shr( intensity_real_fx[i][j], guard_bits - scale_fact2 ); + } + } + q_factor_intensity = 2 * ( scale_fact - 1 ) - 31 - ( guard_bits - scale_fact2 ); + } + ELSE + { + FOR ( i = 0; i < DIRAC_NUM_DIMS; i++ ) + { + FOR ( j = 0; j < MASA_FREQUENCY_BANDS; j++ ) + { + intensity_real_fx[i][j] = L_shl( intensity_real_fx[i][j], scale_fact2 - guard_bits ); + } + } + q_factor_intensity = 2 * ( scale_fact - 1 ) - 31 + scale_fact2 - guard_bits; + } + scale_fact2 = getScaleFactor32( reference_power_fx[ts], MASA_FREQUENCY_BANDS ); + IF ( guard_bits > scale_fact2 ) + { + + FOR ( j = 0; j < MASA_FREQUENCY_BANDS; j++ ) + { + reference_power_fx[ts][j] = L_shr( reference_power_fx[ts][j], guard_bits - scale_fact2 ); + } + + q_factor_energy = 2 * ( scale_fact ) - 31 - ( guard_bits - scale_fact2 ); + } + ELSE + { + FOR ( j = 0; j < MASA_FREQUENCY_BANDS; j++ ) + { + reference_power_fx[ts][j] = L_shl( reference_power_fx[ts][j], scale_fact2 - guard_bits ); + } + + q_factor_energy = 2 * ( scale_fact ) - 31 + scale_fact2 - guard_bits; + } + + IF ( q_factor_intensity_old != 0 ) + { + + IF ( q_factor_intensity_old < q_factor_intensity ) + { + FOR ( i = 0; i < DIRAC_NUM_DIMS; i++ ) + { + FOR ( j = 0; j < MASA_FREQUENCY_BANDS; j++ ) + { + intensity_real_fx[i][j] = L_shr( intensity_real_fx[i][j], q_factor_intensity - q_factor_intensity_old ); + } + } + q_factor_intensity = q_factor_intensity_old; + } + ELSE + { + FOR( i = 0; i < DIRAC_NUM_DIMS; i++ ) + { + FOR ( j = 0; j < index - 1; j++ ) + { + /* only real part needed */ + FOR ( Word16 k = 0; k < num_freq_bands; k++ ) + { + hDirAC->buffer_intensity_real_fx[i][j][k] = L_shr( hDirAC->buffer_intensity_real_fx[i][j][k], q_factor_intensity_old - q_factor_intensity ); + } + } + } + } + } + IF ( q_factor_energy_old != 0 ) + { + + IF ( q_factor_energy_old < q_factor_energy ) + { + + FOR ( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + reference_power_fx[ts][j] = L_shr( reference_power_fx[ts][j], q_factor_energy - q_factor_energy_old ); + } + + q_factor_energy = q_factor_energy_old; + } + ELSE + { + FOR ( i = 0; i < index - 1; i++ ) + { + FOR ( j = 0; j < num_freq_bands; j++ ) + { + FOR ( Word16 k = 0; k < num_freq_bands; k++ ) + { + hDirAC->buffer_energy_fx[i * j + k] = L_shr( hDirAC->buffer_energy_fx[i * j + k], q_factor_energy_old - q_factor_energy_old ); + } + } + } + } + } + + FOR ( i = 0; i < DIRAC_NUM_DIMS; i++ ) + { + /* only real part needed */ + mvr2r_Word32( intensity_real_fx[i], &( hDirAC->buffer_intensity_real_fx[i][index - 1][0] ), num_freq_bands ); + } + mvr2r_Word32( reference_power_fx[ts], &( hDirAC->buffer_energy_fx[( index - 1 ) * num_freq_bands] ), num_freq_bands ); + + computeDiffuseness_fx( hDirAC->buffer_intensity_real_fx, hDirAC->buffer_energy_fx, num_freq_bands, diffuseness_vector_fx, q_factor_intensity, q_factor_energy, diffuseness_vector_exp ); + q_factor_intensity_old = q_factor_intensity; + q_factor_energy_old = q_factor_energy; + FOR ( j = 0; j < MASA_FREQUENCY_BANDS; j++ ) + { + IF ( diffuseness_vector_exp[j] < 10 ) + { + diffuseness_vector_fx[j] = 0; + } + } + + FOR ( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ ) + { + norm_tmp_fx = Mpy_32_32( reference_power_fx[ts][band_m_idx], ( L_sub( ONE_IN_Q30, L_shr( diffuseness_vector_fx[band_m_idx], 30 - diffuseness_vector_exp[band_m_idx] ) ) ) ); // q_factor_energy-1 + + hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx] = L_add( Mpy_32_32( norm_tmp_fx, direction_vector_fx[0][band_m_idx] ), hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx] ); // Q (q_factor_energy + exp -32) + hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx] = L_add( Mpy_32_32( norm_tmp_fx, direction_vector_fx[1][band_m_idx] ), hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx] ); // Q (q_factor_energy + exp -32) + hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] = L_add( Mpy_32_32( norm_tmp_fx, direction_vector_fx[2][band_m_idx] ), hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] ); // Q (q_factor_energy + exp -32) + + diffuseness_m_fx[band_m_idx] = L_add( diffuseness_m_fx[band_m_idx], Mpy_32_32( reference_power_fx[ts][band_m_idx], L_shr( diffuseness_vector_fx[band_m_idx], 30 - diffuseness_vector_exp[band_m_idx] ) ) ); // Qq_factor_energy-1 + renormalization_factor_diff_fx[band_m_idx] = L_add( renormalization_factor_diff_fx[band_m_idx], reference_power_fx[ts][band_m_idx] ); // Qq_factor_energy + } + } + + FOR ( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ ) + { + FOR ( d = 0; d < DIRAC_NUM_DIMS; d++ ) + { + dir_v[d] = hDirAC->direction_vector_m_fx[d][block_m_idx][band_m_idx]; + } + dir_q = q_factor_energy + exp - 32; + ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( dir_v, dir_q, &azimuth_m_values[block_m_idx][band_m_idx], &elevation_m_values[block_m_idx][band_m_idx] ); + } + /* Determine energy ratios */ + FOR ( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ ) + { + IF ( renormalization_factor_diff_fx[band_m_idx] > EPSILON_FX ) + { + diffuseness_m_fx[band_m_idx] = BASOP_Util_Divide3232_Scale( diffuseness_m_fx[band_m_idx], renormalization_factor_diff_fx[band_m_idx], &exp_div ); + } + ELSE + { + diffuseness_m_fx[band_m_idx] = 0; + } + exp_div = 30 - exp_div; + energyRatio[block_m_idx][band_m_idx] = L_sub( L_shl( 1, 30 ), L_shl( diffuseness_m_fx[band_m_idx], 30 - exp_div ) ); // Q30 + } + + FOR ( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ ) + { + spreadCoherence[block_m_idx][band_m_idx] = 0; + surroundingCoherence[block_m_idx][band_m_idx] = 0; + } + } + + return; +} +#else /*--------------------------------------------------------------------------* * Local functions *--------------------------------------------------------------------------*/ @@ -383,7 +738,34 @@ static void ivas_dirac_param_est_ana( return; } +#endif +#ifdef IVAS_FLOAT_FIXED +/* Compute downmix */ +static void ivas_dirac_dmx_fx( + Word32 data_in_f[][L_FRAME48k], + const Word16 input_frame, + const Word16 nchan_transport) +{ + Word16 i; + Word32 data_out_f[MASA_MAX_TRANSPORT_CHANNELS][L_FRAME48k]; + if ( nchan_transport == 2 ) + { + v_add_fx( data_in_f[0], data_in_f[1], data_out_f[0], input_frame ); + v_multc_fixed( data_out_f[0], ONE_IN_Q30, data_out_f[0], input_frame ); // ONE_IN_Q30 = 0.5* ONE_IN_Q31 + + v_sub_fixed( data_in_f[0], data_in_f[1], data_out_f[1], input_frame,0 ); + v_multc_fixed( data_out_f[1], ONE_IN_Q30, data_out_f[1], input_frame ); + + for ( i = 0; i < nchan_transport; i++ ) + { + mvr2r_Word32( data_out_f[i], data_in_f[i], input_frame ); + } + } + /* output Q is same as input Q*/ + return; +} +#endif /* Compute downmix */ static void ivas_dirac_dmx( float data_in_f[][L_FRAME48k], diff --git a/lib_rend/ivas_mcmasa_ana.c b/lib_rend/ivas_mcmasa_ana.c index 17c90643c..456524295 100644 --- a/lib_rend/ivas_mcmasa_ana.c +++ b/lib_rend/ivas_mcmasa_ana.c @@ -41,7 +41,9 @@ #include "ivas_stat_rend.h" #include "ivas_rom_com.h" #include "wmc_auto.h" - +#ifdef IVAS_FLOAT_FIXED +#include "ivas_prot_fx.h" +#endif /*------------------------------------------------------------------------- * Local constants @@ -1048,6 +1050,92 @@ static void computeEvenLayout( return; } +#ifdef IVAS_FLOAT_FIXED +/*------------------------------------------------------------------------- + * ivas_create_masa_out_meta() + * + * + *------------------------------------------------------------------------*/ + +void ivas_create_masa_out_meta_fx( + MASA_DECODER_EXT_OUT_META_HANDLE extOutMeta, /* i/o: MASA metadata handle */ + SPHERICAL_GRID_DATA *Sph_Grid16, /* i : Spherical grid */ + const Word16 nchan_transport, /* i : Number of transport channels */ + Word32 elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated elevation */ + Word32 azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated azimuth */ + Word32 energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated direct-to-total ratio */ + Word32 spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated spread coherence */ + Word32 surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated surround coherence */ + Word16 energyRatio_q, + Word16 spreadCoherence_q, + Word16 surroundingCoherence_q + +) +{ + const uint8_t ivasmasaFormatDescriptor[8] = { 0x49, 0x56, 0x41, 0x53, 0x4D, 0x41, 0x53, 0x41 }; /* "IVASMASA" */ + int16_t i, sf, band; + uint8_t numFrequencyBands; + uint8_t numDirections; + uint16_t spherical_index; + + numDirections = 1; + numFrequencyBands = MASA_FREQUENCY_BANDS; + + /* Construct descriptive meta */ + for ( i = 0; i < 8; i++ ) + { + extOutMeta->descriptiveMeta.formatDescriptor[i] = ivasmasaFormatDescriptor[i]; + } + extOutMeta->descriptiveMeta.numberOfDirections = numDirections - 1; + extOutMeta->descriptiveMeta.numberOfChannels = (uint8_t) ( nchan_transport - 1 ); + /* Following correspond to "unknown" values */ + extOutMeta->descriptiveMeta.sourceFormat = 0x0u; + extOutMeta->descriptiveMeta.transportDefinition = 0x0u; + extOutMeta->descriptiveMeta.channelAngle = 0x0u; + extOutMeta->descriptiveMeta.channelDistance = 0x0u; + extOutMeta->descriptiveMeta.channelLayout = 0x0u; + + /* Construct spatial metadata from estimated values */ + for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) + { + /* Spherical index */ + for ( band = 0; band < numFrequencyBands; band++ ) + { + spherical_index = index_theta_phi_16_fx( &elevation_m_values[sf][band], &azimuth_m_values[sf][band], Sph_Grid16 ); + extOutMeta->directionIndex[0][sf][band] = spherical_index; + extOutMeta->directionIndex[1][sf][band] = SPH_IDX_FRONT; + } + + /* Direct-to-total ratio */ + for ( band = 0; band < numFrequencyBands; band++ ) + { + extOutMeta->directToTotalRatio[0][sf][band] = (uint8_t) L_shr( energyRatio[sf][band], energyRatio_q - 8 ); + extOutMeta->directToTotalRatio[1][sf][band] = 0; + } + + /* Spread coherence */ + for ( band = 0; band < numFrequencyBands; band++ ) + { + extOutMeta->spreadCoherence[0][sf][band] = (uint8_t) L_shr( spreadCoherence[sf][band], spreadCoherence_q - 8 ); + extOutMeta->spreadCoherence[1][sf][band] = 0; + } + + /* Diffuse-to-total ratio = 1 - sum(direct-to-total ratios) */ + for ( band = 0; band < numFrequencyBands; band++ ) + { + extOutMeta->diffuseToTotalRatio[sf][band] = UINT8_MAX - (uint8_t) L_shr( energyRatio[sf][band], energyRatio_q - 8 ); + } + + /* Surround coherence */ + for ( band = 0; band < numFrequencyBands; band++ ) + { + extOutMeta->surroundCoherence[sf][band] = (uint8_t) L_shr( surroundingCoherence[sf][band], surroundingCoherence_q - 8 ); + } + } + + return; +} +#endif /*------------------------------------------------------------------------- * ivas_create_masa_out_meta() @@ -1128,4 +1216,4 @@ void ivas_create_masa_out_meta( } return; -} +} \ No newline at end of file diff --git a/lib_rend/ivas_omasa_ana.c b/lib_rend/ivas_omasa_ana.c index 1f74fdeb0..b8afd6474 100644 --- a/lib_rend/ivas_omasa_ana.c +++ b/lib_rend/ivas_omasa_ana.c @@ -523,7 +523,52 @@ static void ivas_omasa_dmx( return; } +#ifdef IVAS_FLOAT_FIXED +/*--------------------------------------------------------------------------* + * computeIntensityVector_ana() + * + * + *--------------------------------------------------------------------------*/ + +void computeIntensityVector_ana_fx( + const Word16 *band_grouping, /* i : Band grouping for estimation */ + Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal */ + Word32 Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input signal */ + const Word16 num_frequency_bands, /* i : Number of frequency bands */ + Word32 intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] /* o : Intensity vector */ +) +{ + /* Reminder + * X = a + ib; Y = c + id + * X*Y = ac - bd + i(ad +bc) + */ + Word16 i, j; + Word32 real, img; + Word16 brange[2]; + for ( i = 0; i < num_frequency_bands; i++ ) + { + brange[0] = band_grouping[i]; + brange[1] = band_grouping[i + 1]; + + intensity_real[0][i] = 0; + intensity_real[1][i] = 0; + intensity_real[2][i] = 0; + + for ( j = brange[0]; j < brange[1]; j++ ) + { + real = Cldfb_RealBuffer[0][j]; + img = Cldfb_ImagBuffer[0][j]; + /* Intensity is XYZ order, audio is WYZX order. */ + intensity_real[0][i] = L_add( intensity_real[0][i], L_add( Mpy_32_32( Cldfb_RealBuffer[3][j], real ), Mpy_32_32( Cldfb_ImagBuffer[3][j], img ) ) ); //output Q= 2* input_q -31 + intensity_real[1][i] = L_add( intensity_real[1][i], L_add( Mpy_32_32( Cldfb_RealBuffer[1][j], real ), Mpy_32_32( Cldfb_ImagBuffer[1][j], img ) ) );//output Q= 2* input_q -31 + intensity_real[2][i] = L_add( intensity_real[2][i], L_add( Mpy_32_32( Cldfb_RealBuffer[2][j], real ), Mpy_32_32( Cldfb_ImagBuffer[2][j], img ) ) );//output Q= 2* input_q -31 + } + } + + return; +} +#endif /*--------------------------------------------------------------------------* * computeIntensityVector_ana() * @@ -568,6 +613,47 @@ void computeIntensityVector_ana( return; } +#ifdef IVAS_FLOAT_FIXED +/*--------------------------------------------------------------------------* + * computeReferencePower_ana() + * + * + *--------------------------------------------------------------------------*/ + +void computeReferencePower_ana_fx( + const Word16 *band_grouping, /* i : Band grouping for estimation */ + Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal */ + Word32 Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input signal */ + Word32 *reference_power, /* o : Estimated power */ + const Word16 num_freq_bands /* i : Number of frequency bands */ +) +{ + Word16 brange[2]; + Word16 ch_idx, i, j; + + for ( i = 0; i < num_freq_bands; i++ ) + { + brange[0] = band_grouping[i]; + brange[1] = band_grouping[i + 1]; + reference_power[i] = 0; + + for ( ch_idx = 0; ch_idx < FOA_CHANNELS; ch_idx++ ) + { + /* abs()^2 */ + for ( j = brange[0]; j < brange[1]; j++ ) + { + //Q = 2*inputq - 31 + reference_power[i] = L_add( L_add( Mpy_32_32( Cldfb_RealBuffer[ch_idx][j], Cldfb_RealBuffer[ch_idx][j] ), Mpy_32_32( Cldfb_ImagBuffer[ch_idx][j], Cldfb_ImagBuffer[ch_idx][j] ) ), reference_power[i] ); + } + } + } + + // v_multc( reference_power, 0.5f, reference_power, num_freq_bands ); + + /* Bypassing the v_multc ,so output q = 2*inputq - 30*/ + return; +} +#endif /*--------------------------------------------------------------------------* * computeReferencePower_ana() @@ -605,4 +691,4 @@ void computeReferencePower_ana( v_multc( reference_power, 0.5f, reference_power, num_freq_bands ); return; -} +} \ No newline at end of file diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 5ac144bc4..e3cf3e791 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -2013,7 +2013,15 @@ void ivas_omasa_ana( void ivas_omasa_ana_close( OMASA_ANA_HANDLE *hOMasa /* i/o: analysis OMASA handle */ ); - +#ifdef IVAS_FLOAT_FIXED +void computeIntensityVector_ana_fx( + const Word16 *band_grouping, /* i : Band grouping for estimation */ + Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal */ + Word32 Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input signal */ + const Word16 num_frequency_bands, /* i : Number of frequency bands */ + Word32 intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] /* o : Intensity vector */ +); +#endif void computeIntensityVector_ana( const int16_t *band_grouping, /* i : Band grouping for estimation */ float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal */ @@ -2021,7 +2029,15 @@ void computeIntensityVector_ana( const int16_t num_frequency_bands, /* i : Number of frequency bands */ float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] /* o : Intensity vector */ ); - +#ifdef IVAS_FLOAT_FIXED +void computeReferencePower_ana_fx( + const Word16 *band_grouping, /* i : Band grouping for estimation */ + Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal */ + Word32 Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input signal */ + Word32 *reference_power, /* o : Estimated power */ + const Word16 num_freq_bands /* i : Number of frequency bands */ +); +#endif void computeReferencePower_ana( const int16_t *band_grouping, /* i : Band grouping for estimation */ float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal */ @@ -2029,7 +2045,22 @@ void computeReferencePower_ana( float *reference_power, /* o : Estimated power */ const int16_t num_freq_bands /* i : Number of frequency bands */ ); +#ifdef IVAS_FLOAT_FIXED +void ivas_create_masa_out_meta_fx( + MASA_DECODER_EXT_OUT_META_HANDLE extOutMeta, /* i/o: MASA metadata handle */ + SPHERICAL_GRID_DATA *Sph_Grid16, /* i : Spherical grid */ + const Word16 nchan_transport, /* i : Number of transport channels */ + Word32 elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated elevation */ + Word32 azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated azimuth */ + Word32 energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated direct-to-total ratio */ + Word32 spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated spread coherence */ + Word32 surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated surround coherence */ + Word16 energyRatio_q, + Word16 spreadCoherence_q, + Word16 surroundingCoherence_q + ); +#endif void ivas_create_masa_out_meta( MASA_DECODER_EXT_OUT_META_HANDLE extOutMeta, /* i/o: MASA metadata handle */ SPHERICAL_GRID_DATA *Sph_Grid16, /* i : Spherical grid */ @@ -2045,14 +2076,21 @@ ivas_error ivas_dirac_ana_open( DIRAC_ANA_HANDLE *hDirACPtr, /* i/o: DIRAC data handle pointer */ int32_t input_Fs ); - +#ifdef IVAS_FLOAT_FIXED +void ivas_dirac_ana( + DIRAC_ANA_HANDLE hDirAC, /* i/o: DIRAC analysis handle */ + Word32 data_in_f[][L_FRAME48k], /* i/o: Input / transport audio signals */ + const Word16 input_frame, /* i : Input frame size */ + const Word16 nchan_transport /* i : Number of transport channels */ +); +#else void ivas_dirac_ana( DIRAC_ANA_HANDLE hDirAC, /* i/o: DIRAC analysis handle */ float data_in_f[][L_FRAME48k], /* i/o: Input / transport audio signals */ const int16_t input_frame, /* i : Input frame size */ const int16_t nchan_transport /* i : Number of transport channels */ ); - +#endif void ivas_dirac_ana_close( DIRAC_ANA_HANDLE ( *hDirAC ) /* i/o: analysis DIRAC handle */ ); diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 423ef8f91..52f90e8aa 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -2094,7 +2094,35 @@ typedef struct ivas_omasa_ana_data_structure /*----------------------------------------------------------------------------------* * DirAC analysis structure *----------------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +typedef struct ivas_dirac_ana_data_structure +{ + int16_t nbands; + + /* CLDFB analysis */ + int16_t num_Cldfb_instances; + HANDLE_CLDFB_FILTER_BANK cldfbAnaEnc[DIRAC_MAX_ANA_CHANS]; + + /* DirAC parameter estimation */ + float **direction_vector_m[DIRAC_NUM_DIMS]; /* Average direction vector */ + Word32 **direction_vector_m_fx[DIRAC_NUM_DIMS]; /* Average direction vector */ + int16_t band_grouping[MASA_FREQUENCY_BANDS + 1]; + int16_t block_grouping[5]; + /* diffuseness */ + int16_t index_buffer_intensity; + float *buffer_intensity_real[DIRAC_NUM_DIMS][DIRAC_NO_COL_AVG_DIFF]; + Word32 *buffer_intensity_real_fx[DIRAC_NUM_DIMS][DIRAC_NO_COL_AVG_DIFF]; + float buffer_energy[DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS]; + Word32 buffer_energy_fx[DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS]; + MASA_DECODER_EXT_OUT_META_HANDLE hMasaOut; + SPHERICAL_GRID_DATA *sph_grid16; + + float energy[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word32 energy_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + +} DIRAC_ANA_DATA, *DIRAC_ANA_HANDLE; +#else typedef struct ivas_dirac_ana_data_structure { int16_t nbands; @@ -2119,7 +2147,7 @@ typedef struct ivas_dirac_ana_data_structure float energy[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; } DIRAC_ANA_DATA, *DIRAC_ANA_HANDLE; - +#endif /*----------------------------------------------------------------------------------* * MASA prerend structure *----------------------------------------------------------------------------------*/ diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 700401d28..6939d4e32 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -6388,7 +6388,7 @@ static ivas_error renderActiveInputsIsm( } for ( i = 0; i < outAudio.config.numSamplesPerChannel * outAudio.config.numChannels; ++i ) { - outAudio.data_fx[i] = (Word32) ( outAudio.data[i] * ( 1 << (*outAudio.pq_fact-1) ) ); + outAudio.data_fx[i] = (Word32) ( outAudio.data[i] * ( 1 << ( *outAudio.pq_fact - 1 ) ) ); } return IVAS_ERR_OK; } @@ -7366,7 +7366,7 @@ static ivas_error renderActiveInputsMc( } for ( i = 0; i < outAudio.config.numSamplesPerChannel * outAudio.config.numChannels; ++i ) { - outAudio.data_fx[i] = (Word32) ( outAudio.data[i] * ( 1 << ( *outAudio.pq_fact - 1 ) ) );// to make the output buffer Q same as input when it reaches renderActiveInputsSba + outAudio.data_fx[i] = (Word32) ( outAudio.data[i] * ( 1 << ( *outAudio.pq_fact - 1 ) ) ); // to make the output buffer Q same as input when it reaches renderActiveInputsSba } return IVAS_ERR_OK; } @@ -7407,7 +7407,7 @@ static void renderSbaToMc( push_wmops( "renderSbaToMc" ); inAudio = sbaInput->base.inputBuffer; - FOR ( i = 0; i < inAudio.config.numChannels; ++i ) + FOR( i = 0; i < inAudio.config.numChannels; ++i ) { renderBufferChannel_fx( inAudio, i, sbaInput->hoaDecMtx_fx[i], outAudio ); } @@ -7427,7 +7427,7 @@ static void renderSbaToSba( push_wmops( "renderSbaToSba" ); inAudio = sbaInput->base.inputBuffer; - FOR ( i = 0; i < inAudio.config.numChannels; ++i ) + FOR( i = 0; i < inAudio.config.numChannels; ++i ) { renderBufferChannel_fx( inAudio, i, sbaInput->hoaDecMtx_fx[i], outAudio ); } @@ -7838,7 +7838,22 @@ static ivas_error renderSbaToBinauralRoom( return IVAS_ERR_OK; } #endif +#ifdef IVAS_FLOAT_FIXED +static void renderSbaToMasa( + input_sba *sbaInput, + IVAS_REND_AudioBuffer outAudio ) +{ + Word32 tmpRendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + + push_wmops( "renderMcToMasa" ); + copyBufferTo2dArray_fx( sbaInput->base.inputBuffer, tmpRendBuffer ); + ivas_dirac_ana( sbaInput->hDirAC, tmpRendBuffer, sbaInput->base.inputBuffer.config.numSamplesPerChannel, outAudio.config.numChannels ); + accumulate2dArrayToBuffer_fx( tmpRendBuffer, &outAudio ); + pop_wmops(); + return; +} +#else static void renderSbaToMasa( input_sba *sbaInput, IVAS_REND_AudioBuffer outAudio ) @@ -7853,7 +7868,7 @@ static void renderSbaToMasa( pop_wmops(); return; } - +#endif #ifdef IVAS_FLOAT_FIXED static ivas_error renderInputSba( input_sba *sbaInput, @@ -8266,7 +8281,15 @@ static ivas_error renderActiveInputsMasa( int16_t i; input_masa *pCurrentInput; ivas_error error; - +#ifdef IVAS_FLOAT_FIXED + if ( hIvasRend->inputsSba[0].base.inConfig != IVAS_AUDIO_CONFIG_INVALID ) + { + for ( i = 0; i < outAudio.config.numChannels * outAudio.config.numSamplesPerChannel; i++ ) + { + outAudio.data[i] = (float) outAudio.data_fx[i] / ( 1 << *outAudio .pq_fact); + } + } +#endif for ( i = 0, pCurrentInput = hIvasRend->inputsMasa; i < RENDERER_MAX_MASA_INPUTS; ++i, ++pCurrentInput ) { if ( pCurrentInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) @@ -8280,7 +8303,15 @@ static ivas_error renderActiveInputsMasa( return error; } } - +#ifdef IVAS_FLOAT_FIXED + if ( hIvasRend->inputsSba[0].base.inConfig != IVAS_AUDIO_CONFIG_INVALID ) + { + for ( i = 0; i < outAudio.config.numChannels * outAudio.config.numSamplesPerChannel; i++ ) + { + outAudio.data_fx[i] = (Word32) outAudio.data[i] *(1<< *outAudio.pq_fact ); + } + } +#endif return IVAS_ERR_OK; } @@ -8552,7 +8583,7 @@ static ivas_error getSamplesInternal( return error; } - if ( ( ( hIvasRend->inputsSba[0].base.inConfig != IVAS_AUDIO_CONFIG_INVALID ) && ( ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) || ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) || ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) ) ) ) + if ( hIvasRend->inputsSba[0].base.inConfig != IVAS_AUDIO_CONFIG_INVALID ) { #ifndef DISABLE_LIMITER diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index b3aa35446..f9083d086 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -80,7 +80,6 @@ typedef struct Word16 *pq_fact; float *data; Word32 *data_fx; - Word64 *data64_fx; } IVAS_REND_AudioBuffer; #endif -- GitLab