diff --git a/lib_com/cnst.h b/lib_com/cnst.h index a5497787079ec887211efb67a90be65ba2a83c87..cdc395d7aae86e3f9f7ce7e59899ac94411d2483 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -44,6 +44,14 @@ /* clang-format off */ #ifdef IVAS_FLOAT_FIXED #define MATRIX_CONSTANT (759250113) +#define L_SUBFRAME_48k (240) +#define L_SUBFRAME_32k (180) +#define L_SUBFRAME_16k (80) +#define L_SUBFRAME_8k (40) +#define Q31_BY_SUB_FRAME_240 ( 8985287 ) +#define Q31_BY_SUB_FRAME_180 ( 11997115 ) +#define Q31_BY_SUB_FRAME_80 ( 27183337 ) +#define Q31_BY_SUB_FRAME_40 ( 55063683 ) #endif diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal.c index 652833dcad84947aa180c4cc38dca81aaa80850a..5f5f9c75d058d78f2e84bc518b283c11660d4622 100644 --- a/lib_dec/ivas_objectRenderer_internal.c +++ b/lib_dec/ivas_objectRenderer_internal.c @@ -230,7 +230,7 @@ ivas_error ivas_td_binaural_renderer_sf( if ( st_ivas->hRenderConfig != NULL && st_ivas->hIntSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { #ifdef IVAS_FLOAT_FIXED - Word16 i,j, k,exp; + Word16 i,j,exp; Word32 pcm_in_buff[MAX_OUTPUT_CHANNELS][L_FRAME48k]; Word32 pcm_out_buff[BINAURAL_CHANNELS][L_FRAME48k]; Word32 *pcm_in_fx[MAX_OUTPUT_CHANNELS]; @@ -260,25 +260,10 @@ ivas_error ivas_td_binaural_renderer_sf( for ( j = 0; j < ( hReverb->full_block_size ); j++ ) { - - pcm_out_fx[i][0 * hReverb->full_block_size + j] = (Word32) float_to_fix( p_reverb_signal[i][0 * hReverb->full_block_size + j], ( exp - 2 ) ); + pcm_out_fx[i][0 * hReverb->full_block_size + j] = (Word32) float_to_fix( p_reverb_signal[i][0 * hReverb->full_block_size + j], ( exp ) ); } } - for ( i = 0; i < hReverb->nr_of_branches; i++ ) - { - for ( k = 0; k < IVAS_REV_MAX_IIR_FILTER_LENGTH; k++ ) - { - hReverb->t60[i].CoefA_fx[k] = (Word32) ( hReverb->t60[i].CoefA[k] * ONE_IN_Q30 ); - hReverb->t60[i].CoefB_fx[k] = (Word32) ( hReverb->t60[i].CoefB[k] * ONE_IN_Q30 ); - } - } - for ( k = 0; k < hReverb->fft_filter_ols.fft_size; k++ ) - { - hReverb->fft_filter_correl_0.fft_spectrum_fx[k] = (Word32) ( hReverb->fft_filter_correl_0.fft_spectrum[k] * ONE_IN_Q31 ); - hReverb->fft_filter_color_0.fft_spectrum_fx[k] = (Word32) ( hReverb->fft_filter_color_0.fft_spectrum[k] * ONE_IN_Q31 ); - hReverb->fft_filter_correl_1.fft_spectrum_fx[k] = (Word32) ( hReverb->fft_filter_correl_1.fft_spectrum[k] * ONE_IN_Q31 ); - hReverb->fft_filter_color_1.fft_spectrum_fx[k] = (Word32) ( hReverb->fft_filter_color_1.fft_spectrum[k] * ONE_IN_Q31 ); - } + if ( ( error = ivas_reverb_process_fx( st_ivas->hReverb, st_ivas->transport_config, 0, pcm_in_fx, pcm_out_fx, 0 ) ) != IVAS_ERR_OK ) #else if ( ( error = ivas_reverb_process( st_ivas->hReverb, st_ivas->transport_config, 0, tc_local, p_reverb_signal, 0 ) ) != IVAS_ERR_OK ) diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index a0ab425de655ceed50a75b3123a414fd3d04b057..9046678379bcacdb3085184a20f3c73c1fd37877 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -2100,7 +2100,6 @@ ivas_error ivas_rend_initCrendWrapper( { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend Wrapper\n" ); } - ( *pCrend )->binaural_latency_ns = 0; ( *pCrend )->hHrtfCrend = NULL; @@ -2416,7 +2415,6 @@ void ivas_rend_closeCrend( free( hCrend->freq_buffer_re_diffuse_fx ); hCrend->freq_buffer_re_diffuse_fx = NULL; } - if ( hCrend->freq_buffer_im_diffuse_fx != NULL ) { free( hCrend->freq_buffer_im_diffuse_fx ); @@ -2445,7 +2443,6 @@ void ivas_rend_closeCrend( free( hCrend->reflections ); hCrend->reflections = NULL; } - free( hCrend ); hCrend = NULL; ( *pCrend )->hCrend = hCrend; @@ -2724,7 +2721,6 @@ void ivas_rend_closeCrend( #endif - #ifdef IVAS_FLOAT_FIXED /*-----------------------------------------------------------------------------------------* * Function ivas_rend_crendConvolver() @@ -2896,6 +2892,7 @@ static ivas_error ivas_rend_crendConvolver( return IVAS_ERR_OK; } + #else /*-----------------------------------------------------------------------------------------* * Function ivas_rend_crendConvolver() @@ -3082,22 +3079,17 @@ ivas_error ivas_rend_crendProcess( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, IVAS_OUTPUT_SETUP_HANDLE hIntSetup, EFAP_HANDLE hEFAPdata, - float *output[], /* i/o: input/output audio channels */ - const int32_t output_Fs, - const int16_t num_subframes /* i : number of subframes to render */ + Word32 *output_fx[], /* i/o: input/output audio channels */ + const Word32 output_Fs, + const Word16 num_subframes /* i : number of subframes to render */ ) { - int16_t i, subframe_idx, subframe_len; - Word16 j; - int16_t nchan_out, nchan_in;//TODO:nchan_in will remove later for temporary conversion - float pcm_tmp[BINAURAL_CHANNELS][L_FRAME48k]; + Word16 i, subframe_idx, subframe_len; + Word16 nchan_out; Word32 pcm_tmp_fx[BINAURAL_CHANNELS][L_FRAME48k]; - float *p_pcm_tmp[BINAURAL_CHANNELS]; Word32 *p_pcm_tmp_fx[BINAURAL_CHANNELS]; - Word32 output_buffer_fx[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - Word32 *output_fx[MAX_OUTPUT_CHANNELS]; IVAS_REND_AudioConfigType inConfigType; - int8_t combinedOrientationEnabled; + Word8 combinedOrientationEnabled; ivas_error error; CREND_HANDLE hCrend; @@ -3106,12 +3098,12 @@ ivas_error ivas_rend_crendProcess( combinedOrientationEnabled = 0; if ( hCombinedOrientationData != NULL ) { - for ( subframe_idx = 0; subframe_idx < num_subframes; subframe_idx++ ) + FOR ( subframe_idx = 0; subframe_idx < num_subframes; subframe_idx++ ) { - if ( hCombinedOrientationData->enableCombinedOrientation[subframe_idx] != 0 ) + IF( NE_16(hCombinedOrientationData->enableCombinedOrientation[subframe_idx] , 0) ) { combinedOrientationEnabled = 1; - break; + BREAK; } } } @@ -3119,64 +3111,49 @@ ivas_error ivas_rend_crendProcess( push_wmops( "ivas_rend_crendProcess" ); inConfigType = getAudioConfigType( inConfig ); - if ( ( error = getAudioConfigNumChannels( outConfig, &nchan_out ) ) != IVAS_ERR_OK ) + IF ( ( error = getAudioConfigNumChannels( outConfig, &nchan_out ) ) != IVAS_ERR_OK ) { return error; } - // TODO:will remove later for temporary conversion; not there in the float code code - if ( ( error = getAudioConfigNumChannels( inConfig, &nchan_in ) ) != IVAS_ERR_OK ) + subframe_len = L_SUBFRAME_48k; + move16(); + SWITCH( output_Fs ) { - return error; + case 48000: + subframe_len = L_SUBFRAME_48k; + BREAK; + case 32000: + subframe_len = L_SUBFRAME_32k; + BREAK; + case 16000: + subframe_len = L_SUBFRAME_16k; + BREAK; + case 8000: + subframe_len = L_SUBFRAME_8k; + BREAK; + default: + BREAK; } - subframe_len = (int16_t) ( output_Fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ); - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) - { - p_pcm_tmp[i] = pcm_tmp[i]; - } - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + FOR ( i = 0; i < BINAURAL_CHANNELS; i++ ) { p_pcm_tmp_fx[i] = pcm_tmp_fx[i]; + move32(); } - for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) - { - output_fx[i] = output_buffer_fx[i]; - } - Word16 gd_bits = find_guarded_bits_fx( subframe_len ); - Word16 exp = 15; - exp -= gd_bits; - - for ( subframe_idx = 0; subframe_idx < num_subframes; subframe_idx++ ) + + FOR( subframe_idx = 0; subframe_idx < num_subframes; subframe_idx++ ) { /* Early Reflections */ if ( hCrend->reflections != NULL ) { - if ( hCrend->reflections->use_er == 1 && hCrend->reflections->is_ready == 1 ) + test(); + IF( EQ_16( hCrend->reflections->use_er, 1 ) && EQ_16(hCrend->reflections->is_ready , 1) ) { - for ( i = 0; i < hCrend->reflections->shoebox_data.n_sources + 1; i++ ) - { - for ( j = 0; j < L_FRAME48k; j++ ) - { - - output_fx[i][j] = (Word32) float_to_fix( output[i][j], exp ); - } - } - for ( i = 0; i < 150; i++ ) - { - hCrend->reflections->shoebox_data.gains.data_fx[i] = (Word32) float_to_fix( hCrend->reflections->shoebox_data.gains.data[i], 15 ); - } - if ( ( error = ivas_er_process( hCrend->reflections, subframe_len, subframe_idx, output_fx, inConfig ) ) != IVAS_ERR_OK ) + IF ( ( error = ivas_er_process( hCrend->reflections, subframe_len, subframe_idx, output_fx, inConfig ) ) != IVAS_ERR_OK ) { return error; } - for ( i = 0; i < hCrend->reflections->shoebox_data.n_sources + 1; i++ ) - { - for ( j = 0; j < L_FRAME48k; j++ ) - { - - output[i][j] = fix_to_float( output_fx[i][j], exp ); - } - } + } } @@ -3188,104 +3165,46 @@ ivas_error ivas_rend_crendProcess( MC with elevation (5_1_2 / 5_1_4 / 7_1_4) -> BINAURAL SBA SPAR -> BINAURAL or BINAURAL_ROOM */ - if ( inConfig == IVAS_AUDIO_CONFIG_FOA || inConfig == IVAS_AUDIO_CONFIG_HOA2 || inConfig == IVAS_AUDIO_CONFIG_HOA3 ) + test(); + IF ( EQ_16(inConfig ,IVAS_AUDIO_CONFIG_FOA) || EQ_16(inConfig , IVAS_AUDIO_CONFIG_HOA2) || EQ_16(inConfig , IVAS_AUDIO_CONFIG_HOA3) ) { - rotateFrame_shd( hCombinedOrientationData, output, subframe_len, *hIntSetup, subframe_idx ); + rotateFrame_shd( hCombinedOrientationData, output_fx, subframe_len, *hIntSetup, subframe_idx ); } /* Rotation in SD for MC -> BINAURAL_ROOM */ - else if ( ( hIntSetup != NULL ) && hIntSetup->is_loudspeaker_setup ) + ELSE IF ( ( hIntSetup != NULL ) && hIntSetup->is_loudspeaker_setup ) { - rotateFrame_sd( hCombinedOrientationData, output, subframe_len, *hIntSetup, hEFAPdata, subframe_idx ); + rotateFrame_sd( hCombinedOrientationData, output_fx, subframe_len, *hIntSetup, hEFAPdata, subframe_idx ); + } } - - if ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED || inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) + test(); + IF ( EQ_16(inConfigType ,IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED) || EQ_16(inConfigType , IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS) ) { - for ( i = 0; i < nchan_in; i++ ) - { - for ( j = 0; j < L_FRAME48k; j++ ) - { - - output_fx[i][j] = (Word32) float_to_fix( output[i][j], exp ); - } - } - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) - { - - for ( j = 0; j < L_FRAME48k; j++ ) - { - p_pcm_tmp_fx[i][j] = (Word32) float_to_fix( p_pcm_tmp[i][j], exp ); - } - } - if ( ( error = ivas_rend_crendConvolver( pCrend, inConfig, outConfig, output_fx, p_pcm_tmp_fx, output_Fs, subframe_idx ) ) != IVAS_ERR_OK ) + IF ( ( error = ivas_rend_crendConvolver( pCrend, inConfig, outConfig, output_fx, p_pcm_tmp_fx, output_Fs, subframe_idx ) ) != IVAS_ERR_OK ) { return error; } - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + + IF( hCrend->hReverb != NULL ) { - - for ( j = 0; j < L_FRAME48k; j++ ) - { - - p_pcm_tmp[i][j] = fix_to_float( p_pcm_tmp_fx[i][j], exp ); - } - } - if ( hCrend->hReverb != NULL ) - { - Word16 k; - REVERB_HANDLE hReverb = pCrend->hCrend->hReverb; - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) - { - - for ( j = 0; j < ( hReverb->full_block_size ); j++ ) - { - - p_pcm_tmp_fx[i][subframe_idx * hReverb->full_block_size + j] = (Word32)float_to_fix( p_pcm_tmp[i][subframe_idx * hReverb->full_block_size + j], ( exp - 2 ) ); - } - } - for ( i = 0; i < hReverb->nr_of_branches; i++ ) - { - for ( k = 0; k < IVAS_REV_MAX_IIR_FILTER_LENGTH; k++ ) - { - hReverb->t60[i].CoefA_fx[k] = (Word32) ( hReverb->t60[i].CoefA[k] * ONE_IN_Q30 ); - hReverb->t60[i].CoefB_fx[k] = (Word32) ( hReverb->t60[i].CoefB[k] * ONE_IN_Q30 ); - } - } - for ( k = 0; k < hReverb->fft_filter_ols.fft_size; k++ ) - { - hReverb->fft_filter_correl_0.fft_spectrum_fx[k] = (Word32) ( hReverb->fft_filter_correl_0.fft_spectrum[k] * ONE_IN_Q31 ); - hReverb->fft_filter_color_0.fft_spectrum_fx[k] = (Word32) ( hReverb->fft_filter_color_0.fft_spectrum[k] * ONE_IN_Q31 ); - hReverb->fft_filter_correl_1.fft_spectrum_fx[k] = (Word32) ( hReverb->fft_filter_correl_1.fft_spectrum[k] * ONE_IN_Q31 ); - hReverb->fft_filter_color_1.fft_spectrum_fx[k] = (Word32) ( hReverb->fft_filter_color_1.fft_spectrum[k] * ONE_IN_Q31 ); - } - if ( ( error = ivas_reverb_process_fx( pCrend->hCrend->hReverb, inConfig, 1, output_fx, p_pcm_tmp_fx, subframe_idx ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_reverb_process_fx( pCrend->hCrend->hReverb, inConfig, 1, output_fx, p_pcm_tmp_fx, subframe_idx ) ) != IVAS_ERR_OK ) { return error; } - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) - { - - for ( j = 0; j < ( hReverb->full_block_size ); j++ ) - { - - p_pcm_tmp[i][subframe_idx * hReverb->full_block_size + j] = fix_to_float( p_pcm_tmp_fx[i][subframe_idx * hReverb->full_block_size + j], (exp - 2) ); - } - } } } - else + ELSE { return IVAS_ERR_INVALID_INPUT_FORMAT; } } - /* move to output */ - for ( i = 0; i < nchan_out; i++ ) + FOR ( i = 0; i < nchan_out; i++ ) { - mvr2r( pcm_tmp[i], output[i], num_subframes * subframe_len ); + mvr2r_Word32( pcm_tmp_fx[i], output_fx[i], num_subframes * subframe_len ); } - + pop_wmops(); return IVAS_ERR_OK; } @@ -3437,11 +3356,11 @@ ivas_error ivas_rend_crendProcessSubframe( const int32_t output_Fs /* i : output sampling rate */ ) { - int16_t subframe_idx, subframe_len; + int16_t subframe_idx, subframe_len, n; Word16 i, j; int16_t nchan_out, nchan_in, ch, first_sf, last_sf, slot_size, slots_to_render; float *tc_local[MAX_OUTPUT_CHANNELS]; - Word32 tc_local_buffer_fx[MAX_OUTPUT_CHANNELS][L_FRAME48k] = {0}; + Word32 tc_local_buffer_fx[MAX_OUTPUT_CHANNELS][L_FRAME48k] = { 0 }; Word32 *tc_local_fx[MAX_OUTPUT_CHANNELS]; float pcm_tmp[BINAURAL_CHANNELS][L_FRAME48k]; Word32 pcm_tmp_fx[BINAURAL_CHANNELS][L_FRAME48k]; @@ -3552,12 +3471,46 @@ ivas_error ivas_rend_crendProcessSubframe( */ if ( inConfig == IVAS_AUDIO_CONFIG_FOA || inConfig == IVAS_AUDIO_CONFIG_HOA2 || inConfig == IVAS_AUDIO_CONFIG_HOA3 ) { - rotateFrame_shd( hCombinedOrientationData, tc_local, subframe_len, *hIntSetup, 0 ); + rotateFrame_shd( hCombinedOrientationData, tc_local_fx, subframe_len, *hIntSetup, 0 ); } /* Rotation in SD for MC -> BINAURAL_ROOM */ else if ( ( hIntSetup != NULL ) && hIntSetup->is_loudspeaker_setup ) { - rotateFrame_sd( hCombinedOrientationData, tc_local, subframe_len, *hIntSetup, hEFAPdata, 0 ); + Word16 nchan; + nchan = hIntSetup->nchan_out_woLFE + hIntSetup->num_lfe; + for ( i = 0; i < nchan; i++ ) + { + for ( j = 0; j < subframe_len; j++ ) + { + + tc_local_fx[i][j] = (Word32) float_to_fix( tc_local[i][j], exp ); + } + } + for ( n = 0; n < 3; n++ ) + { + for ( i = 0; i < 3; i++ ) + { + hCombinedOrientationData->Rmat_prev_fx[n][i] = (Word32) ( hCombinedOrientationData->Rmat_prev[n][i] * ONE_IN_Q30 ); + hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx][n][i] = (Word32) ( hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx][n][i] * ONE_IN_Q30 ); + } + } + rotateFrame_sd( hCombinedOrientationData, tc_local_fx, subframe_len, *hIntSetup, hEFAPdata, 0 ); + for ( i = 0; i < nchan; i++ ) + { + for ( j = 0; j < subframe_len; j++ ) + { + + tc_local[i][j] = (float) fix_to_float( tc_local_fx[i][j], ( exp - 3 ) ); + } + } + for ( n = 0; n < 3; n++ ) + { + for ( i = 0; i < 3; i++ ) + { + hCombinedOrientationData->Rmat_prev[n][i] = (float) ( hCombinedOrientationData->Rmat_prev_fx[n][i] ) / ONE_IN_Q30; + hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx][n][i] = (float) ( hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx][n][i] ) / ONE_IN_Q30; + } + } } } @@ -3576,7 +3529,7 @@ ivas_error ivas_rend_crendProcessSubframe( for ( j = 0; j < subframe_len; j++ ) { - p_pcm_tmp_fx[i][j] = (Word32)float_to_fix( p_pcm_tmp[i][j], exp ); + p_pcm_tmp_fx[i][j] = (Word32) float_to_fix( p_pcm_tmp[i][j], exp ); } } if ( ( error = ivas_rend_crendConvolver( pCrend, inConfig, outConfig, tc_local_fx, p_pcm_tmp_fx, output_Fs, 0 ) ) != IVAS_ERR_OK ) @@ -3594,7 +3547,6 @@ ivas_error ivas_rend_crendProcessSubframe( } if ( pCrend->hCrend->hReverb != NULL ) { - Word16 k; REVERB_HANDLE hReverb = pCrend->hCrend->hReverb; for ( i = 0; i < BINAURAL_CHANNELS; i++ ) { @@ -3602,25 +3554,11 @@ ivas_error ivas_rend_crendProcessSubframe( for ( j = 0; j < ( hReverb->full_block_size ); j++ ) { - p_pcm_tmp_fx[i][j] = (Word32) float_to_fix( p_pcm_tmp[i][j], ( exp - 2 ) ); - } - } - for ( i = 0; i < hReverb->nr_of_branches; i++ ) - { - for ( k = 0; k < IVAS_REV_MAX_IIR_FILTER_LENGTH; k++ ) - { - hReverb->t60[i].CoefA_fx[k] = (Word32) (hReverb->t60[i].CoefA[k] * ONE_IN_Q30); - hReverb->t60[i].CoefB_fx[k] = (Word32) (hReverb->t60[i].CoefB[k] * ONE_IN_Q30); + p_pcm_tmp_fx[i][j] = (Word32) float_to_fix( p_pcm_tmp[i][j], ( exp ) ); } } - for ( k = 0; k < hReverb->fft_filter_ols.fft_size; k++ ) - { - hReverb->fft_filter_correl_0.fft_spectrum_fx[k] = (Word32) (hReverb->fft_filter_correl_0.fft_spectrum[k] * ONE_IN_Q31); - hReverb->fft_filter_color_0.fft_spectrum_fx[k] = (Word32) (hReverb->fft_filter_color_0.fft_spectrum[k] * ONE_IN_Q31); - hReverb->fft_filter_correl_1.fft_spectrum_fx[k] = (Word32) (hReverb->fft_filter_correl_1.fft_spectrum[k] * ONE_IN_Q31); - hReverb->fft_filter_color_1.fft_spectrum_fx[k] = (Word32) (hReverb->fft_filter_color_1.fft_spectrum[k] * ONE_IN_Q31); - } - if ( ( error = ivas_reverb_process_fx( pCrend->hCrend->hReverb, inConfig, 1, tc_local_fx, p_pcm_tmp_fx, 0) ) != IVAS_ERR_OK ) + + if ( ( error = ivas_reverb_process_fx( pCrend->hCrend->hReverb, inConfig, 1, tc_local_fx, p_pcm_tmp_fx, 0 ) ) != IVAS_ERR_OK ) { return error; } @@ -3630,7 +3568,7 @@ ivas_error ivas_rend_crendProcessSubframe( for ( j = 0; j < ( hReverb->full_block_size ); j++ ) { - p_pcm_tmp[i][j] = fix_to_float( p_pcm_tmp_fx[i][j], (exp - 2 )); + p_pcm_tmp[i][j] = fix_to_float( p_pcm_tmp_fx[i][j], ( exp - 2 ) ); } } } diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index c98bbf2826415733fe9ad4ee7f7a50ea47bb6f9a..a981ac2a68073132fb6581f027532fdc6f670257 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -353,7 +353,7 @@ ivas_error ivas_td_binaural_renderer_unwrap( if ( hReverb != NULL ) { #ifdef IVAS_FLOAT_FIXED - Word16 i, j, k, exp; + Word16 i, j, exp; Word32 pcm_in_buff[MAX_OUTPUT_CHANNELS][L_FRAME48k]; Word32 pcm_out_buff[BINAURAL_CHANNELS][L_FRAME48k]; Word32 *pcm_in_fx[MAX_OUTPUT_CHANNELS]; @@ -382,25 +382,9 @@ ivas_error ivas_td_binaural_renderer_unwrap( for ( j = 0; j < ( hReverb->full_block_size ); j++ ) { - - pcm_out_fx[i][j] = (Word32) float_to_fix( p_reverb_signal[i][j], ( exp - 2 ) ); + pcm_out_fx[i][j] = (Word32) float_to_fix( p_reverb_signal[i][j], ( exp ) ); } } - for ( i = 0; i < hReverb->nr_of_branches; i++ ) - { - for ( k = 0; k < IVAS_REV_MAX_IIR_FILTER_LENGTH; k++ ) - { - hReverb->t60[i].CoefA_fx[k] = (Word32) ( hReverb->t60[i].CoefA[k] * ONE_IN_Q30 ); - hReverb->t60[i].CoefB_fx[k] = (Word32) ( hReverb->t60[i].CoefB[k] * ONE_IN_Q30 ); - } - } - for ( k = 0; k < hReverb->fft_filter_ols.fft_size; k++ ) - { - hReverb->fft_filter_correl_0.fft_spectrum_fx[k] = (Word32) ( hReverb->fft_filter_correl_0.fft_spectrum[k] * ONE_IN_Q31 ); - hReverb->fft_filter_color_0.fft_spectrum_fx[k] = (Word32) ( hReverb->fft_filter_color_0.fft_spectrum[k] * ONE_IN_Q31 ); - hReverb->fft_filter_correl_1.fft_spectrum_fx[k] = (Word32) ( hReverb->fft_filter_correl_1.fft_spectrum[k] * ONE_IN_Q31 ); - hReverb->fft_filter_color_1.fft_spectrum_fx[k] = (Word32) ( hReverb->fft_filter_color_1.fft_spectrum[k] * ONE_IN_Q31 ); - } if ( ( error = ivas_reverb_process_fx( hReverb, transport_config, 0, pcm_in_fx, pcm_out_fx, subframe_idx) ) != IVAS_ERR_OK ) #else if ( ( error = ivas_reverb_process( hReverb, transport_config, 0, output, p_reverb_signal, subframe_idx ) ) != IVAS_ERR_OK ) diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index b8ea58d3de5a0a35255bd11424df8c34c2c502e6..bc14bd292a223a8aa7b72a7fae5ab41b18a59637 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -49,12 +49,17 @@ IVAS_REND_AudioConfigType getAudioConfigType( const AUDIO_CONFIG config ); - +#ifdef IVAS_FLOAT_FIXED +ivas_error getAudioConfigNumChannels( + const AUDIO_CONFIG config, + Word16 *numChannels +); +#else ivas_error getAudioConfigNumChannels( const AUDIO_CONFIG config, int16_t *numChannels ); - +#endif /*----------------------------------------------------------------------------------* * output setup prototypes @@ -943,7 +948,20 @@ ivas_error ivas_hrtf_init( ivas_error ivas_rend_initCrendWrapper( CREND_WRAPPER_HANDLE *pCrend ); - +#ifdef IVAS_FLOAT_FIXED +ivas_error ivas_rend_crendProcess( + const CREND_WRAPPER *pCrend, + const AUDIO_CONFIG inConfig, + const AUDIO_CONFIG outConfig, + DECODER_CONFIG_HANDLE hDecoderConfig, + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, + IVAS_OUTPUT_SETUP_HANDLE hIntSetup, + EFAP_HANDLE hEFAPdata, + Word32 *output[], /* i/o: input/output audio channels */ + const Word32 output_Fs, + const Word16 num_subframes /* i : number of subframes to render */ +); +#else ivas_error ivas_rend_crendProcess( const CREND_WRAPPER *pCrend, const AUDIO_CONFIG inConfig, @@ -956,7 +974,7 @@ ivas_error ivas_rend_crendProcess( const int32_t output_Fs, const int16_t num_subframes /* i : number of subframes to render */ ); - +#endif ivas_error ivas_rend_crendProcessSubframe( const CREND_WRAPPER *pCrend, /* i/o: Crend wrapper handle */ const AUDIO_CONFIG inConfig, /* i : input audio configuration */ @@ -1112,13 +1130,14 @@ void ivas_reverb_iir_filt_init( const uint16_t maxTaps /* i : maximum number of filter taps */ ); + +#ifdef IVAS_FLOAT_FIXED void ivas_reverb_iir_filt_set( ivas_rev_iir_filter_t *iirFilter, /* i/o: IIR filter */ - uint16_t nr_taps, /* i : number of IIR filter taps */ + UWord16 nr_taps, /* i : number of IIR filter taps */ const float *coefA, /* i : A filter coefficients to set */ const float *coefB /* i : the B filter coefficients to set */ ); -#ifdef IVAS_FLOAT_FIXED void ivas_reverb_iir_filt_2taps_feed_blk_fx( ivas_rev_iir_filter_t *iirFilter, /* i/o: IIR filter */ const UWord16 blk_size, /* i : size */ @@ -1129,13 +1148,19 @@ void ivas_reverb_iir_filt_2taps_feed_blk_fx( UWord16 int_log2( UWord32 powerOf2 ); - Word16 ivas_reverb_t2f_f2t_init( ivas_reverb_t2f_f2t_t *t2f_f2t, const Word16 fft_size, const Word16 block_size ); #else +void ivas_reverb_iir_filt_set( + ivas_rev_iir_filter_t *iirFilter, /* i/o: IIR filter */ + uint16_t nr_taps, /* i : number of IIR filter taps */ + const float *coefA, /* i : A filter coefficients to set */ + const float *coefB /* i : the B filter coefficients to set */ +); + uint16_t int_log2( uint32_t powerOf2 ); @@ -1418,6 +1443,25 @@ void SHrotmatgen( const int16_t order /* i : ambisonics order */ ); #endif +#ifdef IVAS_FLOAT_FIXED +void rotateFrame_shd( + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : head and external orientation combined handle */ + Word32 *output[], /* i/o: unrotated HOA3 signal buffer in TD */ + const Word16 subframe_len, /* i : subframe length per channel */ + const IVAS_OUTPUT_SETUP hTransSetup, /* i : format for rotation */ + const Word16 subframe_idx /* i : subframe index */ +); + +void rotateFrame_sd( + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : head and external orientation combined handle */ + Word32 *output[], /* i/o: unrotated SD signal buffer in TD */ + const Word16 subframe_len, /* i : subframe length per channel */ + const IVAS_OUTPUT_SETUP hTransSetup, /* i : format for rotation */ + const EFAP_HANDLE hEFAPdata, /* i : EFAP structure */ + const Word16 subframe_idx /* i : subframe index */ +); +#else + void rotateFrame_shd( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : head and external orientation combined handle */ float *output[], /* i/o: unrotated HOA3 signal buffer in TD */ @@ -1425,7 +1469,6 @@ void rotateFrame_shd( const IVAS_OUTPUT_SETUP hTransSetup, /* i : format for rotation */ const int16_t subframe_idx /* i : subframe index */ ); - void rotateFrame_sd( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : head and external orientation combined handle */ float *output[], /* i/o: unrotated SD signal buffer in TD */ @@ -1434,6 +1477,7 @@ void rotateFrame_sd( const EFAP_HANDLE hEFAPdata, /* i : EFAP structure */ const int16_t subframe_idx /* i : subframe index */ ); +#endif void ivas_combined_orientation_update_index( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientation handle */ const int16_t samples_rendered /* i : samples rendered since the last call */ diff --git a/lib_rend/ivas_reverb.c b/lib_rend/ivas_reverb.c index 7592d6dc2781f05d5d44b846b8e6f54fe535a5f8..7ce8a0d5b1ec8a992a440cc2593eb60bff9796e9 100644 --- a/lib_rend/ivas_reverb.c +++ b/lib_rend/ivas_reverb.c @@ -1698,6 +1698,13 @@ ivas_error ivas_reverb_open( /* init predelay */ ivas_rev_delay_line_init( &( pState->predelay_line ), pState->pPredelay_buffer_fx, params.pre_delay, predelay_bf_len ); + for (Word16 k = 0; k < pState->fft_filter_ols.fft_size; k++ ) + { + pState->fft_filter_correl_0.fft_spectrum_fx[k] = (Word32) ( pState->fft_filter_correl_0.fft_spectrum[k] * ONE_IN_Q31 ); + pState->fft_filter_color_0.fft_spectrum_fx[k] = (Word32) ( pState->fft_filter_color_0.fft_spectrum[k] * ONE_IN_Q31 ); + pState->fft_filter_correl_1.fft_spectrum_fx[k] = (Word32) ( pState->fft_filter_correl_1.fft_spectrum[k] * ONE_IN_Q31 ); + pState->fft_filter_color_1.fft_spectrum_fx[k] = (Word32) ( pState->fft_filter_color_1.fft_spectrum[k] * ONE_IN_Q31 ); + } /* set up feedback delay network */ if ( ( error = setup_FDN_branches( pState, ¶ms ) ) != IVAS_ERR_OK ) @@ -2474,8 +2481,8 @@ static void mix_output_block_fx( for ( i = 0; i < hReverb->full_block_size; i++ ) { - pOutL[i] = L_add( pInL[i], pOutL[i] ); - pOutR[i] = L_add( pInR[i], pOutR[i] ); + pOutL[i] = L_add( pInL[i], ((pOutL[i]) >> 2)); + pOutR[i] = L_add( pInR[i], ((pOutR[i]) >> 2)); } return; diff --git a/lib_rend/ivas_reverb_iir_filter.c b/lib_rend/ivas_reverb_iir_filter.c index 4c53362ce127c7ec2eacfb73057bb53e58df2952..2817bf7f5bd5002746197741aaab42cfeb9f8592 100644 --- a/lib_rend/ivas_reverb_iir_filter.c +++ b/lib_rend/ivas_reverb_iir_filter.c @@ -48,10 +48,9 @@ * * Initialize the IIR filter *-----------------------------------------------------------------------------------------*/ - void ivas_reverb_iir_filt_init( ivas_rev_iir_filter_t *iirFilter, /* o : IIR filter */ - const UWord16 maxTaps /* i : maximum number of filter taps */ + const UWord16 maxTaps /* i : maximum number of filter taps */ ) { iirFilter->MaxTaps = maxTaps; @@ -59,12 +58,12 @@ void ivas_reverb_iir_filt_init( iirFilter->nr_taps = 0; /* filter is set to PASS i.e. input copy to output */ iirFilter->Output_fx = 0; - for ( UWord16 i = 0; i < maxTaps; i++ ) + FOR ( UWord16 i = 0; i < maxTaps; i++ ) { - iirFilter->CoefA[i] = 0; iirFilter->CoefA_fx[i] = 0; - iirFilter->CoefB[i] = 0; + move32(); iirFilter->CoefB_fx[i] = 0; + move32(); } set_val_Word32( iirFilter->pBuffer_fx, 0, iirFilter->MaxTaps ); @@ -99,6 +98,49 @@ void ivas_reverb_iir_filt_init( return; } #endif +#ifdef IVAS_FLOAT_FIXED +/*-----------------------------------------------------------------------------------------* + * Function ivas_reverb_iir_filt_set() + * + * Set the IIR filter + *-----------------------------------------------------------------------------------------*/ + +void ivas_reverb_iir_filt_set( + ivas_rev_iir_filter_t *iirFilter, /* i/o: IIR filter */ + UWord16 nr_taps, /* i : number of IIR filter taps */ + const float *coefA, /* i : A filter coefficients to set */ + const float *coefB /* i : the B filter coefficients to set */ +) +{ + UWord16 i; + + IF ( nr_taps > iirFilter->MaxTaps ) + { + nr_taps = (uint16_t) iirFilter->MaxTaps; + } + + iirFilter->nr_taps = nr_taps; + iirFilter->isFIR = ( coefA == NULL ); + + IF ( iirFilter->isFIR != 0 ) + { + FOR ( i = 0; i < iirFilter->nr_taps; i++ ) + { + iirFilter->CoefB_fx[i] = (Word32) ( coefB[i] * ONE_IN_Q30 ); + } + } + ELSE + { + FOR ( i = 0; i < iirFilter->nr_taps; i++ ) + { + iirFilter->CoefA_fx[i] = (Word32) ( coefA[i] * ONE_IN_Q30 ); + iirFilter->CoefB_fx[i] = (Word32) ( coefB[i] * ONE_IN_Q30 ); + } + } + + return; +} +#else /*-----------------------------------------------------------------------------------------* * Function ivas_reverb_iir_filt_set() * @@ -140,7 +182,7 @@ void ivas_reverb_iir_filt_set( return; } - +#endif #ifdef IVAS_FLOAT_FIXED /*-----------------------------------------------------------------------------------------* * Function ivas_reverb_iir_filt_2taps_feed_blk() @@ -160,7 +202,6 @@ void ivas_reverb_iir_filt_2taps_feed_blk_fx( Word32 flt_CoefB_0_fx = iirFilter->CoefB_fx[0]; Word32 flt_CoefB_1_fx = iirFilter->CoefB_fx[1]; Word32 flt_CoefA_1_fx = iirFilter->CoefA_fx[1] ; - Word32 flt_pBuffer_0_fx = iirFilter->pBuffer_fx[0]; Word32 flt_pBuffer_1_fx = iirFilter->pBuffer_fx[1] ; for ( i = 0; i < blk_size; i++ ) diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index 92264eae8f07253693a22fbfe17c6e5b77fd84e5..f320c4a5221b82f662711fef790f94b0a7c7a72f 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -287,11 +287,11 @@ float rad2deg( *------------------------------------------------------------------------*/ void rotateAziEle_fx( - Word16 azi_in, /* i : output elevation */ - Word16 ele_in, /* i : input elevation */ - Word16 *azi, /* o : rotated azimuth */ - Word16 *ele, /* o : rotated elevation */ - Word32 Rmat_fx[3][3], /* i : real-space rotation matrix */ + Word16 azi_in, /* i : output elevation */ + Word16 ele_in, /* i : input elevation */ + Word16 *azi, /* o : rotated azimuth */ + Word16 *ele, /* o : rotated elevation */ + Word32 Rmat_fx[3][3], /* i : real-space rotation matrix */ const Word16 isPlanar /* i : is rotation planar and elevation meaningless? */ ) { @@ -314,7 +314,7 @@ void rotateAziEle_fx( dv_fx[1] = Mpy_32_32( w_fx, sine_table_Q31[temp + 180] ); temp = ele_in; dv_fx[2] = sine_table_Q31[temp + 180]; - + /*Rotation mtx multiplication*/ for ( n = 0; n < 3; n++ ) { @@ -442,12 +442,13 @@ void rotateAziEle( void rotateFrame_shd( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : head and external orientation combined handle */ - float *output[], /* i/o: unrotated HOA3 signal buffer in TD */ - const int16_t subframe_len, /* i : subframe length per channel */ + Word32 *output[], /* i/o: unrotated HOA3 signal buffer in TD */ + const Word16 subframe_len, /* i : subframe length per channel */ const IVAS_OUTPUT_SETUP hTransSetup, /* i : format for rotation */ - const int16_t subframe_idx /* i : subframe index */ + const Word16 subframe_idx /* i : subframe index */ ) { + // Not yet fully converted the function to fixed, no test cases entering the function. int16_t i, l, n, m, j; int16_t m1, m2; int16_t shd_rot_max_order; @@ -468,7 +469,6 @@ void rotateFrame_shd( { cross_fade[i] = i * tmp; } - /* initialize rotation matrices with zeros */ for ( i = 0; i < HEADROT_SHMAT_DIM; i++ ) { @@ -539,7 +539,7 @@ void rotateFrame_shd( /* write back the result */ for ( n = m1; n < m2; n++ ) { - output[n][subframe_idx * subframe_len + i] = tmpRot[n - m1]; + output[n][subframe_idx * subframe_len + i] = (Word32) tmpRot[n - m1]; } m1 = m2; m2 += 2 * ( l + 1 ) + 1; @@ -686,57 +686,66 @@ void rotateFrame_shd( * * Apply rotation to signals in Spatial Domain *------------------------------------------------------------------------*/ - void rotateFrame_sd( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : head and external orientation combined handle */ - float *output[], /* i/o: unrotated SD signal buffer in TD */ + Word32 *output[], /* i/o: unrotated SD signal buffer in TD */ const Word16 subframe_len, /* i : subframe length per channel */ const IVAS_OUTPUT_SETUP hTransSetup, /* i : format for rotation */ const EFAP_HANDLE hEFAPdata, /* i : EFAP structure */ const Word16 subframe_idx /* i : subframe index */ ) { - Word16 i, j,n; + Word16 i, j; Word16 nchan, index_lfe; Word16 ch_in, ch_in_woLFE, ch_out, ch_out_woLFE; Word16 azimuth, elevation; - Word32 Rmat_fx[3][3], Rmat_prev_fx[3][3]; - float tmp; - float tmp_gains[MAX_CICP_CHANNELS - 1]; - float gains[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS]; - float gains_prev[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS]; - float output_tmp[MAX_CICP_CHANNELS][L_FRAME48k]; - float cross_fade[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; + Word32 azimuth_fx, elevation_fx; + Word32 tmp = Q31_BY_SUB_FRAME_240; + Word32 out_temp; + Word32 tmp_gains_fx[MAX_CICP_CHANNELS - 1]; + Word32 gains_fx[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS]; + Word32 gains_prev_fx[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS]; + Word32 output_tmp_fx[MAX_CICP_CHANNELS][L_FRAME48k]; + Word32 cross_fade_fx[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; push_wmops( "rotateFrame_sd" ); nchan = hTransSetup.nchan_out_woLFE + hTransSetup.num_lfe; index_lfe = hTransSetup.index_lfe[0]; - tmp = 1.0f / ( subframe_len - 1 ); - for ( i = 0; i < subframe_len; i++ ) + SWITCH( subframe_len ) { - cross_fade[i] = i * tmp; + case L_SUBFRAME_48k: + tmp = Q31_BY_SUB_FRAME_240; + BREAK; + case L_SUBFRAME_32k: + tmp = Q31_BY_SUB_FRAME_180; + BREAK; + case L_SUBFRAME_16k: + tmp = Q31_BY_SUB_FRAME_80; + BREAK; + case L_SUBFRAME_8k: + tmp = Q31_BY_SUB_FRAME_40; + BREAK; + default: + BREAK; } - for ( n = 0; n < 3; n++ ) + + FOR( i = 0; i < subframe_len; i++ ) { - for ( i = 0; i < 3; i++ ) - { - Rmat_prev_fx[n][i] = (Word32) (hCombinedOrientationData->Rmat_prev[n][i] * ONE_IN_Q30); - Rmat_fx[n][i] = (Word32) (hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx][n][i] * ONE_IN_Q30); - } + cross_fade_fx[i] = UL_Mpy_32_32( i, tmp ); } - for ( ch_in = 0; ch_in < nchan; ch_in++ ) + + FOR( ch_in = 0; ch_in < nchan; ch_in++ ) { /* zero output and gain buffers */ - set_zero( &output_tmp[ch_in][subframe_idx * subframe_len], subframe_len ); - set_zero( gains_prev[ch_in], nchan ); - set_zero( gains[ch_in], nchan ); - + set_val_Word32( &output_tmp_fx[ch_in][subframe_idx * subframe_len], 0, subframe_len ); + set_val_Word32( gains_prev_fx[ch_in], 0, nchan ); + set_val_Word32( gains_fx[ch_in], 0, nchan ); /* set gains to passthrough by default */ - gains_prev[ch_in][ch_in] = 1.0f; - gains[ch_in][ch_in] = 1.0f; + gains_prev_fx[ch_in][ch_in] = ONE_IN_Q28; + gains_fx[ch_in][ch_in] = ONE_IN_Q28; /* skip LFE */ - if ( ch_in == index_lfe ) + IF ( ch_in == index_lfe ) { continue; } @@ -745,12 +754,16 @@ void rotateFrame_sd( ch_in_woLFE = ( ch_in >= index_lfe ) ? ch_in - 1 : ch_in; /* gains for previous subframe rotation */ - rotateAziEle_fx((Word16) hTransSetup.ls_azimuth[ch_in_woLFE], (Word16)hTransSetup.ls_elevation[ch_in_woLFE], &azimuth, &elevation, Rmat_prev_fx, hTransSetup.is_planar_setup ); + rotateAziEle_fx( (Word16) hTransSetup.ls_azimuth[ch_in_woLFE], (Word16) hTransSetup.ls_elevation[ch_in_woLFE], &azimuth, &elevation, hCombinedOrientationData->Rmat_prev_fx, hTransSetup.is_planar_setup ); - if ( hEFAPdata != NULL && ( hTransSetup.ls_azimuth[ch_in_woLFE] != azimuth || hTransSetup.ls_elevation[ch_in_woLFE] != elevation ) ) + IF ( hEFAPdata != NULL && ( hTransSetup.ls_azimuth[ch_in_woLFE] != azimuth || hTransSetup.ls_elevation[ch_in_woLFE] != elevation ) ) { - efap_determine_gains( hEFAPdata, tmp_gains, azimuth, elevation, EFAP_MODE_EFAP ); - for ( ch_out = 0; ch_out < nchan; ch_out++ ) + azimuth_fx = (Word32) azimuth * ONE_IN_Q22; + elevation_fx = (Word32) elevation * ONE_IN_Q22; + efap_determine_gains_fixed( hEFAPdata, tmp_gains_fx, azimuth_fx, elevation_fx, EFAP_MODE_EFAP ); + + + FOR( ch_out = 0; ch_out < nchan; ch_out++ ) { /* skip LFE */ if ( ch_out == index_lfe ) @@ -760,19 +773,21 @@ void rotateFrame_sd( /* output channel index without LFE */ ch_out_woLFE = ( ch_out >= index_lfe ) ? ch_out - 1 : ch_out; - - gains_prev[ch_in][ch_out] = tmp_gains[ch_out_woLFE]; + gains_prev_fx[ch_in][ch_out] = tmp_gains_fx[ch_out_woLFE]; } } - + /* gains for current subframe rotation */ - rotateAziEle_fx( (Word16)hTransSetup.ls_azimuth[ch_in_woLFE],(Word16) hTransSetup.ls_elevation[ch_in_woLFE], &azimuth, &elevation, Rmat_fx, hTransSetup.is_planar_setup ); + rotateAziEle_fx( (Word16) hTransSetup.ls_azimuth[ch_in_woLFE], (Word16) hTransSetup.ls_elevation[ch_in_woLFE], &azimuth, &elevation, hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx], hTransSetup.is_planar_setup ); - if ( hEFAPdata != NULL && ( hTransSetup.ls_azimuth[ch_in_woLFE] != azimuth || hTransSetup.ls_elevation[ch_in_woLFE] != elevation ) ) + IF ( hEFAPdata != NULL && ( hTransSetup.ls_azimuth[ch_in_woLFE] != azimuth || hTransSetup.ls_elevation[ch_in_woLFE] != elevation ) ) { - efap_determine_gains( hEFAPdata, tmp_gains, azimuth, elevation, EFAP_MODE_EFAP ); - for ( ch_out = 0; ch_out < nchan; ch_out++ ) + azimuth_fx = (Word32) azimuth * ONE_IN_Q22; + elevation_fx = (Word32) elevation * ONE_IN_Q22; + efap_determine_gains_fixed( hEFAPdata, tmp_gains_fx, azimuth_fx, elevation_fx, EFAP_MODE_EFAP ); + + FOR( ch_out = 0; ch_out < nchan; ch_out++ ) { /* skip LFE */ if ( ch_out == index_lfe ) @@ -783,37 +798,39 @@ void rotateFrame_sd( /* output channel index without LFE */ ch_out_woLFE = ( ch_out >= index_lfe ) ? ch_out - 1 : ch_out; - gains[ch_in][ch_out] = tmp_gains[ch_out_woLFE]; + gains_fx[ch_in][ch_out] = tmp_gains_fx[ch_out_woLFE]; } } } /* apply panning gains by mtx multiplication */ - for ( ch_out = 0; ch_out < nchan; ch_out++ ) + FOR( ch_out = 0; ch_out < nchan; ch_out++ ) { - for ( ch_in = 0; ch_in < nchan; ch_in++ ) + FOR( ch_in = 0; ch_in < nchan; ch_in++ ) { /* crossfade with previous rotation gains */ for ( i = subframe_idx * subframe_len, j = 0; j < subframe_len; i++, j++ ) { - output_tmp[ch_out][i] += ( cross_fade[j] ) * gains[ch_in][ch_out] * output[ch_in][i] + ( 1 - cross_fade[j] ) * gains_prev[ch_in][ch_out] * output[ch_in][i]; + out_temp = output[ch_in][i]; + Word32 temp = Mpy_32_32( Mpy_32_32( ( cross_fade_fx[j] ), gains_fx[ch_in][ch_out] ), out_temp ); + Word32 temp1 = Mpy_32_32( Mpy_32_32( ( ONE_IN_Q31 - cross_fade_fx[j] ), gains_prev_fx[ch_in][ch_out] ), out_temp ); + output_tmp_fx[ch_out][i] = L_add( L_add( temp, temp1 ), output_tmp_fx[ch_out][i] ); } } } /* move Rmat to Rmat_prev */ - for ( i = 0; i < 3; i++ ) + FOR ( i = 0; i < 3; i++ ) { - mvr2r( - hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx][i], - hCombinedOrientationData->Rmat_prev[i], + mvr2r_Word32( + hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx][i], + hCombinedOrientationData->Rmat_prev_fx[i], 3 ); } - /* copy to output */ - for ( ch_out = 0; ch_out < nchan; ch_out++ ) + FOR ( ch_out = 0; ch_out < nchan; ch_out++ ) { - mvr2r( &output_tmp[ch_out][subframe_idx * subframe_len], &output[ch_out][subframe_idx * subframe_len], subframe_len ); + mvr2r_Word32( &output_tmp_fx[ch_out][subframe_idx * subframe_len], &output[ch_out][subframe_idx * subframe_len], subframe_len ); } pop_wmops(); @@ -959,7 +976,6 @@ void rotateFrame_sd( * * Apply rotation to signals in Spherical Harmonic Domain and in CLDFB *------------------------------------------------------------------------*/ - void rotateFrame_shd_cldfb( Word32 Cldfb_RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: unrotated HOA3 signal buffer in cldfb domain real part */ Word32 Cldfb_ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: unrotated HOA3 signal buffer in cldfb domain imag part */ @@ -1056,7 +1072,6 @@ void rotateFrame_shd_cldfb( Cldfb_ImagBuffer[0][j][k] = Cldfb_ImagBuffer[0][j][k] / ONE_IN_Q1; } } - return; } #else @@ -1865,7 +1880,6 @@ static bool are_orientations_same( * an implementation of the algorithm in * Ivanic, J. & Ruedenberg, K., J. Phys. Chem. 100, 6342 (1996) *------------------------------------------------------------------------*/ - static Word32 SHrot_p_fx( const Word16 i, const Word16 l, @@ -2141,17 +2155,17 @@ void SHrotmatgen_fx( Word32 result; SHrotmat[0][0] = ONE_IN_Q14; - SHrotmat[1][1] = extract_h(Rmat[1][1]); - SHrotmat[1][2] = extract_h(Rmat[1][2]); - SHrotmat[1][3] = extract_h(Rmat[1][0]); + SHrotmat[1][1] = extract_h( Rmat[1][1] ); + SHrotmat[1][2] = extract_h( Rmat[1][2] ); + SHrotmat[1][3] = extract_h( Rmat[1][0] ); - SHrotmat[2][1] = extract_h(Rmat[2][1]); - SHrotmat[2][2] = extract_h(Rmat[2][2]); - SHrotmat[2][3] = extract_h(Rmat[2][0]); + SHrotmat[2][1] = extract_h( Rmat[2][1] ); + SHrotmat[2][2] = extract_h( Rmat[2][2] ); + SHrotmat[2][3] = extract_h( Rmat[2][0] ); - SHrotmat[3][1] = extract_h(Rmat[0][1]); - SHrotmat[3][2] = extract_h(Rmat[0][2]); - SHrotmat[3][3] = extract_h(Rmat[0][0]); + SHrotmat[3][1] = extract_h( Rmat[0][1] ); + SHrotmat[3][2] = extract_h( Rmat[0][2] ); + SHrotmat[3][3] = extract_h( Rmat[0][0] ); for ( i = 0; i < 2 * 1 + 1; i++ ) { diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 3abaaf07adfa3d05c0a78dfe5118bec79288e987..8014215be17d2e4d659e36207465407223b7c695 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -799,12 +799,12 @@ typedef struct ivas_external_orientation_struct #ifdef IVAS_FLOAT_FIXED typedef struct ivas_combined_orientation_struct { - int16_t enableCombinedOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; + Word16 enableCombinedOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; float interpolationCoefficient; float interpolationIncrement; - int16_t maximumFramesToTargetOrientation; - uint8_t lrSwitchedNext; - uint8_t lrSwitchedCurrent; + Word16 maximumFramesToTargetOrientation; + UWord8 lrSwitchedNext; + UWord8 lrSwitchedCurrent; float lrSwitchInterpVal; bool isInterpolationOngoing; IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES]; @@ -814,20 +814,21 @@ typedef struct ivas_combined_orientation_struct float Rmat[MAX_PARAM_SPATIAL_SUBFRAMES][3][3]; Word32 Rmat_fx[MAX_PARAM_SPATIAL_SUBFRAMES][3][3]; float Rmat_prev[3][3]; + Word32 Rmat_prev_fx[3][3]; float chEneIIR[2][MASA_FREQUENCY_BANDS]; /* independent of the format. MASA bands are suitable for the task and readily available in ROM. */ float procChEneIIR[2][MASA_FREQUENCY_BANDS]; - int16_t shd_rot_max_order; + Word16 shd_rot_max_order; IVAS_VECTOR3 listenerPos[MAX_PARAM_SPATIAL_SUBFRAMES]; IVAS_QUATERNION Quaternion_frozen_ext; IVAS_QUATERNION Quaternion_frozen_head; - int8_t isExtOrientationFrozen; - int8_t isHeadRotationFrozen; - int16_t num_subframes; - int16_t subframe_idx; - int16_t subframe_size; - int16_t cur_subframe_samples_rendered; - int16_t subframe_idx_start; - int16_t cur_subframe_samples_rendered_start; + Word8 isExtOrientationFrozen; + Word8 isHeadRotationFrozen; + Word16 num_subframes; + Word16 subframe_idx; + Word16 subframe_size; + Word16 cur_subframe_samples_rendered; + Word16 subframe_idx_start; + Word16 cur_subframe_samples_rendered_start; } COMBINED_ORIENTATION_DATA, *COMBINED_ORIENTATION_HANDLE; #else typedef struct ivas_combined_orientation_struct diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 2871022ff890869db6f09c26830793a41c092b58..752dd2034322b487c9742a35f137a5936568aebb 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -511,17 +511,17 @@ static ivas_error validateOutputSampleRate( return IVAS_ERR_OK; } - /* Otherwise rendering to binaural, support the same set as IVAS decoder */ - switch ( sampleRate ) - { - case 8000: - case 16000: - case 32000: - case 48000: - return IVAS_ERR_OK; - } + /* Otherwise rendering to binaural, support the same set as IVAS decoder */ + switch ( sampleRate ) + { + case 8000: + case 16000: + case 32000: + case 48000: + return IVAS_ERR_OK; + } - return IVAS_ERR_INVALID_SAMPLING_RATE; + return IVAS_ERR_INVALID_SAMPLING_RATE; } #ifdef IVAS_FLOAT_FIXED @@ -2604,8 +2604,6 @@ static void clearInputMasa( } - - /*------------------------------------------------------------------------- * IVAS_REND_Open() * @@ -4444,7 +4442,7 @@ static ivas_error rotateFrameMc( static ivas_error rotateFrameSba_fx( IVAS_REND_AudioBuffer inAudio, /* i : Input Audio buffer */ const AUDIO_CONFIG inConfig, /* i : Input Audio config */ - const IVAS_REND_HeadRotData *headRotData, /* i : Head rotation data */ + const IVAS_REND_HeadRotData *headRotData, /* i : Head rotation data */ const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData, /* i : Combined head and external orientations */ Word16 gains_prev[MAX_INPUT_CHANNELS][MAX_INPUT_CHANNELS], /* i/o: Previous frame rotation gains */ IVAS_REND_AudioBuffer outAudio /* o : Output Audio buffer */ @@ -4464,7 +4462,7 @@ static ivas_error rotateFrameSba_fx( ivas_error error; Word16 idx; Word16 val, cf, oneminuscf; - + push_wmops( "rotateFrameSba" ); if ( ( error = chooseCrossfade_fx( headRotData, &crossfade ) ) != IVAS_ERR_OK ) @@ -4477,7 +4475,7 @@ static ivas_error rotateFrameSba_fx( { return error; } - + subframe_len = inAudio.config.numSamplesPerChannel / num_subframes; for ( subframe_idx = 0; subframe_idx < num_subframes; subframe_idx++ ) { @@ -4486,14 +4484,15 @@ static ivas_error rotateFrameSba_fx( { set_val_Word16( gains[i], 0, HEADROT_SHMAT_DIM ); } - + for ( i = 0; i < 3; i++ ) { if ( hCombinedOrientationData != NULL ) { for ( l = 0; l < 3; l++ ) { - Rmat[i][l] = ( *hCombinedOrientationData )->Rmat_fx[subframe_idx][i][l];//Q30 + Rmat[i][l] = ( *hCombinedOrientationData )->Rmat_fx[subframe_idx][i][l]; // Q30 + } } else @@ -4505,7 +4504,7 @@ static ivas_error rotateFrameSba_fx( } /* calculate ambisonics rotation matrices for the previous and current frames */ SHrotmatgen_fx( gains, Rmat, shd_rot_max_order ); - + #ifdef DEBUGGING dbgwrite_txt( gains, HEADROT_SHMAT_DIM * HEADROT_SHMAT_DIM, "Fixed_code_gains.txt", NULL ); dbgwrite_txt( Rmat, 3 * 3, "Fixed_code_Rmat.txt", NULL ); @@ -4554,7 +4553,6 @@ static ivas_error rotateFrameSba_fx( } } - pop_wmops(); return IVAS_ERR_OK; @@ -4712,7 +4710,7 @@ static int16_t getNumSubframesInBuffer( return (int16_t) ( buffer->config.numSamplesPerChannel / ( sampleRate / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ) ); } - +#ifdef IVAS_FLOAT_FIXED static ivas_error renderIsmToBinauralRoom( input_ism *ismInput, IVAS_REND_AudioBuffer outAudio ) @@ -4856,17 +4854,63 @@ static ivas_error renderIsmToBinauralRoom( { mvr2r( currentPanGains, ismInput->prev_pan_gains, MAX_OUTPUT_CHANNELS ); } + // Crend_process porting + Word16 nchan_out = 2, nchan_in = 12, subframe_len; + CREND_HANDLE hCrend; + Word32 output_buffer_fx[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + Word32 *output_fx[MAX_OUTPUT_CHANNELS]; + hCrend = ismInput->crendWrapper->hCrend; + subframe_len = (Word16) ( *ismInput->base.ctx.pOutSampleRate / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ); + Word16 gd_bits = find_guarded_bits_fx( subframe_len ); + Word16 exp = 15; + exp -= gd_bits; + Word16 nchan = nchan_in; + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + output_fx[i] = output_buffer_fx[i]; + } + if ( hCrend->reflections != NULL ) + { + if ( hCrend->reflections->use_er == 1 && hCrend->reflections->is_ready == 1 ) + { + nchan = hCrend->reflections->shoebox_data.n_sources + 1; + for ( i = 0; i < 150; i++ ) + { + hCrend->reflections->shoebox_data.gains.data_fx[i] = (Word32) float_to_fix( hCrend->reflections->shoebox_data.gains.data[i], 15 ); + } + } + } + nchan = nchan_in; + for ( i = 0; i < nchan; i++ ) + { + for ( j = 0; j < L_FRAME48k; j++ ) + { + output_fx[i][j] = (Word32) float_to_fix( p_tmpRendBuffer[i][j], exp ); + } + } /* render 7_1_4 with BRIRs */ if ( ( error = ivas_rend_crendProcess( ismInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, - NULL, NULL, NULL, NULL, p_tmpRendBuffer, *ismInput->base.ctx.pOutSampleRate, + NULL, NULL, NULL, NULL, output_fx, *ismInput->base.ctx.pOutSampleRate, getNumSubframesInBuffer( &outAudio, *ismInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) { return error; } + if ( hCrend->hReverb != NULL ) + { + exp -= 2; + } + for ( i = 0; i < nchan_out; i++ ) + { + + for ( j = 0; j < L_FRAME48k; j++ ) + { + p_tmpRendBuffer[i][j] = fix_to_float( output_fx[i][j], exp ); + } + } accumulate2dArrayToBuffer( tmpRendBuffer, &outAudio ); free( tmpMcBuffer.data ); @@ -4874,7 +4918,168 @@ static ivas_error renderIsmToBinauralRoom( return IVAS_ERR_OK; } +#else +static ivas_error renderIsmToBinauralRoom( + input_ism *ismInput, + IVAS_REND_AudioBuffer outAudio ) +{ + int16_t position_changed; + int16_t i, j; + int16_t azi_rot, ele_rot; + int16_t subframe_idx; + int16_t tmp; + rotation_matrix Rmat; + float tmpRendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + ivas_error error; + pan_vector currentPanGains; + IVAS_REND_AudioBuffer tmpMcBuffer; + IVAS_ISM_METADATA rotatedPosPrev; + IVAS_ISM_METADATA rotatedPos; + const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData; + int8_t combinedOrientationEnabled; + float *p_tmpRendBuffer[MAX_OUTPUT_CHANNELS]; + + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + p_tmpRendBuffer[i] = tmpRendBuffer[i]; + } + + push_wmops( "renderIsmToBinauralRoom" ); + + rotatedPosPrev = defaultObjectPosition(); + rotatedPos = defaultObjectPosition(); + + hCombinedOrientationData = ismInput->base.ctx.pCombinedOrientationData; + combinedOrientationEnabled = 0; + if ( hCombinedOrientationData != NULL ) + { + for ( subframe_idx = 0; subframe_idx < ( *hCombinedOrientationData )->num_subframes; subframe_idx++ ) + { + + if ( ( *hCombinedOrientationData )->enableCombinedOrientation[subframe_idx] != 0 ) + { + combinedOrientationEnabled = 1; + break; + } + } + } + + if ( combinedOrientationEnabled ) + { + for ( subframe_idx = 0; subframe_idx < 1; subframe_idx++ ) + { + for ( i = 0; i < 3; i++ ) + { + if ( hCombinedOrientationData != NULL && ( *hCombinedOrientationData )->enableCombinedOrientation[subframe_idx] ) + { + for ( j = 0; j < 3; j++ ) + { + Rmat[i][j] = ( *hCombinedOrientationData )->Rmat[subframe_idx][i][j]; + } + } + else + { + /* Set to identity */ + set_zero( Rmat[i], 3 ); + Rmat[i][i] = 1.0f; + } + } + } + } + + /* get previous position */ + if ( combinedOrientationEnabled ) + { + rotateAziEle( ismInput->previousPos.azimuth, ismInput->previousPos.elevation, &azi_rot, &ele_rot, ismInput->rot_mat_prev, 0 ); + rotatedPosPrev.azimuth = (float) azi_rot; + rotatedPosPrev.elevation = (float) ele_rot; + } + else + { + rotatedPosPrev.azimuth = ismInput->previousPos.azimuth; + rotatedPosPrev.elevation = ismInput->previousPos.elevation; + } + + /* get current position */ + if ( combinedOrientationEnabled ) + { + rotateAziEle( ismInput->currentPos.azimuth, ismInput->currentPos.elevation, &azi_rot, &ele_rot, Rmat, 0 ); + rotatedPos.azimuth = (float) azi_rot; + rotatedPos.elevation = (float) ele_rot; + } + else + { + rotatedPos.azimuth = ismInput->currentPos.azimuth; + rotatedPos.elevation = ismInput->currentPos.elevation; + } + + position_changed = !ismInput->firstFrameRendered || checkObjectPositionChanged( &rotatedPos, &rotatedPosPrev ); + + /* set previous gains if this is the first frame */ + if ( ( error = getEfapGains( *ismInput->base.ctx.pEfapOutWrapper, rotatedPosPrev.azimuth, rotatedPosPrev.elevation, ismInput->prev_pan_gains ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* compute gains only if position changed */ + if ( position_changed ) + { + if ( ( error = getEfapGains( *ismInput->base.ctx.pEfapOutWrapper, + rotatedPos.azimuth, + rotatedPos.elevation, + currentPanGains ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* intermediate rendering to 7_1_4 */ + tmpMcBuffer = ismInput->base.inputBuffer; + + if ( ( error = getAudioConfigNumChannels( IVAS_AUDIO_CONFIG_7_1_4, &tmp ) ) != IVAS_ERR_OK ) + { + return error; + } + + tmpMcBuffer.config.numChannels = tmp; + tmpMcBuffer.data = malloc( tmpMcBuffer.config.numSamplesPerChannel * tmpMcBuffer.config.numChannels * sizeof( float ) ); + set_zero( tmpMcBuffer.data, tmpMcBuffer.config.numSamplesPerChannel * tmpMcBuffer.config.numChannels ); + + renderBufferChannelLerp( ismInput->base.inputBuffer, 0, + position_changed ? currentPanGains : ismInput->prev_pan_gains, + position_changed ? ismInput->prev_pan_gains : NULL, + tmpMcBuffer ); + + copyBufferTo2dArray( tmpMcBuffer, tmpRendBuffer ); + + /* save gains for next frame */ + for ( i = 0; i < 3; i++ ) + { + mvr2r( Rmat[i], ismInput->rot_mat_prev[i], 3 ); + } + + if ( position_changed ) + { + mvr2r( currentPanGains, ismInput->prev_pan_gains, MAX_OUTPUT_CHANNELS ); + } + + /* render 7_1_4 with BRIRs */ + if ( ( error = ivas_rend_crendProcess( ismInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, + NULL, NULL, NULL, NULL, p_tmpRendBuffer, *ismInput->base.ctx.pOutSampleRate, + getNumSubframesInBuffer( &outAudio, *ismInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) + + { + return error; + } + + accumulate2dArrayToBuffer( tmpRendBuffer, &outAudio ); + free( tmpMcBuffer.data ); + pop_wmops(); + + return IVAS_ERR_OK; +} +#endif static ivas_error renderIsmToBinauralReverb( input_ism *ismInput, @@ -5217,7 +5422,7 @@ static ivas_error renderLfeToBinaural( return IVAS_ERR_OK; } - +#ifdef IVAS_FLOAT_FIXED static ivas_error renderMcToBinaural( input_mc *mcInput, const AUDIO_CONFIG outConfig, @@ -5286,13 +5491,76 @@ static ivas_error renderMcToBinaural( { copyBufferTo2dArray( mcInput->base.inputBuffer, tmpRendBuffer ); } + // Porting Crend_process function + Word16 j, nchan_out = 2, nchan_in = 12, subframe_len; + CREND_HANDLE hCrend; + Word32 output_buffer_fx[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + Word32 *output_fx[MAX_OUTPUT_CHANNELS]; + hCrend = mcInput->crendWrapper->hCrend; + IVAS_REND_AudioConfigType inConfigType; + subframe_len = (Word16) ( *mcInput->base.ctx.pOutSampleRate / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ); + Word16 gd_bits = find_guarded_bits_fx( subframe_len ); + Word16 exp = 15; + exp -= gd_bits; + Word16 nchan = nchan_in; + inConfigType = getAudioConfigType( mcInput->base.inConfig ); + + if ( ( error = getAudioConfigNumChannels( outConfig, &nchan_out ) ) != IVAS_ERR_OK ) + { + return error; + } + // TODO:will remove later for temporary conversion; not there in the float code code + if ( ( error = getAudioConfigNumChannels( inConfig, &nchan_in ) ) != IVAS_ERR_OK ) + { + return error; + } + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + output_fx[i] = output_buffer_fx[i]; + } + if ( hCrend->reflections != NULL ) + { + if ( hCrend->reflections->use_er == 1 && hCrend->reflections->is_ready == 1 ) + { + nchan = hCrend->reflections->shoebox_data.n_sources + 1; + for ( i = 0; i < 150; i++ ) + { + hCrend->reflections->shoebox_data.gains.data_fx[i] = (Word32) float_to_fix( hCrend->reflections->shoebox_data.gains.data[i], 15 ); + } + } + } + + if ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED || inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) + { + nchan = nchan_in; + } + for ( i = 0; i < nchan; i++ ) + { + for ( j = 0; j < L_FRAME48k; j++ ) + { + output_fx[i][j] = (Word32) float_to_fix( p_tmpRendBuffer[i][j], exp ); + } + } /* call CREND */ - if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate, + if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, output_fx, *mcInput->base.ctx.pOutSampleRate, getNumSubframesInBuffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) { return error; } + if ( hCrend->hReverb != NULL ) + { + exp -= 2; + } + for ( i = 0; i < nchan_out; i++ ) + { + + for ( j = 0; j < L_FRAME48k; j++ ) + { + + p_tmpRendBuffer[i][j] = fix_to_float( output_fx[i][j], exp ); + } + } } accumulate2dArrayToBuffer( tmpRendBuffer, &outAudio ); @@ -5306,9 +5574,8 @@ static ivas_error renderMcToBinaural( pop_wmops(); return IVAS_ERR_OK; } - - -static ivas_error renderMcToBinauralRoom( +#else +static ivas_error renderMcToBinaural( input_mc *mcInput, const AUDIO_CONFIG outConfig, IVAS_REND_AudioBuffer outAudio ) @@ -5317,18 +5584,18 @@ static ivas_error renderMcToBinauralRoom( AUDIO_CONFIG inConfig; ivas_error error; IVAS_REND_AudioBuffer tmpRotBuffer; - float *p_tmpRendBuffer[MAX_OUTPUT_CHANNELS]; - int16_t i; const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData; int8_t combinedOrientationEnabled; int16_t subframe_idx; + float *p_tmpRendBuffer[MAX_OUTPUT_CHANNELS]; + int16_t i; for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) { p_tmpRendBuffer[i] = tmpRendBuffer[i]; } - push_wmops( "renderMcToBinauralRoom" ); + push_wmops( "renderMcToBinaural" ); inConfig = mcInput->base.inConfig; hCombinedOrientationData = mcInput->base.ctx.pCombinedOrientationData; @@ -5345,7 +5612,7 @@ static ivas_error renderMcToBinauralRoom( } } - if ( ( mcInput->hReverb != NULL && outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) && ( ( inConfig == IVAS_AUDIO_CONFIG_LS_CUSTOM ) || ( combinedOrientationEnabled && ( inConfig == IVAS_AUDIO_CONFIG_5_1 || inConfig == IVAS_AUDIO_CONFIG_7_1 ) ) ) ) + if ( ( inConfig == IVAS_AUDIO_CONFIG_LS_CUSTOM ) || ( combinedOrientationEnabled && ( inConfig == IVAS_AUDIO_CONFIG_5_1 || inConfig == IVAS_AUDIO_CONFIG_7_1 ) ) ) { copyBufferTo2dArray( mcInput->base.inputBuffer, tmpRendBuffer ); @@ -5364,9 +5631,7 @@ static ivas_error renderMcToBinauralRoom( tmpRotBuffer.data = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); set_zero( tmpRotBuffer.data, tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels ); - if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, - mcInput->rot_gains_prev, - mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ) != IVAS_ERR_OK ) + if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, mcInput->rot_gains_prev, mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ) != IVAS_ERR_OK ) { return error; } @@ -5390,6 +5655,7 @@ static ivas_error renderMcToBinauralRoom( accumulate2dArrayToBuffer( tmpRendBuffer, &outAudio ); if ( ( error = renderLfeToBinaural( mcInput, outAudio ) ) != IVAS_ERR_OK ) + { return error; } @@ -5397,9 +5663,253 @@ static ivas_error renderMcToBinauralRoom( pop_wmops(); return IVAS_ERR_OK; } - - -static ivas_error renderMcCustomLsToBinauralRoom( +#endif +#ifdef IVAS_FLOAT_FIXED +static ivas_error renderMcToBinauralRoom( + input_mc *mcInput, + const AUDIO_CONFIG outConfig, + IVAS_REND_AudioBuffer outAudio ) +{ + float tmpRendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + AUDIO_CONFIG inConfig; + ivas_error error; + IVAS_REND_AudioBuffer tmpRotBuffer; + float *p_tmpRendBuffer[MAX_OUTPUT_CHANNELS]; + int16_t i; + const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData; + int8_t combinedOrientationEnabled; + int16_t subframe_idx; + + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + p_tmpRendBuffer[i] = tmpRendBuffer[i]; + } + + push_wmops( "renderMcToBinauralRoom" ); + inConfig = mcInput->base.inConfig; + + hCombinedOrientationData = mcInput->base.ctx.pCombinedOrientationData; + combinedOrientationEnabled = 0; + if ( hCombinedOrientationData != NULL ) + { + for ( subframe_idx = 0; subframe_idx < ( *hCombinedOrientationData )->num_subframes; subframe_idx++ ) + { + if ( ( *hCombinedOrientationData )->enableCombinedOrientation[subframe_idx] != 0 ) + { + combinedOrientationEnabled = 1; + break; + } + } + } + + if ( ( mcInput->hReverb != NULL && outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) && ( ( inConfig == IVAS_AUDIO_CONFIG_LS_CUSTOM ) || ( combinedOrientationEnabled && ( inConfig == IVAS_AUDIO_CONFIG_5_1 || inConfig == IVAS_AUDIO_CONFIG_7_1 ) ) ) ) + { + copyBufferTo2dArray( mcInput->base.inputBuffer, tmpRendBuffer ); + + if ( ( error = ivas_td_binaural_renderer_ext( &mcInput->tdRendWrapper, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pCombinedOrientationData, NULL, mcInput->hReverb, + 0, *mcInput->base.ctx.pOutSampleRate, mcInput->base.inputBuffer.config.numSamplesPerChannel, tmpRendBuffer ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + /* apply rotation */ + if ( combinedOrientationEnabled ) + { + tmpRotBuffer = mcInput->base.inputBuffer; + tmpRotBuffer.data = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); + set_zero( tmpRotBuffer.data, tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels ); + + if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, + mcInput->rot_gains_prev, + mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ) != IVAS_ERR_OK ) + { + return error; + } + + copyBufferTo2dArray( tmpRotBuffer, tmpRendBuffer ); + free( tmpRotBuffer.data ); + } + else + { + copyBufferTo2dArray( mcInput->base.inputBuffer, tmpRendBuffer ); + } + // Porting Crend_process function + Word16 j, nchan_out = 2, nchan_in = 12, subframe_len; + CREND_HANDLE hCrend; + Word32 output_buffer_fx[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + Word32 *output_fx[MAX_OUTPUT_CHANNELS]; + hCrend = mcInput->crendWrapper->hCrend; + IVAS_REND_AudioConfigType inConfigType; + subframe_len = (Word16) ( *mcInput->base.ctx.pOutSampleRate / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ); + Word16 gd_bits = find_guarded_bits_fx( subframe_len ); + Word16 exp = 15; + exp -= gd_bits; + Word16 nchan = nchan_in; + inConfigType = getAudioConfigType( mcInput->base.inConfig ); + + if ( ( error = getAudioConfigNumChannels( outConfig, &nchan_out ) ) != IVAS_ERR_OK ) + { + return error; + } + // TODO:will remove later for temporary conversion; not there in the float code code + if ( ( error = getAudioConfigNumChannels( inConfig, &nchan_in ) ) != IVAS_ERR_OK ) + { + return error; + } + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + output_fx[i] = output_buffer_fx[i]; + } + if ( hCrend->reflections != NULL ) + { + if ( hCrend->reflections->use_er == 1 && hCrend->reflections->is_ready == 1 ) + { + nchan = hCrend->reflections->shoebox_data.n_sources + 1; + for ( i = 0; i < 150; i++ ) + { + hCrend->reflections->shoebox_data.gains.data_fx[i] = (Word32) float_to_fix( hCrend->reflections->shoebox_data.gains.data[i], 15 ); + } + } + } + + if ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED || inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) + { + nchan = nchan_in; + } + for ( i = 0; i < nchan; i++ ) + { + for ( j = 0; j < L_FRAME48k; j++ ) + { + + output_fx[i][j] = (Word32) float_to_fix( p_tmpRendBuffer[i][j], exp ); + } + } + /* call CREND */ + if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, output_fx, *mcInput->base.ctx.pOutSampleRate, + getNumSubframesInBuffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( hCrend->hReverb != NULL ) + { + exp -= 2; + } + for ( i = 0; i < nchan_out; i++ ) + { + + for ( j = 0; j < L_FRAME48k; j++ ) + { + + p_tmpRendBuffer[i][j] = fix_to_float( output_fx[i][j], exp ); + } + } + } + + accumulate2dArrayToBuffer( tmpRendBuffer, &outAudio ); + + if ( ( error = renderLfeToBinaural( mcInput, outAudio ) ) != IVAS_ERR_OK ) + { + return error; + } + + pop_wmops(); + return IVAS_ERR_OK; +} +#else +static ivas_error renderMcToBinauralRoom( + input_mc *mcInput, + const AUDIO_CONFIG outConfig, + IVAS_REND_AudioBuffer outAudio ) +{ + float tmpRendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + AUDIO_CONFIG inConfig; + ivas_error error; + IVAS_REND_AudioBuffer tmpRotBuffer; + float *p_tmpRendBuffer[MAX_OUTPUT_CHANNELS]; + int16_t i; + const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData; + int8_t combinedOrientationEnabled; + int16_t subframe_idx; + + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + p_tmpRendBuffer[i] = tmpRendBuffer[i]; + } + + push_wmops( "renderMcToBinauralRoom" ); + inConfig = mcInput->base.inConfig; + + hCombinedOrientationData = mcInput->base.ctx.pCombinedOrientationData; + combinedOrientationEnabled = 0; + if ( hCombinedOrientationData != NULL ) + { + for ( subframe_idx = 0; subframe_idx < ( *hCombinedOrientationData )->num_subframes; subframe_idx++ ) + { + if ( ( *hCombinedOrientationData )->enableCombinedOrientation[subframe_idx] != 0 ) + { + combinedOrientationEnabled = 1; + break; + } + } + } + + if ( ( mcInput->hReverb != NULL && outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) && ( ( inConfig == IVAS_AUDIO_CONFIG_LS_CUSTOM ) || ( combinedOrientationEnabled && ( inConfig == IVAS_AUDIO_CONFIG_5_1 || inConfig == IVAS_AUDIO_CONFIG_7_1 ) ) ) ) + { + copyBufferTo2dArray( mcInput->base.inputBuffer, tmpRendBuffer ); + + if ( ( error = ivas_td_binaural_renderer_ext( &mcInput->tdRendWrapper, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pCombinedOrientationData, NULL, mcInput->hReverb, + 0, *mcInput->base.ctx.pOutSampleRate, mcInput->base.inputBuffer.config.numSamplesPerChannel, tmpRendBuffer ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + /* apply rotation */ + if ( combinedOrientationEnabled ) + { + tmpRotBuffer = mcInput->base.inputBuffer; + tmpRotBuffer.data = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); + set_zero( tmpRotBuffer.data, tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels ); + + if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, + mcInput->rot_gains_prev, + mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ) != IVAS_ERR_OK ) + { + return error; + } + + copyBufferTo2dArray( tmpRotBuffer, tmpRendBuffer ); + free( tmpRotBuffer.data ); + } + else + { + copyBufferTo2dArray( mcInput->base.inputBuffer, tmpRendBuffer ); + } + + /* call CREND */ + if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate, + getNumSubframesInBuffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + accumulate2dArrayToBuffer( tmpRendBuffer, &outAudio ); + + if ( ( error = renderLfeToBinaural( mcInput, outAudio ) ) != IVAS_ERR_OK ) + { + return error; + } + + pop_wmops(); + return IVAS_ERR_OK; +} +#endif +#ifdef IVAS_FLOAT_FIXED +static ivas_error renderMcCustomLsToBinauralRoom( input_mc *mcInput, const AUDIO_CONFIG outConfig, IVAS_REND_AudioBuffer outAudio ) @@ -5471,14 +5981,72 @@ static ivas_error renderMcCustomLsToBinauralRoom( renderBufferChannel( *tmpBufPtr, i, mcInput->panGains[i], tmpMcBuffer ); } copyBufferTo2dArray( tmpMcBuffer, tmpCrendBuffer ); + // Porting Crend_process function + Word16 j, nchan_out = 2, nchan_in = 12, subframe_len; + CREND_HANDLE hCrend; + Word32 output_buffer_fx[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + Word32 *output_fx[MAX_OUTPUT_CHANNELS]; + hCrend = mcInput->crendWrapper->hCrend; + IVAS_REND_AudioConfigType inConfigType; + subframe_len = (Word16) ( *mcInput->base.ctx.pOutSampleRate / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ); + Word16 gd_bits = find_guarded_bits_fx( subframe_len ); + Word16 exp = 15; + exp -= gd_bits; + Word16 nchan = nchan_in; + inConfigType = getAudioConfigType( mcInput->base.inConfig ); + + if ( ( error = getAudioConfigNumChannels( outConfig, &nchan_out ) ) != IVAS_ERR_OK ) + { + return error; + } + nchan_in = 12; + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + output_fx[i] = output_buffer_fx[i]; + } + if ( hCrend->reflections != NULL ) + { + if ( hCrend->reflections->use_er == 1 && hCrend->reflections->is_ready == 1 ) + { + nchan = hCrend->reflections->shoebox_data.n_sources + 1; + for ( i = 0; i < 150; i++ ) + { + hCrend->reflections->shoebox_data.gains.data_fx[i] = (Word32) float_to_fix( hCrend->reflections->shoebox_data.gains.data[i], 15 ); + } + } + } + if ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED || inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) + { + nchan = nchan_in; + } + for ( i = 0; i < nchan; i++ ) + { + for ( j = 0; j < L_FRAME48k; j++ ) + { + + output_fx[i][j] = (Word32) float_to_fix( p_tmpCrendBuffer[i][j], exp ); + } + } /* call CREND */ if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, NULL, NULL, NULL, NULL, - p_tmpCrendBuffer, *mcInput->base.ctx.pOutSampleRate, getNumSubframesInBuffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) + output_fx, *mcInput->base.ctx.pOutSampleRate, getNumSubframesInBuffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) { return error; } + if ( hCrend->hReverb != NULL ) + { + exp -= 2; + } + for ( i = 0; i < nchan_out; i++ ) + { + + for ( j = 0; j < L_FRAME48k; j++ ) + { + p_tmpCrendBuffer[i][j] = fix_to_float( output_fx[i][j], exp ); + } + } accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); if ( ( error = renderLfeToBinaural( mcInput, outAudio ) ) != IVAS_ERR_OK ) @@ -5495,7 +6063,104 @@ static ivas_error renderMcCustomLsToBinauralRoom( pop_wmops(); return IVAS_ERR_OK; } +#else +static ivas_error renderMcCustomLsToBinauralRoom( + input_mc *mcInput, + const AUDIO_CONFIG outConfig, + IVAS_REND_AudioBuffer outAudio ) +{ + int16_t i; + int16_t tmp; + float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + ivas_error error; + IVAS_REND_AudioBuffer tmpRotBuffer; + IVAS_REND_AudioBuffer tmpMcBuffer; + IVAS_REND_AudioBuffer *tmpBufPtr; + float *p_tmpCrendBuffer[MAX_OUTPUT_CHANNELS]; + const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData; + int8_t combinedOrientationEnabled; + int16_t subframe_idx; + + push_wmops( "renderMcCustomLsToBinauralRoom" ); + tmpRotBuffer = outAudio; /* avoid compilation warning */ + + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + p_tmpCrendBuffer[i] = tmpCrendBuffer[i]; + } + + hCombinedOrientationData = mcInput->base.ctx.pCombinedOrientationData; + combinedOrientationEnabled = 0; + if ( hCombinedOrientationData != NULL ) + { + for ( subframe_idx = 0; subframe_idx < ( *hCombinedOrientationData )->num_subframes; subframe_idx++ ) + { + if ( ( *hCombinedOrientationData )->enableCombinedOrientation[subframe_idx] != 0 ) + { + combinedOrientationEnabled = 1; + break; + } + } + } + + /* apply rotation */ + if ( combinedOrientationEnabled ) + { + tmpRotBuffer = mcInput->base.inputBuffer; + tmpRotBuffer.data = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); + set_zero( tmpRotBuffer.data, tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels ); + + if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, + mcInput->rot_gains_prev, + mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ) != IVAS_ERR_OK ) + { + return error; + } + } + /* intermediate conversion to 7_1_4 */ + tmpMcBuffer = mcInput->base.inputBuffer; + + if ( ( error = getAudioConfigNumChannels( IVAS_AUDIO_CONFIG_7_1_4, &tmp ) ) != IVAS_ERR_OK ) + { + return error; + } + + tmpMcBuffer.config.numChannels = tmp; + tmpMcBuffer.data = malloc( tmpMcBuffer.config.numSamplesPerChannel * tmpMcBuffer.config.numChannels * sizeof( float ) ); + set_zero( tmpMcBuffer.data, tmpMcBuffer.config.numSamplesPerChannel * tmpMcBuffer.config.numChannels ); + + tmpBufPtr = ( combinedOrientationEnabled ) ? &tmpRotBuffer : &mcInput->base.inputBuffer; + for ( i = 0; i < mcInput->base.inputBuffer.config.numChannels; i++ ) + { + renderBufferChannel( *tmpBufPtr, i, mcInput->panGains[i], tmpMcBuffer ); + } + copyBufferTo2dArray( tmpMcBuffer, tmpCrendBuffer ); + + /* call CREND */ + if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, NULL, NULL, NULL, NULL, + p_tmpCrendBuffer, *mcInput->base.ctx.pOutSampleRate, getNumSubframesInBuffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) + { + return error; + } + + accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); + + if ( ( error = renderLfeToBinaural( mcInput, outAudio ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( combinedOrientationEnabled ) + { + free( tmpRotBuffer.data ); + } + free( tmpMcBuffer.data ); + + pop_wmops(); + return IVAS_ERR_OK; +} +#endif static void renderMcToMc( const input_mc *mcInput, @@ -5694,7 +6359,7 @@ static ivas_error renderSbaToBinaural( ivas_error error; IVAS_REND_AudioBuffer tmpRotBuffer; float *p_tmpCrendBuffer[MAX_OUTPUT_CHANNELS]; - int16_t i,j; + int16_t i, j; const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData; int8_t combinedOrientationEnabled; int16_t subframe_idx; @@ -5726,7 +6391,7 @@ static ivas_error renderSbaToBinaural( tmpRotBuffer = sbaInput->base.inputBuffer; tmpRotBuffer.data = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); tmpRotBuffer.data_fx = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( Word32 ) ); - sbaInput->base.inputBuffer.data_fx = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( Word32 ) );//for now keeping the buffer local + sbaInput->base.inputBuffer.data_fx = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( Word32 ) ); // for now keeping the buffer local /* copy input for in-place rotation */ mvr2r( sbaInput->base.inputBuffer.data, tmpRotBuffer.data, tmpRotBuffer.config.numChannels * tmpRotBuffer.config.numSamplesPerChannel ); for ( Word16 smpl = 0; smpl < tmpRotBuffer.config.numSamplesPerChannel; ++smpl ) @@ -5739,7 +6404,7 @@ static ivas_error renderSbaToBinaural( } for ( i = 0; i < L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { - sbaInput->base.ctx.pHeadRotData->crossfade_fx[i] = (Word16)float_to_fix( sbaInput->base.ctx.pHeadRotData->crossfade[i], 14 ); + sbaInput->base.ctx.pHeadRotData->crossfade_fx[i] = (Word16) float_to_fix( sbaInput->base.ctx.pHeadRotData->crossfade[i], 14 ); } for ( i = 0; i < HEADROT_SHMAT_DIM; i++ ) { @@ -5759,7 +6424,7 @@ static ivas_error renderSbaToBinaural( } } if ( ( error = rotateFrameSba_fx( sbaInput->base.inputBuffer, sbaInput->base.inConfig, sbaInput->base.ctx.pHeadRotData, - sbaInput->base.ctx.pCombinedOrientationData, sbaInput->rot_gains_prev_fx, tmpRotBuffer ) ) != IVAS_ERR_OK ) + sbaInput->base.ctx.pCombinedOrientationData, sbaInput->rot_gains_prev_fx, tmpRotBuffer ) ) != IVAS_ERR_OK ) { return error; } @@ -5780,20 +6445,82 @@ static ivas_error renderSbaToBinaural( copyBufferTo2dArray( tmpRotBuffer, tmpCrendBuffer ); free( tmpRotBuffer.data ); free( tmpRotBuffer.data_fx ); - free( sbaInput->base.inputBuffer.data_fx );//for now keeping the buffer local + free( sbaInput->base.inputBuffer.data_fx ); // for now keeping the buffer local } else { copyBufferTo2dArray( sbaInput->base.inputBuffer, tmpCrendBuffer ); } + // Porting Crend_process function + Word16 nchan_out = 2, nchan_in = 12, subframe_len; + CREND_HANDLE hCrend; + Word32 output_buffer_fx[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + Word32 *output_fx[MAX_OUTPUT_CHANNELS]; + hCrend = sbaInput->crendWrapper->hCrend; + IVAS_REND_AudioConfigType inConfigType; + subframe_len = (Word16) ( *sbaInput->base.ctx.pOutSampleRate / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ); + Word16 gd_bits = find_guarded_bits_fx( subframe_len ); + Word16 exp = 15; + exp -= gd_bits; + Word16 nchan = nchan_in; + inConfigType = getAudioConfigType( sbaInput->base.inConfig ); + + if ( ( error = getAudioConfigNumChannels( outConfig, &nchan_out ) ) != IVAS_ERR_OK ) + { + return error; + } + // TODO:will remove later for temporary conversion; not there in the float code code + if ( ( error = getAudioConfigNumChannels( sbaInput->base.inConfig, &nchan_in ) ) != IVAS_ERR_OK ) + { + return error; + } + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + output_fx[i] = output_buffer_fx[i]; + } + if ( hCrend->reflections != NULL ) + { + if ( hCrend->reflections->use_er == 1 && hCrend->reflections->is_ready == 1 ) + { + nchan = hCrend->reflections->shoebox_data.n_sources + 1; + for ( i = 0; i < 150; i++ ) + { + hCrend->reflections->shoebox_data.gains.data_fx[i] = (Word32) float_to_fix( hCrend->reflections->shoebox_data.gains.data[i], 15 ); + } + } + } + + if ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED || inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) + { + nchan = nchan_in; + } + for ( i = 0; i < nchan; i++ ) + { + for ( j = 0; j < L_FRAME48k; j++ ) + { + output_fx[i][j] = (Word32) float_to_fix( p_tmpCrendBuffer[i][j], exp ); + } + } /* call CREND */ - if ( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, sbaInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate, + if ( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, sbaInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, output_fx, *sbaInput->base.ctx.pOutSampleRate, getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) { return error; } + if ( hCrend->hReverb != NULL ) + { + exp -= 2; + } + for ( i = 0; i < nchan_out; i++ ) + { + + for ( j = 0; j < L_FRAME48k; j++ ) + { + p_tmpCrendBuffer[i][j] = fix_to_float( output_fx[i][j], exp ); + } + } accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); } @@ -5920,8 +6647,8 @@ static ivas_error renderSbaToBinauralRoom( tmpRotBuffer = sbaInput->base.inputBuffer; tmpRotBuffer.data = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); tmpRotBuffer.data_fx = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( Word32 ) ); - sbaInput->base.inputBuffer.data_fx = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( Word32 ) );//for now keeping the buffer local - + sbaInput->base.inputBuffer.data_fx = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( Word32 ) ); // for now keeping the buffer local + /* copy input for in-place rotation */ mvr2r( sbaInput->base.inputBuffer.data, tmpRotBuffer.data, tmpRotBuffer.config.numChannels * tmpRotBuffer.config.numSamplesPerChannel ); for ( Word16 smpl = 0; smpl < tmpRotBuffer.config.numSamplesPerChannel; ++smpl ) @@ -5954,9 +6681,9 @@ static ivas_error renderSbaToBinauralRoom( } } if ( ( error = rotateFrameSba_fx( sbaInput->base.inputBuffer, sbaInput->base.inConfig, sbaInput->base.ctx.pHeadRotData, - sbaInput->base.ctx.pCombinedOrientationData, - sbaInput->rot_gains_prev_fx, - tmpRotBuffer ) ) != IVAS_ERR_OK ) + sbaInput->base.ctx.pCombinedOrientationData, + sbaInput->rot_gains_prev_fx, + tmpRotBuffer ) ) != IVAS_ERR_OK ) { return error; } @@ -5995,22 +6722,78 @@ static ivas_error renderSbaToBinauralRoom( } copyBufferTo2dArray( tmpMcBuffer, tmpCrendBuffer ); + // Porting Crend_process function + Word16 nchan_out , nchan_in , subframe_len; + CREND_HANDLE hCrend; + Word32 output_buffer_fx[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + Word32 *output_fx[MAX_OUTPUT_CHANNELS]; + hCrend = sbaInput->crendWrapper->hCrend; + IVAS_REND_AudioConfigType inConfigType; + subframe_len = (Word16) ( *sbaInput->base.ctx.pOutSampleRate / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ); + Word16 gd_bits = find_guarded_bits_fx( subframe_len ); + Word16 exp = 15; + exp -= gd_bits; + Word16 nchan ; + inConfigType = getAudioConfigType( sbaInput->base.inConfig ); + + if ( ( error = getAudioConfigNumChannels( outConfig, &nchan_out ) ) != IVAS_ERR_OK ) + { + return error; + } + nchan_in = 12; + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + output_fx[i] = output_buffer_fx[i]; + } + if ( hCrend->reflections != NULL ) + { + if ( hCrend->reflections->use_er == 1 && hCrend->reflections->is_ready == 1 ) + { + nchan = hCrend->reflections->shoebox_data.n_sources + 1; + for ( i = 0; i < 150; i++ ) + { + hCrend->reflections->shoebox_data.gains.data_fx[i] = (Word32) float_to_fix( hCrend->reflections->shoebox_data.gains.data[i], 15 ); + } + } + } + + + nchan = nchan_in; + for ( i = 0; i < nchan; i++ ) + { + for ( j = 0; j < L_FRAME48k; j++ ) + { + output_fx[i][j] = (Word32) float_to_fix( p_tmpCrendBuffer[i][j], exp ); + } + } /* call CREND */ if ( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, - NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate, + NULL, NULL, NULL, NULL, output_fx, *sbaInput->base.ctx.pOutSampleRate, getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) { return error; } + if ( hCrend->hReverb != NULL ) + { + exp -= 2; + } + for ( i = 0; i < nchan_out; i++ ) + { + for ( j = 0; j < L_FRAME48k; j++ ) + { + + p_tmpCrendBuffer[i][j] = fix_to_float( output_fx[i][j], exp ); + } + } accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); if ( combinedOrientationEnabled ) { free( tmpRotBuffer.data ); free( tmpRotBuffer.data_fx ); - free( sbaInput->base.inputBuffer.data_fx );//for now keeping the buffer local + free( sbaInput->base.inputBuffer.data_fx ); // for now keeping the buffer local } free( tmpMcBuffer.data ); @@ -6188,8 +6971,6 @@ static ivas_error renderInputSba( } - - static ivas_error renderActiveInputsSba( IVAS_REND_HANDLE hIvasRend, IVAS_REND_AudioBuffer outAudio ) @@ -6436,25 +7217,25 @@ static ivas_error renderInputMasa( num_subframes = (int16_t) ( masaInput->base.inputBuffer.config.numSamplesPerChannel / ( *masaInput->base.ctx.pOutSampleRate / ( IVAS_NUM_FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ) ); - switch ( masaInput->hMasaExtRend->renderer_type ) - { - case RENDERER_DIRAC: - copyMasaMetadataToDiracRenderer( &masaInput->masaMetadata, masaInput->hMasaExtRend->hSpatParamRendCom, maxBin ); - ivas_masa_ext_dirac_render( masaInput->hMasaExtRend, tmpBuffer, num_subframes ); - break; - case RENDERER_STEREO_PARAMETRIC: - case RENDERER_BINAURAL_PARAMETRIC: - case RENDERER_BINAURAL_PARAMETRIC_ROOM: - copyMasaMetadataToDiracRenderer( &masaInput->masaMetadata, masaInput->hMasaExtRend->hSpatParamRendCom, maxBin ); + switch ( masaInput->hMasaExtRend->renderer_type ) + { + case RENDERER_DIRAC: + copyMasaMetadataToDiracRenderer( &masaInput->masaMetadata, masaInput->hMasaExtRend->hSpatParamRendCom, maxBin ); + ivas_masa_ext_dirac_render( masaInput->hMasaExtRend, tmpBuffer, num_subframes ); + break; + case RENDERER_STEREO_PARAMETRIC: + case RENDERER_BINAURAL_PARAMETRIC: + case RENDERER_BINAURAL_PARAMETRIC_ROOM: + copyMasaMetadataToDiracRenderer( &masaInput->masaMetadata, masaInput->hMasaExtRend->hSpatParamRendCom, maxBin ); ivas_masa_ext_rend_parambin_render( masaInput->hMasaExtRend, *masaInput->base.ctx.pCombinedOrientationData, tmpBuffer, num_subframes ); - break; - case RENDERER_DISABLE: - break; /* This happens for 1TC MASA to MONO where we just copy input transport to output */ - default: - return ( IVAS_ERROR( IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED, "Wrong output config for MASA input in external renderer\n" ) ); - } + break; + case RENDERER_DISABLE: + break; /* This happens for 1TC MASA to MONO where we just copy input transport to output */ + default: + return ( IVAS_ERROR( IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED, "Wrong output config for MASA input in external renderer\n" ) ); + } - accumulate2dArrayToBuffer( tmpBuffer_buff, &outAudio ); + accumulate2dArrayToBuffer( tmpBuffer_buff, &outAudio ); } return IVAS_ERR_OK; @@ -6663,7 +7444,7 @@ ivas_error IVAS_REND_SetIsmMetadataDelay( *-------------------------------------------------------------------*/ static ivas_error getSamplesInternal( - IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ ) { @@ -6758,7 +7539,7 @@ static ivas_error getSamplesInternal( #ifndef DISABLE_LIMITER - limitRendererOutput( hIvasRend->hLimiter, outAudio.data, outAudio.config.numSamplesPerChannel, IVAS_LIMITER_THRESHOLD ); + limitRendererOutput( hIvasRend->hLimiter, outAudio.data, outAudio.config.numSamplesPerChannel, IVAS_LIMITER_THRESHOLD ); #endif /* update global cominbed orientation start index */ @@ -6784,8 +7565,6 @@ ivas_error IVAS_REND_GetSamples( } - - /*-------------------------------------------------------------------* * IVAS_REND_Close() * @@ -6847,9 +7626,6 @@ void IVAS_REND_Close( } - - - static ivas_error ivas_masa_ext_rend_dirac_rend_init( input_masa *inputMasa ) { @@ -7235,99 +8011,99 @@ static ivas_error ivas_masa_ext_rend_parambin_init( hDiracDecBin = inputMasa->hMasaExtRend->hDiracDecBin; - /* Init assumes that no reconfiguration is required in external renderer. Instead, free and rebuild whole rendering. */ - if ( ( hDiracDecBin = (DIRAC_DEC_BIN_HANDLE) malloc( sizeof( DIRAC_DEC_BIN_DATA ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC binaural handle " ); - } + /* Init assumes that no reconfiguration is required in external renderer. Instead, free and rebuild whole rendering. */ + if ( ( hDiracDecBin = (DIRAC_DEC_BIN_HANDLE) malloc( sizeof( DIRAC_DEC_BIN_DATA ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC binaural handle " ); + } - hDiracDecBin->hTdDecorr = NULL; - hDiracDecBin->hReverb = NULL; - hDiracDecBin->h_freq_domain_decorr_ap_params = NULL; - hDiracDecBin->h_freq_domain_decorr_ap_state = NULL; - hDiracDecBin->hDiffuseDist = NULL; /* Not used in external renderer */ - hDiracDecBin->useTdDecorr = 0; /* Always use frequency domain decorrelator in external renderer */ + hDiracDecBin->hTdDecorr = NULL; + hDiracDecBin->hReverb = NULL; + hDiracDecBin->h_freq_domain_decorr_ap_params = NULL; + hDiracDecBin->h_freq_domain_decorr_ap_state = NULL; + hDiracDecBin->hDiffuseDist = NULL; /* Not used in external renderer */ + hDiracDecBin->useTdDecorr = 0; /* Always use frequency domain decorrelator in external renderer */ - for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + for ( k = 0; k < BINAURAL_CHANNELS + MAX_NUM_OBJECTS; k++ ) { - for ( k = 0; k < BINAURAL_CHANNELS + MAX_NUM_OBJECTS; k++ ) - { - set_zero( hDiracDecBin->processMtxRe[j][k], nBins ); - set_zero( hDiracDecBin->processMtxIm[j][k], nBins ); - } - - for ( k = 0; k < BINAURAL_CHANNELS; k++ ) - { - set_zero( hDiracDecBin->processMtxDecRe[j][k], nBins ); - set_zero( hDiracDecBin->processMtxDecIm[j][k], nBins ); - } - set_zero( hDiracDecBin->ChEnePrev[j], nBins ); - set_zero( hDiracDecBin->ChEneOutPrev[j], nBins ); + set_zero( hDiracDecBin->processMtxRe[j][k], nBins ); + set_zero( hDiracDecBin->processMtxIm[j][k], nBins ); } - set_zero( hDiracDecBin->ChCrossRePrev, nBins ); - set_zero( hDiracDecBin->ChCrossImPrev, nBins ); - set_zero( hDiracDecBin->ChCrossReOutPrev, nBins ); - set_zero( hDiracDecBin->ChCrossImOutPrev, nBins ); - hDiracDecBin->renderStereoOutputInsteadOfBinaural = 0; - for ( bin = 0; bin < nBins; bin++ ) + for ( k = 0; k < BINAURAL_CHANNELS; k++ ) { - binCenterFreq = ( (float) bin + 0.5f ) / (float) nBins * ( (float) output_Fs / 2.0f ); - /* 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 ); + set_zero( hDiracDecBin->processMtxDecRe[j][k], nBins ); + set_zero( hDiracDecBin->processMtxDecIm[j][k], nBins ); } + set_zero( hDiracDecBin->ChEnePrev[j], nBins ); + set_zero( hDiracDecBin->ChEneOutPrev[j], nBins ); + } + set_zero( hDiracDecBin->ChCrossRePrev, nBins ); + set_zero( hDiracDecBin->ChCrossImPrev, nBins ); + set_zero( hDiracDecBin->ChCrossReOutPrev, nBins ); + set_zero( hDiracDecBin->ChCrossImOutPrev, nBins ); + hDiracDecBin->renderStereoOutputInsteadOfBinaural = 0; - /* No SPAR in external renderer so set directive diffuse field coherence tables to zero */ - set_zero( hDiracDecBin->diffuseFieldCoherenceX, BINAURAL_COHERENCE_DIFFERENCE_BINS ); - set_zero( hDiracDecBin->diffuseFieldCoherenceY, BINAURAL_COHERENCE_DIFFERENCE_BINS ); - set_zero( hDiracDecBin->diffuseFieldCoherenceZ, BINAURAL_COHERENCE_DIFFERENCE_BINS ); + for ( bin = 0; bin < nBins; bin++ ) + { + binCenterFreq = ( (float) bin + 0.5f ) / (float) nBins * ( (float) output_Fs / 2.0f ); + /* 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 ); + } - if ( renderer_type == RENDERER_BINAURAL_PARAMETRIC ) /* Indication of binaural rendering without room effect */ - { - set_f( hDiracDecBin->earlyPartEneCorrection, 1.0f, CLDFB_NO_CHANNELS_MAX ); - hDiracDecBin->hReverb = NULL; - } - else if ( renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) /* Indication of binaural rendering with room effect */ - { - mvr2r( hHrtfParambin->parametricEarlyPartEneCorrection, hDiracDecBin->earlyPartEneCorrection, nBins ); + /* No SPAR in external renderer so set directive diffuse field coherence tables to zero */ + set_zero( hDiracDecBin->diffuseFieldCoherenceX, BINAURAL_COHERENCE_DIFFERENCE_BINS ); + set_zero( hDiracDecBin->diffuseFieldCoherenceY, BINAURAL_COHERENCE_DIFFERENCE_BINS ); + set_zero( hDiracDecBin->diffuseFieldCoherenceZ, BINAURAL_COHERENCE_DIFFERENCE_BINS ); + + if ( renderer_type == RENDERER_BINAURAL_PARAMETRIC ) /* Indication of binaural rendering without room effect */ + { + set_f( hDiracDecBin->earlyPartEneCorrection, 1.0f, CLDFB_NO_CHANNELS_MAX ); + hDiracDecBin->hReverb = NULL; + } + else if ( renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) /* Indication of binaural rendering with room effect */ + { + mvr2r( hHrtfParambin->parametricEarlyPartEneCorrection, hDiracDecBin->earlyPartEneCorrection, nBins ); if ( hDiracDecBin->hReverb == NULL ) - { - /* Todo Philips: Room acoustics should be passed here once the underlying part works. In this case, it probably should come from render context or somewhere else suitable. */ - if ( ( error = ivas_binaural_reverb_open_parambin( &hDiracDecBin->hReverb, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, NULL, output_Fs, hHrtfParambin ) ) != IVAS_ERR_OK ) - { - return error; - } - } - } - else if ( renderer_type == RENDERER_STEREO_PARAMETRIC ) - { - set_f( hDiracDecBin->earlyPartEneCorrection, 1.0f, CLDFB_NO_CHANNELS_MAX ); - hDiracDecBin->hReverb = NULL; - hDiracDecBin->renderStereoOutputInsteadOfBinaural = 1; - } - else /* Not valid renderer type for this renderer */ { - assert( false ); - } - - /* Always open frequency domain decorrelator */ - ivas_dirac_dec_get_frequency_axis( frequency_axis, output_Fs, nBins ); - if ( ( error = ivas_dirac_dec_decorr_open( &( hDiracDecBin->h_freq_domain_decorr_ap_params ), - &( hDiracDecBin->h_freq_domain_decorr_ap_state ), - nBins, - BINAURAL_CHANNELS, - BINAURAL_CHANNELS, - DIRAC_SYNTHESIS_PSD_LS, - frequency_axis, - BINAURAL_CHANNELS, - output_Fs ) ) != IVAS_ERR_OK ) + /* Todo Philips: Room acoustics should be passed here once the underlying part works. In this case, it probably should come from render context or somewhere else suitable. */ + if ( ( error = ivas_binaural_reverb_open_parambin( &hDiracDecBin->hReverb, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, NULL, output_Fs, hHrtfParambin ) ) != IVAS_ERR_OK ) { return error; } - /* External renderer uses constant regularization factor */ - hDiracDecBin->reqularizationFactor = 0.4f; + } + } + else if ( renderer_type == RENDERER_STEREO_PARAMETRIC ) + { + set_f( hDiracDecBin->earlyPartEneCorrection, 1.0f, CLDFB_NO_CHANNELS_MAX ); + hDiracDecBin->hReverb = NULL; + hDiracDecBin->renderStereoOutputInsteadOfBinaural = 1; + } + else /* Not valid renderer type for this renderer */ + { + assert( false ); + } + + /* Always open frequency domain decorrelator */ + ivas_dirac_dec_get_frequency_axis( frequency_axis, output_Fs, nBins ); + if ( ( error = ivas_dirac_dec_decorr_open( &( hDiracDecBin->h_freq_domain_decorr_ap_params ), + &( hDiracDecBin->h_freq_domain_decorr_ap_state ), + nBins, + BINAURAL_CHANNELS, + BINAURAL_CHANNELS, + DIRAC_SYNTHESIS_PSD_LS, + frequency_axis, + BINAURAL_CHANNELS, + output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + /* External renderer uses constant regularization factor */ + hDiracDecBin->reqularizationFactor = 0.4f; inputMasa->hMasaExtRend->hDiracDecBin = hDiracDecBin;