diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index c0f50d4b75dbefa0383ed807b904fd73aae1719f..1322256041dcd1402bb4d9de72dcb00e79de9c12 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -135,11 +135,13 @@ static void ivas_dirac_dec_decorrelate_slot_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBi static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Word32 Rmat_fx[3][3], const Word16 subframe, const Word16 isHeadtracked, const MASA_ISM_DATA_HANDLE hMasaIsmData, Word16 q ); #else static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float Rmat[3][3], const int16_t subframe, const int16_t isHeadtracked, const MASA_ISM_DATA_HANDLE hMasaIsmData ); -#endif static void ivas_dirac_dec_binaural_determine_processing_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, const int16_t max_band_decorr, float Rmat[3][3], const int16_t subframe, const int16_t isHeadtracked, const int16_t nchanSeparateChannels, const MASA_ISM_DATA_HANDLE hMasaIsmData ); +#endif #ifdef IVAS_FLOAT_FIXED +static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, const int16_t max_band_decorr, Word32 Rmat[3][3], const Word16 subframe, const Word16 isHeadtracked, const Word16 nchanSeparateChannels, const MASA_ISM_DATA_HANDLE hMasaIsmData ); + static void ivas_dirac_dec_binaural_process_output_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, HANDLE_CLDFB_FILTER_BANK cldfbSynDec[MAX_OUTPUT_CHANNELS], Word32 *output_fx[], Word16 *q_out, Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const Word16 q_inp, const Word16 max_band_decorr, const Word16 numInChannels, const Word16 processReverb, const Word16 subframe, const Word16 q_mat ); static void adaptTransportSignalsHeadtracked_fx( COMBINED_ORIENTATION_HANDLE hHeadTrackData, Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Word16 q_inp, const Word16 nBins, const Word16 nSlots, Word32 Rmat[3][3] ); @@ -171,10 +173,10 @@ static void getDirectPartGains_fx( const Word16 bin, Word16 aziDeg, Word16 eleDe #else static void getDirectPartGains( const int16_t bin, int16_t aziDeg, int16_t eleDeg, float *lRealp, float *lImagp, float *rRealp, float *rImagp, const uint8_t stereoMode, float Rmat[3][3], PARAMBIN_HRTF_GAIN_CACHE *gainCache, const int16_t isHeadtracked ); -#endif static void matrixMul( float Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Aim[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Bre[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS] ); static void matrixTransp2Mul( float Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Aim[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Bre[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS] ); +#endif static void ivas_masa_ext_rend_parambin_internal( MASA_EXT_REND_HANDLE hMasaExtRend, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, float *output_f[], const int16_t subframe ); @@ -372,6 +374,11 @@ ivas_error ivas_dirac_dec_init_binaural_data_fx( Word32 output_Fs; RENDERER_TYPE renderer_type; Word16 j, k, bin; + Word32 binCenterFreq_fx; + Word16 tmpFloat_fx; + Word16 tmp; + Word16 tmp_e; + Word16 tmp2; ivas_error error; hDiracDecBin = st_ivas->hDiracDecBin; @@ -398,12 +405,6 @@ ivas_error ivas_dirac_dec_init_binaural_data_fx( { FOR( k = 0; k < BINAURAL_CHANNELS + MAX_NUM_OBJECTS; k++ ) { -#if 1 /* todo: remove float */ - set_zero( hDiracDecBin->processMtxRe[j][k], nBins ); - set_zero( hDiracDecBin->processMtxIm[j][k], nBins ); - set_zero( hDiracDecBin->processMtxRePrev[j][k], nBins ); - set_zero( hDiracDecBin->processMtxImPrev[j][k], nBins ); -#endif set16_fx( hDiracDecBin->processMtxRe_fx[j][k], 0, nBins ); set16_fx( hDiracDecBin->processMtxIm_fx[j][k], 0, nBins ); set16_fx( hDiracDecBin->processMtxRePrev_fx[j][k], 0, nBins ); @@ -412,96 +413,110 @@ ivas_error ivas_dirac_dec_init_binaural_data_fx( FOR( k = 0; k < BINAURAL_CHANNELS; k++ ) { -#if 1 /* todo: remove float */ - set_zero( hDiracDecBin->processMtxDecRe[j][k], nBins ); - set_zero( hDiracDecBin->processMtxDecIm[j][k], nBins ); -#endif set16_fx( hDiracDecBin->processMtxDecRe_fx[j][k], 0, nBins ); set16_fx( hDiracDecBin->processMtxDecIm_fx[j][k], 0, nBins ); } -#if 1 /* to be converted */ - set_zero( hDiracDecBin->ChEnePrev[j], nBins ); - set_zero( hDiracDecBin->ChEneOutPrev[j], nBins ); -#endif - } -#if 1 /* to be converted */ - set_zero( hDiracDecBin->ChCrossRePrev, nBins ); - set_zero( hDiracDecBin->ChCrossImPrev, nBins ); - set_zero( hDiracDecBin->ChCrossReOutPrev, nBins ); - set_zero( hDiracDecBin->ChCrossImOutPrev, nBins ); -#endif + set32_fx( hDiracDecBin->ChEnePrev_fx[j], 0, nBins ); + set32_fx( hDiracDecBin->ChEneOutPrev_fx[j], 0, nBins ); + set16_fx( hDiracDecBin->ChEnePrev_e[j], 0, nBins ); + set16_fx( hDiracDecBin->ChEneOutPrev_e[j], 0, nBins ); + } + set32_fx( hDiracDecBin->ChCrossRePrev_fx, 0, nBins ); + set32_fx( hDiracDecBin->ChCrossImPrev_fx, 0, nBins ); + set16_fx( hDiracDecBin->ChCrossRePrev_e, 0, nBins ); + set16_fx( hDiracDecBin->ChCrossImPrev_e, 0, nBins ); + set32_fx( hDiracDecBin->ChCrossReOutPrev_fx, 0, nBins ); + set32_fx( hDiracDecBin->ChCrossImOutPrev_fx, 0, nBins ); + set16_fx( hDiracDecBin->ChCrossReOutPrev_e, 0, nBins ); + set16_fx( hDiracDecBin->ChCrossImOutPrev_e, 0, nBins ); hDiracDecBin->renderStereoOutputInsteadOfBinaural = 0; + hDiracDecBin->q_processMtx = Q15; + hDiracDecBin->q_processMtxSCCR = Q15; + hDiracDecBin->q_processMtxPrev = Q15; + hDiracDecBin->q_processMtxPrevSCCR = Q15; + hDiracDecBin->q_processMtxDec = Q15; + hDiracDecBin->q_processMtxDecPrev = Q15; + FOR( bin = 0; bin < nBins; bin++ ) { - float binCenterFreq, tmpFloat; - binCenterFreq = ( (float) bin + CLDFB_HALF_BIN_FREQUENCY_OFFSET ) / (float) nBins * ( (float) output_Fs / 2.0f ); + binCenterFreq_fx = L_mult0( extract_l( L_shr( output_Fs, 1 ) ), div_s( add( shl( bin, 1 ), 1 ), shl( nBins, 1 ) ) ) /*( (float) bin + 0.5f ) / (float) nBins * ( (float) output_Fs / 2.0f )*/; /*Q15*/ /* These formulas and values are from Christian Borss's publication for binaural diffuse field coherence */ - tmpFloat = max( 0.0f, 1.0f - binCenterFreq / 2700.0f ); - hDiracDecBin->diffuseFieldCoherence[bin] = tmpFloat * sinf( binCenterFreq * EVS_PI / 550.0f ) / ( binCenterFreq * EVS_PI / 550.0f ); + tmp = BASOP_Util_Divide3232_Scale( binCenterFreq_fx, 2700 << Q15, &tmp_e ); + IF( tmp_e < 0 ) + { + tmp = shl( tmp, tmp_e ); /*q15*/ + tmp_e = 0; + } + tmpFloat_fx = s_max( 0, sub( shl_sat( 1, 15 - tmp_e ), tmp ) ) /*max( 0.0f, 1.0f - binCenterFreq / 2700.0f )*/; /*Q30*/ + tmp2 = extract_l( Mult_32_32( binCenterFreq_fx, 1952258 /*=2^31*180/(550)/360*/ ) % 32767 ); //*binCenterFreq_fx * EVS_PI / 550.0f*/ + hDiracDecBin->diffuseFieldCoherence_fx[bin] = L_shl( L_mult0( divide3232( tmpFloat_fx, Mult_32_16( binCenterFreq_fx, 187 /*2^15*pi/550*/ ) ), getSineWord16R2( tmp2 ) ), tmp_e ); /*tmpFloat * sinf( binCenterFreq * EVS_PI / 550.0f ) / ( binCenterFreq * EVS_PI / 550.0f );*/ + hDiracDecBin->diffuseFieldCoherence_fx[bin] = L_shl( hDiracDecBin->diffuseFieldCoherence_fx[bin], 1 ); } - for ( bin = 0; bin < BINAURAL_COHERENCE_DIFFERENCE_BINS; bin++ ) + FOR( bin = 0; bin < BINAURAL_COHERENCE_DIFFERENCE_BINS; bin++ ) { - hDiracDecBin->diffuseFieldCoherenceX[bin] = hDiracDecBin->diffuseFieldCoherence[bin] + diffuseFieldCoherenceDifferenceX[bin]; - hDiracDecBin->diffuseFieldCoherenceY[bin] = hDiracDecBin->diffuseFieldCoherence[bin] + diffuseFieldCoherenceDifferenceY[bin]; - hDiracDecBin->diffuseFieldCoherenceZ[bin] = hDiracDecBin->diffuseFieldCoherence[bin] + diffuseFieldCoherenceDifferenceZ[bin]; + hDiracDecBin->diffuseFieldCoherenceX_fx[bin] = L_add( hDiracDecBin->diffuseFieldCoherence_fx[bin], diffuseFieldCoherenceDifferenceX_fx[bin] ); + hDiracDecBin->diffuseFieldCoherenceY_fx[bin] = L_add( hDiracDecBin->diffuseFieldCoherence_fx[bin], diffuseFieldCoherenceDifferenceY_fx[bin] ); + hDiracDecBin->diffuseFieldCoherenceZ_fx[bin] = L_add( hDiracDecBin->diffuseFieldCoherence_fx[bin], diffuseFieldCoherenceDifferenceZ_fx[bin] ); } - if ( renderer_type == RENDERER_BINAURAL_PARAMETRIC ) /* Indication of binaural rendering without room effect */ + IF( EQ_32( renderer_type, RENDERER_BINAURAL_PARAMETRIC ) ) /* Indication of binaural rendering without room effect */ { - set_f( hDiracDecBin->earlyPartEneCorrection, 1.0f, CLDFB_NO_CHANNELS_MAX ); + set32_fx( hDiracDecBin->earlyPartEneCorrection_fx, ONE_IN_Q28, CLDFB_NO_CHANNELS_MAX ); + hDiracDecBin->q_earlyPartEneCorrection = Q28; hDiracDecBin->hReverb = NULL; } - else if ( renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) /* Indication of binaural rendering with room effect */ + ELSE IF( EQ_32( renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) /* Indication of binaural rendering with room effect */ { - mvr2r( hHrtfParambin->parametricEarlyPartEneCorrection, hDiracDecBin->earlyPartEneCorrection, nBins ); - + Copy32( hHrtfParambin->parametricEarlyPartEneCorrection_fx, hDiracDecBin->earlyPartEneCorrection_fx, nBins ); + hDiracDecBin->q_earlyPartEneCorrection = Q28; /* reconfiguration needed when Reverb. parameters are changed -> close and open the handle again */ - if ( hDiracDecBin->hReverb != NULL && ( ( hDiracDecBin->hReverb->numBins != nBins ) || - ( hDiracDecBin->hReverb->blockSize != CLDFB_SLOTS_PER_SUBFRAME ) ) ) + IF( hDiracDecBin->hReverb != NULL && ( ( hDiracDecBin->hReverb->numBins != nBins ) || + ( hDiracDecBin->hReverb->blockSize != CLDFB_SLOTS_PER_SUBFRAME ) ) ) { ivas_binaural_reverb_close_fx( &( hDiracDecBin->hReverb ) ); } - if ( hDiracDecBin->hReverb == NULL ) + IF( hDiracDecBin->hReverb == NULL ) { /* Todo Philips: Room acoustics should be passed here once the underlying part works. Probably enough to pick it from st_ivas but you know best. */ - if ( ( error = ivas_binaural_reverb_open_parambin( &hDiracDecBin->hReverb, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, NULL, output_Fs, st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_binaural_reverb_open_parambin( &hDiracDecBin->hReverb, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, NULL, output_Fs, st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK ) { return error; } } } - else if ( renderer_type == RENDERER_STEREO_PARAMETRIC ) + ELSE IF( EQ_32( renderer_type, RENDERER_STEREO_PARAMETRIC ) ) { - set_f( hDiracDecBin->earlyPartEneCorrection, 1.0f, CLDFB_NO_CHANNELS_MAX ); + set32_fx( hDiracDecBin->earlyPartEneCorrection_fx, ONE_IN_Q28, CLDFB_NO_CHANNELS_MAX ); + hDiracDecBin->q_earlyPartEneCorrection = Q28; hDiracDecBin->hReverb = NULL; hDiracDecBin->renderStereoOutputInsteadOfBinaural = 1; } - else /* Not valid renderer type for this renderer */ + ELSE /* Not valid renderer type for this renderer */ { assert( false ); } hDiracDecBin->hDiffuseDist = NULL; /* Memory is allocated from stack during runtime when needed */ - if ( hDiracDecBin->hTdDecorr == NULL ) + IF( hDiracDecBin->hTdDecorr == NULL ) { hDiracDecBin->useTdDecorr = 0; } - if ( hDiracDecBin->h_freq_domain_decorr_ap_params != NULL ) + IF( hDiracDecBin->h_freq_domain_decorr_ap_params != NULL ) { ivas_dirac_dec_decorr_close_fx( &hDiracDecBin->h_freq_domain_decorr_ap_params, &hDiracDecBin->h_freq_domain_decorr_ap_state ); } - if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( hDiracDecBin->hTdDecorr ), &( hDiracDecBin->useTdDecorr ) ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( hDiracDecBin->hTdDecorr ), &( hDiracDecBin->useTdDecorr ) ) ) != IVAS_ERR_OK ) { return error; } - if ( !hDiracDecBin->useTdDecorr && !( st_ivas->ivas_format == ISM_FORMAT && st_ivas->ism_mode == ISM_MODE_PARAM ) ) + IF( !hDiracDecBin->useTdDecorr && !( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) ) ) { Word16 frequency_axis_fx[CLDFB_NO_CHANNELS_MAX]; ivas_dirac_dec_get_frequency_axis_fx( frequency_axis_fx, output_Fs, nBins ); @@ -525,19 +540,19 @@ ivas_error ivas_dirac_dec_init_binaural_data_fx( st_ivas->hDiracDecBin = hDiracDecBin; /* allocate transport channels */ - if ( st_ivas->hTcBuffer == NULL ) + IF( st_ivas->hTcBuffer == NULL ) { - int16_t nchan_to_allocate; - int16_t n_samples_granularity; + Word16 nchan_to_allocate; + Word16 n_samples_granularity; nchan_to_allocate = 2 * BINAURAL_CHANNELS; - if ( st_ivas->ivas_format == MASA_ISM_FORMAT ) + IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) ) { nchan_to_allocate = 2 * BINAURAL_CHANNELS + 2; } n_samples_granularity = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); - if ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) + IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) && EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) { n_samples_granularity = NS2SA( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ); /* Use the same granularity as tdrend */ } @@ -686,7 +701,7 @@ ivas_error ivas_dirac_dec_binaural_copy_hrtfs( Copy32( parametricReverberationTimes_fx, hrtfParambin->parametricReverberationTimes_fx, CLDFB_NO_CHANNELS_MAX ); Copy32( parametricReverberationEneCorrections_fx, hrtfParambin->parametricReverberationEneCorrections_fx, CLDFB_NO_CHANNELS_MAX ); - mvr2r( parametricEarlyPartEneCorrection, hrtfParambin->parametricEarlyPartEneCorrection, CLDFB_NO_CHANNELS_MAX ); + Copy32( parametricEarlyPartEneCorrection_fx, hrtfParambin->parametricEarlyPartEneCorrection_fx, CLDFB_NO_CHANNELS_MAX ); *hHrtfParambin = hrtfParambin; } @@ -1179,6 +1194,7 @@ static void ivas_dirac_dec_binaural_internal( DIFFUSE_DISTRIBUTION_DATA diffuseDistData; Word16 nBins, offsetSamples; Word16 i, j; + Word16 q_mat; hDiracDecBin = st_ivas->hDiracDecBin; assert( hDiracDecBin ); hSpatParamRendCom = st_ivas->hSpatParamRendCom; @@ -1368,14 +1384,12 @@ static void ivas_dirac_dec_binaural_internal( FOR( int idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) { - // floatToFixed_arrL( st_ivas->hSpar->hFbMixer->pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band[idx], st_ivas->hSpar->hFbMixer->pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[idx], Q31, IVAS_MAX_NUM_FB_BANDS ); Scale_sig32( st_ivas->hSpar->hFbMixer->pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[idx], IVAS_MAX_NUM_FB_BANDS, sub( Q31, Q22 ) ); } #endif ivas_sba_prototype_renderer_fx( st_ivas, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_cldfb, subframe ); FOR( int idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) { - // floatToFixed_arrL( st_ivas->hSpar->hFbMixer->pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band[idx], st_ivas->hSpar->hFbMixer->pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[idx], Q31, IVAS_MAX_NUM_FB_BANDS ); Scale_sig32( st_ivas->hSpar->hFbMixer->pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[idx], IVAS_MAX_NUM_FB_BANDS, sub( Q22, Q31 ) ); } } @@ -1413,32 +1427,6 @@ static void ivas_dirac_dec_binaural_internal( } } -#if 1 - Word16 q_earlyPartEneCorrection = Q_factor_arrL( hDiracDecBin->earlyPartEneCorrection, hSpatParamRendCom->num_freq_bands ); - hDiracDecBin->q_earlyPartEneCorrection = q_earlyPartEneCorrection; - floatToFixed_arr32( hDiracDecBin->earlyPartEneCorrection, hDiracDecBin->earlyPartEneCorrection_fx, q_earlyPartEneCorrection, hSpatParamRendCom->num_freq_bands ); - floatToFixed_arr32( hDiracDecBin->diffuseFieldCoherence, hDiracDecBin->diffuseFieldCoherence_fx, Q31, hSpatParamRendCom->num_freq_bands ); - - FOR( j = 0; j < nBins; j++ ) - { - f2me( hDiracDecBin->ChCrossRePrev[j], &hDiracDecBin->ChCrossRePrev_fx[j], &hDiracDecBin->ChCrossRePrev_e[j] ); - f2me( hDiracDecBin->ChCrossImPrev[j], &hDiracDecBin->ChCrossImPrev_fx[j], &hDiracDecBin->ChCrossImPrev_e[j] ); - f2me( hDiracDecBin->ChCrossReOutPrev[j], &hDiracDecBin->ChCrossReOutPrev_fx[j], &hDiracDecBin->ChCrossReOutPrev_e[j] ); - f2me( hDiracDecBin->ChCrossImOutPrev[j], &hDiracDecBin->ChCrossImOutPrev_fx[j], &hDiracDecBin->ChCrossImOutPrev_e[j] ); - FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) - { - f2me( hDiracDecBin->ChEnePrev[i][j], &hDiracDecBin->ChEnePrev_fx[i][j], &hDiracDecBin->ChEnePrev_e[i][j] ); - f2me( hDiracDecBin->ChEneOutPrev[i][j], &hDiracDecBin->ChEneOutPrev_fx[i][j], &hDiracDecBin->ChEneOutPrev_e[i][j] ); - } - } - floatToFixed_arr32( hDiracDecBin->diffuseFieldCoherence, hDiracDecBin->diffuseFieldCoherence_fx, 31, hSpatParamRendCom->num_freq_bands ); - IF( hDiracDecBin->hDiffuseDist ) - { - floatToFixed_arr32( hDiracDecBin->diffuseFieldCoherenceX, hDiracDecBin->diffuseFieldCoherenceX_fx, 31, 9 ); - floatToFixed_arr32( hDiracDecBin->diffuseFieldCoherenceY, hDiracDecBin->diffuseFieldCoherenceY_fx, 31, 9 ); - floatToFixed_arr32( hDiracDecBin->diffuseFieldCoherenceZ, hDiracDecBin->diffuseFieldCoherenceZ_fx, 31, 9 ); - } -#endif Word16 shift = 31; Word32 Cldfb_RealBuffer_inTmp_fx[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Cldfb_ImagBuffer_inTmp_fx[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; FOR( i = 0; i < 2; i++ ) @@ -1497,46 +1485,14 @@ static void ivas_dirac_dec_binaural_internal( move16(); } -#if 1 - FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) - { - FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) - { - hDiracDecBin->ChEnePrev[i][j] = me2f( hDiracDecBin->ChEnePrev_fx[i][j], hDiracDecBin->ChEnePrev_e[i][j] ); - hDiracDecBin->ChEne[i][j] = me2f( hDiracDecBin->ChEne_fx[i][j], hDiracDecBin->ChEne_e[i][j] ); - hDiracDecBin->ChEneOut[i][j] = me2f( hDiracDecBin->ChEneOut_fx[i][j], hDiracDecBin->ChEneOut_e[i][j] ); - hDiracDecBin->ChEneOutPrev[i][j] = me2f( hDiracDecBin->ChEneOutPrev_fx[i][j], hDiracDecBin->ChEneOutPrev_e[i][j] ); - } - } - - FOR( j = 0; j < nBins; j++ ) - { - hDiracDecBin->ChCrossRePrev[j] = me2f( hDiracDecBin->ChCrossRePrev_fx[j], hDiracDecBin->ChCrossRePrev_e[j] ); - hDiracDecBin->ChCrossImPrev[j] = me2f( hDiracDecBin->ChCrossImPrev_fx[j], hDiracDecBin->ChCrossImPrev_e[j] ); - hDiracDecBin->ChCrossRe[j] = me2f( hDiracDecBin->ChCrossRe_fx[j], hDiracDecBin->ChCrossRe_e[j] ); - hDiracDecBin->ChCrossIm[j] = me2f( hDiracDecBin->ChCrossIm_fx[j], hDiracDecBin->ChCrossIm_e[j] ); - hDiracDecBin->ChCrossReOut[j] = me2f( hDiracDecBin->ChCrossReOut_fx[j], hDiracDecBin->ChCrossReOut_e[j] ); - hDiracDecBin->ChCrossImOut[j] = me2f( hDiracDecBin->ChCrossImOut_fx[j], hDiracDecBin->ChCrossImOut_e[j] ); - hDiracDecBin->ChCrossReOutPrev[j] = me2f( hDiracDecBin->ChCrossReOutPrev_fx[j], hDiracDecBin->ChCrossReOutPrev_e[j] ); - hDiracDecBin->ChCrossImOutPrev[j] = me2f( hDiracDecBin->ChCrossImOutPrev_fx[j], hDiracDecBin->ChCrossImOutPrev_e[j] ); - } - fixedToFloat_arrL( hDiracDecBin->frameMeanDiffuseness_fx, hDiracDecBin->frameMeanDiffuseness, 29, CLDFB_NO_CHANNELS_MAX ); -#endif - - // TODO: To be removed once below function is fixed - float Rmat[3][3]; - for ( i = 0; i < 3; i++ ) - { - fixedToFloat_arrL32( Rmat_fx[i], Rmat[i], Q30, 3 ); - } - ivas_dirac_dec_binaural_determine_processing_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat, subframe, - hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, nchanSeparateChannels, st_ivas->hMasaIsmData ); + ivas_dirac_dec_binaural_determine_processing_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat_fx, subframe, + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, nchanSeparateChannels, st_ivas->hMasaIsmData ); #if 1 Word32 *output_fx[MAX_OUTPUT_CHANNELS]; Word32 output_fx_buff[MAX_OUTPUT_CHANNELS][L_FRAME48k]; Word16 q_out; - Word16 q_mat = 15; + q_inp = Q6; FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { @@ -1544,47 +1500,41 @@ static void ivas_dirac_dec_binaural_internal( } FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - FOR( slot = 0; slot < BINAURAL_CHANNELS; slot++ ) - { - q_mat = s_min( q_mat, Q_factor_arr( hDiracDecBin->processMtxDecRe[ch][slot], nBins ) ); - q_mat = s_min( q_mat, Q_factor_arr( hDiracDecBin->processMtxDecIm[ch][slot], nBins ) ); - q_mat = s_min( q_mat, Q_factor_arr( hDiracDecBin->processMtxDecRePrev[ch][slot], nBins ) ); - q_mat = s_min( q_mat, Q_factor_arr( hDiracDecBin->processMtxDecImPrev[ch][slot], nBins ) ); - } - } - FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - FOR( slot = 0; slot < numInChannels; slot++ ) - { - q_mat = s_min( q_mat, Q_factor_arr( hDiracDecBin->processMtxRe[ch][slot], nBins ) ); - q_mat = s_min( q_mat, Q_factor_arr( hDiracDecBin->processMtxIm[ch][slot], nBins ) ); - q_mat = s_min( q_mat, Q_factor_arr( hDiracDecBin->processMtxRePrev[ch][slot], nBins ) ); - q_mat = s_min( q_mat, Q_factor_arr( hDiracDecBin->processMtxImPrev[ch][slot], nBins ) ); - } + st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q11; } - q_mat = sub( q_mat, 1 ); // guardbits// +#endif + + q_mat = hDiracDecBin->q_processMtx; + q_mat = s_min( q_mat, hDiracDecBin->q_processMtxPrev ); + q_mat = s_min( q_mat, hDiracDecBin->q_processMtxDec ); + q_mat = s_min( q_mat, hDiracDecBin->q_processMtxDecPrev ); + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { FOR( slot = 0; slot < BINAURAL_CHANNELS; slot++ ) { - floatToFixed_arr16( hDiracDecBin->processMtxDecRe[ch][slot], hDiracDecBin->processMtxDecRe_fx[ch][slot], q_mat, nBins ); - floatToFixed_arr16( hDiracDecBin->processMtxDecIm[ch][slot], hDiracDecBin->processMtxDecIm_fx[ch][slot], q_mat, nBins ); - floatToFixed_arr16( hDiracDecBin->processMtxDecRePrev[ch][slot], hDiracDecBin->processMtxDecRePrev_fx[ch][slot], q_mat, nBins ); - floatToFixed_arr16( hDiracDecBin->processMtxDecImPrev[ch][slot], hDiracDecBin->processMtxDecImPrev_fx[ch][slot], q_mat, nBins ); + Scale_sig( hDiracDecBin->processMtxRe_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); + Scale_sig( hDiracDecBin->processMtxIm_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); + Scale_sig( hDiracDecBin->processMtxRePrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); + Scale_sig( hDiracDecBin->processMtxImPrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); + Scale_sig( hDiracDecBin->processMtxDecRe_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDec ) ); + Scale_sig( hDiracDecBin->processMtxDecIm_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDec ) ); + Scale_sig( hDiracDecBin->processMtxDecRePrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDecPrev ) ); + Scale_sig( hDiracDecBin->processMtxDecImPrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDecPrev ) ); } - } - FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - FOR( slot = 0; slot < numInChannels; slot++ ) + FOR( slot = 0; slot < nchanSeparateChannels; slot++ ) { - floatToFixed_arr16( hDiracDecBin->processMtxRe[ch][slot], hDiracDecBin->processMtxRe_fx[ch][slot], q_mat, nBins ); - floatToFixed_arr16( hDiracDecBin->processMtxIm[ch][slot], hDiracDecBin->processMtxIm_fx[ch][slot], q_mat, nBins ); - floatToFixed_arr16( hDiracDecBin->processMtxRePrev[ch][slot], hDiracDecBin->processMtxRePrev_fx[ch][slot], q_mat, nBins ); - floatToFixed_arr16( hDiracDecBin->processMtxImPrev[ch][slot], hDiracDecBin->processMtxImPrev_fx[ch][slot], q_mat, nBins ); + Scale_sig( hDiracDecBin->processMtxRe_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); + Scale_sig( hDiracDecBin->processMtxIm_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); + Scale_sig( hDiracDecBin->processMtxRePrev_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); + Scale_sig( hDiracDecBin->processMtxImPrev_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); } - st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q11; } -#endif + hDiracDecBin->q_processMtx = q_mat; + hDiracDecBin->q_processMtxPrev = q_mat; + hDiracDecBin->q_processMtxDec = q_mat; + hDiracDecBin->q_processMtxDecPrev = q_mat; + ivas_dirac_dec_binaural_process_output_fx( hDiracDecBin, hSpatParamRendCom, st_ivas->cldfbSynDec, output_fx, &q_out, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_inp, max_band_decorr, numInChannels, config_data.processReverb, subframe, q_mat ); hDiracDecBin->hDiffuseDist = NULL; @@ -2221,7 +2171,6 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric Word16 nchan_transport; Word16 gainCacheBaseIndex; Word16 q_earlyPartEneCorrection; - q_earlyPartEneCorrection = hDiracDecBin->q_earlyPartEneCorrection; separateCenterChannelRendering = hConfig->separateCenterChannelRendering; move16(); @@ -2237,6 +2186,10 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric nBins = hSpatParamRendCom->num_freq_bands; /* Actually bins */ move16(); + q_earlyPartEneCorrection = s_min( Q31, add( getScaleFactor32( hDiracDecBin->earlyPartEneCorrection_fx, nBins ), hDiracDecBin->q_earlyPartEneCorrection ) ); + scale_sig32( hDiracDecBin->earlyPartEneCorrection_fx, nBins, sub( q_earlyPartEneCorrection, hDiracDecBin->q_earlyPartEneCorrection ) ); + hDiracDecBin->q_earlyPartEneCorrection = q_earlyPartEneCorrection; + set32_fx( hDiracDecBin->ChCrossRe_fx, 0, nBins ); set32_fx( hDiracDecBin->ChCrossIm_fx, 0, nBins ); set32_fx( hDiracDecBin->ChCrossReOut_fx, 0, nBins ); @@ -2810,6 +2763,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric } #endif +#ifndef IVAS_FLOAT_FIXED static void ivas_dirac_dec_binaural_determine_processing_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, @@ -2857,32 +2811,266 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices( float CrEneL, CrEneR; /* Cr = residual decorrelated sound covariance matrix */ float CrCrossRe, CrCrossIm; float Mre[BINAURAL_CHANNELS][BINAURAL_CHANNELS], Mim[BINAURAL_CHANNELS][BINAURAL_CHANNELS], MdecRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS], MdecIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; /* M = mixing matrix; Mdec = residual decorrelated signal mixing matrix */ -#ifndef IVAS_FLOAT_FIXED - float prototypeMtx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { { 1.0f, 0.05f }, { 0.05f, 1.0f } }; /* Prototype matrix determines a reference signal in mixing matrix determination */ -#endif + float prototypeMtx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { { 1.0f, 0.05f }, { 0.05f, 1.0f } }; /* Prototype matrix determines a reference signal in mixing matrix determination */ + CrEneL = 0.0f; CrEneR = 0.0f; /* Formulate main processing matrix M */ -#ifndef IVAS_FLOAT_FIXED formulate2x2MixingMatrix( hDiracDecBin->ChEne[0][bin], hDiracDecBin->ChEne[1][bin], hDiracDecBin->ChCrossRe[bin], hDiracDecBin->ChCrossIm[bin], hDiracDecBin->ChEneOut[0][bin], hDiracDecBin->ChEneOut[1][bin], hDiracDecBin->ChCrossReOut[bin], hDiracDecBin->ChCrossImOut[bin], prototypeMtx, Mre, Mim, -#ifdef IVAS_FLOAT_FIXED - fix16_to_float( hDiracDecBin->reqularizationFactor_fx, Q14 ) ); -#else hDiracDecBin->reqularizationFactor ); -#endif + + /* Load estimated covariance matrix to the [2][2] matrix form */ + CxRe[0][0] = hDiracDecBin->ChEne[0][bin]; + CxRe[1][1] = hDiracDecBin->ChEne[1][bin]; + CxRe[1][0] = hDiracDecBin->ChCrossRe[bin]; + CxRe[0][1] = hDiracDecBin->ChCrossRe[bin]; + CxIm[0][0] = 0.0f; + CxIm[1][1] = 0.0f; + CxIm[1][0] = hDiracDecBin->ChCrossIm[bin]; + CxIm[0][1] = -hDiracDecBin->ChCrossIm[bin]; + + /* Make matrix multiplication M*Cx*M' to determine resulting covariance matrix of processing input with M */ + matrixMul( Mre, Mim, CxRe, CxIm, tmpMtxRe, tmpMtxIm ); + matrixTransp2Mul( tmpMtxRe, tmpMtxIm, Mre, Mim, resultMtxRe, resultMtxIm ); + + /* When below the frequency limit where decorrelation is applied, we inject the decorrelated + * residual (or missing) signal component. The procedure is active when there are not enough independent + * signal energy to synthesize a signal with the target covariance matrix from the non-decorrelated signals */ + if ( bin < max_band_decorr ) + { + float decorrelationReductionFactor; + + /* Subtract the resulting covariance matrix from the target covariance matrix to determine + * what signal component is missing. The result is the target covariance matrix for the residual signal, i.e., + * a residual covariance matrix. */ + CrEneL = max( 0.0f, hDiracDecBin->ChEneOut[0][bin] - resultMtxRe[0][0] ); + CrEneR = max( 0.0f, hDiracDecBin->ChEneOut[1][bin] - resultMtxRe[1][1] ); + CrCrossRe = hDiracDecBin->ChCrossReOut[bin] - resultMtxRe[1][0]; + CrCrossIm = hDiracDecBin->ChCrossImOut[bin] - resultMtxIm[1][0]; + + /* The amount of the decorrelated sound is further controlled based on the spatial metadata, + * by determining an energy-suppressed residual covariance matrix that is a control parameter + * that guides the processing of the decorrelated sound to a residual signal. + * The procedure improves quality in e.g. double-talk 2-direction rendering situations.*/ + if ( ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE ) + { + decorrelationReductionFactor = 1.0f; + } + else if ( ( ivas_format == MC_FORMAT && mc_mode == MC_MODE_MCMASA ) || ( ivas_format == MASA_FORMAT && nchan_transport == 1 ) ) + { + decorrelationReductionFactor = sqrtf( fmaxf( 0.0f, hDiracDecBin->frameMeanDiffuseness[bin] ) ); + } + else if ( ( ivas_format == SBA_FORMAT || ivas_format == SBA_ISM_FORMAT ) && nchan_transport == 1 ) + { + decorrelationReductionFactor = 1.0f; + } + else + { + decorrelationReductionFactor = fmaxf( 0.0f, hDiracDecBin->frameMeanDiffuseness[bin] ); + } + CrEneL *= decorrelationReductionFactor; + CrEneR *= decorrelationReductionFactor; + CrCrossRe *= decorrelationReductionFactor; + CrCrossIm *= decorrelationReductionFactor; + + /* Determine a residual mixing matrix Mdec for processing the decorrelated signal to obtain + * the residual signal (that has the residual covariance matrix) */ + formulate2x2MixingMatrix( hDiracDecBin->ChEne[0][bin], hDiracDecBin->ChEne[1][bin], + 0.0f, 0.0f, /* Decorrelated signal has ideally no cross-terms */ + CrEneL, CrEneR, + CrCrossRe, CrCrossIm, + prototypeMtx, MdecRe, MdecIm, 0.2f ); + } + else + { + for ( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) + { + set_zero( MdecRe[chA], BINAURAL_CHANNELS ); + set_zero( MdecIm[chA], BINAURAL_CHANNELS ); + } + } + + /* The regularizations at determining mixing matrices cause signal energy to be lost to some degree, which is compensated for here */ + realizedOutputEne = CrEneL + CrEneR + resultMtxRe[0][0] + resultMtxRe[1][1]; + targetOutputEne = hDiracDecBin->ChEneOut[0][bin] + hDiracDecBin->ChEneOut[1][bin]; + missingOutputEne = fmaxf( 0.0f, targetOutputEne - realizedOutputEne ); + + gain = sqrtf( ( resultMtxRe[0][0] + resultMtxRe[1][1] + missingOutputEne ) / + fmaxf( 1e-12f, resultMtxRe[0][0] + resultMtxRe[1][1] ) ); + gain = fminf( 4.0f, gain ); + + for ( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) + { + for ( chB = 0; chB < BINAURAL_CHANNELS; chB++ ) + { + Mre[chA][chB] *= gain; + Mim[chA][chB] *= gain; + } + } + + /* Store processing matrices */ + for ( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) + { + for ( chB = 0; chB < BINAURAL_CHANNELS; chB++ ) + { + hDiracDecBin->processMtxRePrev[chA][chB][bin] = hDiracDecBin->processMtxRe[chA][chB][bin]; + hDiracDecBin->processMtxImPrev[chA][chB][bin] = hDiracDecBin->processMtxIm[chA][chB][bin]; + hDiracDecBin->processMtxDecRePrev[chA][chB][bin] = hDiracDecBin->processMtxDecRe[chA][chB][bin]; + hDiracDecBin->processMtxDecImPrev[chA][chB][bin] = hDiracDecBin->processMtxDecIm[chA][chB][bin]; + + hDiracDecBin->processMtxRe[chA][chB][bin] = Mre[chA][chB]; + hDiracDecBin->processMtxIm[chA][chB][bin] = Mim[chA][chB]; + hDiracDecBin->processMtxDecRe[chA][chB][bin] = MdecRe[chA][chB]; + hDiracDecBin->processMtxDecIm[chA][chB][bin] = MdecIm[chA][chB]; + } + } + + if ( separateCenterChannelRendering ) + { + /* The rendering of the separate center channel in masa + mono mode. + * The center channel is processed with a gain factor 0.8414f to match the loudness of different processing paths */ + float lRealp, lImagp, rRealp, rImagp; + float gainFactor; + int16_t aziDeg = 0; + int16_t eleDeg = 0; + uint8_t instantChange = 0; + + if ( ivas_format == MASA_ISM_FORMAT ) + { + gainFactor = 0.7943f * sqrtf( hDiracDecBin->earlyPartEneCorrection[bin] ); + } + else + { + gainFactor = 0.8414f * sqrtf( hDiracDecBin->earlyPartEneCorrection[bin] ); + } + + for ( chB = 0; chB < nchanSeparateChannels; chB++ ) + { + if ( ivas_format == MASA_ISM_FORMAT ) + { + if ( ism_mode == ISM_MASA_MODE_DISC ) + { + aziDeg = hMasaIsmData->azimuth_ism[chB][dirac_read_idx]; + eleDeg = hMasaIsmData->elevation_ism[chB][dirac_read_idx]; + } + else + { + aziDeg = hMasaIsmData->azimuth_separated_ism[dirac_read_idx]; + eleDeg = hMasaIsmData->elevation_separated_ism[dirac_read_idx]; + instantChange = 1; + } + } + + for ( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) + { + hDiracDecBin->processMtxRePrev[chA][chB + 2][bin] = hDiracDecBin->processMtxRe[chA][chB + 2][bin]; + hDiracDecBin->processMtxImPrev[chA][chB + 2][bin] = hDiracDecBin->processMtxIm[chA][chB + 2][bin]; + } + + getDirectPartGains( bin, aziDeg, eleDeg, &lRealp, &lImagp, &rRealp, &rImagp, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[chB], isHeadtracked ); + + hDiracDecBin->processMtxRe[0][chB + 2][bin] = lRealp * gainFactor; + hDiracDecBin->processMtxIm[0][chB + 2][bin] = lImagp * gainFactor; + hDiracDecBin->processMtxRe[1][chB + 2][bin] = rRealp * gainFactor; + hDiracDecBin->processMtxIm[1][chB + 2][bin] = rImagp * gainFactor; + + if ( instantChange ) + { + for ( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) + { + hDiracDecBin->processMtxRePrev[chA][chB + 2][bin] = hDiracDecBin->processMtxRe[chA][chB + 2][bin]; + hDiracDecBin->processMtxImPrev[chA][chB + 2][bin] = hDiracDecBin->processMtxIm[chA][chB + 2][bin]; + } + } + } + } + } + + return; +} #else - Word16 q_M, q_Mdec = 0, q_CrEne, q_CrCross; - Word32 prototypeMtx_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { { ONE_IN_Q31, 107374182 }, { 107374182, ONE_IN_Q31 } }; - Word32 Mre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], Mim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], MdecRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], MdecIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; /* M = mixing matrix; Mdec = residual decorrelated signal mixing matrix */ - Word32 CrEneL_fx, CrEneR_fx; /* Cr = residual decorrelated sound covariance matrix */ +static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( + DIRAC_DEC_BIN_HANDLE hDiracDecBin, + SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, + PARAMBIN_REND_CONFIG_HANDLE hConfig, + const Word16 max_band_decorr, + Word32 Rmat[3][3], + const Word16 subframe, + const Word16 isHeadtracked, + const Word16 nchanSeparateChannels, + const MASA_ISM_DATA_HANDLE hMasaIsmData ) +{ + Word16 chA, chB, bin; + Word16 separateCenterChannelRendering; + Word16 nBins; + Word16 dirac_read_idx; + PARAMBIN_HRTF_GAIN_CACHE gainCache[MAX_NUM_OBJECTS]; + Word16 idx; + ISM_MODE ism_mode; + IVAS_FORMAT ivas_format; + MC_MODE mc_mode; + Word32 ivas_total_brate; + Word16 nchan_transport; + Word16 exp; + Word16 q_processMtx[CLDFB_NO_CHANNELS_MAX], q_processMtxPrev[CLDFB_NO_CHANNELS_MAX]; + Word16 q_processMtx_SCCR[CLDFB_NO_CHANNELS_MAX], q_processMtxPrev_SCCR[CLDFB_NO_CHANNELS_MAX]; + Word16 q_processMtxDec[CLDFB_NO_CHANNELS_MAX], q_processMtxDecPrev[CLDFB_NO_CHANNELS_MAX]; + set_s( q_processMtx, hDiracDecBin->q_processMtx, CLDFB_NO_CHANNELS_MAX ); + set_s( q_processMtxPrev, hDiracDecBin->q_processMtxPrev, CLDFB_NO_CHANNELS_MAX ); + set_s( q_processMtx_SCCR, hDiracDecBin->q_processMtx, CLDFB_NO_CHANNELS_MAX ); + set_s( q_processMtxPrev_SCCR, hDiracDecBin->q_processMtxPrev, CLDFB_NO_CHANNELS_MAX ); + set_s( q_processMtxDec, hDiracDecBin->q_processMtxDec, CLDFB_NO_CHANNELS_MAX ); + set_s( q_processMtxDecPrev, hDiracDecBin->q_processMtxDecPrev, CLDFB_NO_CHANNELS_MAX ); + + ivas_format = hConfig->ivas_format; + separateCenterChannelRendering = extract_l( GT_16( nchanSeparateChannels, 0 ) ); + move16(); + mc_mode = hConfig->mc_mode; + ivas_total_brate = hConfig->ivas_total_brate; + move32(); + nchan_transport = hConfig->nchan_transport; + move16(); + nBins = hSpatParamRendCom->num_freq_bands; /* Actually bins */ + move16(); + + ism_mode = hConfig->ism_mode; + + dirac_read_idx = hSpatParamRendCom->render_to_md_map[subframe]; + move16(); + + FOR( idx = 0; idx < MAX_NUM_OBJECTS; idx++ ) + { + gainCache[idx].azi = -1000; /* Use -1000 as value for uninitialized cache. */ + move16(); + } + + FOR( bin = 0; bin < nBins; bin++ ) + { + Word32 tmpMtxRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], tmpMtxIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], resultMtxRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], resultMtxIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], gain_fx; + Word32 CxRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], CxIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; /* Input covariance matrix */ + Word32 realizedOutputEne_fx, targetOutputEne_fx, missingOutputEne_fx; + Word32 CrEneL_fx, CrEneR_fx; /* Cr = residual decorrelated sound covariance matrix */ Word32 CrCrossRe_fx, CrCrossIm_fx; + Word32 Mre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], Mim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], MdecRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], MdecIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; /* M = mixing matrix; Mdec = residual decorrelated signal mixing matrix */ + Word32 prototypeMtx_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { { ONE_IN_Q31, 107374182 }, { 107374182, ONE_IN_Q31 } }; + Word16 q_M, q_Cx, q_tmp, q_res, q_CrEne, q_CrCross, q_Mdec = 0; + Word32 tmp1, tmp2, res1, res2; + Word16 q_tmp1, q_tmp2, q_realizedOutputEne, q_targetOutputEne, q_missingOutputEne, q_gain; + Word16 exp1, exp2, q_processMtx_bin, q_processMtxDec_bin; + + CrEneL_fx = 0; + move32(); + CrEneR_fx = 0; + move32(); + q_CrEne = Q31; + move16(); - IF( hDiracDecBin->ChEne_e[0][bin] > hDiracDecBin->ChEne_e[1][bin] ) + IF( GT_16( hDiracDecBin->ChEne_e[0][bin], hDiracDecBin->ChEne_e[1][bin] ) ) { hDiracDecBin->ChEne_fx[1][bin] = L_shr( hDiracDecBin->ChEne_fx[1][bin], sub( hDiracDecBin->ChEne_e[0][bin], hDiracDecBin->ChEne_e[1][bin] ) ); hDiracDecBin->q_ChEne = 31 - hDiracDecBin->ChEne_e[0][bin]; @@ -2894,7 +3082,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices( hDiracDecBin->q_ChEne = 31 - hDiracDecBin->ChEne_e[1][bin]; hDiracDecBin->ChEne_e[0][bin] = hDiracDecBin->ChEne_e[1][bin]; } - IF( hDiracDecBin->ChEneOut_e[0][bin] > hDiracDecBin->ChEneOut_e[1][bin] ) + IF( GT_16( hDiracDecBin->ChEneOut_e[0][bin], hDiracDecBin->ChEneOut_e[1][bin] ) ) { hDiracDecBin->ChEneOut_fx[1][bin] = L_shr( hDiracDecBin->ChEneOut_fx[1][bin], sub( hDiracDecBin->ChEneOut_e[0][bin], hDiracDecBin->ChEneOut_e[1][bin] ) ); hDiracDecBin->q_ChEneOut = 31 - hDiracDecBin->ChEneOut_e[0][bin]; @@ -2907,7 +3095,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices( hDiracDecBin->ChEneOut_e[0][bin] = hDiracDecBin->ChEneOut_e[1][bin]; } - IF( hDiracDecBin->ChCrossRe_e[bin] > hDiracDecBin->ChCrossIm_e[bin] ) + IF( GT_16( hDiracDecBin->ChCrossRe_e[bin], hDiracDecBin->ChCrossIm_e[bin] ) ) { hDiracDecBin->ChCrossIm_fx[bin] = L_shr( hDiracDecBin->ChCrossIm_fx[bin], sub( hDiracDecBin->ChCrossRe_e[bin], hDiracDecBin->ChCrossIm_e[bin] ) ); hDiracDecBin->q_ChCross = 31 - hDiracDecBin->ChCrossRe_e[bin]; @@ -2919,7 +3107,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices( hDiracDecBin->q_ChCross = 31 - hDiracDecBin->ChCrossIm_e[bin]; hDiracDecBin->ChCrossRe_e[bin] = hDiracDecBin->ChCrossIm_e[bin]; } - IF( hDiracDecBin->ChCrossReOut_e[bin] > hDiracDecBin->ChCrossImOut_e[bin] ) + IF( GT_16( hDiracDecBin->ChCrossReOut_e[bin], hDiracDecBin->ChCrossImOut_e[bin] ) ) { hDiracDecBin->ChCrossImOut_fx[bin] = L_shr( hDiracDecBin->ChCrossImOut_fx[bin], sub( hDiracDecBin->ChCrossReOut_e[bin], hDiracDecBin->ChCrossImOut_e[bin] ) ); hDiracDecBin->q_ChCrossOut = 31 - hDiracDecBin->ChCrossReOut_e[bin]; @@ -2942,237 +3130,434 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices( hDiracDecBin->q_ChCrossOut, prototypeMtx_fx, Mre_fx, Mim_fx, &q_M, hDiracDecBin->reqularizationFactor_fx ); - for ( int a = 0; a < BINAURAL_CHANNELS; a++ ) + IF( LT_16( hDiracDecBin->q_ChEne, hDiracDecBin->q_ChCross ) ) { - for ( int b = 0; b < BINAURAL_CHANNELS; b++ ) - { - Mre[a][b] = (float) Mre_fx[a][b] / (float) pow( 2, q_M ); - Mim[a][b] = (float) Mim_fx[a][b] / (float) pow( 2, q_M ); - } + CxRe_fx[0][0] = hDiracDecBin->ChEne_fx[0][bin]; + move32(); + CxRe_fx[1][1] = hDiracDecBin->ChEne_fx[1][bin]; + move32(); + CxRe_fx[1][0] = L_shr( hDiracDecBin->ChCrossRe_fx[bin], sub( hDiracDecBin->q_ChCross, hDiracDecBin->q_ChEne ) ); + move32(); + CxRe_fx[0][1] = L_shr( hDiracDecBin->ChCrossRe_fx[bin], sub( hDiracDecBin->q_ChCross, hDiracDecBin->q_ChEne ) ); + move32(); + CxIm_fx[0][0] = 0; + move32(); + CxIm_fx[1][1] = 0; + move32(); + CxIm_fx[1][0] = L_shr( hDiracDecBin->ChCrossIm_fx[bin], sub( hDiracDecBin->q_ChCross, hDiracDecBin->q_ChEne ) ); + move32(); + CxIm_fx[0][1] = L_shr( -hDiracDecBin->ChCrossIm_fx[bin], sub( hDiracDecBin->q_ChCross, hDiracDecBin->q_ChEne ) ); + move32(); + q_Cx = hDiracDecBin->q_ChEne; + move16(); + } + ELSE + { + CxRe_fx[0][0] = L_shr( hDiracDecBin->ChEne_fx[0][bin], sub( hDiracDecBin->q_ChEne, hDiracDecBin->q_ChCross ) ); + move32(); + CxRe_fx[1][1] = L_shr( hDiracDecBin->ChEne_fx[1][bin], sub( hDiracDecBin->q_ChEne, hDiracDecBin->q_ChCross ) ); + move32(); + CxRe_fx[1][0] = hDiracDecBin->ChCrossRe_fx[bin]; + move32(); + CxRe_fx[0][1] = hDiracDecBin->ChCrossRe_fx[bin]; + move32(); + CxIm_fx[0][0] = 0; + move32(); + CxIm_fx[1][1] = 0; + move32(); + CxIm_fx[1][0] = hDiracDecBin->ChCrossIm_fx[bin]; + move32(); + CxIm_fx[0][1] = -hDiracDecBin->ChCrossIm_fx[bin]; + move32(); + q_Cx = hDiracDecBin->q_ChCross; + move16(); } -#endif - - /* Load estimated covariance matrix to the [2][2] matrix form */ - CxRe[0][0] = hDiracDecBin->ChEne[0][bin]; - CxRe[1][1] = hDiracDecBin->ChEne[1][bin]; - CxRe[1][0] = hDiracDecBin->ChCrossRe[bin]; - CxRe[0][1] = hDiracDecBin->ChCrossRe[bin]; - CxIm[0][0] = 0.0f; - CxIm[1][1] = 0.0f; - CxIm[1][0] = hDiracDecBin->ChCrossIm[bin]; - CxIm[0][1] = -hDiracDecBin->ChCrossIm[bin]; /* Make matrix multiplication M*Cx*M' to determine resulting covariance matrix of processing input with M */ - matrixMul( Mre, Mim, CxRe, CxIm, tmpMtxRe, tmpMtxIm ); - matrixTransp2Mul( tmpMtxRe, tmpMtxIm, Mre, Mim, resultMtxRe, resultMtxIm ); + matrixMul_fx( Mre_fx, Mim_fx, &q_M, CxRe_fx, CxIm_fx, &q_Cx, tmpMtxRe_fx, tmpMtxIm_fx, &q_tmp ); + matrixTransp2Mul_fx( tmpMtxRe_fx, tmpMtxIm_fx, &q_tmp, Mre_fx, Mim_fx, &q_M, resultMtxRe_fx, resultMtxIm_fx, &q_res ); /* When below the frequency limit where decorrelation is applied, we inject the decorrelated * residual (or missing) signal component. The procedure is active when there are not enough independent * signal energy to synthesize a signal with the target covariance matrix from the non-decorrelated signals */ - if ( bin < max_band_decorr ) + IF( LT_16( bin, max_band_decorr ) ) { - float decorrelationReductionFactor; + Word32 decorrelationReductionFactor_fx; + Word16 q_decorrelationReductionFactor; /* Subtract the resulting covariance matrix from the target covariance matrix to determine * what signal component is missing. The result is the target covariance matrix for the residual signal, i.e., * a residual covariance matrix. */ - CrEneL = max( 0.0f, hDiracDecBin->ChEneOut[0][bin] - resultMtxRe[0][0] ); - CrEneR = max( 0.0f, hDiracDecBin->ChEneOut[1][bin] - resultMtxRe[1][1] ); - CrCrossRe = hDiracDecBin->ChCrossReOut[bin] - resultMtxRe[1][0]; - CrCrossIm = hDiracDecBin->ChCrossImOut[bin] - resultMtxIm[1][0]; + exp = sub( get_min_scalefactor( hDiracDecBin->ChEneOut_fx[0][bin], hDiracDecBin->ChEneOut_fx[1][bin] ), 3 ); + tmp1 = L_shl( hDiracDecBin->ChEneOut_fx[0][bin], exp ); + tmp2 = L_shl( hDiracDecBin->ChEneOut_fx[1][bin], exp ); + q_tmp1 = add( hDiracDecBin->q_ChEneOut, exp ); - /* The amount of the decorrelated sound is further controlled based on the spatial metadata, - * by determining an energy-suppressed residual covariance matrix that is a control parameter - * that guides the processing of the decorrelated sound to a residual signal. - * The procedure improves quality in e.g. double-talk 2-direction rendering situations.*/ - if ( ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE ) + exp = sub( get_min_scalefactor( resultMtxRe_fx[0][0], resultMtxRe_fx[1][1] ), 3 ); + res1 = L_shl( resultMtxRe_fx[0][0], exp ); + res2 = L_shl( resultMtxRe_fx[1][1], exp ); + q_tmp2 = add( q_res, exp ); + + IF( LT_16( q_tmp1, q_tmp2 ) ) { - decorrelationReductionFactor = 1.0f; + CrEneL_fx = L_max( 0, L_sub( tmp1, L_shr( res1, sub( q_tmp2, q_tmp1 ) ) ) ); + CrEneR_fx = L_max( 0, L_sub( tmp2, L_shr( res2, sub( q_tmp2, q_tmp1 ) ) ) ); + q_CrEne = q_tmp1; + move16(); } - else if ( ( ivas_format == MC_FORMAT && mc_mode == MC_MODE_MCMASA ) || ( ivas_format == MASA_FORMAT && nchan_transport == 1 ) ) + ELSE { - decorrelationReductionFactor = sqrtf( fmaxf( 0.0f, hDiracDecBin->frameMeanDiffuseness[bin] ) ); + CrEneL_fx = L_max( 0, L_sub( L_shr( tmp1, sub( q_tmp1, q_tmp2 ) ), res1 ) ); + CrEneR_fx = L_max( 0, L_sub( L_shr( tmp2, sub( q_tmp1, q_tmp2 ) ), res2 ) ); + q_CrEne = q_tmp2; + move16(); } - else if ( ( ivas_format == SBA_FORMAT || ivas_format == SBA_ISM_FORMAT ) && nchan_transport == 1 ) + + exp = sub( get_min_scalefactor( hDiracDecBin->ChCrossReOut_fx[bin], hDiracDecBin->ChCrossImOut_fx[bin] ), 3 ); + tmp1 = L_shl( hDiracDecBin->ChCrossReOut_fx[bin], exp ); + tmp2 = L_shl( hDiracDecBin->ChCrossImOut_fx[bin], exp ); + q_tmp1 = add( hDiracDecBin->q_ChCrossOut, exp ); + + exp = sub( get_min_scalefactor( resultMtxRe_fx[1][0], resultMtxIm_fx[1][0] ), 3 ); + res1 = L_shl( resultMtxRe_fx[1][0], exp ); + res2 = L_shl( resultMtxIm_fx[1][0], exp ); + q_tmp2 = add( q_res, exp ); + + IF( LT_16( q_tmp1, q_tmp2 ) ) { - decorrelationReductionFactor = 1.0f; + CrCrossRe_fx = L_sub( tmp1, L_shr( res1, sub( q_tmp2, q_tmp1 ) ) ); + CrCrossIm_fx = L_sub( tmp2, L_shr( res2, sub( q_tmp2, q_tmp1 ) ) ); + q_CrCross = q_tmp1; + move16(); } - else + ELSE { - decorrelationReductionFactor = fmaxf( 0.0f, hDiracDecBin->frameMeanDiffuseness[bin] ); + CrCrossRe_fx = L_sub( L_shr( tmp1, sub( q_tmp1, q_tmp2 ) ), res1 ); + CrCrossIm_fx = L_sub( L_shr( tmp2, sub( q_tmp1, q_tmp2 ) ), res2 ); + q_CrCross = q_tmp2; + move16(); } - CrEneL *= decorrelationReductionFactor; - CrEneR *= decorrelationReductionFactor; - CrCrossRe *= decorrelationReductionFactor; - CrCrossIm *= decorrelationReductionFactor; - - /* Determine a residual mixing matrix Mdec for processing the decorrelated signal to obtain - * the residual signal (that has the residual covariance matrix) */ -#ifndef IVAS_FLOAT_FIXED - formulate2x2MixingMatrix( hDiracDecBin->ChEne[0][bin], hDiracDecBin->ChEne[1][bin], - 0.0f, 0.0f, /* Decorrelated signal has ideally no cross-terms */ - CrEneL, CrEneR, - CrCrossRe, CrCrossIm, - prototypeMtx, MdecRe, MdecIm, 0.2f ); -#else - int16_t exp, exp1; - f2me( CrEneL, &CrEneL_fx, &exp ); - f2me( CrEneR, &CrEneR_fx, &exp1 ); - if ( exp > exp1 ) + /* The amount of the decorrelated sound is further controlled based on the spatial metadata, + * by determining an energy-suppressed residual covariance matrix that is a control parameter + * that guides the processing of the decorrelated sound to a residual signal. + * The procedure improves quality in e.g. double-talk 2-direction rendering situations.*/ + IF( EQ_16( ivas_format, MASA_FORMAT ) && LT_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) ) { - CrEneR_fx = L_shr( CrEneR_fx, exp - exp1 ); - q_CrEne = 31 - exp; + decorrelationReductionFactor_fx = ONE_IN_Q30; + move32(); + q_decorrelationReductionFactor = Q30; + move16(); } - else + ELSE IF( L_or( L_and( EQ_16( ivas_format, MC_FORMAT ), EQ_16( mc_mode, MC_MODE_MCMASA ) ), L_and( EQ_16( ivas_format, MASA_FORMAT ), EQ_16( nchan_transport, 1 ) ) ) ) { - CrEneL_fx = L_shr( CrEneL_fx, exp1 - exp ); - q_CrEne = 31 - exp1; + exp = sub( 31, 29 ); + decorrelationReductionFactor_fx = Sqrt32( L_max( 0, hDiracDecBin->frameMeanDiffuseness_fx[bin] ), &exp ); + q_decorrelationReductionFactor = sub( 31, exp ); } - - f2me( CrCrossRe, &CrCrossRe_fx, &exp ); - f2me( CrCrossIm, &CrCrossIm_fx, &exp1 ); - if ( exp > exp1 ) + ELSE IF( L_and( L_or( EQ_16( ivas_format, SBA_FORMAT ), EQ_16( ivas_format, SBA_ISM_FORMAT ) ), EQ_16( nchan_transport, 1 ) ) ) { - CrCrossIm_fx = L_shr( CrCrossIm_fx, exp - exp1 ); - q_CrCross = 31 - exp; + decorrelationReductionFactor_fx = ONE_IN_Q30; + move32(); + q_decorrelationReductionFactor = Q30; + move16(); } - else + ELSE { - CrCrossRe_fx = L_shr( CrCrossRe_fx, exp1 - exp ); - q_CrCross = 31 - exp1; + decorrelationReductionFactor_fx = L_max( 0, hDiracDecBin->frameMeanDiffuseness_fx[bin] ); + q_decorrelationReductionFactor = 29; + move16(); } + CrEneL_fx = Mpy_32_32( CrEneL_fx, decorrelationReductionFactor_fx ); + CrEneR_fx = Mpy_32_32( CrEneR_fx, decorrelationReductionFactor_fx ); + q_CrEne = sub( add( q_CrEne, q_decorrelationReductionFactor ), 31 ); + CrCrossRe_fx = Mpy_32_32( CrCrossRe_fx, decorrelationReductionFactor_fx ); + CrCrossIm_fx = Mpy_32_32( CrCrossIm_fx, decorrelationReductionFactor_fx ); + q_CrCross = sub( add( q_CrCross, q_decorrelationReductionFactor ), 31 ); + formulate2x2MixingMatrix_fx( hDiracDecBin->ChEne_fx[0][bin], hDiracDecBin->ChEne_fx[1][bin], hDiracDecBin->q_ChEne, 0, 0, /* Decorrelated signal has ideally no cross-terms */ Q31, CrEneL_fx, CrEneR_fx, q_CrEne, CrCrossRe_fx, CrCrossIm_fx, q_CrCross, prototypeMtx_fx, MdecRe_fx, MdecIm_fx, &q_Mdec, 3277 ); // 3277 = 0.2 in Q14 - - for ( int a = 0; a < BINAURAL_CHANNELS; a++ ) - { - for ( int b = 0; b < BINAURAL_CHANNELS; b++ ) - { - MdecRe[a][b] = (float) MdecRe_fx[a][b] / (float) pow( 2, q_Mdec ); - MdecIm[a][b] = (float) MdecIm_fx[a][b] / (float) pow( 2, q_Mdec ); - } - } -#endif } - else + ELSE { - for ( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) + FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) { - set_zero( MdecRe[chA], BINAURAL_CHANNELS ); - set_zero( MdecIm[chA], BINAURAL_CHANNELS ); + set_zero_fx( MdecRe_fx[chA], BINAURAL_CHANNELS ); + set_zero_fx( MdecIm_fx[chA], BINAURAL_CHANNELS ); } + q_Mdec = Q31; + move16(); } /* The regularizations at determining mixing matrices cause signal energy to be lost to some degree, which is compensated for here */ - realizedOutputEne = CrEneL + CrEneR + resultMtxRe[0][0] + resultMtxRe[1][1]; - targetOutputEne = hDiracDecBin->ChEneOut[0][bin] + hDiracDecBin->ChEneOut[1][bin]; - missingOutputEne = fmaxf( 0.0f, targetOutputEne - realizedOutputEne ); + tmp1 = L_add( CrEneL_fx, CrEneR_fx ); + exp = sub( get_min_scalefactor( resultMtxRe_fx[0][0], resultMtxRe_fx[1][1] ), 2 ); + tmp2 = L_add( L_shl( resultMtxRe_fx[0][0], exp ), L_shl( resultMtxRe_fx[1][1], exp ) ); + q_tmp2 = add( q_res, exp ); + IF( LT_16( q_CrEne, q_tmp2 ) ) + { + realizedOutputEne_fx = L_add( tmp1, L_shr( tmp2, sub( q_tmp2, q_CrEne ) ) ); + q_realizedOutputEne = q_CrEne; + move16(); + } + ELSE + { + realizedOutputEne_fx = L_add( L_shr( tmp1, sub( q_CrEne, q_tmp2 ) ), tmp2 ); + q_realizedOutputEne = q_tmp2; + move16(); + } - gain = sqrtf( ( resultMtxRe[0][0] + resultMtxRe[1][1] + missingOutputEne ) / - fmaxf( 1e-12f, resultMtxRe[0][0] + resultMtxRe[1][1] ) ); - gain = fminf( 4.0f, gain ); + exp = sub( get_min_scalefactor( hDiracDecBin->ChEneOut_fx[0][bin], hDiracDecBin->ChEneOut_fx[1][bin] ), 1 ); + targetOutputEne_fx = L_add( L_shl( hDiracDecBin->ChEneOut_fx[0][bin], exp ), L_shl( hDiracDecBin->ChEneOut_fx[1][bin], exp ) ); + q_targetOutputEne = add( hDiracDecBin->q_ChEneOut, exp ); - for ( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) + exp = sub( norm_l( targetOutputEne_fx ), 2 ); + targetOutputEne_fx = L_shl( targetOutputEne_fx, exp ); + q_targetOutputEne = add( q_targetOutputEne, exp ); + exp = sub( norm_l( -realizedOutputEne_fx ), 2 ); + realizedOutputEne_fx = L_shl( -realizedOutputEne_fx, exp ); + q_realizedOutputEne = add( q_realizedOutputEne, exp ); + IF( LT_16( q_realizedOutputEne, q_targetOutputEne ) ) { - for ( chB = 0; chB < BINAURAL_CHANNELS; chB++ ) + missingOutputEne_fx = L_max( 0, L_add( L_shr( targetOutputEne_fx, sub( q_targetOutputEne, q_realizedOutputEne ) ), realizedOutputEne_fx ) ); + q_missingOutputEne = q_realizedOutputEne; + move16(); + } + ELSE + { + missingOutputEne_fx = L_max( 0, L_add( targetOutputEne_fx, L_shr( realizedOutputEne_fx, sub( q_realizedOutputEne, q_targetOutputEne ) ) ) ); + q_missingOutputEne = q_targetOutputEne; + move16(); + } + + tmp1 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), missingOutputEne_fx, sub( 31, q_missingOutputEne ), &exp1 ); + + { + Word16 exp_temp; + tmp2 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), EPSILON_MANT, EPSILON_EXP, &exp_temp ); + tmp2 = BASOP_Util_Divide3232_Scale_cadence( tmp1, tmp2, &exp ); + exp2 = add( exp, sub( exp1, exp_temp ) ); + } + gain_fx = Sqrt32( tmp2, &exp2 ); + q_gain = sub( 31, exp2 ); + + // 1073741824 = 4 in Q28 + IF( LT_16( q_gain, Q28 ) ) + { + gain_fx = L_min( gain_fx, L_shr( 1073741824, sub( Q28, q_gain ) ) ); + } + ELSE + { + gain_fx = L_min( L_shr( gain_fx, sub( q_gain, Q28 ) ), 1073741824 ); + q_gain = Q28; + move16(); + } + + FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) + { + FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ ) { - Mre[chA][chB] *= gain; - Mim[chA][chB] *= gain; + Mre_fx[chA][chB] = Mpy_32_32( Mre_fx[chA][chB], gain_fx ); + move32(); + Mim_fx[chA][chB] = Mpy_32_32( Mim_fx[chA][chB], gain_fx ); + move32(); } } + q_M = sub( add( q_M, q_gain ), 31 ); + + exp = s_min( L_norm_arr( Mre_fx[0], i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ) ), L_norm_arr( Mim_fx[0], i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ) ) ); + scale_sig32( Mre_fx[0], i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ), exp ); + scale_sig32( Mim_fx[0], i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ), exp ); + q_M = add( q_M, exp ); + exp = s_min( L_norm_arr( MdecRe_fx[0], i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ) ), L_norm_arr( MdecIm_fx[0], i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ) ) ); + scale_sig32( MdecRe_fx[0], i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ), exp ); + scale_sig32( MdecIm_fx[0], i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ), exp ); + q_Mdec = add( q_Mdec, exp ); + + q_processMtx_bin = q_processMtx[bin]; + q_processMtxDec_bin = q_processMtxDec[bin]; /* Store processing matrices */ - for ( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) + FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) { - for ( chB = 0; chB < BINAURAL_CHANNELS; chB++ ) + FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ ) { - hDiracDecBin->processMtxRePrev[chA][chB][bin] = hDiracDecBin->processMtxRe[chA][chB][bin]; - hDiracDecBin->processMtxImPrev[chA][chB][bin] = hDiracDecBin->processMtxIm[chA][chB][bin]; - hDiracDecBin->processMtxDecRePrev[chA][chB][bin] = hDiracDecBin->processMtxDecRe[chA][chB][bin]; - hDiracDecBin->processMtxDecImPrev[chA][chB][bin] = hDiracDecBin->processMtxDecIm[chA][chB][bin]; + hDiracDecBin->processMtxRePrev_fx[chA][chB][bin] = hDiracDecBin->processMtxRe_fx[chA][chB][bin]; + move16(); + hDiracDecBin->processMtxImPrev_fx[chA][chB][bin] = hDiracDecBin->processMtxIm_fx[chA][chB][bin]; + move16(); - hDiracDecBin->processMtxRe[chA][chB][bin] = Mre[chA][chB]; - hDiracDecBin->processMtxIm[chA][chB][bin] = Mim[chA][chB]; - hDiracDecBin->processMtxDecRe[chA][chB][bin] = MdecRe[chA][chB]; - hDiracDecBin->processMtxDecIm[chA][chB][bin] = MdecIm[chA][chB]; + hDiracDecBin->processMtxDecRePrev_fx[chA][chB][bin] = hDiracDecBin->processMtxDecRe_fx[chA][chB][bin]; + move16(); + hDiracDecBin->processMtxDecImPrev_fx[chA][chB][bin] = hDiracDecBin->processMtxDecIm_fx[chA][chB][bin]; + move16(); + + hDiracDecBin->processMtxRe_fx[chA][chB][bin] = extract_h( Mre_fx[chA][chB] ); + move16(); + hDiracDecBin->processMtxIm_fx[chA][chB][bin] = extract_h( Mim_fx[chA][chB] ); + move16(); + + hDiracDecBin->processMtxDecRe_fx[chA][chB][bin] = extract_h( MdecRe_fx[chA][chB] ); + move16(); + hDiracDecBin->processMtxDecIm_fx[chA][chB][bin] = extract_h( MdecIm_fx[chA][chB] ); + move16(); } } + q_processMtxPrev[bin] = q_processMtx_bin; + move16(); + q_processMtxDecPrev[bin] = q_processMtxDec_bin; + move16(); + q_processMtx[bin] = sub( q_M, 16 ); + move16(); + q_processMtxDec[bin] = sub( q_Mdec, 16 ); + move16(); - if ( separateCenterChannelRendering ) + IF( separateCenterChannelRendering ) { /* The rendering of the separate center channel in masa + mono mode. * The center channel is processed with a gain factor 0.8414f to match the loudness of different processing paths */ - float lRealp, lImagp, rRealp, rImagp; - float gainFactor; - int16_t aziDeg = 0; - int16_t eleDeg = 0; - uint8_t instantChange = 0; + Word32 lRealp_fx, lImagp_fx, rRealp_fx, rImagp_fx; + Word32 gainFactor_fx; + Word16 q_tmp_sq; + Word16 aziDeg = 0; + move16(); + Word16 eleDeg = 0; + move16(); + UWord8 instantChange = 0; + move16(); - if ( ivas_format == MASA_ISM_FORMAT ) + exp = sub( 31, hDiracDecBin->q_earlyPartEneCorrection ); + tmp1 = Sqrt32( hDiracDecBin->earlyPartEneCorrection_fx[bin], &exp ); + q_tmp_sq = sub( 31, exp ); + IF( EQ_16( ivas_format, MASA_ISM_FORMAT ) ) { - gainFactor = 0.7943f * sqrtf( hDiracDecBin->earlyPartEneCorrection[bin] ); + gainFactor_fx = Mpy_32_32( 1705746262, tmp1 ); // 1705746262 = 0.7943f in Q31 } - else + ELSE { - gainFactor = 0.8414f * sqrtf( hDiracDecBin->earlyPartEneCorrection[bin] ); + gainFactor_fx = Mpy_32_32( 1806892741, tmp1 ); // 1806892741 = 0.8414f in Q31 } + q_gain = sub( add( q_tmp_sq, 31 ), 31 ); - for ( chB = 0; chB < nchanSeparateChannels; chB++ ) + q_processMtx_bin = q_processMtx_SCCR[bin]; + + FOR( chB = 0; chB < nchanSeparateChannels; chB++ ) { - if ( ivas_format == MASA_ISM_FORMAT ) + IF( EQ_16( ivas_format, MASA_ISM_FORMAT ) ) { - if ( ism_mode == ISM_MASA_MODE_DISC ) + IF( EQ_16( ism_mode, ISM_MASA_MODE_DISC ) ) { aziDeg = hMasaIsmData->azimuth_ism[chB][dirac_read_idx]; + move16(); eleDeg = hMasaIsmData->elevation_ism[chB][dirac_read_idx]; + move16(); } - else + ELSE { aziDeg = hMasaIsmData->azimuth_separated_ism[dirac_read_idx]; + move16(); eleDeg = hMasaIsmData->elevation_separated_ism[dirac_read_idx]; + move16(); instantChange = 1; + move16(); } } - for ( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) - { - hDiracDecBin->processMtxRePrev[chA][chB + 2][bin] = hDiracDecBin->processMtxRe[chA][chB + 2][bin]; - hDiracDecBin->processMtxImPrev[chA][chB + 2][bin] = hDiracDecBin->processMtxIm[chA][chB + 2][bin]; - } -#ifdef IVAS_FLOAT_FIXED - Word32 Rmat_fx[3][3], lRealp_fx, lImagp_fx, rRealp_fx, rImagp_fx; - for ( int p = 0; p < 3; p++ ) + FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) { - floatToFixed_arrL( Rmat[p], Rmat_fx[p], Q30, 3 ); + hDiracDecBin->processMtxRePrev_fx[chA][add( chB, 2 )][bin] = hDiracDecBin->processMtxRe_fx[chA][add( chB, 2 )][bin]; + move16(); + hDiracDecBin->processMtxImPrev_fx[chA][add( chB, 2 )][bin] = hDiracDecBin->processMtxIm_fx[chA][add( chB, 2 )][bin]; + move16(); } + q_processMtxPrev_SCCR[bin] = q_processMtx_bin; + move16(); - getDirectPartGains_fx( bin, aziDeg, eleDeg, &lRealp_fx, &lImagp_fx, &rRealp_fx, &rImagp_fx, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat_fx, &gainCache[chB], isHeadtracked ); + getDirectPartGains_fx( bin, aziDeg, eleDeg, &lRealp_fx, &lImagp_fx, &rRealp_fx, &rImagp_fx, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[chB], isHeadtracked ); - lRealp = fixedToFloat_32( lRealp_fx, Q28 ); - lImagp = fixedToFloat_32( lImagp_fx, Q28 ); - rRealp = fixedToFloat_32( rRealp_fx, Q28 ); - rImagp = fixedToFloat_32( rImagp_fx, Q28 ); -#else - getDirectPartGains( bin, aziDeg, eleDeg, &lRealp, &lImagp, &rRealp, &rImagp, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[chB], isHeadtracked ); -#endif - hDiracDecBin->processMtxRe[0][chB + 2][bin] = lRealp * gainFactor; - hDiracDecBin->processMtxIm[0][chB + 2][bin] = lImagp * gainFactor; - hDiracDecBin->processMtxRe[1][chB + 2][bin] = rRealp * gainFactor; - hDiracDecBin->processMtxIm[1][chB + 2][bin] = rImagp * gainFactor; + hDiracDecBin->processMtxRe_fx[0][add( chB, 2 )][bin] = extract_h( Mpy_32_32( lRealp_fx, gainFactor_fx ) ); + move16(); + hDiracDecBin->processMtxIm_fx[0][add( chB, 2 )][bin] = extract_h( Mpy_32_32( lImagp_fx, gainFactor_fx ) ); + move16(); + hDiracDecBin->processMtxRe_fx[1][add( chB, 2 )][bin] = extract_h( Mpy_32_32( rRealp_fx, gainFactor_fx ) ); + move16(); + hDiracDecBin->processMtxIm_fx[1][add( chB, 2 )][bin] = extract_h( Mpy_32_32( rImagp_fx, gainFactor_fx ) ); + move16(); + q_processMtx_SCCR[bin] = sub( sub( add( Q28, q_gain ), 31 ), 16 ); + move16(); - if ( instantChange ) + IF( instantChange ) { - for ( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) + FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) { - hDiracDecBin->processMtxRePrev[chA][chB + 2][bin] = hDiracDecBin->processMtxRe[chA][chB + 2][bin]; - hDiracDecBin->processMtxImPrev[chA][chB + 2][bin] = hDiracDecBin->processMtxIm[chA][chB + 2][bin]; + hDiracDecBin->processMtxRePrev_fx[chA][add( chB, 2 )][bin] = hDiracDecBin->processMtxRe_fx[chA][add( chB, 2 )][bin]; + move16(); + hDiracDecBin->processMtxImPrev_fx[chA][add( chB, 2 )][bin] = hDiracDecBin->processMtxIm_fx[chA][add( chB, 2 )][bin]; + move16(); } + q_processMtxPrev_SCCR[bin] = q_processMtx_SCCR[bin]; + move16(); + } + } + } + } + /* Aligning Q-factors of all bins in the processing matrices to a common Q-factor */ + minimum_s( q_processMtx, nBins, &hDiracDecBin->q_processMtx ); + minimum_s( q_processMtxPrev, nBins, &hDiracDecBin->q_processMtxPrev ); + IF( separateCenterChannelRendering ) + { + minimum_s( q_processMtx_SCCR, nBins, &hDiracDecBin->q_processMtxSCCR ); + minimum_s( q_processMtxPrev_SCCR, nBins, &hDiracDecBin->q_processMtxPrevSCCR ); + } + hDiracDecBin->q_processMtx = s_min( hDiracDecBin->q_processMtx, hDiracDecBin->q_processMtxSCCR ); + hDiracDecBin->q_processMtxPrev = s_min( hDiracDecBin->q_processMtxPrev, hDiracDecBin->q_processMtxPrevSCCR ); + hDiracDecBin->q_processMtxSCCR = hDiracDecBin->q_processMtx; + move16(); + hDiracDecBin->q_processMtxPrevSCCR = hDiracDecBin->q_processMtxPrev; + move16(); + minimum_s( q_processMtxDec, nBins, &hDiracDecBin->q_processMtxDec ); + minimum_s( q_processMtxDecPrev, nBins, &hDiracDecBin->q_processMtxDecPrev ); + + FOR( bin = 0; bin < nBins; bin++ ) + { + FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) + { + FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ ) + { + hDiracDecBin->processMtxRe_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxRe_fx[chA][chB][bin], sub( q_processMtx[bin], hDiracDecBin->q_processMtx ) ); + move16(); + hDiracDecBin->processMtxIm_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxIm_fx[chA][chB][bin], sub( q_processMtx[bin], hDiracDecBin->q_processMtx ) ); + move16(); + hDiracDecBin->processMtxRePrev_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxRePrev_fx[chA][chB][bin], sub( q_processMtxPrev[bin], hDiracDecBin->q_processMtxPrev ) ); + move16(); + hDiracDecBin->processMtxImPrev_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxImPrev_fx[chA][chB][bin], sub( q_processMtxPrev[bin], hDiracDecBin->q_processMtxPrev ) ); + move16(); + hDiracDecBin->processMtxDecRe_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxDecRe_fx[chA][chB][bin], sub( q_processMtxDec[bin], hDiracDecBin->q_processMtxDec ) ); + move16(); + hDiracDecBin->processMtxDecIm_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxDecIm_fx[chA][chB][bin], sub( q_processMtxDec[bin], hDiracDecBin->q_processMtxDec ) ); + move16(); + hDiracDecBin->processMtxDecRePrev_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxDecRePrev_fx[chA][chB][bin], sub( q_processMtxDecPrev[bin], hDiracDecBin->q_processMtxDecPrev ) ); + move16(); + hDiracDecBin->processMtxDecImPrev_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxDecImPrev_fx[chA][chB][bin], sub( q_processMtxDecPrev[bin], hDiracDecBin->q_processMtxDecPrev ) ); + move16(); + } + IF( separateCenterChannelRendering ) + { + FOR( chB = 0; chB < nchanSeparateChannels; chB++ ) + { + hDiracDecBin->processMtxRe_fx[chA][add( chB, 2 )][bin] = shr( hDiracDecBin->processMtxRe_fx[chA][add( chB, 2 )][bin], sub( q_processMtx_SCCR[bin], hDiracDecBin->q_processMtx ) ); + move16(); + hDiracDecBin->processMtxIm_fx[chA][add( chB, 2 )][bin] = shr( hDiracDecBin->processMtxIm_fx[chA][add( chB, 2 )][bin], sub( q_processMtx_SCCR[bin], hDiracDecBin->q_processMtx ) ); + move16(); + hDiracDecBin->processMtxRePrev_fx[chA][add( chB, 2 )][bin] = shr( hDiracDecBin->processMtxRePrev_fx[chA][add( chB, 2 )][bin], sub( q_processMtxPrev_SCCR[bin], hDiracDecBin->q_processMtxPrev ) ); + move16(); + hDiracDecBin->processMtxImPrev_fx[chA][add( chB, 2 )][bin] = shr( hDiracDecBin->processMtxImPrev_fx[chA][add( chB, 2 )][bin], sub( q_processMtxPrev_SCCR[bin], hDiracDecBin->q_processMtxPrev ) ); + move16(); } } } @@ -3180,7 +3565,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices( return; } - +#endif #ifdef IVAS_FLOAT_FIXED static void ivas_dirac_dec_binaural_process_output_fx( @@ -4573,7 +4958,7 @@ static void matrixDiagMul_fx( } #endif // IVAS_FLOAT_FIXED - +#ifndef IVAS_FLOAT_FIXED static void matrixMul( float Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Aim[BINAURAL_CHANNELS][BINAURAL_CHANNELS], @@ -4597,7 +4982,7 @@ static void matrixMul( return; } -#ifdef IVAS_FLOAT_FIXED +#else static void matrixMul_fx( Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], Word32 Aim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], @@ -4706,7 +5091,6 @@ static void matrixTransp1Mul_fx( Word16 size = i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ); Word32 tmp1, tmp2; - FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) { FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ ) @@ -4746,7 +5130,7 @@ static void matrixTransp1Mul_fx( } #endif // IVAS_FLOAT_FIXED - +#ifndef IVAS_FLOAT_FIXED static void matrixTransp2Mul( float Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Aim[BINAURAL_CHANNELS][BINAURAL_CHANNELS], @@ -4770,7 +5154,7 @@ static void matrixTransp2Mul( return; } -#ifdef IVAS_FLOAT_FIXED +#else static void matrixTransp2Mul_fx( Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], Word32 Aim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], @@ -6802,35 +7186,13 @@ static void ivas_masa_ext_rend_parambin_internal( Word16 nBins; Word16 i, j; Word16 nchan_transport; + Word16 q_mat; #if 1 hDiracDecBin = hMasaExtRend->hDiracDecBin; hSpatParamRendCom = hMasaExtRend->hSpatParamRendCom; Word32 *output_fx[MAX_OUTPUT_CHANNELS]; Word32 output_fx_buff[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - Word16 q_earlyPartEneCorrection = Q_factor_arrL( hDiracDecBin->earlyPartEneCorrection, hSpatParamRendCom->num_freq_bands ); - hDiracDecBin->q_earlyPartEneCorrection = q_earlyPartEneCorrection; - floatToFixed_arr32( hDiracDecBin->earlyPartEneCorrection, hDiracDecBin->earlyPartEneCorrection_fx, q_earlyPartEneCorrection, hSpatParamRendCom->num_freq_bands ); - floatToFixed_arr32( hDiracDecBin->diffuseFieldCoherence, hDiracDecBin->diffuseFieldCoherence_fx, Q31, hSpatParamRendCom->num_freq_bands ); - FOR( j = 0; j < hSpatParamRendCom->num_freq_bands; j++ ) - { - f2me( hDiracDecBin->ChCrossRePrev[j], &hDiracDecBin->ChCrossRePrev_fx[j], &hDiracDecBin->ChCrossRePrev_e[j] ); - f2me( hDiracDecBin->ChCrossImPrev[j], &hDiracDecBin->ChCrossImPrev_fx[j], &hDiracDecBin->ChCrossImPrev_e[j] ); - f2me( hDiracDecBin->ChCrossReOutPrev[j], &hDiracDecBin->ChCrossReOutPrev_fx[j], &hDiracDecBin->ChCrossReOutPrev_e[j] ); - f2me( hDiracDecBin->ChCrossImOutPrev[j], &hDiracDecBin->ChCrossImOutPrev_fx[j], &hDiracDecBin->ChCrossImOutPrev_e[j] ); - FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) - { - f2me( hDiracDecBin->ChEnePrev[i][j], &hDiracDecBin->ChEnePrev_fx[i][j], &hDiracDecBin->ChEnePrev_e[i][j] ); - f2me( hDiracDecBin->ChEneOutPrev[i][j], &hDiracDecBin->ChEneOutPrev_fx[i][j], &hDiracDecBin->ChEneOutPrev_e[i][j] ); - } - } - floatToFixed_arr32( hDiracDecBin->diffuseFieldCoherence, hDiracDecBin->diffuseFieldCoherence_fx, 31, hSpatParamRendCom->num_freq_bands ); - IF( hDiracDecBin->hDiffuseDist ) - { - floatToFixed_arr32( hDiracDecBin->diffuseFieldCoherenceX, hDiracDecBin->diffuseFieldCoherenceX_fx, 31, 9 ); - floatToFixed_arr32( hDiracDecBin->diffuseFieldCoherenceY, hDiracDecBin->diffuseFieldCoherenceY_fx, 31, 9 ); - floatToFixed_arr32( hDiracDecBin->diffuseFieldCoherenceZ, hDiracDecBin->diffuseFieldCoherenceZ_fx, 31, 9 ); - } FOR( ch = 0; ch < 2; ch++ ) { output_fx[ch] = output_fx_buff[ch]; @@ -6966,46 +7328,13 @@ static void ivas_masa_ext_rend_parambin_internal( /* Always using CLDFB decorrelation in MASA EXT renderer */ max_band_decorr = hDiracDecBin->h_freq_domain_decorr_ap_params->max_band_decorr; -#if 1 - FOR( i = 0; i < BINAURAL_CHANNELS; i++ ) - { - FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) - { - hDiracDecBin->ChEnePrev[i][j] = me2f( hDiracDecBin->ChEnePrev_fx[i][j], hDiracDecBin->ChEnePrev_e[i][j] ); - hDiracDecBin->ChEne[i][j] = me2f( hDiracDecBin->ChEne_fx[i][j], hDiracDecBin->ChEne_e[i][j] ); - hDiracDecBin->ChEneOut[i][j] = me2f( hDiracDecBin->ChEneOut_fx[i][j], hDiracDecBin->ChEneOut_e[i][j] ); - hDiracDecBin->ChEneOutPrev[i][j] = me2f( hDiracDecBin->ChEneOutPrev_fx[i][j], hDiracDecBin->ChEneOutPrev_e[i][j] ); - } - } - - FOR( j = 0; j < nBins; j++ ) - { - hDiracDecBin->ChCrossRePrev[j] = me2f( hDiracDecBin->ChCrossRePrev_fx[j], hDiracDecBin->ChCrossRePrev_e[j] ); - hDiracDecBin->ChCrossImPrev[j] = me2f( hDiracDecBin->ChCrossImPrev_fx[j], hDiracDecBin->ChCrossImPrev_e[j] ); - hDiracDecBin->ChCrossRe[j] = me2f( hDiracDecBin->ChCrossRe_fx[j], hDiracDecBin->ChCrossRe_e[j] ); - hDiracDecBin->ChCrossIm[j] = me2f( hDiracDecBin->ChCrossIm_fx[j], hDiracDecBin->ChCrossIm_e[j] ); - hDiracDecBin->ChCrossReOut[j] = me2f( hDiracDecBin->ChCrossReOut_fx[j], hDiracDecBin->ChCrossReOut_e[j] ); - hDiracDecBin->ChCrossImOut[j] = me2f( hDiracDecBin->ChCrossImOut_fx[j], hDiracDecBin->ChCrossImOut_e[j] ); - hDiracDecBin->ChCrossReOutPrev[j] = me2f( hDiracDecBin->ChCrossReOutPrev_fx[j], hDiracDecBin->ChCrossReOutPrev_e[j] ); - hDiracDecBin->ChCrossImOutPrev[j] = me2f( hDiracDecBin->ChCrossImOutPrev_fx[j], hDiracDecBin->ChCrossImOutPrev_e[j] ); - } - fixedToFloat_arrL( hDiracDecBin->frameMeanDiffuseness_fx, hDiracDecBin->frameMeanDiffuseness, 29, CLDFB_NO_CHANNELS_MAX ); -#endif - - - float Rmat[3][3]; - for ( i = 0; i < 3; i++ ) // TODO: To be removed - { - fixedToFloat_arrL32( Rmat_fx[i], Rmat[i], Q30, 3 ); - } - ivas_dirac_dec_binaural_determine_processing_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat, subframe, - hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, - 0, NULL ); + ivas_dirac_dec_binaural_determine_processing_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat_fx, subframe, + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, + 0, NULL ); #if 1 Word16 q_out; - Word16 q_mat = 15; q_inp = Q6; FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { @@ -7013,46 +7342,39 @@ static void ivas_masa_ext_rend_parambin_internal( } FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - FOR( slot = 0; slot < BINAURAL_CHANNELS; slot++ ) - { - q_mat = s_min( q_mat, Q_factor_arr( hDiracDecBin->processMtxDecRe[ch][slot], nBins ) ); - q_mat = s_min( q_mat, Q_factor_arr( hDiracDecBin->processMtxDecIm[ch][slot], nBins ) ); - q_mat = s_min( q_mat, Q_factor_arr( hDiracDecBin->processMtxDecRePrev[ch][slot], nBins ) ); - q_mat = s_min( q_mat, Q_factor_arr( hDiracDecBin->processMtxDecImPrev[ch][slot], nBins ) ); - } - } - FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - FOR( slot = 0; slot < numInChannels; slot++ ) - { - q_mat = s_min( q_mat, Q_factor_arr( hDiracDecBin->processMtxRe[ch][slot], nBins ) ); - q_mat = s_min( q_mat, Q_factor_arr( hDiracDecBin->processMtxIm[ch][slot], nBins ) ); - q_mat = s_min( q_mat, Q_factor_arr( hDiracDecBin->processMtxRePrev[ch][slot], nBins ) ); - q_mat = s_min( q_mat, Q_factor_arr( hDiracDecBin->processMtxImPrev[ch][slot], nBins ) ); - } + hMasaExtRend->cldfbSynRend[ch]->Q_cldfb_state = Q11; } +#endif // Float to fix ends + + q_mat = hDiracDecBin->q_processMtx; + q_mat = s_min( q_mat, hDiracDecBin->q_processMtxPrev ); + q_mat = s_min( q_mat, hDiracDecBin->q_processMtxDec ); + q_mat = s_min( q_mat, hDiracDecBin->q_processMtxDecPrev ); + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { FOR( slot = 0; slot < BINAURAL_CHANNELS; slot++ ) { - floatToFixed_arr16( hDiracDecBin->processMtxDecRe[ch][slot], hDiracDecBin->processMtxDecRe_fx[ch][slot], q_mat, nBins ); - floatToFixed_arr16( hDiracDecBin->processMtxDecIm[ch][slot], hDiracDecBin->processMtxDecIm_fx[ch][slot], q_mat, nBins ); - floatToFixed_arr16( hDiracDecBin->processMtxDecRePrev[ch][slot], hDiracDecBin->processMtxDecRePrev_fx[ch][slot], q_mat, nBins ); - floatToFixed_arr16( hDiracDecBin->processMtxDecImPrev[ch][slot], hDiracDecBin->processMtxDecImPrev_fx[ch][slot], q_mat, nBins ); + Scale_sig( hDiracDecBin->processMtxDecRe_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDec ) ); + Scale_sig( hDiracDecBin->processMtxDecIm_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDec ) ); + Scale_sig( hDiracDecBin->processMtxDecRePrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDecPrev ) ); + Scale_sig( hDiracDecBin->processMtxDecImPrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDecPrev ) ); } } FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { FOR( slot = 0; slot < numInChannels; slot++ ) { - floatToFixed_arr16( hDiracDecBin->processMtxRe[ch][slot], hDiracDecBin->processMtxRe_fx[ch][slot], q_mat, nBins ); - floatToFixed_arr16( hDiracDecBin->processMtxIm[ch][slot], hDiracDecBin->processMtxIm_fx[ch][slot], q_mat, nBins ); - floatToFixed_arr16( hDiracDecBin->processMtxRePrev[ch][slot], hDiracDecBin->processMtxRePrev_fx[ch][slot], q_mat, nBins ); - floatToFixed_arr16( hDiracDecBin->processMtxImPrev[ch][slot], hDiracDecBin->processMtxImPrev_fx[ch][slot], q_mat, nBins ); + Scale_sig( hDiracDecBin->processMtxRe_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); + Scale_sig( hDiracDecBin->processMtxIm_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); + Scale_sig( hDiracDecBin->processMtxRePrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); + Scale_sig( hDiracDecBin->processMtxImPrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); } - hMasaExtRend->cldfbSynRend[ch]->Q_cldfb_state = Q11; } -#endif // Float to fix ends + hDiracDecBin->q_processMtx = q_mat; + hDiracDecBin->q_processMtxPrev = q_mat; + hDiracDecBin->q_processMtxDec = q_mat; + hDiracDecBin->q_processMtxDecPrev = q_mat; ivas_dirac_dec_binaural_process_output_fx( hDiracDecBin, hSpatParamRendCom, hMasaExtRend->cldfbSynRend, output_fx, &q_out, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_inp, max_band_decorr, numInChannels, config_data.processReverb, subframe, q_mat ); diff --git a/lib_rend/ivas_rom_rend.c b/lib_rend/ivas_rom_rend.c index 97bed6db4b84e5a8fde2f65c018660f1ccf0d666..dab91ad0a4a414d592a6c62c1c17b478e4533896 100644 --- a/lib_rend/ivas_rom_rend.c +++ b/lib_rend/ivas_rom_rend.c @@ -319,7 +319,19 @@ const float diffuseFieldCoherenceDifferenceZ[BINAURAL_COHERENCE_DIFFERENCE_BINS] { 0.048207f, 0.10796f, 0.11845f, 0.047886f, 0.035917f, 0.045196f, 0.018863f, 0.015547f, 0.014157f }; +#ifdef IVAS_FLOAT_FIXED +const Word32 diffuseFieldCoherenceDifferenceX_fx[BINAURAL_COHERENCE_DIFFERENCE_BINS] = { /* Q31 */ + 101835824, 424621952, 484944768, 228427840, 18706944, 25829934, 68659344, 42236708, 17164408, +}; + +const Word32 diffuseFieldCoherenceDifferenceY_fx[BINAURAL_COHERENCE_DIFFERENCE_BINS] = { /* Q31 */ + -205359568, -656464256, -739314176, -331249344, -95837904, -122887608, -109167328, -75621488, -47566764, +}; +const Word32 diffuseFieldCoherenceDifferenceZ_fx[BINAURAL_COHERENCE_DIFFERENCE_BINS] = { /* Q31 */ + 103523744, 231842336, 254369440, 102834400, 77131168, 97057672, 40507984, 33386928, 30401926, +}; +#endif /*----------------------------------------------------------------------------------* * TD ISM binaural renderer ROM tables diff --git a/lib_rend/ivas_rom_rend.h b/lib_rend/ivas_rom_rend.h index 3ccdaa007b8688e33de006dfd8a403f8fa21ebe5..720fc2c80a64b3725aa3a26ebdfb440c71038f60 100644 --- a/lib_rend/ivas_rom_rend.h +++ b/lib_rend/ivas_rom_rend.h @@ -99,6 +99,11 @@ extern const Word32 lowBitRateBinauralEQ_fx[LOW_BIT_RATE_BINAURAL_EQ_BINS]; extern const float diffuseFieldCoherenceDifferenceX[BINAURAL_COHERENCE_DIFFERENCE_BINS]; extern const float diffuseFieldCoherenceDifferenceY[BINAURAL_COHERENCE_DIFFERENCE_BINS]; extern const float diffuseFieldCoherenceDifferenceZ[BINAURAL_COHERENCE_DIFFERENCE_BINS]; +#ifdef IVAS_FLOAT_FIXED +extern const Word32 diffuseFieldCoherenceDifferenceX_fx[BINAURAL_COHERENCE_DIFFERENCE_BINS]; +extern const Word32 diffuseFieldCoherenceDifferenceY_fx[BINAURAL_COHERENCE_DIFFERENCE_BINS]; +extern const Word32 diffuseFieldCoherenceDifferenceZ_fx[BINAURAL_COHERENCE_DIFFERENCE_BINS]; +#endif // IVAS_FLOAT_FIXED /*----------------------------------------------------------------------------------* diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 6cbd09ebb238ce08af8fe02e4d0ec78f4e225e81..8d83587e6a2288b6e51a85b508e3caed6e54616f 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -874,6 +874,7 @@ typedef struct ivas_diffuse_distribution_data_structure /* Parametric binaural data structure */ typedef struct ivas_dirac_dec_binaural_data_structure { +#ifndef IVAS_FLOAT_FIXED float ChEnePrev[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX]; float ChCrossRePrev[CLDFB_NO_CHANNELS_MAX]; float ChCrossImPrev[CLDFB_NO_CHANNELS_MAX]; @@ -895,13 +896,16 @@ typedef struct ivas_dirac_dec_binaural_data_structure float diffuseFieldCoherenceY[BINAURAL_COHERENCE_DIFFERENCE_BINS]; float diffuseFieldCoherenceZ[BINAURAL_COHERENCE_DIFFERENCE_BINS]; float earlyPartEneCorrection[CLDFB_NO_CHANNELS_MAX]; +#endif REVERB_STRUCT_HANDLE hReverb; uint8_t renderStereoOutputInsteadOfBinaural; +#ifndef IVAS_FLOAT_FIXED float frameMeanDiffuseness[CLDFB_NO_CHANNELS_MAX]; float processMtxRePrev[BINAURAL_CHANNELS][BINAURAL_CHANNELS + MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX]; float processMtxImPrev[BINAURAL_CHANNELS][BINAURAL_CHANNELS + MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX]; float processMtxDecRePrev[BINAURAL_CHANNELS][BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX]; float processMtxDecImPrev[BINAURAL_CHANNELS][BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX]; +#endif #ifdef IVAS_FLOAT_FIXED Word32 earlyPartEneCorrection_fx[CLDFB_NO_CHANNELS_MAX]; Word16 q_earlyPartEneCorrection; @@ -914,6 +918,13 @@ typedef struct ivas_dirac_dec_binaural_data_structure Word16 processMtxDecRePrev_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX]; Word16 processMtxDecImPrev_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX]; + Word16 q_processMtx; + Word16 q_processMtxSCCR; + Word16 q_processMtxPrev; + Word16 q_processMtxPrevSCCR; + Word16 q_processMtxDec; + Word16 q_processMtxDecPrev; + Word32 ChEnePrev_fx[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX]; Word32 ChCrossRePrev_fx[CLDFB_NO_CHANNELS_MAX]; Word32 ChCrossImPrev_fx[CLDFB_NO_CHANNELS_MAX]; @@ -2191,8 +2202,8 @@ typedef struct ivas_hrtfs_parambin_struct #ifndef IVAS_FLOAT_FIXED float parametricReverberationTimes[CLDFB_NO_CHANNELS_MAX]; float parametricReverberationEneCorrections[CLDFB_NO_CHANNELS_MAX]; -#endif float parametricEarlyPartEneCorrection[CLDFB_NO_CHANNELS_MAX]; +#endif #ifdef IVAS_FLOAT_FIXED Word32 parametricReverberationTimes_fx[CLDFB_NO_CHANNELS_MAX]; /* Q31 */ Word32 parametricReverberationEneCorrections_fx[CLDFB_NO_CHANNELS_MAX]; /* Q31 */ diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 135522e3ba262150d0f4c99e676323ca420c88b3..4a2db082758b5896b7c936d4c1c5913ef9010ba0 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -5253,11 +5253,6 @@ static ivas_error setRendInputActiveMasa( } #if 1 /*TODO: To be removed later(fixed to float)*/ - IF( inputMasa->hMasaExtRend ) - { - IF( inputMasa->hMasaExtRend->hDiracDecBin ) - fixedToFloat_arrL( inputMasa->hMasaExtRend->hDiracDecBin->earlyPartEneCorrection_fx, inputMasa->hMasaExtRend->hDiracDecBin->earlyPartEneCorrection, (Word16) Q28 /*1.0f Q28*/, (Word16) CLDFB_NO_CHANNELS_MAX ); - } inputMasa->base.inputBuffer.data = inputMasa->bufferData; fixedToFloat_arrL( inputMasa->base.inputBuffer.data_fx, inputMasa->base.inputBuffer.data, 0, MAX_BUFFER_LENGTH ); /*fixed to float only for set zero(that's why q0)*/ #endif @@ -14119,40 +14114,34 @@ static ivas_error ivas_masa_ext_rend_parambin_init( { FOR( k = 0; k < BINAURAL_CHANNELS + MAX_NUM_OBJECTS; k++ ) { -#if 1 /*To be removed later(floating buffer init)*/ - set_zero( hDiracDecBin->processMtxRe[j][k], nBins ); - set_zero( hDiracDecBin->processMtxIm[j][k], nBins ); -#endif set16_fx( hDiracDecBin->processMtxRe_fx[j][k], 0, nBins ); set16_fx( hDiracDecBin->processMtxIm_fx[j][k], 0, nBins ); } FOR( k = 0; k < BINAURAL_CHANNELS; k++ ) { -#if 1 /*To be removed later(floating buffer init)*/ - set_zero( hDiracDecBin->processMtxDecRe[j][k], nBins ); - set_zero( hDiracDecBin->processMtxDecIm[j][k], nBins ); -#endif set16_fx( hDiracDecBin->processMtxDecRe_fx[j][k], 0, nBins ); set16_fx( hDiracDecBin->processMtxDecIm_fx[j][k], 0, nBins ); } -#if 1 /*TODO:To be removed later(floating buffer init)*/ - set_zero( hDiracDecBin->ChEnePrev[j], nBins ); - set_zero( hDiracDecBin->ChEneOutPrev[j], nBins ); -#endif + hDiracDecBin->q_processMtx = Q15; + hDiracDecBin->q_processMtxSCCR = Q15; + hDiracDecBin->q_processMtxPrev = Q15; + hDiracDecBin->q_processMtxPrevSCCR = Q15; + hDiracDecBin->q_processMtxDec = Q15; + hDiracDecBin->q_processMtxDecPrev = Q15; set_zero_fx( hDiracDecBin->ChEnePrev_fx[j], nBins ); set_zero_fx( hDiracDecBin->ChEneOutPrev_fx[j], nBins ); + set16_fx( hDiracDecBin->ChEnePrev_e[j], 0, nBins ); + set16_fx( hDiracDecBin->ChEneOutPrev_e[j], 0, nBins ); } -#if 1 /*TODO:To be removed later(floating buffer init)*/ - set_zero( hDiracDecBin->ChCrossRePrev, nBins ); - set_zero( hDiracDecBin->ChCrossImPrev, nBins ); - set_zero( hDiracDecBin->ChCrossReOutPrev, nBins ); - set_zero( hDiracDecBin->ChCrossImOutPrev, nBins ); -#endif set_zero_fx( hDiracDecBin->ChCrossRePrev_fx, nBins ); set_zero_fx( hDiracDecBin->ChCrossImPrev_fx, nBins ); set_zero_fx( hDiracDecBin->ChCrossReOutPrev_fx, nBins ); set_zero_fx( hDiracDecBin->ChCrossImOutPrev_fx, nBins ); + set16_fx( hDiracDecBin->ChCrossRePrev_e, 0, nBins ); + set16_fx( hDiracDecBin->ChCrossImPrev_e, 0, nBins ); + set16_fx( hDiracDecBin->ChCrossReOutPrev_e, 0, nBins ); + set16_fx( hDiracDecBin->ChCrossImOutPrev_e, 0, nBins ); hDiracDecBin->renderStereoOutputInsteadOfBinaural = 0; FOR( bin = 0; bin < nBins; bin++ ) @@ -14168,15 +14157,10 @@ static ivas_error ivas_masa_ext_rend_parambin_init( tmpFloat_fx = s_max( 0, sub( shl_sat( 1, 15 - tmp_e ), tmp ) ) /*max( 0.0f, 1.0f - binCenterFreq / 2700.0f )*/; /*Q30*/ tmp2 = extract_l( Mult_32_32( binCenterFreq_fx, 1952258 /*=2^31*180/(550)/360*/ ) % 32767 ); //*binCenterFreq_fx * EVS_PI / 550.0f*/ hDiracDecBin->diffuseFieldCoherence_fx[bin] = L_shl( L_mult0( divide3232( tmpFloat_fx, Mult_32_16( binCenterFreq_fx, 187 /*2^15*pi/550*/ ) ), getSineWord16R2( tmp2 ) ), tmp_e ); /*tmpFloat * sinf( binCenterFreq * EVS_PI / 550.0f ) / ( binCenterFreq * EVS_PI / 550.0f );*/ - hDiracDecBin->diffuseFieldCoherence[bin] = fixedToFloat( hDiracDecBin->diffuseFieldCoherence_fx[bin], Q30 ); + hDiracDecBin->diffuseFieldCoherence_fx[bin] = L_shl( hDiracDecBin->diffuseFieldCoherence_fx[bin], 1 ); // Q31 } /* No SPAR in external renderer so set directive diffuse field coherence tables to zero */ -#if 1 /*TODO: To be removed later(floating buffer init)*/ - set_zero( hDiracDecBin->diffuseFieldCoherenceX, BINAURAL_COHERENCE_DIFFERENCE_BINS ); - set_zero( hDiracDecBin->diffuseFieldCoherenceY, BINAURAL_COHERENCE_DIFFERENCE_BINS ); - set_zero( hDiracDecBin->diffuseFieldCoherenceZ, BINAURAL_COHERENCE_DIFFERENCE_BINS ); -#endif set_zero_fx( hDiracDecBin->diffuseFieldCoherenceX_fx, BINAURAL_COHERENCE_DIFFERENCE_BINS ); set_zero_fx( hDiracDecBin->diffuseFieldCoherenceY_fx, BINAURAL_COHERENCE_DIFFERENCE_BINS ); set_zero_fx( hDiracDecBin->diffuseFieldCoherenceZ_fx, BINAURAL_COHERENCE_DIFFERENCE_BINS ); @@ -14184,11 +14168,13 @@ static ivas_error ivas_masa_ext_rend_parambin_init( IF( EQ_16( renderer_type, RENDERER_BINAURAL_PARAMETRIC ) ) /* Indication of binaural rendering without room effect */ { set32_fx( hDiracDecBin->earlyPartEneCorrection_fx, ONE_IN_Q28 /*1.0f Q28*/, CLDFB_NO_CHANNELS_MAX ); + hDiracDecBin->q_earlyPartEneCorrection = Q28; hDiracDecBin->hReverb = NULL; } ELSE IF( EQ_16( renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) /* Indication of binaural rendering with room effect */ { Copy32( hHrtfParambin->parametricEarlyPartEneCorrection_fx, hDiracDecBin->earlyPartEneCorrection_fx, nBins ); + hDiracDecBin->q_earlyPartEneCorrection = Q28; IF( hDiracDecBin->hReverb == NULL ) { @@ -14202,6 +14188,7 @@ static ivas_error ivas_masa_ext_rend_parambin_init( ELSE IF( EQ_16( renderer_type, RENDERER_STEREO_PARAMETRIC ) ) { set32_fx( hDiracDecBin->earlyPartEneCorrection_fx, ONE_IN_Q28 /*1.0f Q28*/, CLDFB_NO_CHANNELS_MAX ); + hDiracDecBin->q_earlyPartEneCorrection = Q28; hDiracDecBin->hReverb = NULL; hDiracDecBin->renderStereoOutputInsteadOfBinaural = 1; } diff --git a/lib_util/hrtf_file_reader.c b/lib_util/hrtf_file_reader.c index e7f77bf2bd865e1b83fc2ef5a52b546a76bafdbd..549d4cb4d17804f2b2128fda6da026b8bfbc029e 100644 --- a/lib_util/hrtf_file_reader.c +++ b/lib_util/hrtf_file_reader.c @@ -2186,8 +2186,11 @@ static ivas_error create_parambin_HRTF_from_rawdata( /*adding conversion as file reading is done in float*/ floatToFixed_arrL( f_tmp_reverb, ( *hHRTF )->parametricReverberationEneCorrections_fx, Q31, CLDFB_NO_CHANNELS_MAX ); - memcpy( ( *hHRTF )->parametricEarlyPartEneCorrection, hrtf_data_rptr, CLDFB_NO_CHANNELS_MAX * sizeof( float ) ); + // memcpy( ( *hHRTF )->parametricEarlyPartEneCorrection, hrtf_data_rptr, CLDFB_NO_CHANNELS_MAX * sizeof( float ) ); + memcpy( f_tmp_reverb, hrtf_data_rptr, CLDFB_NO_CHANNELS_MAX * sizeof( float ) ); hrtf_data_rptr += CLDFB_NO_CHANNELS_MAX * sizeof( float ); + /*adding conversion as file reading is done in float*/ + floatToFixed_arrL( f_tmp_reverb, ( *hHRTF )->parametricEarlyPartEneCorrection_fx, Q28, CLDFB_NO_CHANNELS_MAX ); return IVAS_ERR_OK; }