From b5c592321611730c6161641cac6fa045aa017e61 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Sun, 4 Feb 2024 07:29:17 +0530 Subject: [PATCH] hoa gain matrix and bin renderer changes [x] Contains changes for conversion of 3 subfunctions used in binRenderer_internal.c along with changes to accomodate fixed buffers (hoa_gain_matrix). --- lib_com/ivas_prot.h | 13 +- lib_com/prot_fx2.h | 16 + lib_com/tools.c | 48 + lib_dec/ivas_binRenderer_internal.c | 1036 ++++++++++++++++---- lib_dec/ivas_rom_dec.c | 9 + lib_dec/ivas_rom_dec.h | 1 + lib_dec/ivas_sba_rendering_internal.c | 69 +- lib_dec/ivas_stat_dec.h | 12 + lib_rend/ivas_allrad_dec.c | 63 +- lib_rend/ivas_dirac_output_synthesis_dec.c | 14 + lib_rend/ivas_dirac_rend.c | 9 + lib_rend/ivas_prot_rend.h | 40 +- lib_rend/ivas_reverb.c | 319 +++++- lib_rend/ivas_rotation.c | 133 ++- lib_rend/ivas_stat_rend.h | 47 +- lib_rend/lib_rend.c | 8 + 16 files changed, 1534 insertions(+), 303 deletions(-) diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 25a0813a4..67158d6e1 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -3715,6 +3715,7 @@ void ivas_sba_dirac_stereo_smooth_parameters( const int16_t num_md_sub_frames /* i : number of subframes in mixing matrix */ ); +#ifndef IVAS_FLOAT_FIXED void ivas_sba2mc_cldfb( IVAS_OUTPUT_SETUP hInSetup, /* i : Format of input layout */ float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: cldfb real part */ @@ -3724,7 +3725,17 @@ void ivas_sba2mc_cldfb( const int16_t nb_timeslots, /* i : number of time slots to process */ const float *hoa_dec_mtx /* i : HOA decoding mtx */ ); - +#else +void ivas_sba2mc_cldfb_fixed( + IVAS_OUTPUT_SETUP hInSetup, /* i : Format of input layout */ + Word32 RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: cldfb real part (Q_real) */ + Word32 ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: cldfb imag part (Q_imag) */ + const Word16 nb_channels_out, /* i : nb of output channels */ + const Word16 nb_bands, /* i : nb of CLDFB bands to process */ + const Word16 nb_timeslots, /* i : number of time slots to process */ + const Word32 *hoa_dec_mtx /* i : HOA decoding mtx */ +); +#endif /*----------------------------------------------------------------------------------* * DirAC prototypes diff --git a/lib_com/prot_fx2.h b/lib_com/prot_fx2.h index 168e7451f..c686696a8 100644 --- a/lib_com/prot_fx2.h +++ b/lib_com/prot_fx2.h @@ -5145,6 +5145,22 @@ void v_multc_fixed( const Word16 N /* i : Vector length */ ); +void v_add_fixed( + const Word32 x1[], /* i : Input vector 1 */ + const Word32 x2[], /* i : Input vector 2 */ + Word32 y[], /* o : Output vector that contains vector 1 - vector 2 */ + const Word16 N, /* i : Vector length */ + const Word16 hdrm /* i : headroom for when subtraction result > 1 or < -1 */ +); + +void v_add_w64( + const Word64 x1[], /* i : Input vector 1 */ + const Word64 x2[], /* i : Input vector 2 */ + Word64 y[], /* o : Output vector that contains vector 1 - vector 2 */ + const Word16 N, /* i : Vector length */ + const Word16 hdrm /* i : headroom for when subtraction result > 1 or < -1 */ +); + void v_sub_fixed( const Word32 x1[], /* i : Input vector 1 */ const Word32 x2[], /* i : Input vector 2 */ diff --git a/lib_com/tools.c b/lib_com/tools.c index 40996701c..4e07856a4 100644 --- a/lib_com/tools.c +++ b/lib_com/tools.c @@ -964,6 +964,54 @@ void v_add( return; } +/*-------------------------------------------------------------------* + * v_add_fixed() + * + * Subtraction of two vectors sample by sample + *-------------------------------------------------------------------*/ + +void v_add_fixed( + const Word32 x1[], /* i : Input vector 1 */ + const Word32 x2[], /* i : Input vector 2 */ + Word32 y[], /* o : Output vector that contains vector 1 - vector 2 */ + const Word16 N, /* i : Vector length */ + const Word16 hdrm /* i : headroom for when subtraction result > 1 or < -1 */ +) +{ + Word16 i; + + FOR( i = 0; i < N; i++ ) + { + y[i] = L_add( L_shr( x1[i], hdrm ), L_shr( x2[i], hdrm ) ); + } + + return; +} + +/*-------------------------------------------------------------------* + * v_add_w64() + * + * Subtraction of two vectors sample by sample + *-------------------------------------------------------------------*/ + +void v_add_w64( + const Word64 x1[], /* i : Input vector 1 */ + const Word64 x2[], /* i : Input vector 2 */ + Word64 y[], /* o : Output vector that contains vector 1 - vector 2 */ + const Word16 N, /* i : Vector length */ + const Word16 hdrm /* i : headroom for when subtraction result > 1 or < -1 */ +) +{ + Word16 i; + + FOR( i = 0; i < N; i++ ) + { + y[i] = W_add( W_shr( x1[i], hdrm ), W_shr( x2[i], hdrm ) ); + } + + return; +} + /*-------------------------------------------------------------------* * v_sub() diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index 7b71eb328..fcdf99e10 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -47,10 +47,12 @@ #include "prot_fx1.h" #include "prot_fx2.h" #include "debug.h" -#define float_to_fix( n, factor ) ( round( n * ( 1 << factor ) ) ) -#define fix_to_float( n, factor ) ( (float) n / ( 1 << factor ) ) +#define float_to_fix( n, factor ) ( round( n * ( 1 << factor ) ) ) +#define float_to_fixQ29( n ) float_to_fix( n, Q29 ) +#define fix_to_float( n, factor ) ( (float) n / ( 1 << factor ) ) +#define fix_W64_to_float( n, factor ) ( (float) n / ( ( (Word64) 1 ) << factor ) ) #endif - +#ifndef IVAS_FLOAT_FIXED /*------------------------------------------------------------------------- * ivas_binRenderer_filterModule() * @@ -63,7 +65,7 @@ static void ivas_binRenderer_filterModule( float CLDFB_real[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : real part of LS signals */ float CLDFB_imag[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : imag part of LS signals */ const Word16 numTimeSlots, /* i : number of time slots to process */ - BINAURAL_RENDERER_HANDLE hBinRenderer /* i/o: fastconv binaural renderer handle */ + BINAURAL_RENDERER_HANDLE hBinRenderer /* i/o: fastconv binaural renderer handle */ ) { Word16 bandIdx, k, chIdx, tapIdx; @@ -117,7 +119,108 @@ static void ivas_binRenderer_filterModule( return; } +#else +/*------------------------------------------------------------------------- + * ivas_binRenderer_filterModule_fixed() + * + * + *-------------------------------------------------------------------------*/ + +static void ivas_binRenderer_filterModule_fixed( + Word64 out_Conv_CLDFB_real[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : real part of Binaural signals */ + Word64 out_Conv_CLDFB_imag[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : imag part of Binaural signals */ + Word32 CLDFB_real[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : real part of LS signals */ + Word32 CLDFB_imag[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : imag part of LS signals */ + const Word16 numTimeSlots, /* i : number of time slots to process */ + BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: fastconv binaural renderer handle */ + Word16 Q_curr ) +{ + Word16 bandIdx, k, chIdx, tapIdx; + Word32 *filterStatesLeftRealPtr_fx, *filterStatesLeftImagPtr_fx; + Word16 *Q_filterStates; + const Word32 *filterTapsLeftRealPtr_fx, *filterTapsLeftImagPtr_fx, *filterTapsRightRealPtr_fx, *filterTapsRightImagPtr_fx; + + FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) + { + FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) + { + filterStatesLeftRealPtr_fx = (Word32 *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx][0] ); + filterStatesLeftImagPtr_fx = (Word32 *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx][0] ); + Q_filterStates = (Word16 *) &( hBinRenderer->hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx][0] ); + + filterTapsLeftRealPtr_fx = hBinRenderer->hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx]; // Q29 + filterTapsLeftImagPtr_fx = hBinRenderer->hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx]; // Q29 + filterTapsRightRealPtr_fx = hBinRenderer->hBinRenConvModule->filterTapsRightReal_fx[bandIdx][chIdx]; // Q29 + filterTapsRightImagPtr_fx = hBinRenderer->hBinRenConvModule->filterTapsRightImag_fx[bandIdx][chIdx]; // Q29 + + FOR( k = 0; k < numTimeSlots; k++ ) + { + Word64 outRealLeft_fx = 0, outRealRight_fx = 0, outImagLeft_fx = 0, outImagRight_fx = 0; + Word64 W_sub1 = 0, W_add1 = 0, W_sub2 = 0, W_add2 = 0; + + FOR( tapIdx = hBinRenderer->hBinRenConvModule->numTapsArray[bandIdx] - 1; tapIdx > 0; tapIdx-- ) + { + filterStatesLeftRealPtr_fx[tapIdx] = filterStatesLeftRealPtr_fx[tapIdx - 1]; + filterStatesLeftImagPtr_fx[tapIdx] = filterStatesLeftImagPtr_fx[tapIdx - 1]; + + W_sub1 = W_sub( W_mult0_32_32( filterStatesLeftRealPtr_fx[tapIdx], filterTapsLeftRealPtr_fx[tapIdx] ), + W_mult0_32_32( filterStatesLeftImagPtr_fx[tapIdx], filterTapsLeftImagPtr_fx[tapIdx] ) ); // Q29 + Q_filterStates[tapIdx - 1] + W_add1 = W_add( W_mult0_32_32( filterStatesLeftRealPtr_fx[tapIdx], filterTapsLeftImagPtr_fx[tapIdx] ), + W_mult0_32_32( filterStatesLeftImagPtr_fx[tapIdx], filterTapsLeftRealPtr_fx[tapIdx] ) ); // Q29 + Q_filterStates[tapIdx - 1] + W_sub2 = W_sub( W_mult0_32_32( filterStatesLeftRealPtr_fx[tapIdx], filterTapsRightRealPtr_fx[tapIdx] ), + W_mult0_32_32( filterStatesLeftImagPtr_fx[tapIdx], filterTapsRightImagPtr_fx[tapIdx] ) ); // Q29 + Q_filterStates[tapIdx - 1] + W_add2 = W_add( W_mult0_32_32( filterStatesLeftRealPtr_fx[tapIdx], filterTapsRightImagPtr_fx[tapIdx] ), + W_mult0_32_32( filterStatesLeftImagPtr_fx[tapIdx], filterTapsRightRealPtr_fx[tapIdx] ) ); // Q29 + Q_filterStates[tapIdx - 1] + + outRealLeft_fx = W_shr( outRealLeft_fx, Q_filterStates[tapIdx] - Q_filterStates[tapIdx - 1] ); + outImagLeft_fx = W_shr( outImagLeft_fx, Q_filterStates[tapIdx] - Q_filterStates[tapIdx - 1] ); + outRealRight_fx = W_shr( outRealRight_fx, Q_filterStates[tapIdx] - Q_filterStates[tapIdx - 1] ); + outImagRight_fx = W_shr( outImagRight_fx, Q_filterStates[tapIdx] - Q_filterStates[tapIdx - 1] ); + + Q_filterStates[tapIdx] = Q_filterStates[tapIdx - 1]; + + /* Left Real and Imag */ + outRealLeft_fx = W_add( outRealLeft_fx, W_sub1 ); // Q29 + Q_filterStates[1] + outImagLeft_fx = W_add( outImagLeft_fx, W_add1 ); // Q29 + Q_filterStates[1] + + /* Right Real and Imag*/ + outRealRight_fx = W_add( outRealRight_fx, W_sub2 ); // Q29 + Q_filterStates[1] + outImagRight_fx = W_add( outImagRight_fx, W_add2 ); // Q29 + Q_filterStates[1] + } + + filterStatesLeftRealPtr_fx[0] = CLDFB_real[chIdx][k][bandIdx]; + filterStatesLeftImagPtr_fx[0] = CLDFB_imag[chIdx][k][bandIdx]; + Q_filterStates[0] = Q_curr; + + + /* Left Real and Imag */ + // Q29 + Q_curr + + out_Conv_CLDFB_real[0][k][bandIdx] = W_add( out_Conv_CLDFB_real[0][k][bandIdx], + W_add( W_shr( outRealLeft_fx, Q_filterStates[1] - Q_curr ), + W_sub( W_mult0_32_32( filterStatesLeftRealPtr_fx[0], filterTapsLeftRealPtr_fx[0] ), + W_mult0_32_32( filterStatesLeftImagPtr_fx[0], filterTapsLeftImagPtr_fx[0] ) ) ) ); // Q29 + out_Conv_CLDFB_imag[0][k][bandIdx] = W_add( out_Conv_CLDFB_imag[0][k][bandIdx], + W_add( W_shr( outImagLeft_fx, Q_filterStates[1] - Q_curr ), + W_add( W_mult0_32_32( filterStatesLeftRealPtr_fx[0], filterTapsLeftImagPtr_fx[0] ), + W_mult0_32_32( filterStatesLeftImagPtr_fx[0], filterTapsLeftRealPtr_fx[0] ) ) ) ); // Q29 + + /* Right Real and Imag */ + out_Conv_CLDFB_real[1][k][bandIdx] = W_add( out_Conv_CLDFB_real[1][k][bandIdx], + W_add( W_shr( outRealRight_fx, Q_filterStates[1] - Q_curr ), + W_sub( W_mult0_32_32( filterStatesLeftRealPtr_fx[0], filterTapsRightRealPtr_fx[0] ), + W_mult0_32_32( filterStatesLeftImagPtr_fx[0], filterTapsRightImagPtr_fx[0] ) ) ) ); // Q29 + out_Conv_CLDFB_imag[1][k][bandIdx] = W_add( out_Conv_CLDFB_imag[1][k][bandIdx], + W_add( W_shr( outImagRight_fx, Q_filterStates[1] - Q_curr ), + W_add( W_mult0_32_32( filterStatesLeftRealPtr_fx[0], filterTapsRightImagPtr_fx[0] ), + W_mult0_32_32( filterStatesLeftImagPtr_fx[0], filterTapsRightRealPtr_fx[0] ) ) ) ); // Q29 + } + } + } + return; +} +#endif /*------------------------------------------------------------------------- * ivas_binRenderer_convModuleOpen() @@ -135,22 +238,34 @@ static ivas_error ivas_binRenderer_convModuleOpen( const Word16 renderer_type, const Word16 isLoudspeaker, const AUDIO_CONFIG input_config, - const HRTFS_FASTCONV_HANDLE hHrtf -) + const HRTFS_FASTCONV_HANDLE hHrtf ) { Word16 bandIdx, chIdx; +#ifndef IVAS_FLOAT_FIXED BINRENDERER_CONV_MODULE_HANDLE hBinRenConvModule; /*-----------------------------------------------------------------* * prepare library opening *-----------------------------------------------------------------*/ - IF ( ( hBinRenConvModule = (BINRENDERER_CONV_MODULE_HANDLE) malloc( sizeof( BINRENDERER_CONV_MODULE ) ) ) == NULL ) + IF( ( hBinRenConvModule = (BINRENDERER_CONV_MODULE_HANDLE) malloc( sizeof( BINRENDERER_CONV_MODULE ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } +#else + BINRENDERER_CONV_MODULE_HANDLE_FX hBinRenConvModule; + + /*-----------------------------------------------------------------* + * prepare library opening + *-----------------------------------------------------------------*/ + + IF( ( hBinRenConvModule = (BINRENDERER_CONV_MODULE_HANDLE_FX) malloc( sizeof( BINRENDERER_CONV_MODULE_FX ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } +#endif - IF ( !isLoudspeaker ) + IF( !isLoudspeaker ) { hBinRenderer->nInChannels = audioCfg2channels( input_config ); } @@ -160,36 +275,36 @@ static ivas_error ivas_binRenderer_convModuleOpen( hBinRenderer->nInChannels = ( audioCfg2channels( input_config ) - isLoudspeaker ); } - IF ( renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + IF( renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { hBinRenConvModule->numTaps = BINAURAL_NTAPS_MAX; /* Use variable order filtering */ bandIdx = 0; - FOR ( ; bandIdx < 5; bandIdx++ ) + FOR( ; bandIdx < 5; bandIdx++ ) { hBinRenConvModule->numTapsArray[bandIdx] = hBinRenConvModule->numTaps; } - FOR ( ; bandIdx < 10; bandIdx++ ) + FOR( ; bandIdx < 10; bandIdx++ ) { hBinRenConvModule->numTapsArray[bandIdx] = NUM_TAPS_F0_6; } - FOR ( ; bandIdx < 20; bandIdx++ ) + FOR( ; bandIdx < 20; bandIdx++ ) { hBinRenConvModule->numTapsArray[bandIdx] = NUM_TAPS_F0_5; } - FOR ( ; bandIdx < 30; bandIdx++ ) + FOR( ; bandIdx < 30; bandIdx++ ) { hBinRenConvModule->numTapsArray[bandIdx] = NUM_TAPS_F0_4; } - FOR ( ; bandIdx < hBinRenderer->conv_band; bandIdx++ ) + FOR( ; bandIdx < hBinRenderer->conv_band; bandIdx++ ) { hBinRenConvModule->numTapsArray[bandIdx] = NUM_TAPS_F0_3; } } ELSE { - IF ( hBinRenderer->ivas_format == SBA_FORMAT ) + IF( hBinRenderer->ivas_format == SBA_FORMAT ) { hBinRenConvModule->numTaps = BINAURAL_NTAPS_SBA; } @@ -200,130 +315,250 @@ static ivas_error ivas_binRenderer_convModuleOpen( /* Use fixed order filtering */ bandIdx = 0; - FOR ( ; bandIdx < hBinRenderer->conv_band; bandIdx++ ) + FOR( ; bandIdx < hBinRenderer->conv_band; bandIdx++ ) { hBinRenConvModule->numTapsArray[bandIdx] = hBinRenConvModule->numTaps; } } /* allocate memory for filter states */ - IF ( ( hBinRenConvModule->filterTapsLeftReal = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL ) +#ifndef IVAS_FLOAT_FIXED + IF( ( hBinRenConvModule->filterTapsLeftReal = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } - IF ( ( hBinRenConvModule->filterTapsLeftImag = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL ) + IF( ( hBinRenConvModule->filterTapsLeftImag = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } - IF ( ( hBinRenConvModule->filterTapsRightReal = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL ) + IF( ( hBinRenConvModule->filterTapsRightReal = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } - IF ( ( hBinRenConvModule->filterTapsRightImag = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL ) + IF( ( hBinRenConvModule->filterTapsRightImag = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } - FOR ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) + FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) { - IF ( ( hBinRenConvModule->filterTapsLeftReal[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL ) + IF( ( hBinRenConvModule->filterTapsLeftReal[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } - IF ( ( hBinRenConvModule->filterTapsLeftImag[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL ) + IF( ( hBinRenConvModule->filterTapsLeftImag[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } - IF ( ( hBinRenConvModule->filterTapsRightReal[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL ) + IF( ( hBinRenConvModule->filterTapsRightReal[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } - IF ( ( hBinRenConvModule->filterTapsRightImag[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL ) + IF( ( hBinRenConvModule->filterTapsRightImag[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } } - IF ( ( hBinRenConvModule->filterStatesLeftReal = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL ) + IF( ( hBinRenConvModule->filterStatesLeftReal = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } - IF ( ( hBinRenConvModule->filterStatesLeftImag = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL ) + IF( ( hBinRenConvModule->filterStatesLeftImag = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } - FOR ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) + FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) { - IF ( ( hBinRenConvModule->filterStatesLeftReal[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL ) + IF( ( hBinRenConvModule->filterStatesLeftReal[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } - IF ( ( hBinRenConvModule->filterStatesLeftImag[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL ) + IF( ( hBinRenConvModule->filterStatesLeftImag[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } - FOR ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) + FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) { - IF ( ( hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx] = (float *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( float ) ) ) == NULL ) + IF( ( hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx] = (float *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( float ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } - IF ( ( hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx] = (float *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( float ) ) ) == NULL ) + IF( ( hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx] = (float *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( float ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } } } +#else + IF( ( hBinRenConvModule->filterTapsLeftReal_fx = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + IF( ( hBinRenConvModule->filterTapsLeftImag_fx = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + IF( ( hBinRenConvModule->filterTapsRightReal_fx = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + IF( ( hBinRenConvModule->filterTapsRightImag_fx = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) + { + IF( ( hBinRenConvModule->filterTapsLeftReal_fx[bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + IF( ( hBinRenConvModule->filterTapsLeftImag_fx[bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + IF( ( hBinRenConvModule->filterTapsRightReal_fx[bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + IF( ( hBinRenConvModule->filterTapsRightImag_fx[bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) + { + IF( ( hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx] = (Word32 *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + IF( ( hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx] = (Word32 *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + IF( ( hBinRenConvModule->filterTapsRightReal_fx[bandIdx][chIdx] = (Word32 *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + IF( ( hBinRenConvModule->filterTapsRightImag_fx[bandIdx][chIdx] = (Word32 *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + } + } + + + IF( ( hBinRenConvModule->filterStatesLeftReal_fx = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + IF( ( hBinRenConvModule->filterStatesLeftImag_fx = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + IF( ( hBinRenConvModule->Q_filterStatesLeft = (Word16 ***) malloc( hBinRenderer->conv_band * sizeof( Word16 ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) + { + IF( ( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + IF( ( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + IF( ( hBinRenConvModule->Q_filterStatesLeft[bandIdx] = (Word16 **) malloc( hBinRenderer->nInChannels * sizeof( Word16 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) + { + IF( ( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx] = (Word32 *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + IF( ( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx] = (Word32 *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + IF( ( hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx] = (Word16 *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( Word16 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + } + } +#endif /* set memories */ - FOR ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) + FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) { - FOR ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) + FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) { Word16 tmp = 0; - IF ( isLoudspeaker ) + IF( isLoudspeaker ) { - IF ( input_config == IVAS_AUDIO_CONFIG_5_1 ) + IF( input_config == IVAS_AUDIO_CONFIG_5_1 ) { tmp = channelIndex_CICP6[chIdx]; } - ELSE IF ( input_config == IVAS_AUDIO_CONFIG_7_1 ) + ELSE IF( input_config == IVAS_AUDIO_CONFIG_7_1 ) { tmp = channelIndex_CICP12[chIdx]; } - ELSE IF ( input_config == IVAS_AUDIO_CONFIG_5_1_2 ) + ELSE IF( input_config == IVAS_AUDIO_CONFIG_5_1_2 ) { tmp = channelIndex_CICP14[chIdx]; } - ELSE IF ( input_config == IVAS_AUDIO_CONFIG_5_1_4 ) + ELSE IF( input_config == IVAS_AUDIO_CONFIG_5_1_4 ) { tmp = channelIndex_CICP16[chIdx]; } - ELSE IF ( input_config == IVAS_AUDIO_CONFIG_7_1_4 ) + ELSE IF( input_config == IVAS_AUDIO_CONFIG_7_1_4 ) { tmp = channelIndex_CICP19[chIdx]; } } - IF ( renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) +#ifndef IVAS_FLOAT_FIXED + IF( renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { /* set the memories to zero */ set_zero( hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx], hBinRenConvModule->numTapsArray[bandIdx] ); set_zero( hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx], hBinRenConvModule->numTapsArray[bandIdx] ); - IF ( isLoudspeaker ) + IF( isLoudspeaker ) { hBinRenConvModule->filterTapsLeftReal[bandIdx][chIdx] = hHrtf->leftBRIRReal[bandIdx][tmp]; hBinRenConvModule->filterTapsLeftImag[bandIdx][chIdx] = hHrtf->leftBRIRImag[bandIdx][tmp]; @@ -336,7 +571,7 @@ static ivas_error ivas_binRenderer_convModuleOpen( /* set the memories to zero */ set_zero( hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx], hBinRenConvModule->numTaps ); set_zero( hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx], hBinRenConvModule->numTaps ); - IF ( isLoudspeaker ) + IF( isLoudspeaker ) { hBinRenConvModule->filterTapsLeftReal[bandIdx][chIdx] = hHrtf->leftHRIRReal[bandIdx][tmp]; hBinRenConvModule->filterTapsLeftImag[bandIdx][chIdx] = hHrtf->leftHRIRImag[bandIdx][tmp]; @@ -345,7 +580,7 @@ static ivas_error ivas_binRenderer_convModuleOpen( } ELSE { - IF ( input_config == IVAS_AUDIO_CONFIG_HOA3 ) + IF( input_config == IVAS_AUDIO_CONFIG_HOA3 ) { /* HOA3 filter coefficients */ hBinRenConvModule->filterTapsLeftReal[bandIdx][chIdx] = hHrtf->leftHRIRReal_HOA3[bandIdx][chIdx]; @@ -353,7 +588,7 @@ static ivas_error ivas_binRenderer_convModuleOpen( hBinRenConvModule->filterTapsRightReal[bandIdx][chIdx] = hHrtf->rightHRIRReal_HOA3[bandIdx][chIdx]; hBinRenConvModule->filterTapsRightImag[bandIdx][chIdx] = hHrtf->rightHRIRImag_HOA3[bandIdx][chIdx]; } - ELSE IF ( input_config == IVAS_AUDIO_CONFIG_HOA2 ) + ELSE IF( input_config == IVAS_AUDIO_CONFIG_HOA2 ) { /* HOA2 filter coefficients */ hBinRenConvModule->filterTapsLeftReal[bandIdx][chIdx] = hHrtf->leftHRIRReal_HOA2[bandIdx][chIdx]; @@ -361,7 +596,7 @@ static ivas_error ivas_binRenderer_convModuleOpen( hBinRenConvModule->filterTapsRightReal[bandIdx][chIdx] = hHrtf->rightHRIRReal_HOA2[bandIdx][chIdx]; hBinRenConvModule->filterTapsRightImag[bandIdx][chIdx] = hHrtf->rightHRIRImag_HOA2[bandIdx][chIdx]; } - ELSE IF ( input_config == IVAS_AUDIO_CONFIG_FOA ) + ELSE IF( input_config == IVAS_AUDIO_CONFIG_FOA ) { /* FOA filter coefficients */ hBinRenConvModule->filterTapsLeftReal[bandIdx][chIdx] = hHrtf->leftHRIRReal_FOA[bandIdx][chIdx]; @@ -375,6 +610,83 @@ static ivas_error ivas_binRenderer_convModuleOpen( } } } +#else + Word32 idx; + IF( renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + { + /* set the memories to zero */ + set_l( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTapsArray[bandIdx] ); + set_l( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTapsArray[bandIdx] ); + set_s( hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx], 31, hBinRenConvModule->numTapsArray[bandIdx] ); + IF( isLoudspeaker ) + { + FOR( idx = 0; idx < hBinRenConvModule->numTapsArray[bandIdx]; idx++ ) + { + hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx][idx] = (Word32) float_to_fixQ29( hHrtf->leftBRIRReal[bandIdx][tmp][idx] ); + hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx][idx] = (Word32) float_to_fixQ29( hHrtf->leftBRIRImag[bandIdx][tmp][idx] ); + hBinRenConvModule->filterTapsRightReal_fx[bandIdx][chIdx][idx] = (Word32) float_to_fixQ29( hHrtf->rightBRIRReal[bandIdx][tmp][idx] ); + hBinRenConvModule->filterTapsRightImag_fx[bandIdx][chIdx][idx] = (Word32) float_to_fixQ29( hHrtf->rightBRIRImag[bandIdx][tmp][idx] ); + } + } + } + ELSE + { + /* set the memories to zero */ + set_l( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTaps ); + set_l( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTaps ); + set_s( hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx], 31, hBinRenConvModule->numTaps ); + IF( isLoudspeaker ) + { + FOR( idx = 0; idx < hBinRenConvModule->numTapsArray[bandIdx]; idx++ ) + { + hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx][idx] = (Word32) float_to_fixQ29( hHrtf->leftHRIRReal[bandIdx][tmp][idx] ); + hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx][idx] = (Word32) float_to_fixQ29( hHrtf->leftHRIRImag[bandIdx][tmp][idx] ); + hBinRenConvModule->filterTapsRightReal_fx[bandIdx][chIdx][idx] = (Word32) float_to_fixQ29( hHrtf->rightHRIRReal[bandIdx][tmp][idx] ); + hBinRenConvModule->filterTapsRightImag_fx[bandIdx][chIdx][idx] = (Word32) float_to_fixQ29( hHrtf->rightHRIRImag[bandIdx][tmp][idx] ); + } + } + ELSE + { + IF( input_config == IVAS_AUDIO_CONFIG_HOA3 ) + { + /* HOA3 filter coefficients */ + FOR( idx = 0; idx < hBinRenConvModule->numTapsArray[bandIdx]; idx++ ) + { + hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx][idx] = (Word32) float_to_fixQ29( hHrtf->leftHRIRReal_HOA3[bandIdx][chIdx][idx] ); + hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx][idx] = (Word32) float_to_fixQ29( hHrtf->leftHRIRImag_HOA3[bandIdx][chIdx][idx] ); + hBinRenConvModule->filterTapsRightReal_fx[bandIdx][chIdx][idx] = (Word32) float_to_fixQ29( hHrtf->rightHRIRReal_HOA3[bandIdx][chIdx][idx] ); + hBinRenConvModule->filterTapsRightImag_fx[bandIdx][chIdx][idx] = (Word32) float_to_fixQ29( hHrtf->rightHRIRImag_HOA3[bandIdx][chIdx][idx] ); + } + } + ELSE IF( input_config == IVAS_AUDIO_CONFIG_HOA2 ) + { + /* HOA2 filter coefficients */ + FOR( idx = 0; idx < hBinRenConvModule->numTapsArray[bandIdx]; idx++ ) + { + hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx][idx] = (Word32) float_to_fixQ29( hHrtf->leftHRIRReal_HOA2[bandIdx][chIdx][idx] ); + hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx][idx] = (Word32) float_to_fixQ29( hHrtf->leftHRIRImag_HOA2[bandIdx][chIdx][idx] ); + hBinRenConvModule->filterTapsRightReal_fx[bandIdx][chIdx][idx] = (Word32) float_to_fixQ29( hHrtf->rightHRIRReal_HOA2[bandIdx][chIdx][idx] ); + hBinRenConvModule->filterTapsRightImag_fx[bandIdx][chIdx][idx] = (Word32) float_to_fixQ29( hHrtf->rightHRIRImag_HOA2[bandIdx][chIdx][idx] ); + } + } + ELSE IF( input_config == IVAS_AUDIO_CONFIG_FOA ) + { + /* FOA filter coefficients */ + FOR( idx = 0; idx < hBinRenConvModule->numTapsArray[bandIdx]; idx++ ) + { + hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx][idx] = (Word32) float_to_fixQ29( hHrtf->leftHRIRReal_FOA[bandIdx][chIdx][idx] ); + hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx][idx] = (Word32) float_to_fixQ29( hHrtf->leftHRIRImag_FOA[bandIdx][chIdx][idx] ); + hBinRenConvModule->filterTapsRightReal_fx[bandIdx][chIdx][idx] = (Word32) float_to_fixQ29( hHrtf->rightHRIRReal_FOA[bandIdx][chIdx][idx] ); + hBinRenConvModule->filterTapsRightImag_fx[bandIdx][chIdx][idx] = (Word32) float_to_fixQ29( hHrtf->rightHRIRImag_FOA[bandIdx][chIdx][idx] ); + } + } + ELSE + { + return IVAS_ERR_INVALID_INPUT_FORMAT; + } + } + } +#endif } } @@ -429,7 +741,7 @@ void ivas_init_binaural_hrtf( HrtfFastConv->allocate_init_flag = 0x00; - FOR ( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) + FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) { HrtfFastConv->fastconvReverberationEneCorrections[i] = 0x00; HrtfFastConv->fastconvReverberationEneCorrections[i] = 0x00; @@ -455,22 +767,22 @@ static ivas_error ivas_alloc_pppMem( Word16 i, j; float ***localMem = NULL; - IF ( ( localMem = (float ***) malloc( dim1 * sizeof( float ** ) ) ) == NULL ) + IF( ( localMem = (float ***) malloc( dim1 * sizeof( float ** ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HRTF memory" ); } - FOR ( i = 0; i < dim1; i++ ) + FOR( i = 0; i < dim1; i++ ) { - IF ( ( localMem[i] = (float **) malloc( dim2 * sizeof( float * ) ) ) == NULL ) + IF( ( localMem[i] = (float **) malloc( dim2 * sizeof( float * ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HRTF memory" ); } - IF ( allocate_init_flag == 0 ) + IF( allocate_init_flag == 0 ) { - FOR ( j = 0; j < dim2; j++ ) + FOR( j = 0; j < dim2; j++ ) { - IF ( ( localMem[i][j] = (float *) malloc( dim3 * sizeof( float ) ) ) == NULL ) + IF( ( localMem[i][j] = (float *) malloc( dim3 * sizeof( float ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HRTF memory" ); } @@ -495,139 +807,139 @@ ivas_error ivas_allocate_binaural_hrtf( const AUDIO_CONFIG input_config, /* i : input audio configuration */ const BINAURAL_INPUT_AUDIO_CONFIG bin_input_config, /* i : binaural input audio config */ const RENDERER_TYPE renderer_type, /* i : renderer type */ - const Word16 allocate_init_flag /* i : Memory allocation flag */ + const Word16 allocate_init_flag /* i : Memory allocation flag */ ) { - IF ( input_config == IVAS_AUDIO_CONFIG_HOA3 || bin_input_config == BINAURAL_INPUT_AUDIO_CONFIG_HOA3 ) + IF( input_config == IVAS_AUDIO_CONFIG_HOA3 || bin_input_config == BINAURAL_INPUT_AUDIO_CONFIG_HOA3 ) { - IF ( ( HrtfFastConv->leftHRIRReal_HOA3 != NULL ) && ( HrtfFastConv->leftHRIRImag_HOA3 != NULL ) && ( HrtfFastConv->rightHRIRReal_HOA3 != NULL ) && ( HrtfFastConv->rightHRIRImag_HOA3 != NULL ) ) + IF( ( HrtfFastConv->leftHRIRReal_HOA3 != NULL ) && ( HrtfFastConv->leftHRIRImag_HOA3 != NULL ) && ( HrtfFastConv->rightHRIRReal_HOA3 != NULL ) && ( HrtfFastConv->rightHRIRImag_HOA3 != NULL ) ) { return IVAS_ERR_OK; } ELSE { - IF ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftHRIRReal_HOA3, BINAURAL_CONVBANDS, HOA3_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) + IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftHRIRReal_HOA3, BINAURAL_CONVBANDS, HOA3_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRReal_HOA3" ); } - IF ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftHRIRImag_HOA3, BINAURAL_CONVBANDS, HOA3_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) + IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftHRIRImag_HOA3, BINAURAL_CONVBANDS, HOA3_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRImag_HOA3" ); } - IF ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightHRIRReal_HOA3, BINAURAL_CONVBANDS, HOA3_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) + IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightHRIRReal_HOA3, BINAURAL_CONVBANDS, HOA3_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRReal_HOA3" ); } - IF ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightHRIRImag_HOA3, BINAURAL_CONVBANDS, HOA3_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) + IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightHRIRImag_HOA3, BINAURAL_CONVBANDS, HOA3_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRImag_HOA3" ); } } } - IF ( input_config == IVAS_AUDIO_CONFIG_HOA2 || bin_input_config == BINAURAL_INPUT_AUDIO_CONFIG_HOA2 ) + IF( input_config == IVAS_AUDIO_CONFIG_HOA2 || bin_input_config == BINAURAL_INPUT_AUDIO_CONFIG_HOA2 ) { - IF ( ( HrtfFastConv->leftHRIRReal_HOA2 != NULL ) && ( HrtfFastConv->leftHRIRImag_HOA2 != NULL ) && ( HrtfFastConv->rightHRIRReal_HOA2 != NULL ) && ( HrtfFastConv->rightHRIRImag_HOA2 != NULL ) ) + IF( ( HrtfFastConv->leftHRIRReal_HOA2 != NULL ) && ( HrtfFastConv->leftHRIRImag_HOA2 != NULL ) && ( HrtfFastConv->rightHRIRReal_HOA2 != NULL ) && ( HrtfFastConv->rightHRIRImag_HOA2 != NULL ) ) { return IVAS_ERR_OK; } ELSE { - IF ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftHRIRReal_HOA2, BINAURAL_CONVBANDS, HOA2_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) + IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftHRIRReal_HOA2, BINAURAL_CONVBANDS, HOA2_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRReal_HOA2" ); } - IF ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftHRIRImag_HOA2, BINAURAL_CONVBANDS, HOA2_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) + IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftHRIRImag_HOA2, BINAURAL_CONVBANDS, HOA2_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRImag_HOA2" ); } - IF ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightHRIRReal_HOA2, BINAURAL_CONVBANDS, HOA2_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) + IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightHRIRReal_HOA2, BINAURAL_CONVBANDS, HOA2_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRReal_HOA2" ); } - IF ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightHRIRImag_HOA2, BINAURAL_CONVBANDS, HOA2_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) + IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightHRIRImag_HOA2, BINAURAL_CONVBANDS, HOA2_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRImag_HOA2" ); } } } - IF ( input_config == IVAS_AUDIO_CONFIG_FOA || bin_input_config == BINAURAL_INPUT_AUDIO_CONFIG_FOA ) + IF( input_config == IVAS_AUDIO_CONFIG_FOA || bin_input_config == BINAURAL_INPUT_AUDIO_CONFIG_FOA ) { - IF ( ( HrtfFastConv->leftHRIRReal_FOA != NULL ) && ( HrtfFastConv->leftHRIRImag_FOA != NULL ) && ( HrtfFastConv->rightHRIRReal_FOA != NULL ) && ( HrtfFastConv->rightHRIRImag_FOA != NULL ) ) + IF( ( HrtfFastConv->leftHRIRReal_FOA != NULL ) && ( HrtfFastConv->leftHRIRImag_FOA != NULL ) && ( HrtfFastConv->rightHRIRReal_FOA != NULL ) && ( HrtfFastConv->rightHRIRImag_FOA != NULL ) ) { return IVAS_ERR_OK; } ELSE { - IF ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftHRIRReal_FOA, BINAURAL_CONVBANDS, FOA_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) + IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftHRIRReal_FOA, BINAURAL_CONVBANDS, FOA_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRReal_FOA" ); } - IF ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftHRIRImag_FOA, BINAURAL_CONVBANDS, FOA_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) + IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftHRIRImag_FOA, BINAURAL_CONVBANDS, FOA_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRImag_FOA" ); } - IF ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightHRIRReal_FOA, BINAURAL_CONVBANDS, FOA_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) + IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightHRIRReal_FOA, BINAURAL_CONVBANDS, FOA_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRReal_FOA" ); } - IF ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightHRIRImag_FOA, BINAURAL_CONVBANDS, FOA_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) + IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightHRIRImag_FOA, BINAURAL_CONVBANDS, FOA_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRImag_FOA" ); } } } - IF ( renderer_type == RENDERER_BINAURAL_FASTCONV || bin_input_config == BINAURAL_INPUT_AUDIO_CONFIG_COMBINED ) + IF( renderer_type == RENDERER_BINAURAL_FASTCONV || bin_input_config == BINAURAL_INPUT_AUDIO_CONFIG_COMBINED ) { - IF ( ( HrtfFastConv->leftHRIRReal != NULL ) && ( HrtfFastConv->leftHRIRImag != NULL ) && ( HrtfFastConv->rightHRIRReal != NULL ) && ( HrtfFastConv->rightHRIRImag != NULL ) ) + IF( ( HrtfFastConv->leftHRIRReal != NULL ) && ( HrtfFastConv->leftHRIRImag != NULL ) && ( HrtfFastConv->rightHRIRReal != NULL ) && ( HrtfFastConv->rightHRIRImag != NULL ) ) { return IVAS_ERR_OK; } ELSE { - IF ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftHRIRReal, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS, allocate_init_flag ) ) + IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftHRIRReal, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS, allocate_init_flag ) ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRReal" ); } - IF ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftHRIRImag, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS, allocate_init_flag ) ) + IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftHRIRImag, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS, allocate_init_flag ) ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRImag" ); } - IF ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightHRIRReal, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS, allocate_init_flag ) ) + IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightHRIRReal, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS, allocate_init_flag ) ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRReal" ); } - IF ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightHRIRImag, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS, allocate_init_flag ) ) + IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightHRIRImag, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS, allocate_init_flag ) ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRImag" ); } } } - IF ( renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || bin_input_config == BINAURAL_INPUT_AUDIO_CONFIG_COMBINED ) + IF( renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || bin_input_config == BINAURAL_INPUT_AUDIO_CONFIG_COMBINED ) { - IF ( ( HrtfFastConv->leftBRIRReal != NULL ) && ( HrtfFastConv->leftBRIRImag != NULL ) && ( HrtfFastConv->rightBRIRReal != NULL ) && ( HrtfFastConv->rightBRIRImag != NULL ) ) + IF( ( HrtfFastConv->leftBRIRReal != NULL ) && ( HrtfFastConv->leftBRIRImag != NULL ) && ( HrtfFastConv->rightBRIRReal != NULL ) && ( HrtfFastConv->rightBRIRImag != NULL ) ) { return IVAS_ERR_OK; } ELSE { - IF ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftBRIRReal, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS_MAX, allocate_init_flag ) ) + IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftBRIRReal, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS_MAX, allocate_init_flag ) ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftBRIRReal" ); } - IF ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftBRIRImag, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS_MAX, allocate_init_flag ) ) + IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftBRIRImag, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS_MAX, allocate_init_flag ) ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftBRIRImag" ); } - IF ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightBRIRReal, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS_MAX, allocate_init_flag ) ) + IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightBRIRReal, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS_MAX, allocate_init_flag ) ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightBRIRReal" ); } - IF ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightBRIRImag, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS_MAX, allocate_init_flag ) ) + IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightBRIRImag, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS_MAX, allocate_init_flag ) ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightBRIRImag" ); } @@ -653,7 +965,7 @@ static ivas_error ivas_binaural_hrtf_open( Word16 i, j; ivas_error error; - IF ( hHrtfFastConv != NULL && *hHrtfFastConv != NULL ) + IF( hHrtfFastConv != NULL && *hHrtfFastConv != NULL ) { /* Tables already loaded from file */ return IVAS_ERR_OK; @@ -663,45 +975,45 @@ static ivas_error ivas_binaural_hrtf_open( /* Initialise tables from ROM */ HRTFS_FASTCONV *HrtfFastConv; - IF ( ( HrtfFastConv = (HRTFS_FASTCONV *) malloc( sizeof( HRTFS_FASTCONV ) ) ) == NULL ) + IF( ( HrtfFastConv = (HRTFS_FASTCONV *) malloc( sizeof( HRTFS_FASTCONV ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate memory for FastConv HRTF tables" ); } ivas_init_binaural_hrtf( HrtfFastConv ); - IF ( input_config == IVAS_AUDIO_CONFIG_BINAURAL || renderer_type == RENDERER_BINAURAL_FASTCONV ) + IF( input_config == IVAS_AUDIO_CONFIG_BINAURAL || renderer_type == RENDERER_BINAURAL_FASTCONV ) { HrtfFastConv->FASTCONV_HRIR_latency_s = FASTCONV_HRIR_latency_s; } - IF ( input_config == IVAS_AUDIO_CONFIG_HOA2 ) + IF( input_config == IVAS_AUDIO_CONFIG_HOA2 ) { HrtfFastConv->FASTCONV_HOA2_latency_s = FASTCONV_HOA2_latency_s; } - IF ( input_config == IVAS_AUDIO_CONFIG_HOA3 ) + IF( input_config == IVAS_AUDIO_CONFIG_HOA3 ) { HrtfFastConv->FASTCONV_HOA3_latency_s = FASTCONV_HOA3_latency_s; } - IF ( input_config == IVAS_AUDIO_CONFIG_FOA ) + IF( input_config == IVAS_AUDIO_CONFIG_FOA ) { HrtfFastConv->FASTCONV_FOA_latency_s = FASTCONV_FOA_latency_s; } - IF ( input_config == IVAS_AUDIO_CONFIG_BINAURAL || renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + IF( input_config == IVAS_AUDIO_CONFIG_BINAURAL || renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { HrtfFastConv->FASTCONV_BRIR_latency_s = FASTCONV_BRIR_latency_s; } HrtfFastConv->allocate_init_flag = 1; - IF ( ( error = ivas_allocate_binaural_hrtf( HrtfFastConv, input_config, BINAURAL_INPUT_AUDIO_CONFIG_INVALID, renderer_type, HrtfFastConv->allocate_init_flag ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_allocate_binaural_hrtf( HrtfFastConv, input_config, BINAURAL_INPUT_AUDIO_CONFIG_INVALID, renderer_type, HrtfFastConv->allocate_init_flag ) ) != IVAS_ERR_OK ) { return error; } - FOR ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + FOR( i = 0; i < BINAURAL_CONVBANDS; i++ ) { - IF ( renderer_type == RENDERER_BINAURAL_FASTCONV ) + IF( renderer_type == RENDERER_BINAURAL_FASTCONV ) { - FOR ( j = 0; j < HRTF_LS_CHANNELS; j++ ) + FOR( j = 0; j < HRTF_LS_CHANNELS; j++ ) { HrtfFastConv->leftHRIRReal[i][j] = leftHRIRReal[i][j]; HrtfFastConv->leftHRIRImag[i][j] = leftHRIRImag[i][j]; @@ -709,9 +1021,9 @@ static ivas_error ivas_binaural_hrtf_open( HrtfFastConv->rightHRIRImag[i][j] = rightHRIRImag[i][j]; } } - ELSE IF ( renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + ELSE IF( renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { - FOR ( j = 0; j < HRTF_LS_CHANNELS; j++ ) + FOR( j = 0; j < HRTF_LS_CHANNELS; j++ ) { HrtfFastConv->leftBRIRReal[i][j] = leftBRIRReal[i][j]; HrtfFastConv->leftBRIRImag[i][j] = leftBRIRImag[i][j]; @@ -719,9 +1031,9 @@ static ivas_error ivas_binaural_hrtf_open( HrtfFastConv->rightBRIRImag[i][j] = rightBRIRImag[i][j]; } } - IF ( input_config == IVAS_AUDIO_CONFIG_HOA3 ) + IF( input_config == IVAS_AUDIO_CONFIG_HOA3 ) { - FOR ( j = 0; j < HOA3_CHANNELS; j++ ) + FOR( j = 0; j < HOA3_CHANNELS; j++ ) { HrtfFastConv->leftHRIRReal_HOA3[i][j] = leftHRIRReal_HOA3[i][j]; HrtfFastConv->leftHRIRImag_HOA3[i][j] = leftHRIRImag_HOA3[i][j]; @@ -729,9 +1041,9 @@ static ivas_error ivas_binaural_hrtf_open( HrtfFastConv->rightHRIRImag_HOA3[i][j] = rightHRIRImag_HOA3[i][j]; } } - IF ( input_config == IVAS_AUDIO_CONFIG_HOA2 ) + IF( input_config == IVAS_AUDIO_CONFIG_HOA2 ) { - FOR ( j = 0; j < HOA2_CHANNELS; j++ ) + FOR( j = 0; j < HOA2_CHANNELS; j++ ) { HrtfFastConv->leftHRIRReal_HOA2[i][j] = leftHRIRReal_HOA2[i][j]; HrtfFastConv->leftHRIRImag_HOA2[i][j] = leftHRIRImag_HOA2[i][j]; @@ -739,9 +1051,9 @@ static ivas_error ivas_binaural_hrtf_open( HrtfFastConv->rightHRIRImag_HOA2[i][j] = rightHRIRImag_HOA2[i][j]; } } - IF ( input_config == IVAS_AUDIO_CONFIG_FOA ) + IF( input_config == IVAS_AUDIO_CONFIG_FOA ) { - FOR ( j = 0; j < FOA_CHANNELS; j++ ) + FOR( j = 0; j < FOA_CHANNELS; j++ ) { HrtfFastConv->leftHRIRReal_FOA[i][j] = leftHRIRReal_FOA[i][j]; HrtfFastConv->leftHRIRImag_FOA[i][j] = leftHRIRImag_FOA[i][j]; @@ -759,7 +1071,7 @@ static ivas_error ivas_binaural_hrtf_open( return IVAS_ERR_OK; } - +#ifndef IVAS_FLOAT_FIXED /*-------------------------------------------------------------------------* * ivas_binaural_obtain_DMX() * @@ -877,9 +1189,157 @@ static void ivas_binaural_obtain_DMX( return; } +#else +/*-------------------------------------------------------------------------* + * ivas_binaural_obtain_DMX_fx() + * + * + *-------------------------------------------------------------------------*/ + +static void ivas_binaural_obtain_DMX_fx( + const int16_t numTimeSlots, + BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: fastconv binaural renderer handle */ + Word32 RealBuffer[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Contains the LS signals */ + Word32 ImagBuffer[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Contains the LS signals */ + Word32 realDMX[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + Word32 imagDMX[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] ) +{ + int16_t chIdx, bandIdx, k; + + IF( hBinRenderer->ivas_format == MC_FORMAT ) + { + /* Obtain the downmix */ + // float P_in[CLDFB_NO_CHANNELS_MAX]; + Word32 P_in_fx[CLDFB_NO_CHANNELS_MAX]; + // float P_out, factEQ; + Word32 P_out_fx, factEQ_fx; + int16_t chOutIdx; + // float temp1, temp2; + Word32 temp1_fx, temp2_fx; + + FOR( k = 0; k < numTimeSlots; k++ ) + { + FOR( chOutIdx = 0; chOutIdx < BINAURAL_CHANNELS; chOutIdx++ ) + { + set_l( realDMX[chOutIdx][k], 0, CLDFB_NO_CHANNELS_MAX ); + set_l( imagDMX[chOutIdx][k], 0, CLDFB_NO_CHANNELS_MAX ); + } + } + + FOR( chOutIdx = 0; chOutIdx < BINAURAL_CHANNELS; chOutIdx++ ) + { + set_l( P_in_fx, 0, hBinRenderer->conv_band ); + + FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) + { + Word32 dmxConst = hBinRenderer->hReverb->dmxmtx_fx[chOutIdx][chIdx]; + + FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) + { + FOR( k = 0; k < numTimeSlots; k++ ) + { + //temp1 = RealBuffer[chIdx][k][bandIdx] * dmxConst; + //temp2 = ImagBuffer[chIdx][k][bandIdx] * dmxConst; + //realDMX[chOutIdx][k][bandIdx] += temp1; + //imagDMX[chOutIdx][k][bandIdx] += temp2; + temp1_fx = Mpy_32_32(RealBuffer[chIdx][k][bandIdx], dmxConst); // Q_in + temp2_fx = Mpy_32_32( ImagBuffer[chIdx][k][bandIdx], dmxConst ); // Q_in + realDMX[chOutIdx][k][bandIdx] = L_add( realDMX[chOutIdx][k][bandIdx], temp1_fx ); // Q_in + imagDMX[chOutIdx][k][bandIdx] = L_add( imagDMX[chOutIdx][k][bandIdx], temp2_fx ); // Q_in + + //P_in[bandIdx] += temp1 * temp1 + temp2 * temp2; + P_in_fx[bandIdx] = L_add( P_in_fx[bandIdx], L_add( Mpy_32_32( temp1_fx, temp1_fx ), Mpy_32_32( temp2_fx, temp2_fx ) ) ); // Q31-2*Q_in + } + } + } + FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) + { + P_out_fx = 0; + FOR( k = 0; k < numTimeSlots; k++ ) + { + temp1_fx = realDMX[chOutIdx][k][bandIdx]; + temp2_fx = imagDMX[chOutIdx][k][bandIdx]; + //P_out += temp1 * temp1 + temp2 * temp2; + P_out_fx = L_add( P_out_fx, L_add( Mpy_32_32( temp1_fx, temp1_fx ), Mpy_32_32( temp2_fx, temp2_fx ) ) ); //Q31-2*Q_in + } + // if ( ( factEQ <= 1e-20f ) || ( P_in[bandIdx] <= 1e-20f ) || ( P_out <= 1e-20f ) ) + IF ( LE_32( P_in_fx[bandIdx], 0 ) || LE_32( P_out_fx, 0 ) ) + { + //factEQ = 1.0f; + factEQ_fx = 0x40000000; + } + ELSE + { + // factEQ = sqrtf( P_in[bandIdx] / ( P_out + 1e-20f ) ); + Word16 div = divide3232( P_in_fx[bandIdx], P_out_fx ); + Word16 exp = norm_l( div ); + factEQ_fx = Sqrt32( L_shl( div, Q16 ), &exp ); + factEQ_fx = L_shl( factEQ_fx, exp - 1 ); // Q30 + } + IF( LE_32( factEQ_fx, 0 ) ) + { + factEQ_fx = 0x40000000; + } + + //factEQ = max( min( factEQ, 2.0f ), 0.5f ); + factEQ_fx = max( min( factEQ_fx, 0x7fffffff ), 0x20000000 ); // Q30 + FOR( k = 0; k < numTimeSlots; k++ ) + { + //realDMX[chOutIdx][k][bandIdx] *= factEQ; + //imagDMX[chOutIdx][k][bandIdx] *= factEQ; + realDMX[chOutIdx][k][bandIdx] = Mpy_32_32( realDMX[chOutIdx][k][bandIdx], factEQ_fx ); //Q_in - 1 + imagDMX[chOutIdx][k][bandIdx] = Mpy_32_32( imagDMX[chOutIdx][k][bandIdx], factEQ_fx ); //Q_in - 1 + } + } + } + } + ELSE IF( hBinRenderer->ivas_format == SBA_FORMAT || hBinRenderer->ivas_format == MASA_FORMAT ) + { + //float *outRealLeftPtr, *outImagLeftPtr, *outRealRightPtr, *outImagRightPtr; + //float *inRealPtr, *inImagPtr; + Word32 *outRealLeftPtr_fx, *outImagLeftPtr_fx, *outRealRightPtr_fx, *outImagRightPtr_fx; + Word32 *inRealPtr_fx, *inImagPtr_fx; + /*compute DMX */ + FOR( k = 0; k < numTimeSlots; k++ ) + { + outRealLeftPtr_fx = realDMX[0][k]; + outImagLeftPtr_fx = imagDMX[0][k]; + outRealRightPtr_fx = realDMX[1][k]; + outImagRightPtr_fx = imagDMX[1][k]; + set_l( outRealLeftPtr_fx, 0, CLDFB_NO_CHANNELS_MAX ); + set_l( outImagLeftPtr_fx, 0, CLDFB_NO_CHANNELS_MAX ); + set_l( outRealRightPtr_fx, 0, CLDFB_NO_CHANNELS_MAX ); + set_l( outImagRightPtr_fx, 0, CLDFB_NO_CHANNELS_MAX ); + + FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) + { + //float foa_const = hBinRenderer->hReverb->foa_enc[chIdx][1]; + Word32 foa_const_fx = L_shl(hBinRenderer->hReverb->foa_enc_fx[chIdx][1], 1); // Q30 + inRealPtr_fx = (Word32 *) &( RealBuffer[chIdx][k][0] ); + inImagPtr_fx = (Word32 *) &( ImagBuffer[chIdx][k][0] ); + + FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) + { + //outRealLeftPtr[bandIdx] += inRealPtr[bandIdx] * ( 1.f + foa_const ); + //outImagLeftPtr[bandIdx] += inImagPtr[bandIdx] * ( 1.f + foa_const ); + outRealLeftPtr_fx[bandIdx] = L_add( outRealLeftPtr_fx[bandIdx], Mpy_32_32( inRealPtr_fx[bandIdx], L_add( ONE_IN_Q30, foa_const_fx ) ) ); //Q_in - 1 + outImagLeftPtr_fx[bandIdx] = L_add( outImagLeftPtr_fx[bandIdx], Mpy_32_32( inImagPtr_fx[bandIdx], L_add( ONE_IN_Q30, foa_const_fx ) ) ); //Q_in - 1 + + //outRealRightPtr[bandIdx] += inRealPtr[bandIdx] * ( 1.f - foa_const ); + //outImagRightPtr[bandIdx] += inImagPtr[bandIdx] * ( 1.f - foa_const ); + outRealRightPtr_fx[bandIdx] += L_add( outRealRightPtr_fx[bandIdx], Mpy_32_32( inRealPtr_fx[bandIdx], L_sub( ONE_IN_Q30, foa_const_fx ) ) ); //Q_in - 1 + outImagRightPtr_fx[bandIdx] += L_add( outImagRightPtr_fx[bandIdx], Mpy_32_32( inImagPtr_fx[bandIdx], L_sub( ONE_IN_Q30, foa_const_fx ) ) ); //Q_in - 1 + } + } + } + } + + return; +} +#endif /*------------------------------------------------------------------------- * ivas_binRenderer_open() @@ -901,7 +1361,7 @@ ivas_error ivas_binRenderer_open( * prepare library opening *-----------------------------------------------------------------*/ - IF ( ( hBinRenderer = (BINAURAL_RENDERER_HANDLE) malloc( sizeof( BINAURAL_RENDERER ) ) ) == NULL ) + IF( ( hBinRenderer = (BINAURAL_RENDERER_HANDLE) malloc( sizeof( BINAURAL_RENDERER ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Renderer\n" ) ); } @@ -910,7 +1370,7 @@ ivas_error ivas_binRenderer_open( /* Define of head rotation has to be done in binRendeder in CLDFB*/ hBinRenderer->rotInCldfb = 0; - IF ( st_ivas->ivas_format == MC_FORMAT || st_ivas->ivas_format == SBA_FORMAT ) + IF( st_ivas->ivas_format == MC_FORMAT || st_ivas->ivas_format == SBA_FORMAT ) { hBinRenderer->rotInCldfb = 1; } @@ -918,7 +1378,7 @@ ivas_error ivas_binRenderer_open( /* Declare some common variables needed for renderer */ /* Which format used for binaural rendering (needed for late reverb) ? MC or SBA */ - IF ( st_ivas->hIntSetup.is_loudspeaker_setup ) + IF( st_ivas->hIntSetup.is_loudspeaker_setup ) { hBinRenderer->ivas_format = MC_FORMAT; } @@ -931,7 +1391,7 @@ ivas_error ivas_binRenderer_open( hBinRenderer->timeSlots = MAX_PARAM_SPATIAL_SUBFRAMES; /* Corresponds to 5 msec sound to motion latency */ - IF ( convBand > BINAURAL_CONVBANDS ) + IF( convBand > BINAURAL_CONVBANDS ) { hBinRenderer->conv_band = BINAURAL_CONVBANDS; } @@ -943,32 +1403,32 @@ ivas_error ivas_binRenderer_open( /*LFE rendering switched off by default*/ hBinRenderer->render_lfe = 0; - IF ( st_ivas->ivas_format != ISM_FORMAT && st_ivas->hIntSetup.is_loudspeaker_setup ) + IF( st_ivas->ivas_format != ISM_FORMAT && st_ivas->hIntSetup.is_loudspeaker_setup ) { hBinRenderer->render_lfe = 1; } /* Load HRTF tables */ - IF ( ( error = ivas_binaural_hrtf_open( &st_ivas->hHrtfFastConv, st_ivas->hIntSetup.output_config, st_ivas->renderer_type ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_binaural_hrtf_open( &st_ivas->hHrtfFastConv, st_ivas->hIntSetup.output_config, st_ivas->renderer_type ) ) != IVAS_ERR_OK ) { return error; } - IF ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM && ( st_ivas->hIntSetup.is_loudspeaker_setup == 0 ) ) + IF( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM && ( st_ivas->hIntSetup.is_loudspeaker_setup == 0 ) ) { IVAS_OUTPUT_SETUP out_setup; /* Allocate memories and buffers needed for convolutional module in CICP19 */ - IF ( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, st_ivas->renderer_type, 1, IVAS_AUDIO_CONFIG_7_1_4, st_ivas->hHrtfFastConv ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, st_ivas->renderer_type, 1, IVAS_AUDIO_CONFIG_7_1_4, st_ivas->hHrtfFastConv ) ) != IVAS_ERR_OK ) { return error; } ivas_output_init( &out_setup, IVAS_AUDIO_CONFIG_7_1_4 ); - IF ( st_ivas->hoa_dec_mtx == NULL ) + IF( st_ivas->hoa_dec_mtx == NULL ) { - IF ( ( error = ivas_sba_get_hoa_dec_matrix( out_setup, &st_ivas->hoa_dec_mtx, st_ivas->hIntSetup.ambisonics_order ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_sba_get_hoa_dec_matrix( out_setup, &st_ivas->hoa_dec_mtx, st_ivas->hIntSetup.ambisonics_order ) ) != IVAS_ERR_OK ) { return error; } @@ -980,28 +1440,28 @@ ivas_error ivas_binRenderer_open( ELSE { /* Allocate memories and buffers needed for convolutional module */ - IF ( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, st_ivas->renderer_type, st_ivas->hIntSetup.is_loudspeaker_setup, st_ivas->hIntSetup.output_config, st_ivas->hHrtfFastConv ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, st_ivas->renderer_type, st_ivas->hIntSetup.is_loudspeaker_setup, st_ivas->hIntSetup.output_config, st_ivas->hHrtfFastConv ) ) != IVAS_ERR_OK ) { return error; } - IF ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) + IF( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) { - IF ( hBinRenderer->ivas_format == MC_FORMAT ) + IF( hBinRenderer->ivas_format == MC_FORMAT ) { st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_HRIR_latency_s * 1000000000.f ); } ELSE { - IF ( hBinRenderer->nInChannels == 16 ) + IF( hBinRenderer->nInChannels == 16 ) { st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_HOA3_latency_s * 1000000000.f ); } - ELSE IF ( hBinRenderer->nInChannels == 9 ) + ELSE IF( hBinRenderer->nInChannels == 9 ) { st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_HOA2_latency_s * 1000000000.f ); } - ELSE IF ( hBinRenderer->nInChannels == 4 ) + ELSE IF( hBinRenderer->nInChannels == 4 ) { st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_FOA_latency_s * 1000000000.f ); } @@ -1019,19 +1479,23 @@ ivas_error ivas_binRenderer_open( } /* Allocate memories needed for reverb module */ - IF ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->hIntSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) + IF( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->hIntSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { - IF ( ( error = ivas_binaural_reverb_open_fastconv( &( hBinRenderer->hReverb ), hBinRenderer->conv_band, hBinRenderer->timeSlots, &( st_ivas->hRenderConfig->roomAcoustics ), st_ivas->hIntSetup.output_config, st_ivas->hDecoderConfig->output_Fs, st_ivas->hHrtfFastConv ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_binaural_reverb_open_fastconv( &( hBinRenderer->hReverb ), hBinRenderer->conv_band, hBinRenderer->timeSlots, &( st_ivas->hRenderConfig->roomAcoustics ), st_ivas->hIntSetup.output_config, st_ivas->hDecoderConfig->output_Fs, st_ivas->hHrtfFastConv ) ) != IVAS_ERR_OK ) { return error; } /* initialize the dmx matrix */ - FOR ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) + FOR( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) { - FOR ( k = 0; k < hBinRenderer->nInChannels; k++ ) + FOR( k = 0; k < hBinRenderer->nInChannels; k++ ) { +#ifndef IVAS_FLOAT_FIXED hBinRenderer->hReverb->dmxmtx[chIdx][k] = dmxmtx_table[chIdx][k]; +#else + hBinRenderer->hReverb->dmxmtx_fx[chIdx][k] = dmxmtx_table_fx[chIdx][k]; +#endif } } } @@ -1042,29 +1506,23 @@ ivas_error ivas_binRenderer_open( hBinRenderer->hEFAPdata = NULL; - IF ( hBinRenderer->hReverb != NULL ) + IF( hBinRenderer->hReverb != NULL ) { - IF ( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 ) + IF( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 ) { -#ifdef IVAS_FLOAT_FIXED - Word32 foa_enc_int[FOA_CHANNELS]; -#endif - FOR ( k = 0; k < 11; k++ ) + FOR( k = 0; k < 11; k++ ) { #ifndef IVAS_FLOAT_FIXED ivas_dirac_dec_get_response( (int16_t) ls_azimuth_CICP19[k], (int16_t) ls_elevation_CICP19[k], hBinRenderer->hReverb->foa_enc[k], 1 ); #else - ivas_dirac_dec_get_response_fixed( (int16_t) ls_azimuth_CICP19[k], (int16_t) ls_elevation_CICP19[k], foa_enc_int, 1 ); - FOR( int foa_idx = 0; foa_idx < FOA_CHANNELS; foa_idx++ ) - { - hBinRenderer->hReverb->foa_enc[k][foa_idx] = ( (float) foa_enc_int[foa_idx] ) / ( 1 << Q29 ); - } + ivas_dirac_dec_get_response_fixed( (int16_t) ls_azimuth_CICP19[k], (int16_t) ls_elevation_CICP19[k], hBinRenderer->hReverb->foa_enc_fx[k], 1 ); + // Q29: hBinRenderer->hReverb->foa_enc_fx[k] #endif } } - ELSE IF ( st_ivas->ivas_format == MC_FORMAT && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) ) + ELSE IF( st_ivas->ivas_format == MC_FORMAT && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) ) { - IF ( ( error = efap_init_data( &( st_ivas->hEFAPdata ), st_ivas->hIntSetup.ls_azimuth, st_ivas->hIntSetup.ls_elevation, st_ivas->hIntSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) + IF( ( error = efap_init_data( &( st_ivas->hEFAPdata ), st_ivas->hIntSetup.ls_azimuth, st_ivas->hIntSetup.ls_elevation, st_ivas->hIntSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) { return error; } @@ -1092,16 +1550,17 @@ static void ivas_binRenderer_convModuleClose( ) { Word16 bandIdx, chIdx; +#ifndef IVAS_FLOAT_FIXED BINRENDERER_CONV_MODULE_HANDLE hBinRenConvModule; hBinRenConvModule = ( *hBinRenderer )->hBinRenConvModule; - IF ( hBinRenConvModule == NULL ) + IF( hBinRenConvModule == NULL ) { return; } - FOR ( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ ) + FOR( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ ) { free( hBinRenConvModule->filterTapsLeftReal[bandIdx] ); hBinRenConvModule->filterTapsLeftReal[bandIdx] = NULL; @@ -1128,9 +1587,9 @@ static void ivas_binRenderer_convModuleClose( free( hBinRenConvModule->filterTapsRightImag ); hBinRenConvModule->filterTapsRightImag = NULL; - FOR ( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ ) + FOR( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ ) { - FOR ( chIdx = 0; chIdx < ( *hBinRenderer )->nInChannels; chIdx++ ) + FOR( chIdx = 0; chIdx < ( *hBinRenderer )->nInChannels; chIdx++ ) { free( hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx] ); hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx] = NULL; @@ -1151,7 +1610,91 @@ static void ivas_binRenderer_convModuleClose( free( hBinRenConvModule->filterStatesLeftImag ); hBinRenConvModule->filterStatesLeftImag = NULL; +#else + BINRENDERER_CONV_MODULE_HANDLE_FX hBinRenConvModule; + + hBinRenConvModule = ( *hBinRenderer )->hBinRenConvModule; + + IF( hBinRenConvModule == NULL ) + { + return; + } + + FOR( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ ) + { + FOR( chIdx = 0; chIdx < ( *hBinRenderer )->nInChannels; chIdx++ ) + { + free( hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx] ); + hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx] = NULL; + + free( hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx] ); + hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx] = NULL; + + free( hBinRenConvModule->filterTapsRightReal_fx[bandIdx][chIdx] ); + hBinRenConvModule->filterTapsRightReal_fx[bandIdx][chIdx] = NULL; + + free( hBinRenConvModule->filterTapsRightImag_fx[bandIdx][chIdx] ); + hBinRenConvModule->filterTapsRightImag_fx[bandIdx][chIdx] = NULL; + } + + free( hBinRenConvModule->filterTapsLeftReal_fx[bandIdx] ); + hBinRenConvModule->filterTapsLeftReal_fx[bandIdx] = NULL; + + free( hBinRenConvModule->filterTapsLeftImag_fx[bandIdx] ); + hBinRenConvModule->filterTapsLeftImag_fx[bandIdx] = NULL; + + free( hBinRenConvModule->filterTapsRightReal_fx[bandIdx] ); + hBinRenConvModule->filterTapsRightReal_fx[bandIdx] = NULL; + + free( hBinRenConvModule->filterTapsRightImag_fx[bandIdx] ); + hBinRenConvModule->filterTapsRightImag_fx[bandIdx] = NULL; + } + + free( hBinRenConvModule->filterTapsLeftReal_fx ); + hBinRenConvModule->filterTapsLeftReal_fx = NULL; + + free( hBinRenConvModule->filterTapsLeftImag_fx ); + hBinRenConvModule->filterTapsLeftImag_fx = NULL; + + free( hBinRenConvModule->filterTapsRightReal_fx ); + hBinRenConvModule->filterTapsRightReal_fx = NULL; + + free( hBinRenConvModule->filterTapsRightImag_fx ); + hBinRenConvModule->filterTapsRightImag_fx = NULL; + + FOR( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ ) + { + FOR( chIdx = 0; chIdx < ( *hBinRenderer )->nInChannels; chIdx++ ) + { + free( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx] ); + hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx] = NULL; + + free( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx] ); + hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx] = NULL; + + free( hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx] ); + hBinRenConvModule->Q_filterStatesLeft[bandIdx][chIdx] = NULL; + } + + free( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx] ); + hBinRenConvModule->filterStatesLeftReal_fx[bandIdx] = NULL; + + free( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx] ); + hBinRenConvModule->filterStatesLeftImag_fx[bandIdx] = NULL; + + free( hBinRenConvModule->Q_filterStatesLeft[bandIdx] ); + hBinRenConvModule->Q_filterStatesLeft[bandIdx] = NULL; + } + free( hBinRenConvModule->filterStatesLeftReal_fx ); + hBinRenConvModule->filterStatesLeftReal_fx = NULL; + + free( hBinRenConvModule->filterStatesLeftImag_fx ); + hBinRenConvModule->filterStatesLeftImag_fx = NULL; + + free( hBinRenConvModule->Q_filterStatesLeft ); + hBinRenConvModule->Q_filterStatesLeft = NULL; +#endif free( ( *hBinRenderer )->hBinRenConvModule ); ( *hBinRenderer )->hBinRenConvModule = NULL; @@ -1169,17 +1712,17 @@ void ivas_binRenderer_close( BINAURAL_RENDERER_HANDLE *hBinRenderer /* i/o: fastconv binaural renderer handle */ ) { - IF ( hBinRenderer == NULL || *hBinRenderer == NULL ) + IF( hBinRenderer == NULL || *hBinRenderer == NULL ) { return; } - IF ( ( *hBinRenderer )->hBinRenConvModule != NULL ) + IF( ( *hBinRenderer )->hBinRenConvModule != NULL ) { ivas_binRenderer_convModuleClose( hBinRenderer ); } - IF ( ( *hBinRenderer )->hReverb != NULL ) + IF( ( *hBinRenderer )->hReverb != NULL ) { ivas_binaural_reverb_close( &( ( *hBinRenderer )->hReverb ) ); } @@ -1204,9 +1747,9 @@ static void ivas_free_pppHrtfMem( { Word16 i, j; - IF ( *ppppHRIR != NULL ) + IF( *ppppHRIR != NULL ) { - FOR ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + FOR( i = 0; i < BINAURAL_CONVBANDS; i++ ) { IF( alloc_init == 0 ) { @@ -1239,7 +1782,7 @@ void ivas_binaural_hrtf_close( { Word16 allocate_init_flag; - IF ( hHrtfFastConv == NULL || *hHrtfFastConv == NULL ) + IF( hHrtfFastConv == NULL || *hHrtfFastConv == NULL ) { return; } @@ -1324,8 +1867,6 @@ void ivas_binaural_add_LFE( } - - /*------------------------------------------------------------------------- * ivas_binRenderer() * @@ -1333,13 +1874,13 @@ void ivas_binaural_add_LFE( *-------------------------------------------------------------------------*/ void ivas_binRenderer( - BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle*/ - const int16_t numTimeSlots, /* i : number of time slots to render */ + BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle*/ + const int16_t numTimeSlots, /* i : number of time slots to render */ float Cldfb_RealBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ float Cldfb_ImagBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ - float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */ - float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] /* i : LS signals */ + float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */ + float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] /* i : LS signals */ ) { int16_t chIdx, k; @@ -1357,16 +1898,48 @@ void ivas_binRenderer( } } + +#ifdef IVAS_FLOAT_FIXED + Word16 exp_real_final = 0, exp_im_final = 0; + Word32 RealBuffer_fx[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + Word32 ImagBuffer_fx[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + Word16 i, j; + Word32 max32_real = 1, max32_im = 1; + + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + for ( k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ ) + { + max32_real = (Word32) L_max( max32_real, L_abs( (Word32) RealBuffer[i][j][k] ) ); + max32_im = (Word32) L_max( max32_im, L_abs( (Word32) ImagBuffer[i][j][k] ) ); + } + } + } + Word16 exp_real = norm_l( max32_real ); + Word16 exp_im = norm_l( max32_im ); + exp_real = exp_im = min( exp_real, exp_im ); + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + for ( k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ ) + { + RealBuffer_fx[i][j][k] = (Word32) float_to_fix( RealBuffer[i][j][k], exp_real ); + exp_real_final = exp_real; + ImagBuffer_fx[i][j][k] = (Word32) float_to_fix( ImagBuffer[i][j][k], exp_im ); + exp_im_final = exp_im; + } + } + } +#endif /* Head rotation in HOA3 or CICPx */ if ( hCombinedOrientationData != NULL && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] && hBinRenderer->rotInCldfb ) { if ( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 ) { #ifdef IVAS_FLOAT_FIXED - Word16 i, j; - Word32 max32_real = 1, max32_im = 1; - Word32 RealBuffer_fx[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - Word32 ImagBuffer_fx[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; for ( i = 0; i < 3; i++ ) { for ( j = 0; j < 3; j++ ) @@ -1374,63 +1947,21 @@ void ivas_binRenderer( hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx][i][j] = (Word32) float_to_fix( hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx][i][j], 30 ); } } - for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) - { - for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) - { - for ( k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ ) - { - max32_real = (Word32) L_max( max32_real, L_abs( (Word32) RealBuffer[i][j][k] ) ); - max32_im = (Word32) L_max( max32_im, L_abs( (Word32) ImagBuffer[i][j][k] ) ); - } - } - } - Word16 exp_real = norm_l( max32_real ); - Word16 exp_im = norm_l( max32_im ); - for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) - { - for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) - { - for ( k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ ) - { - RealBuffer_fx[i][j][k] = (Word32) float_to_fix( RealBuffer[i][j][k], exp_real ); - ImagBuffer_fx[i][j][k] = (Word32) float_to_fix( ImagBuffer[i][j][k], exp_im ); - } - } - } /* Rotation in SHD (HOA3) */ if ( hCombinedOrientationData->shd_rot_max_order == -1 ) { rotateFrame_shd_cldfb( RealBuffer_fx, ImagBuffer_fx, hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, 3 ); - for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) - { - for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) - { - for ( k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ ) - { - RealBuffer[i][j][k] = fix_to_float( RealBuffer_fx[i][j][k], ( exp_real + 14 - 15 ) ); - ImagBuffer[i][j][k] = fix_to_float( ImagBuffer_fx[i][j][k], ( exp_im + 14 - 15 ) ); - } - } - } + exp_real_final--; //( exp_real + 14 - 15 ) + exp_im_final--; //( exp_im + 14 - 15 ) } else if ( hCombinedOrientationData->shd_rot_max_order > 0 ) { rotateFrame_shd_cldfb( RealBuffer_fx, ImagBuffer_fx, hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, hCombinedOrientationData->shd_rot_max_order ); - for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) - { - for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) - { - for ( k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ ) - { - RealBuffer[i][j][k] = fix_to_float( RealBuffer_fx[i][j][k], ( exp_real + 14 - 15 ) ); - ImagBuffer[i][j][k] = fix_to_float( ImagBuffer_fx[i][j][k], ( exp_im + 14 - 15 ) ); - } - } - } + exp_real_final--; //( exp_real + 14 - 15 ) + exp_im_final--; //( exp_im + 14 - 15 ) } - - + + #else /* Rotation in SHD (HOA3) */ if ( hCombinedOrientationData->shd_rot_max_order == -1 ) @@ -1446,22 +1977,45 @@ void ivas_binRenderer( else { /* Rotation in SD (CICPx) */ +#ifndef IVAS_FLOAT_FIXED rotateFrame_sd_cldfb( hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx], RealBuffer, ImagBuffer, hBinRenderer->hInputSetup, hBinRenderer->hEFAPdata, numTimeSlots, hBinRenderer->conv_band ); +#else + rotateFrame_sd_cldfb_fixed( hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx], RealBuffer_fx, ImagBuffer_fx, + hBinRenderer->hInputSetup, hBinRenderer->hEFAPdata, numTimeSlots, hBinRenderer->conv_band ); +#endif } } /* HOA decoding to CICP19 if needed*/ if ( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 && hBinRenderer->nInChannels != 16 ) { +#ifndef IVAS_FLOAT_FIXED ivas_sba2mc_cldfb( *( hBinRenderer->hInputSetup ), RealBuffer, ImagBuffer, hBinRenderer->nInChannels, hBinRenderer->conv_band, numTimeSlots, hBinRenderer->hoa_dec_mtx ); +#else + ivas_sba2mc_cldfb_fixed( *( hBinRenderer->hInputSetup ), RealBuffer_fx, ImagBuffer_fx, + hBinRenderer->nInChannels, hBinRenderer->conv_band, numTimeSlots, hBinRenderer->hoa_dec_mtx ); +#endif } - +#ifndef IVAS_FLOAT_FIXED ivas_binRenderer_filterModule( Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, RealBuffer, ImagBuffer, numTimeSlots, hBinRenderer ); - +#else + Word64 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + Word64 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + for ( j = 0; j < numTimeSlots; j++ ) + { + set64_fx( Cldfb_RealBuffer_Binaural_fx[i][j], 0, hBinRenderer->conv_band ); + set64_fx( Cldfb_ImagBuffer_Binaural_fx[i][j], 0, hBinRenderer->conv_band ); + } + } + ivas_binRenderer_filterModule_fixed( Cldfb_RealBuffer_Binaural_fx, Cldfb_ImagBuffer_Binaural_fx, RealBuffer_fx, ImagBuffer_fx, numTimeSlots, hBinRenderer, exp_real_final ); +#endif /* Obtain the binaural dmx and compute the reverb */ if ( hBinRenderer->hReverb != NULL ) { +#ifndef IVAS_FLOAT_FIXED float reverbRe[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; float reverbIm[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; float inRe[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; @@ -1490,10 +2044,68 @@ void ivas_binRenderer( v_add( Cldfb_ImagBuffer_Binaural[chIdx][k], reverbIm[chIdx][k], Cldfb_ImagBuffer_Binaural[chIdx][k], hBinRenderer->conv_band ); } } - } +#else + //float reverbRe[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + //float reverbIm[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + Word64 reverbRe_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + Word64 reverbIm_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + //float inRe[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + //float inIm[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + Word32 inRe_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + Word32 inIm_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + + ivas_binaural_obtain_DMX_fx( numTimeSlots, hBinRenderer, RealBuffer_fx, ImagBuffer_fx, inRe_fx, inIm_fx ); + // inRe_fx Q = exp_real_final - Q1 + + FOR( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) + { + FOR( k = 0; k < numTimeSlots; k++ ) + { + set64_fx( reverbRe_fx[chIdx][k], 0, hBinRenderer->max_band ); + set64_fx( reverbIm_fx[chIdx][k], 0, hBinRenderer->max_band ); + } + } + + ivas_binaural_reverb_processSubframe_fx( hBinRenderer->hReverb, BINAURAL_CHANNELS, numTimeSlots, inRe_fx, inIm_fx, reverbRe_fx, reverbIm_fx ); + // reverbRe_fx Q = exp_real_final - Q1 + Q30 = exp_real_final + Q29 + /* Add the conv module and reverb module output */ + FOR( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) + { + FOR( k = 0; k < numTimeSlots; k++ ) + { + /* Combine first and second parts to generate binaural output signal with room effect */ + v_add_w64( Cldfb_RealBuffer_Binaural_fx[chIdx][k], reverbRe_fx[chIdx][k], Cldfb_RealBuffer_Binaural_fx[chIdx][k], hBinRenderer->conv_band, 0 ); + v_add_w64( Cldfb_ImagBuffer_Binaural_fx[chIdx][k], reverbIm_fx[chIdx][k], Cldfb_ImagBuffer_Binaural_fx[chIdx][k], hBinRenderer->conv_band, 0 ); + } + } +#endif + } +#ifdef IVAS_FLOAT_FIXED + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + for ( k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ ) + { + RealBuffer[i][j][k] = fix_to_float( RealBuffer_fx[i][j][k], exp_real_final ); + ImagBuffer[i][j][k] = fix_to_float( ImagBuffer_fx[i][j][k], exp_im_final ); + } + } + } + + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + for ( j = 0; j < numTimeSlots; j++ ) + { + for ( k = 0; k < hBinRenderer->conv_band; k++ ) + { + Cldfb_RealBuffer_Binaural[i][j][k] = fix_W64_to_float( Cldfb_RealBuffer_Binaural_fx[i][j][k], ( exp_real_final + Q29 ) ); + Cldfb_ImagBuffer_Binaural[i][j][k] = fix_W64_to_float( Cldfb_ImagBuffer_Binaural_fx[i][j][k], ( exp_im_final + Q29 ) ); + } + } + } +#endif pop_wmops(); return; } - - diff --git a/lib_dec/ivas_rom_dec.c b/lib_dec/ivas_rom_dec.c index e0b7e6604..85525fc99 100644 --- a/lib_dec/ivas_rom_dec.c +++ b/lib_dec/ivas_rom_dec.c @@ -504,6 +504,15 @@ const float dmxmtx_table[BINAURAL_CHANNELS][11] = { 0.0f, 1.0f, 0.70709997f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f }, }; +/*----------------------------------------------------------------------------------* + * FASTCONV and PARAMETRIC binaural renderer ROM tables + *----------------------------------------------------------------------------------*/ + +const Word32 dmxmtx_table_fx[BINAURAL_CHANNELS][11] = +{ // Q31 + { 0x7fffffff, 0, 1518485623, 0x7fffffff, 0, 0x7fffffff, 0, 0x7fffffff, 0, 0x7fffffff, 0 }, + { 0, 0x7fffffff, 1518485623, 0, 0x7fffffff, 0, 0x7fffffff, 0, 0x7fffffff, 0, 0x7fffffff }, +}; diff --git a/lib_dec/ivas_rom_dec.h b/lib_dec/ivas_rom_dec.h index 03c83b711..1c1b6ce77 100644 --- a/lib_dec/ivas_rom_dec.h +++ b/lib_dec/ivas_rom_dec.h @@ -116,6 +116,7 @@ extern const Word16 dirac_dithering_ele_scale_fx[DIRAC_DIFFUSE_LEVELS]; *----------------------------------------------------------------------------------*/ extern const float dmxmtx_table[BINAURAL_CHANNELS][11]; +extern const Word32 dmxmtx_table_fx[BINAURAL_CHANNELS][11]; diff --git a/lib_dec/ivas_sba_rendering_internal.c b/lib_dec/ivas_sba_rendering_internal.c index fc36e4991..6e6ab82dd 100644 --- a/lib_dec/ivas_sba_rendering_internal.c +++ b/lib_dec/ivas_sba_rendering_internal.c @@ -47,13 +47,13 @@ #endif // DUMPS_ENABLED - /*-------------------------------------------------------------------------* * ivas_sba2MC_cldfb() * * SBA signals transformed into MC in CLDFB domain *-------------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED void ivas_sba2mc_cldfb( IVAS_OUTPUT_SETUP hInSetup, /* i : Format of input layout */ float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: cldfb real part */ @@ -120,7 +120,74 @@ void ivas_sba2mc_cldfb( pop_wmops(); return; } +#else +void ivas_sba2mc_cldfb_fixed( + IVAS_OUTPUT_SETUP hInSetup, /* i : Format of input layout */ + Word32 RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: cldfb real part (Q_real) */ + Word32 ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: cldfb imag part (Q_imag) */ + const Word16 nb_channels_out, /* i : nb of output channels */ + const Word16 nb_bands, /* i : nb of CLDFB bands to process */ + const Word16 nb_timeslots, /* i : number of time slots to process */ + const Word32 *hoa_dec_mtx /* i : HOA decoding mtx */ +) +{ + int16_t iBlock, iBand, n, m; + Word32 realOut_fx[16][MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX], imagOut_fx[16][MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX]; + Word32 g_fx; + Word32 *p_real_fx, *p_imag_fx, *p_realOut_fx, *p_imagOut_fx; + int16_t nb_channels_in; + + push_wmops( "ivas_sba2mc_cldfb_fixed" ); + nb_channels_in = hInSetup.nchan_out_woLFE; + assert( ( nb_channels_in == 16 ) && ( nb_channels_out == 11 ) && "ivas_sba2mc_cldfb_fixed; only HOA3 to CICP19 is for now supported!" ); + + FOR( n = 0; n < nb_channels_out; n++ ) + { + set_l( realOut_fx[n], 0, MAX_PARAM_SPATIAL_SUBFRAMES * nb_bands ); + set_l( imagOut_fx[n], 0, MAX_PARAM_SPATIAL_SUBFRAMES * nb_bands ); + + FOR( m = 0; m < nb_channels_in; m++ ) + { + g_fx = hoa_dec_mtx[SBA_NHARM_HOA3 * n + m]; //Q29 + p_realOut_fx = realOut_fx[n]; + p_imagOut_fx = imagOut_fx[n]; + FOR( iBlock = 0; iBlock < nb_timeslots; iBlock++ ) + { + p_real_fx = RealBuffer[m][iBlock]; + p_imag_fx = ImagBuffer[m][iBlock]; + FOR( iBand = 0; iBand < nb_bands; iBand++ ) + { + *p_realOut_fx = *p_realOut_fx + Mpy_32_32( L_shl_sat( g_fx, Q2 ), *( p_real_fx++ ) ); // Q_real + *p_imagOut_fx = *p_imagOut_fx + Mpy_32_32( L_shl_sat( g_fx, Q2 ), *( p_imag_fx++ ) ); // Q_imag + p_realOut_fx++; + p_imagOut_fx++; + } + } + } + } + + FOR( n = 0; n < nb_channels_out; n++ ) + { + p_realOut_fx = realOut_fx[n]; + p_imagOut_fx = imagOut_fx[n]; + + FOR( iBlock = 0; iBlock < nb_timeslots; iBlock++ ) + { + p_real_fx = RealBuffer[n][iBlock]; + p_imag_fx = ImagBuffer[n][iBlock]; + FOR( iBand = 0; iBand < nb_bands; iBand++ ) + { + *( p_real_fx++ ) = *p_realOut_fx++; + *( p_imag_fx++ ) = *p_imagOut_fx++; + } + } + } + + pop_wmops(); + return; +} +#endif /*-------------------------------------------------------------------------* * ivas_mc2sba() diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index ee204828f..ee505ac2d 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -908,7 +908,11 @@ typedef struct ivas_binaural_rendering_struct /* Common variables for all modules */ IVAS_OUTPUT_SETUP_HANDLE hInputSetup; /* pointer to input spatial format for binaural renderer*/ EFAP_HANDLE hEFAPdata; /* EFAP structure*/ +#ifndef IVAS_FLOAT_FIXED float *hoa_dec_mtx; /* pointer to HOA decoder mtx */ +#else + Word32 *hoa_dec_mtx; /* pointer to HOA decoder mtx */ +#endif int8_t rotInCldfb; /* Flag to enable rotation within bin Renderer in CLDFB*/ int16_t max_band; /* band upto which rendering is performed */ int16_t conv_band; /* band upto which convolution in cldfb domain is performed */ @@ -918,7 +922,11 @@ typedef struct ivas_binaural_rendering_struct IVAS_FORMAT ivas_format; /* format; corresponds to st_ivas->ivas_format, unless the signal gets transormed to a different domain for rendering */ /* Convolution module structure */ +#ifndef IVAS_FLOAT_FIXED BINRENDERER_CONV_MODULE_HANDLE hBinRenConvModule; +#else + BINRENDERER_CONV_MODULE_HANDLE_FX hBinRenConvModule; +#endif /* Variables related to reverberator module */ float earlyPartEneCorrection[CLDFB_NO_CHANNELS_MAX]; @@ -1177,7 +1185,11 @@ typedef struct Decoder_Struct HRTFS_FASTCONV_HANDLE hHrtfFastConv; /* FASTCONV HRTF tables for binaural rendering */ HRTFS_PARAMBIN_HANDLE hHrtfParambin; /* HRTF tables for parametric binauralizer */ LSSETUP_CUSTOM_HANDLE hLsSetupCustom; /* Custom LS configuration handle */ +#ifndef IVAS_FLOAT_FIXED float *hoa_dec_mtx; /* Pointer to decoder matrix for SBA */ +#else + Word32 *hoa_dec_mtx; /* Pointer to decoder matrix for SBA */ +#endif HEAD_TRACK_DATA_HANDLE hHeadTrackData; /* Head tracking data structure */ RENDER_CONFIG_DATA *hRenderConfig; /* Renderer config pointer */ int32_t binaural_latency_ns; /* Binauralization latency in ns */ diff --git a/lib_rend/ivas_allrad_dec.c b/lib_rend/ivas_allrad_dec.c index d4bafb471..8d1132aee 100644 --- a/lib_rend/ivas_allrad_dec.c +++ b/lib_rend/ivas_allrad_dec.c @@ -161,10 +161,10 @@ ivas_error ivas_sba_get_hoa_dec_matrix( return error; } #else -#define TEMP_VAL 30678337 // Q31 (1.f / num_td) +#define TEMP_VAL 1963413621 // Q37 (1.f / num_td) ivas_error ivas_sba_get_hoa_dec_matrix( const IVAS_OUTPUT_SETUP hOutSetup, /* i : target output setup */ - float **hoa_dec_mtx, /* o : ALLRAD decoder matrix */ + Word32 **hoa_dec_mtx, /* o : ALLRAD decoder matrix */ const Word16 ambisonics_order /* i : Ambisonics order */ ) { @@ -174,7 +174,7 @@ ivas_error ivas_sba_get_hoa_dec_matrix( Word32 tmp_val; Word32 G_td_int[MAX_OUTPUT_CHANNELS]; Word32 Y_td_int[SBA_NHARM_HOA3]; - float *p_dec_mtx; + Word32 *p_dec_mtx; EFAP_HANDLE hEFAP; ivas_error error; @@ -182,7 +182,7 @@ ivas_error ivas_sba_get_hoa_dec_matrix( /* Allocate memory */ assert( *hoa_dec_mtx == NULL && "hoa_dec_mtx != NULL" ); - IF ( ( *hoa_dec_mtx = (float *) malloc( SBA_NHARM_HOA3 * ( hOutSetup.nchan_out_woLFE ) * sizeof( float ) ) ) == NULL ) + IF( ( *hoa_dec_mtx = (Word32 *) malloc( SBA_NHARM_HOA3 * ( hOutSetup.nchan_out_woLFE ) * sizeof( Word32 ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "ALLRAD: Cannot allocate memory!" ) ); } @@ -191,29 +191,29 @@ ivas_error ivas_sba_get_hoa_dec_matrix( num_spk = hOutSetup.nchan_out_woLFE; p_dec_mtx = *hoa_dec_mtx; - FOR ( i = 0; i < num_spk; i++ ) + FOR( i = 0; i < num_spk; i++ ) { - FOR ( j = 0; j < SBA_NHARM_HOA3; j++ ) + FOR( j = 0; j < SBA_NHARM_HOA3; j++ ) { - *( p_dec_mtx++ ) = 0.f; + *( p_dec_mtx++ ) = 0; } } - IF ( hOutSetup.output_config == IVAS_AUDIO_CONFIG_MONO ) + IF( hOutSetup.output_config == IVAS_AUDIO_CONFIG_MONO ) { - ( *hoa_dec_mtx )[0] = 1.f; + ( *hoa_dec_mtx )[0] = ONE_IN_Q29; // 1.f in Q29 } - ELSE IF ( hOutSetup.output_config == IVAS_AUDIO_CONFIG_STEREO ) + ELSE IF( hOutSetup.output_config == IVAS_AUDIO_CONFIG_STEREO ) { - ( *hoa_dec_mtx )[0] = 0.5f; - ( *hoa_dec_mtx )[1] = 0.5f; - ( *hoa_dec_mtx )[SBA_NHARM_HOA3] = 0.5f; - ( *hoa_dec_mtx )[SBA_NHARM_HOA3 + 1] = -0.5f; + ( *hoa_dec_mtx )[0] = ONE_IN_Q28; // 0.5f in Q29 + ( *hoa_dec_mtx )[1] = ONE_IN_Q28; // 0.5f in Q29 + ( *hoa_dec_mtx )[SBA_NHARM_HOA3] = ONE_IN_Q28; // 0.5f in Q29 + ( *hoa_dec_mtx )[SBA_NHARM_HOA3 + 1] = -ONE_IN_Q28; // 0.5f in Q29 } - ELSE IF ( hOutSetup.is_loudspeaker_setup ) + ELSE IF( hOutSetup.is_loudspeaker_setup ) { /* init EFIP */ - IF ( ( error = efap_init_data( &( hEFAP ), hOutSetup.ls_azimuth, hOutSetup.ls_elevation, num_spk, EFAP_MODE_EFIP ) ) != IVAS_ERR_OK ) + IF( ( error = efap_init_data( &( hEFAP ), hOutSetup.ls_azimuth, hOutSetup.ls_elevation, num_spk, EFAP_MODE_EFIP ) ) != IVAS_ERR_OK ) { return error; } @@ -226,29 +226,31 @@ ivas_error ivas_sba_get_hoa_dec_matrix( t_design_ele = t_design_11_elevation_int; /* dec_mtx = ( 1 / num_td ) * (G_td * Y_td') * diag(norm_sn3d) */ - FOR ( i = 0; i < num_td; i++ ) + FOR( i = 0; i < num_td; i++ ) { /* spherical harmonics response for t-design, corresponding to ambisonic order */ - ivas_dirac_dec_get_response_fixed( - ( (Word16) ( t_design_azi[i] >> 22 ) ) > 0 ? ( (Word16) ( t_design_azi[i] >> 22 ) ) : ( (Word16) ( t_design_azi[i] >> 22 ) ) + 1, - ( (Word16) ( t_design_ele[i] >> 22 ) ) > 0 ? ( (Word16) ( t_design_ele[i] >> 22 ) ) : ( (Word16) ( t_design_ele[i] >> 22 ) ) + 1, + ivas_dirac_dec_get_response_fixed( + ( (Word16) L_shr( t_design_azi[i], 22 ) ) > 0 ? ( (Word16) L_shr( t_design_azi[i], 22 ) ) : ( (Word16) L_shr( t_design_azi[i], 22 ) ) + 1, + ( (Word16) L_shr( t_design_ele[i], 22 ) ) > 0 ? ( (Word16) L_shr( t_design_ele[i], 22 ) ) : ( (Word16) L_shr( t_design_ele[i], 22 ) ) + 1, Y_td_int, ambisonics_order ); - FOR ( j = 0; j < num_harm; j++ ) + FOR( j = 0; j < num_harm; j++ ) { - Y_td_int[j] = Mpy_32_32( Y_td_int[j], norm_sn3d_hoa3_int[j] ) << 1; // Q28 + Y_td_int[j] = L_shl( Mpy_32_32( Y_td_int[j], norm_sn3d_hoa3_int[j] ), Q1 ); // Q28 } /* t-design to real LS panning gains */ - efap_determine_gains_fixed( hEFAP, G_td_int, t_design_azi[i], t_design_ele[i] , EFAP_MODE_EFIP ); // G_td_int Q30 + efap_determine_gains_fixed( hEFAP, G_td_int, t_design_azi[i], t_design_ele[i], EFAP_MODE_EFIP ); // G_td_int Q30 p_dec_mtx = *hoa_dec_mtx; - FOR ( j = 0; j < num_spk; j++ ) + FOR( j = 0; j < num_spk; j++ ) { Word32 dec_mtx_temp = 0; - FOR ( k = 0; k < num_harm; k++ ) + FOR( k = 0; k < num_harm; k++ ) { dec_mtx_temp = Mpy_32_32( G_td_int[j], Y_td_int[k] ); // Q27 - *( p_dec_mtx++ ) += ( (float) dec_mtx_temp ) / ( 1 << Q27 ); + *p_dec_mtx = L_add( *p_dec_mtx, L_shr( dec_mtx_temp, 2 ) ); // Q25 + //printf( "\n%f", ((float)*p_dec_mtx)/ ONE_IN_Q25 ); + p_dec_mtx++; } p_dec_mtx += ( SBA_NHARM_HOA3 - num_harm ); } @@ -256,13 +258,14 @@ ivas_error ivas_sba_get_hoa_dec_matrix( tmp_val = TEMP_VAL; p_dec_mtx = *hoa_dec_mtx; - FOR ( i = 0; i < num_spk; i++ ) + FOR( i = 0; i < num_spk; i++ ) { Word32 dec_mtx_temp_scale = 0; - FOR ( j = 0; j < num_harm; j++ ) + FOR( j = 0; j < num_harm; j++ ) { - dec_mtx_temp_scale = Mpy_32_32( tmp_val, norm_sn3d_hoa3_int[j] ); - *( p_dec_mtx++ ) *= ( (float) dec_mtx_temp_scale ) / ( 1 << Q29 ); + dec_mtx_temp_scale = Mpy_32_32( tmp_val, norm_sn3d_hoa3_int[j] ); // Q35 + *p_dec_mtx = Mpy_32_32(*p_dec_mtx, dec_mtx_temp_scale); // Q29 + p_dec_mtx++; } p_dec_mtx += ( SBA_NHARM_HOA3 - num_harm ); } diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 2d175d1bf..097063a8b 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -1139,7 +1139,11 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( if ( hDirACRend->hOutSetup.is_loudspeaker_setup && hDirACRend->hoa_decoder != NULL ) { float *p_real, *p_imag; +#ifndef IVAS_FLOAT_FIXED const float *hoa_decoder; +#else + const Word32 *hoa_decoder; +#endif hoa_decoder = hDirACRend->hoa_decoder; @@ -1152,12 +1156,22 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( { p_out_real = output_real + l * num_channels_dir; p_out_imag = output_imag + l * num_channels_dir; +#ifndef IVAS_FLOAT_FIXED p_real[l] = *( p_out_real++ ) * hoa_decoder[0]; p_imag[l] = *( p_out_imag++ ) * hoa_decoder[0]; +#else + p_real[l] = *( p_out_real++ ) * ( (float) hoa_decoder[0] ) / ONE_IN_Q29; + p_imag[l] = *( p_out_imag++ ) * ( (float) hoa_decoder[0] ) / ONE_IN_Q29; +#endif for ( i = 1; i < num_channels_dir; i++ ) { +#ifndef IVAS_FLOAT_FIXED p_real[l] += *( p_out_real++ ) * hoa_decoder[i]; p_imag[l] += *( p_out_imag++ ) * hoa_decoder[i]; +#else + p_real[l] += *( p_out_real++ ) * ( (float) hoa_decoder[i] ) / ONE_IN_Q29; + p_imag[l] += *( p_out_imag++ ) * ( (float) hoa_decoder[i] ) / ONE_IN_Q29; +#endif } } hoa_decoder += 16; diff --git a/lib_rend/ivas_dirac_rend.c b/lib_rend/ivas_dirac_rend.c index dab3bbd78..09929453f 100644 --- a/lib_rend/ivas_dirac_rend.c +++ b/lib_rend/ivas_dirac_rend.c @@ -2090,7 +2090,11 @@ void protoSignalComputation4( const int16_t slot_index, const int16_t num_outputs_diff, const int16_t num_freq_bands, +#ifndef IVAS_FLOAT_FIXED const float *mtx_hoa_decoder, +#else + const Word32 *mtx_hoa_decoder, +#endif const int16_t nchan_transport, const int16_t *sba_map_tc_ind ) { @@ -2118,8 +2122,13 @@ void protoSignalComputation4( proto_frame_f[2 * l * num_freq_bands + 2 * k + 1] = 0.f; for ( n = 0; n < nchan_transport; n++ ) { +#ifndef IVAS_FLOAT_FIXED proto_frame_f[2 * l * num_freq_bands + 2 * k] += RealBuffer[n][0][k] * mtx_hoa_decoder[l * 16 + sba_map_tc_ind[n]]; proto_frame_f[2 * l * num_freq_bands + 2 * k + 1] += ImagBuffer[n][0][k] * mtx_hoa_decoder[l * 16 + sba_map_tc_ind[n]]; +#else + proto_frame_f[2 * l * num_freq_bands + 2 * k] += RealBuffer[n][0][k] * ( (float) mtx_hoa_decoder[l * 16 + sba_map_tc_ind[n]] ) / ONE_IN_Q29; + proto_frame_f[2 * l * num_freq_bands + 2 * k + 1] += ImagBuffer[n][0][k] * ( (float) mtx_hoa_decoder[l * 16 + sba_map_tc_ind[n]] ) / ONE_IN_Q29; +#endif } } } diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 6094a0919..0fc612616 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -283,12 +283,19 @@ void ivas_sba_prototype_renderer( const int16_t subframe /* i : Subframe to render */ ); +#ifndef IVAS_FLOAT_FIXED ivas_error ivas_sba_get_hoa_dec_matrix( const IVAS_OUTPUT_SETUP hOutSetup, /* i : target output setup */ float **hoa_dec_mtx, /* o : ALLRAD decoder matrix */ const Word16 ambisonics_order /* i : Ambisonics order */ ); - +#else +ivas_error ivas_sba_get_hoa_dec_matrix( + const IVAS_OUTPUT_SETUP hOutSetup, /* i : target output setup */ + Word32 **hoa_dec_mtx, /* o : ALLRAD decoder matrix */ + const Word16 ambisonics_order /* i : Ambisonics order */ +); +#endif void ivas_dirac_dec_binaural_sba_gain( float *output[], /* i/o: synthesized core-coder transport channels/DirAC output */ const int16_t nchan_remapped, /* i : num channels after remapping of TCs */ @@ -409,8 +416,11 @@ void protoSignalComputation4( const int16_t slot_index, const int16_t num_outputs_diff, const int16_t num_freq_bands, - const - float *mtx_hoa_decoder, +#ifndef IVAS_FLOAT_FIXED + const float *mtx_hoa_decoder, +#else + const Word32 *mtx_hoa_decoder, +#endif const int16_t nchan_transport, const int16_t *sba_map_tc_ind ); @@ -1143,6 +1153,18 @@ void ivas_binaural_reverb_processSubframe( float outImag[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /* o : output CLDFB data imag */ ); +#ifdef IVAS_FLOAT_FIXED +void ivas_binaural_reverb_processSubframe_fx( + REVERB_STRUCT_HANDLE hReverb, /* i/o: binaural reverb handle */ + const int16_t numInChannels, /* i : num inputs to be processed */ + const int16_t numSlots, /* i : number of slots to be processed */ + Word32 inReal[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : input CLDFB data real, Comment: This change swaps two first dimensions as first dimension is not constant. */ + Word32 inImag[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : input CLDFB data imag */ + Word64 outReal[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* o : output CLDFB data real */ + Word64 outImag[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /* o : output CLDFB data imag */ +); +#endif + ivas_error ivas_reverb_open( REVERB_HANDLE *hReverb, /* i/o: Reverberator handle */ const AUDIO_CONFIG input_audio_config, /* i : reverb. input audio configuration */ @@ -1631,6 +1653,7 @@ void rotateFrame_shd_cldfb( const Word16 shd_rot_max_order /* i : split-order rotation method */ ); #endif +#ifndef IVAS_FLOAT_FIXED void rotateFrame_sd_cldfb( float Rmat[3][3], /* i : real-space rotation matrix */ float Cldfb_RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: unrotated HOA3 signal buffer in cldfb domain real part */ @@ -1640,6 +1663,17 @@ void rotateFrame_sd_cldfb( const int16_t numTimeSlots, /* i : number of time slots to process */ const int16_t nb_band /* i : number of CLDFB bands to process */ ); +#else +void rotateFrame_sd_cldfb_fixed( + Word32 Rmat[3][3], /* i : real-space rotation matrix */ + 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 */ + const IVAS_OUTPUT_SETUP_HANDLE hOutputSetup, /* i : output format setup number of channels */ + const EFAP_HANDLE hEFAPdata, /* i : EFAP structure */ + const int16_t numTimeSlots, /* i : number of time slots to process */ + const int16_t nb_band /* i : number of CLDFB bands to process */ +); +#endif ivas_error ivas_external_orientation_open( EXTERNAL_ORIENTATION_HANDLE *hExtOrientationData, /* o : external orientation handle */ diff --git a/lib_rend/ivas_reverb.c b/lib_rend/ivas_reverb.c index 0a67670f9..cbaea7654 100644 --- a/lib_rend/ivas_reverb.c +++ b/lib_rend/ivas_reverb.c @@ -44,6 +44,7 @@ #include "prot_fx2.h" #include "debug.h" #define float_to_fix( n, factor ) ( round( n * ( 1 << factor ) ) ) +#define float_to_fixQ31( n ) ( round( n * 0x7fffffff ) ) #define fix_to_float( n, factor ) ( (float) n / ( 1 << factor ) ) #endif @@ -55,11 +56,11 @@ * Local constants *------------------------------------------------------------------------*/ -#define BIN_REND_RANDOM_SEED 1 /* random seed for generating reverb decorrelators */ +#define BIN_REND_RANDOM_SEED 1 /* random seed for generating reverb decorrelators */ #define CLDFB_SLOTS_PER_SECOND 800 /* Used for initializing reverb */ -#define INNER_BLK_SIZE 80 /* size of data blocks used for more efficient delay line and IIR filter processing */ +#define INNER_BLK_SIZE 80 /* size of data blocks used for more efficient delay line and IIR filter processing */ /* should be a divisor of the frame length at any sampling rate and an even number*/ #define FFT_FILTER_WND_FLAT_REGION ( 0.40f ) /* flat section (==1) length of FFT filter window, in proportion to overlap */ #define FFT_FILTER_WND_TRANS_REGION ( 0.15f ) /* transition (1->0) length of FFT filter window, in proportion to overlap */ @@ -116,9 +117,9 @@ typedef struct ivas_reverb_params_t const float *pHrtf_avg_pwr_response_r_const; /* The HRTF set's average right ear power response */ const float *pHrtf_inter_aural_coherence_const; /* The HRTF set's inter-aural coherence for diffuse sound */ - Word16 do_corr_filter; /* Flag indicating whether correlation filters should be used. */ - /* Correlation only supported and needed for binaural playback (i.e. */ - /* when nr_outputs != 2 correlation filtering is never supported). */ + Word16 do_corr_filter; /* Flag indicating whether correlation filters should be used. */ + /* Correlation only supported and needed for binaural playback (i.e. */ + /* when nr_outputs != 2 correlation filtering is never supported). */ } ivas_reverb_params_t; #else typedef struct ivas_reverb_params_t @@ -147,9 +148,9 @@ typedef struct ivas_reverb_params_t const float *pHrtf_avg_pwr_response_r_const; /* The HRTF set's average right ear power response */ const float *pHrtf_inter_aural_coherence_const; /* The HRTF set's inter-aural coherence for diffuse sound */ - int16_t do_corr_filter; /* Flag indicating whether correlation filters should be used. */ - /* Correlation only supported and needed for binaural playback (i.e. */ - /* when nr_outputs != 2 correlation filtering is never supported). */ + int16_t do_corr_filter; /* Flag indicating whether correlation filters should be used. */ + /* Correlation only supported and needed for binaural playback (i.e. */ + /* when nr_outputs != 2 correlation filtering is never supported). */ } ivas_reverb_params_t; #endif @@ -285,10 +286,17 @@ static void ivas_binaural_reverb_setReverbTimes( hReverb->binauralCoherenceCrossmixGains[bin] = -sqrtf( fabsf( tmpVal ) ); } hReverb->binauralCoherenceDirectGains[bin] = sqrtf( 1.0f - fabsf( tmpVal ) ); +#ifdef IVAS_FLOAT_FIXED + hReverb->binauralCoherenceCrossmixGains_fx[bin] = (Word32) float_to_fixQ31( hReverb->binauralCoherenceCrossmixGains[bin] ); + hReverb->binauralCoherenceDirectGains_fx[bin] = (Word32) float_to_fixQ31( hReverb->binauralCoherenceDirectGains[bin] ); +#endif /* Determine attenuation factor that generates the appropriate energy decay according to reverberation time */ attenuationFactorPerSample = powf( 10.0f, -3.0f * ( 1.0f / ( (float) CLDFB_SLOTS_PER_SECOND * revTimes[bin] ) ) ); hReverb->loopAttenuationFactor[bin] = powf( attenuationFactorPerSample, hReverb->loopBufLength[bin] ); +#ifdef IVAS_FLOAT_FIXED + hReverb->loopAttenuationFactor_fx[bin] = (Word32) float_to_fixQ31( hReverb->loopAttenuationFactor[bin] ); +#endif attenuationFactorPerSampleSq = attenuationFactorPerSample * attenuationFactorPerSample; /* Design sparse decorrelation filters. The decorrelation filters, due to random procedures involved, @@ -316,6 +324,10 @@ static void ivas_binaural_reverb_setReverbTimes( /* Set the tapPointer to point to the determined sample at the loop buffer */ hReverb->tapPointersReal[bin][ch][tap] = &( hReverb->loopBufReal[bin][sample] ); hReverb->tapPointersImag[bin][ch][tap] = &( hReverb->loopBufImag[bin][sample] ); +#ifdef IVAS_FLOAT_FIXED + hReverb->tapPointersReal_fx[bin][ch][tap] = &( hReverb->loopBufReal_fx[bin][sample] ); + hReverb->tapPointersImag_fx[bin][ch][tap] = &( hReverb->loopBufImag_fx[bin][sample] ); +#endif energyBuildup -= 1.0f; /* A tap is added, thus remove its energy from the buildup */ tap++; actualizedEnergy += 1.0f; @@ -329,6 +341,9 @@ static void ivas_binaural_reverb_setReverbTimes( hReverb->reverbEqGains[bin] = sqrtf( revEnes[bin] ); /* Determined reverb spectrum */ hReverb->reverbEqGains[bin] *= sqrtf( intendedEnergy / actualizedEnergy ); /* Correction of random effects at the decorrelator design */ hReverb->reverbEqGains[bin] *= sqrtf( 0.5f * ( 1.0f - attenuationFactorPerSampleSq ) ); /* Correction of IIR decay rate */ +#ifdef IVAS_FLOAT_FIXED + hReverb->reverbEqGains_fx[bin] = (Word32) float_to_fixQ31( hReverb->reverbEqGains[bin] ); +#endif } return; @@ -507,7 +522,7 @@ static ivas_error set_base_config( Word16 loop_idx; const Word16 *selected_loop_delay = NULL; - IF ( pParams == NULL ) + IF( pParams == NULL ) { return IVAS_ERR_INTERNAL; } @@ -520,27 +535,27 @@ static ivas_error set_base_config( move16(); /* set loop delays to default */ - IF ( EQ_32( output_Fs, 48000 ) ) + IF( EQ_32( output_Fs, 48000 ) ) { selected_loop_delay = default_loop_delay_48k; } - ELSE IF ( EQ_32( output_Fs, 32000 ) ) + ELSE IF( EQ_32( output_Fs, 32000 ) ) { selected_loop_delay = default_loop_delay_32k; } - ELSE IF ( EQ_32( output_Fs, 16000 ) ) + ELSE IF( EQ_32( output_Fs, 16000 ) ) { selected_loop_delay = default_loop_delay_16k; } - FOR ( loop_idx = 0; loop_idx < pParams->nr_loops; loop_idx++ ) + FOR( loop_idx = 0; loop_idx < pParams->nr_loops; loop_idx++ ) { pParams->pLoop_delays[loop_idx] = selected_loop_delay[loop_idx]; move16(); } /* set feedback and output matrices */ - IF ( NE_32( ( error = compute_feedback_matrix_fx( pParams->pLoop_feedback_matrix_fx, pParams->nr_loops ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = compute_feedback_matrix_fx( pParams->pLoop_feedback_matrix_fx, pParams->nr_loops ) ), IVAS_ERR_OK ) ) { return error; } @@ -550,7 +565,7 @@ static ivas_error set_base_config( pParams->t60_filter_order = 1; /* set to 1 in base config. */ move16(); - IF ( EQ_16( pParams->nr_outputs, 2 ) ) + IF( EQ_16( pParams->nr_outputs, 2 ) ) { pParams->do_corr_filter = 1; move16(); @@ -578,7 +593,7 @@ static ivas_error set_base_config( Word16 loop_idx; const Word16 *selected_loop_delay = NULL; - IF ( pParams == NULL ) + IF( pParams == NULL ) { return IVAS_ERR_INTERNAL; } @@ -588,26 +603,26 @@ static ivas_error set_base_config( pParams->nr_loops = IVAS_REV_MAX_NR_BRANCHES; /* set loop delays to default */ - IF ( EQ_32( output_Fs, 48000 ) ) + IF( EQ_32( output_Fs, 48000 ) ) { selected_loop_delay = default_loop_delay_48k; } - ELSE IF ( EQ_32( output_Fs, 32000 ) ) + ELSE IF( EQ_32( output_Fs, 32000 ) ) { selected_loop_delay = default_loop_delay_32k; } - ELSE IF ( EQ_32( output_Fs, 16000 ) ) + ELSE IF( EQ_32( output_Fs, 16000 ) ) { selected_loop_delay = default_loop_delay_16k; } - FOR ( loop_idx = 0; loop_idx < pParams->nr_loops; loop_idx++ ) + FOR( loop_idx = 0; loop_idx < pParams->nr_loops; loop_idx++ ) { pParams->pLoop_delays[loop_idx] = selected_loop_delay[loop_idx]; } /* set feedback and output matrices */ - IF ( ( error = compute_feedback_matrix( pParams->pLoop_feedback_matrix, pParams->nr_loops ) ) != IVAS_ERR_OK ) + IF( ( error = compute_feedback_matrix( pParams->pLoop_feedback_matrix, pParams->nr_loops ) ) != IVAS_ERR_OK ) { return error; } @@ -617,7 +632,7 @@ static ivas_error set_base_config( /* pre-set the various filters; they will be set later based on reverb configuration */ pParams->t60_filter_order = 1; /* set to 1 in base config. */ - IF ( EQ_16( pParams->nr_outputs, 2 ) ) + IF( EQ_16( pParams->nr_outputs, 2 ) ) { pParams->do_corr_filter = 1; } @@ -1705,7 +1720,7 @@ 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++ ) + 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 ); @@ -1926,14 +1941,14 @@ void ivas_reverb_close( hReverb = *hReverb_in; - IF ( hReverb_in == NULL || *hReverb_in == NULL ) + IF( hReverb_in == NULL || *hReverb_in == NULL ) { return; } - FOR ( loop_idx = 0; loop_idx < IVAS_REV_MAX_NR_BRANCHES; loop_idx++ ) + FOR( loop_idx = 0; loop_idx < IVAS_REV_MAX_NR_BRANCHES; loop_idx++ ) { - IF ( hReverb->loop_delay_buffer_fx[loop_idx] != NULL ) + IF( hReverb->loop_delay_buffer_fx[loop_idx] != NULL ) { free( hReverb->loop_delay_buffer_fx[loop_idx] ); hReverb->loop_delay_buffer_fx[loop_idx] = NULL; @@ -1964,14 +1979,14 @@ void ivas_reverb_close( hReverb = *hReverb_in; - IF ( hReverb_in == NULL || *hReverb_in == NULL ) + IF( hReverb_in == NULL || *hReverb_in == NULL ) { return; } - FOR ( loop_idx = 0; loop_idx < IVAS_REV_MAX_NR_BRANCHES; loop_idx++ ) + FOR( loop_idx = 0; loop_idx < IVAS_REV_MAX_NR_BRANCHES; loop_idx++ ) { - IF ( hReverb->loop_delay_buffer[loop_idx] != NULL ) + IF( hReverb->loop_delay_buffer[loop_idx] != NULL ) { free( hReverb->loop_delay_buffer[loop_idx] ); hReverb->loop_delay_buffer[loop_idx] = NULL; @@ -2488,8 +2503,8 @@ static void mix_output_block_fx( for ( i = 0; i < hReverb->full_block_size; i++ ) { - pOutL[i] = L_add( pInL[i], ((pOutL[i]) >> 2)); - pOutR[i] = L_add( pInR[i], ((pOutR[i]) >> 2)); + pOutL[i] = L_add( pInL[i], ( ( pOutL[i] ) >> 2 ) ); + pOutR[i] = L_add( pInR[i], ( ( pOutR[i] ) >> 2 ) ); } return; @@ -2529,22 +2544,22 @@ static void mix_output_block( ivas_error ivas_reverb_process_fx( const REVERB_HANDLE hReverb, /* i : Reverberator handle */ const AUDIO_CONFIG input_audio_config, /* i : reverb. input audio configuration */ - const Word16 mix_signals, /* i : add reverb to output signal */ - Word32 *pcm_in_fx[], /* i : the PCM audio to apply reverb on */ - Word32 *pcm_out_fx[], /* o : the PCM audio with reverb applied */ - const Word16 i_ts /* i : subframe index */ - ) + const Word16 mix_signals, /* i : add reverb to output signal */ + Word32 *pcm_in_fx[], /* i : the PCM audio to apply reverb on */ + Word32 *pcm_out_fx[], /* o : the PCM audio with reverb applied */ + const Word16 i_ts /* i : subframe index */ +) { Word32 tmp0_fx[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES], tmp1_fx[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES], tmp2_fx[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; ivas_error error; - + if ( ( error = downmix_input_block_fx( hReverb, pcm_in_fx, input_audio_config, tmp1_fx, i_ts * hReverb->full_block_size ) ) != IVAS_ERR_OK ) { return error; } predelay_block_fx( hReverb, tmp1_fx, tmp0_fx ); - + reverb_block_fx( hReverb, tmp0_fx, tmp1_fx, tmp2_fx ); if ( mix_signals ) @@ -2556,7 +2571,7 @@ ivas_error ivas_reverb_process_fx( mvr2r_Word32( tmp1_fx, &pcm_out_fx[0][i_ts * hReverb->full_block_size], hReverb->full_block_size ); mvr2r_Word32( tmp2_fx, &pcm_out_fx[1][i_ts * hReverb->full_block_size], hReverb->full_block_size ); } - + return IVAS_ERR_OK; } #else @@ -2761,7 +2776,175 @@ void ivas_binaural_reverb_processSubframe( return; } +#ifdef IVAS_FLOAT_FIXED +/*------------------------------------------------------------------------- + * ivas_binaural_reverb_processSubFrame_fx() + * + * Compute the reverberation - room effect + *------------------------------------------------------------------------*/ + +void ivas_binaural_reverb_processSubframe_fx( + REVERB_STRUCT_HANDLE hReverb, /* i/o: binaural reverb handle */ + const int16_t numInChannels, /* i : num inputs to be processed */ + const int16_t numSlots, /* i : number of slots to be processed */ + Word32 inReal[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i (Q_in) : input CLDFB data real, Comment: This change swaps two first dimensions as first dimension is not constant. */ + Word32 inImag[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i (Q_in) : input CLDFB data imag */ + Word64 outReal[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* o : output CLDFB data real */ + Word64 outImag[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /* o : output CLDFB data imag */ +) +{ + /* Declare the required variables */ + int16_t idx, bin, ch, sample, invertSampleIndex, tapIdx, *phaseShiftTypePr; + // float **tapRealPr, **tapImagPr; + Word32 **tapRealPr_fx, **tapImagPr_fx; + push_wmops( "binaural_reverb" ); + + /* 1) Rotate the data in the loop buffer of the reverberator. + * Notice that the audio at the loop buffers is at time-inverted order + * for convolution purposes later on. */ + FOR( bin = 0; bin < hReverb->numBins; bin++ ) + { + /* Move the data forwards by blockSize (i.e. by the frame size of 16 CLDFB slots) */ + mvl2l( hReverb->loopBufReal_fx[bin], hReverb->loopBufReal_fx[bin] + numSlots, hReverb->loopBufLength[bin] ); + mvl2l( hReverb->loopBufImag_fx[bin], hReverb->loopBufImag_fx[bin] + numSlots, hReverb->loopBufLength[bin] ); + + /* Add the data from the end of the loop to the beginning, with an attenuation factor + * according to RT60. This procedure generates an IIR decaying response. The response + * is decorrelated later on. */ + v_multc_fixed( hReverb->loopBufReal_fx[bin] + hReverb->loopBufLength[bin], hReverb->loopAttenuationFactor_fx[bin], hReverb->loopBufReal_fx[bin], numSlots ); + v_multc_fixed( hReverb->loopBufImag_fx[bin] + hReverb->loopBufLength[bin], hReverb->loopAttenuationFactor_fx[bin], hReverb->loopBufImag_fx[bin], numSlots ); + } + + /* 2) Apply the determined pre-delay to the input audio, and add the delayed audio to the loop. */ + idx = hReverb->preDelayBufferIndex; + FOR( sample = 0; sample < numSlots; sample++ ) + { + invertSampleIndex = numSlots - sample - 1; + + FOR( bin = 0; bin < hReverb->numBins; bin++ ) + { + /* Add from pre-delay buffer a sample to the loop buffer, in a time-inverted order. + * Also apply the spectral gains determined for the reverberation */ + hReverb->loopBufReal_fx[bin][invertSampleIndex] = L_add( hReverb->loopBufReal_fx[bin][invertSampleIndex], + Mpy_32_32( hReverb->preDelayBufferReal_fx[idx][bin], hReverb->reverbEqGains_fx[bin] ) ); + hReverb->loopBufImag_fx[bin][invertSampleIndex] = L_add( hReverb->loopBufImag_fx[bin][invertSampleIndex], + Mpy_32_32( hReverb->preDelayBufferImag_fx[idx][bin], hReverb->reverbEqGains_fx[bin] ) ); + hReverb->preDelayBufferReal_fx[idx][bin] = 0; + hReverb->preDelayBufferImag_fx[idx][bin] = 0; + } + + /* Add every second input channel as is to the pre-delay buffer, and every second input channel with + * 90 degrees phase shift to reduce energy imbalances between coherent and incoherent sounds */ + FOR( ch = 0; ch < numInChannels; ch++ ) + { + IF( ch % 2 ) + { + v_add_fixed( hReverb->preDelayBufferReal_fx[idx], inReal[ch][sample], hReverb->preDelayBufferReal_fx[idx], hReverb->numBins, 0 ); + v_add_fixed( hReverb->preDelayBufferImag_fx[idx], inImag[ch][sample], hReverb->preDelayBufferImag_fx[idx], hReverb->numBins, 0 ); + } + ELSE + { + v_sub_fixed( hReverb->preDelayBufferReal_fx[idx], inImag[ch][sample], hReverb->preDelayBufferReal_fx[idx], hReverb->numBins, 0 ); + v_add_fixed( hReverb->preDelayBufferImag_fx[idx], inReal[ch][sample], hReverb->preDelayBufferImag_fx[idx], hReverb->numBins, 0 ); + } + } + idx = ( idx + 1 ) % hReverb->preDelayBufferLength; + } + hReverb->preDelayBufferIndex = idx; + + /* 3) Perform the filtering/decorrelating, using complex and sparse FIR filtering */ + FOR( bin = 0; bin < hReverb->numBins; bin++ ) + { + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + /* These tap pointers have been determined to point to the loop buffer at sparse locations */ + tapRealPr_fx = hReverb->tapPointersReal_fx[bin][ch]; + tapImagPr_fx = hReverb->tapPointersImag_fx[bin][ch]; + + phaseShiftTypePr = hReverb->tapPhaseShiftType[bin][ch]; + + /* Flush output */ + set_l( hReverb->outputBufferReal_fx[bin][ch], 0, numSlots ); + set_l( hReverb->outputBufferImag_fx[bin][ch], 0, numSlots ); + + /* Add from temporally decaying sparse tap locations the audio to the output. */ + FOR( tapIdx = 0; tapIdx < hReverb->taps[bin][ch]; tapIdx++ ) + { + SWITCH( phaseShiftTypePr[tapIdx] ) + { + case 0: /* 0 degrees phase */ + v_add_fixed( hReverb->outputBufferReal_fx[bin][ch], tapRealPr_fx[tapIdx], hReverb->outputBufferReal_fx[bin][ch], numSlots, 0 ); + v_add_fixed( hReverb->outputBufferImag_fx[bin][ch], tapImagPr_fx[tapIdx], hReverb->outputBufferImag_fx[bin][ch], numSlots, 0 ); + break; + case 1: /* 90 degrees phase */ + v_sub_fixed( hReverb->outputBufferReal_fx[bin][ch], tapImagPr_fx[tapIdx], hReverb->outputBufferReal_fx[bin][ch], numSlots, 0 ); + v_add_fixed( hReverb->outputBufferImag_fx[bin][ch], tapRealPr_fx[tapIdx], hReverb->outputBufferImag_fx[bin][ch], numSlots, 0 ); + break; + case 2: /* 180 degrees phase */ + v_sub_fixed( hReverb->outputBufferReal_fx[bin][ch], tapRealPr_fx[tapIdx], hReverb->outputBufferReal_fx[bin][ch], numSlots, 0 ); + v_sub_fixed( hReverb->outputBufferImag_fx[bin][ch], tapImagPr_fx[tapIdx], hReverb->outputBufferImag_fx[bin][ch], numSlots, 0 ); + break; + default: /* 270 degrees phase */ + v_add_fixed( hReverb->outputBufferReal_fx[bin][ch], tapImagPr_fx[tapIdx], hReverb->outputBufferReal_fx[bin][ch], numSlots, 0 ); + v_sub_fixed( hReverb->outputBufferImag_fx[bin][ch], tapRealPr_fx[tapIdx], hReverb->outputBufferImag_fx[bin][ch], numSlots, 0 ); + break; + } + } + } + + /* Generate diffuse field binaural coherence by mixing the incoherent reverberated channels with pre-defined gains */ + IF( LE_16( bin, hReverb->highestBinauralCoherenceBin ) ) + { + IF( hReverb->useBinauralCoherence ) + { + FOR( sample = 0; sample < numSlots; sample++ ) + { + //float leftRe, rightRe, leftIm, rightIm; + Word32 leftRe_fx, rightRe_fx, leftIm_fx, rightIm_fx; + + leftRe_fx = L_add( Mpy_32_32( hReverb->binauralCoherenceDirectGains_fx[bin], hReverb->outputBufferReal_fx[bin][0][sample] ), + Mpy_32_32( hReverb->binauralCoherenceCrossmixGains_fx[bin], hReverb->outputBufferReal_fx[bin][1][sample] ) ); + rightRe_fx = L_add( Mpy_32_32( hReverb->binauralCoherenceDirectGains_fx[bin], hReverb->outputBufferReal_fx[bin][1][sample] ), + Mpy_32_32( hReverb->binauralCoherenceCrossmixGains_fx[bin], hReverb->outputBufferReal_fx[bin][0][sample] ) ); + leftIm_fx = L_add( Mpy_32_32( hReverb->binauralCoherenceDirectGains_fx[bin], hReverb->outputBufferImag_fx[bin][0][sample] ), + Mpy_32_32( hReverb->binauralCoherenceCrossmixGains_fx[bin], hReverb->outputBufferImag_fx[bin][1][sample] ) ); + rightIm_fx = L_add( Mpy_32_32( hReverb->binauralCoherenceDirectGains_fx[bin], hReverb->outputBufferImag_fx[bin][1][sample] ), + Mpy_32_32( hReverb->binauralCoherenceCrossmixGains_fx[bin], hReverb->outputBufferImag_fx[bin][0][sample] ) ); + + hReverb->outputBufferReal_fx[bin][0][sample] = leftRe_fx; // Q_in + hReverb->outputBufferReal_fx[bin][1][sample] = rightRe_fx; // Q_in + hReverb->outputBufferImag_fx[bin][0][sample] = leftIm_fx; // Q_in + hReverb->outputBufferImag_fx[bin][1][sample] = rightIm_fx; // Q_in + } + } + } + } + /* 4) Write data to output */ + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + FOR( sample = 0; sample < numSlots; sample++ ) + { + /* Audio was in the temporally inverted order for convolution, re-invert audio to output */ + invertSampleIndex = numSlots - sample - 1; + + FOR( bin = 0; bin < hReverb->numBins; bin++ ) + { + outReal[ch][sample][bin] = W_shl( hReverb->outputBufferReal_fx[bin][ch][invertSampleIndex], Q30 ); //Q_in + Q30 + outImag[ch][sample][bin] = W_shl( hReverb->outputBufferImag_fx[bin][ch][invertSampleIndex], Q30 ); //Q_in + Q30 + } + FOR( ; bin < CLDFB_NO_CHANNELS_MAX; bin++ ) + { + outReal[ch][sample][bin] = 0; + outImag[ch][sample][bin] = 0; + } + } + } + + pop_wmops(); + return; +} +#endif /*------------------------------------------------------------------------- * ivas_binaural_reverb_open() * @@ -2799,6 +2982,10 @@ static ivas_error ivas_binaural_reverb_open( { set_f( hReverb->preDelayBufferReal[k], 0.0f, hReverb->numBins ); set_f( hReverb->preDelayBufferImag[k], 0.0f, hReverb->numBins ); +#ifdef IVAS_FLOAT_FIXED + set_l( hReverb->preDelayBufferReal_fx[k], 0, hReverb->numBins ); + set_l( hReverb->preDelayBufferImag_fx[k], 0, hReverb->numBins ); +#endif } for ( bin = 0; bin < hReverb->numBins; bin++ ) @@ -2816,9 +3003,21 @@ static ivas_error ivas_binaural_reverb_open( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Reverberator\n" ) ); } - set_f( hReverb->loopBufReal[bin], 0.0f, len ); set_f( hReverb->loopBufImag[bin], 0.0f, len ); +#ifdef IVAS_FLOAT_FIXED + if ( ( hReverb->loopBufReal_fx[bin] = (Word32 *) malloc( len * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Reverberator\n" ) ); + } + + if ( ( hReverb->loopBufImag_fx[bin] = (Word32 *) malloc( len * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Reverberator\n" ) ); + } + set_l( hReverb->loopBufReal_fx[bin], 0, len ); + set_l( hReverb->loopBufImag_fx[bin], 0, len ); +#endif /* Determine loop buffer length. The following formula is manually tuned to generate sufficiently long * but not excessively long loops to generate reverberation. */ @@ -2846,6 +3045,17 @@ static ivas_error ivas_binaural_reverb_open( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Reverberator\n" ) ); } +#ifdef IVAS_FLOAT_FIXED + if ( ( hReverb->tapPointersReal_fx[bin][chIdx] = (Word32 **) malloc( len * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Reverberator\n" ) ); + } + + if ( ( hReverb->tapPointersImag_fx[bin][chIdx] = (Word32 **) malloc( len * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Reverberator\n" ) ); + } +#endif len = hReverb->blockSize; if ( ( hReverb->outputBufferReal[bin][chIdx] = (float *) malloc( len * sizeof( float ) ) ) == NULL ) @@ -2860,6 +3070,19 @@ static ivas_error ivas_binaural_reverb_open( set_f( hReverb->outputBufferReal[bin][chIdx], 0.0f, len ); set_f( hReverb->outputBufferImag[bin][chIdx], 0.0f, len ); +#ifdef IVAS_FLOAT_FIXED + if ( ( hReverb->outputBufferReal_fx[bin][chIdx] = (Word32 *) malloc( len * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Reverberator\n" ) ); + } + + if ( ( hReverb->outputBufferImag_fx[bin][chIdx] = (Word32 *) malloc( len * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Reverberator\n" ) ); + } + set_l( hReverb->outputBufferReal_fx[bin][chIdx], 0, len ); + set_l( hReverb->outputBufferImag_fx[bin][chIdx], 0, len ); +#endif } } @@ -2979,23 +3202,33 @@ void ivas_binaural_reverb_close( { Word16 bin, chIdx; - IF ( hReverb == NULL || *hReverb == NULL ) + IF( hReverb == NULL || *hReverb == NULL ) { return; } - FOR ( bin = 0; bin < ( *hReverb )->numBins; bin++ ) + FOR( bin = 0; bin < ( *hReverb )->numBins; bin++ ) { - FOR ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) + FOR( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) { free( ( *hReverb )->tapPhaseShiftType[bin][chIdx] ); free( ( *hReverb )->tapPointersReal[bin][chIdx] ); free( ( *hReverb )->tapPointersImag[bin][chIdx] ); free( ( *hReverb )->outputBufferReal[bin][chIdx] ); free( ( *hReverb )->outputBufferImag[bin][chIdx] ); +#ifdef IVAS_FLOAT_FIXED + free( ( *hReverb )->tapPointersReal_fx[bin][chIdx] ); + free( ( *hReverb )->tapPointersImag_fx[bin][chIdx] ); + free( ( *hReverb )->outputBufferReal_fx[bin][chIdx] ); + free( ( *hReverb )->outputBufferImag_fx[bin][chIdx] ); +#endif } free( ( *hReverb )->loopBufReal[bin] ); free( ( *hReverb )->loopBufImag[bin] ); +#ifdef IVAS_FLOAT_FIXED + free( ( *hReverb )->loopBufReal_fx[bin] ); + free( ( *hReverb )->loopBufImag_fx[bin] ); +#endif } free( ( *hReverb ) ); diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index e9810c293..ccd4b7431 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -745,7 +745,7 @@ void rotateFrame_sd( gains_fx[ch_in][ch_in] = ONE_IN_Q28; /* skip LFE */ - IF ( ch_in == index_lfe ) + IF( ch_in == index_lfe ) { continue; } @@ -756,7 +756,7 @@ void rotateFrame_sd( /* gains for previous subframe rotation */ 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 ) ) { azimuth_fx = (Word32) azimuth * ONE_IN_Q22; elevation_fx = (Word32) elevation * ONE_IN_Q22; @@ -780,7 +780,7 @@ void rotateFrame_sd( /* gains for current subframe rotation */ 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 ) ) { azimuth_fx = (Word32) azimuth * ONE_IN_Q22; @@ -820,7 +820,7 @@ void rotateFrame_sd( } /* move Rmat to Rmat_prev */ - FOR ( i = 0; i < 3; i++ ) + FOR( i = 0; i < 3; i++ ) { mvr2r_Word32( hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx][i], @@ -828,7 +828,7 @@ void rotateFrame_sd( 3 ); } /* copy to output */ - FOR ( ch_out = 0; ch_out < nchan; ch_out++ ) + FOR( ch_out = 0; ch_out < nchan; ch_out++ ) { mvr2r_Word32( &output_tmp_fx[ch_out][subframe_idx * subframe_len], &output[ch_out][subframe_idx * subframe_len], subframe_len ); } @@ -1168,7 +1168,7 @@ void rotateFrame_shd_cldfb( return; } #endif - +#ifndef IVAS_FLOAT_FIXED /*------------------------------------------------------------------------- * rotateFrame_sd_cldfb() * @@ -1275,7 +1275,116 @@ void rotateFrame_sd_cldfb( return; } +#else +/*------------------------------------------------------------------------- + * rotateFrame_sd_cldfb() + * + * Apply rotation to signals in Spatial Domain and in CLDFB + *------------------------------------------------------------------------*/ + +void rotateFrame_sd_cldfb_fixed( + Word32 Rmat_fx[3][3], /* i : real-space rotation matrix (Q30) */ + 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 */ + const IVAS_OUTPUT_SETUP_HANDLE hOutputSetup, /* i : output format setup number of channels */ + const EFAP_HANDLE hEFAPdata, /* i : EFAP structure */ + const int16_t numTimeSlots, /* i : number of time slots to process */ + const int16_t nb_band /* i : number of CLDFB bands to process */ +) +{ + int16_t iBlock, iBand, m, n; + Word32 gains_fx[MAX_CICP_CHANNELS - 1][MAX_CICP_CHANNELS - 1]; + int16_t azimuth, elevation; + Word32 g1_fx; + Word32 realRot_fx[MAX_CICP_CHANNELS - 1][MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX]; + Word32 imagRot_fx[MAX_CICP_CHANNELS - 1][MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX]; + Word32 *p_realRot_fx, *p_imagRot_fx; + Word32 *p_real_fx, *p_imag_fx; + int16_t nInChannels; + int16_t isPlanar; + push_wmops( "rotateFrame_sd_cldfb" ); + + nInChannels = hOutputSetup->nchan_out_woLFE; + isPlanar = 1; + FOR( n = 0; n < nInChannels; n++ ) + { + IF( hOutputSetup->ls_elevation[n] != 0 ) + { + isPlanar = 0; + break; + } + } + + /* rotation of Euler angles */ + FOR( n = 0; n < nInChannels; n++ ) + { + //rotateAziEle( hOutputSetup->ls_azimuth[n], hOutputSetup->ls_elevation[n], &azimuth, &elevation, Rmat, isPlanar ); + rotateAziEle_fx( (Word16) hOutputSetup->ls_azimuth[n], (Word16) hOutputSetup->ls_elevation[n], &azimuth, &elevation, Rmat_fx, isPlanar ); + IF( hEFAPdata != NULL && ( hOutputSetup->ls_azimuth[n] != azimuth || hOutputSetup->ls_elevation[n] != elevation ) ) + { + //efap_determine_gains( hEFAPdata, gains[n], azimuth, elevation, EFAP_MODE_EFAP ); + efap_determine_gains_fixed( hEFAPdata, gains_fx[n], L_shl( azimuth, Q22 ), L_shl( elevation, Q22 ), EFAP_MODE_EFAP ); + } + ELSE + { + set_l( gains_fx[n], 0, nInChannels ); + gains_fx[n][n] = 0x7fffffff; + } + } + + /* Apply panning gains by mtx multiplication*/ + FOR( n = 0; n < nInChannels; n++ ) + { + set_l( realRot_fx[n], 0, MAX_PARAM_SPATIAL_SUBFRAMES * nb_band ); + set_l( imagRot_fx[n], 0, MAX_PARAM_SPATIAL_SUBFRAMES * nb_band ); + FOR( m = 0; m < nInChannels; m++ ) + { + g1_fx = gains_fx[m][n]; + p_realRot_fx = realRot_fx[n]; + p_imagRot_fx = imagRot_fx[n]; + IF( GT_32( g1_fx, 0 ) ) + { + FOR( iBlock = 0; iBlock < numTimeSlots; iBlock++ ) + { + p_real_fx = Cldfb_RealBuffer[m][iBlock]; + p_imag_fx = Cldfb_ImagBuffer[m][iBlock]; + FOR( iBand = 0; iBand < nb_band; iBand++ ) + { + *( p_realRot_fx ) = *p_realRot_fx + Mpy_32_32( g1_fx, *( p_real_fx++ ) ); + *( p_imagRot_fx ) = *p_imagRot_fx + Mpy_32_32( g1_fx, *( p_imag_fx++ ) ); + p_realRot_fx++; + p_imagRot_fx++; + } + } + } + } + } + FOR( n = 0; n < nInChannels; n++ ) + { + p_realRot_fx = realRot_fx[n]; + p_imagRot_fx = imagRot_fx[n]; + FOR( iBlock = 0; iBlock < numTimeSlots; iBlock++ ) + { + p_real_fx = Cldfb_RealBuffer[n][iBlock]; + p_imag_fx = Cldfb_ImagBuffer[n][iBlock]; + FOR( iBand = 0; iBand < nb_band; iBand++ ) + { + *( p_real_fx++ ) = *( p_realRot_fx++ ); + *( p_imag_fx++ ) = *( p_imagRot_fx++ ); + } + FOR( ; iBand < CLDFB_NO_CHANNELS_MAX; iBand++ ) + { + *( p_real_fx++ ) = 0; + *( p_imag_fx++ ) = 0; + } + } + } + pop_wmops(); + + return; +} +#endif /*-----------------------------------------------------------------------* * ivas_external_orientation_open() @@ -2142,7 +2251,7 @@ static Word32 SHrot_w_fx( #ifdef IVAS_FLOAT_FIXED /*------------------------------------------------------------------------- - * rotateFrame_sd_cldfb() + * SHrotmatgen_fx() * * *------------------------------------------------------------------------*/ @@ -2255,7 +2364,7 @@ void SHrotmatgen_fx( } #else /*------------------------------------------------------------------------- - * rotateFrame_sd_cldfb() + * SHrotmatgen() * * *------------------------------------------------------------------------*/ @@ -2407,7 +2516,7 @@ void ivas_combined_orientation_set_to_start_index( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ ) { - IF ( hCombinedOrientationData != NULL ) + IF( hCombinedOrientationData != NULL ) { hCombinedOrientationData->subframe_idx = hCombinedOrientationData->subframe_idx_start; move16(); @@ -2447,12 +2556,12 @@ void ivas_combined_orientation_set_to_start_index( void ivas_combined_orientation_update_start_index( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientation handle */ - const Word16 samples_rendered /* i : samples rendered since the last call */ + const Word16 samples_rendered /* i : samples rendered since the last call */ ) { - IF ( hCombinedOrientationData != NULL ) + IF( hCombinedOrientationData != NULL ) { - IF ( hCombinedOrientationData->num_subframes == 1 ) + IF( hCombinedOrientationData->num_subframes == 1 ) { /* only one orientation available anyway or split rendering with low resolution*/ hCombinedOrientationData->subframe_idx = 0; diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index cea26b77a..9afb1529b 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -438,7 +438,11 @@ typedef struct ivas_dirac_rend_data_structure float *frequency_axis; float *diffuse_response_function; float *hoa_encoder; +#ifndef IVAS_FLOAT_FIXED const float *hoa_decoder; +#else + const Word32 *hoa_decoder; +#endif /*Decoder parameters */ /*Prototypes*/ @@ -554,6 +558,22 @@ typedef struct ivas_binaural_reverb_struct float *outputBufferReal[CLDFB_NO_CHANNELS_MAX][BINAURAL_CHANNELS]; float *outputBufferImag[CLDFB_NO_CHANNELS_MAX][BINAURAL_CHANNELS]; +#ifdef IVAS_FLOAT_FIXED + Word32 *loopBufReal_fx[CLDFB_NO_CHANNELS_MAX]; + Word32 *loopBufImag_fx[CLDFB_NO_CHANNELS_MAX]; + Word32 preDelayBufferReal_fx[REVERB_PREDELAY_MAX + 1][CLDFB_NO_CHANNELS_MAX]; + Word32 preDelayBufferImag_fx[REVERB_PREDELAY_MAX + 1][CLDFB_NO_CHANNELS_MAX]; + Word32 **tapPointersReal_fx[CLDFB_NO_CHANNELS_MAX][BINAURAL_CHANNELS]; + Word32 **tapPointersImag_fx[CLDFB_NO_CHANNELS_MAX][BINAURAL_CHANNELS]; + + Word32 binauralCoherenceCrossmixGains_fx[CLDFB_NO_CHANNELS_MAX]; + Word32 binauralCoherenceDirectGains_fx[CLDFB_NO_CHANNELS_MAX]; + Word32 reverbEqGains_fx[CLDFB_NO_CHANNELS_MAX]; + Word32 loopAttenuationFactor_fx[CLDFB_NO_CHANNELS_MAX]; + + Word32 *outputBufferReal_fx[CLDFB_NO_CHANNELS_MAX][BINAURAL_CHANNELS]; + Word32 *outputBufferImag_fx[CLDFB_NO_CHANNELS_MAX][BINAURAL_CHANNELS]; +#endif int16_t numBins; int16_t useBinauralCoherence; @@ -569,8 +589,13 @@ typedef struct ivas_binaural_reverb_struct uint32_t binRend_RandNext; int16_t highestBinauralCoherenceBin; +#ifndef IVAS_FLOAT_FIXED float dmxmtx[BINAURAL_CHANNELS][MAX_OUTPUT_CHANNELS]; float foa_enc[MAX_OUTPUT_CHANNELS][FOA_CHANNELS]; +#else + Word32 dmxmtx_fx[BINAURAL_CHANNELS][MAX_OUTPUT_CHANNELS]; + Word32 foa_enc_fx[MAX_OUTPUT_CHANNELS][FOA_CHANNELS]; +#endif } REVERB_STRUCT, *REVERB_STRUCT_HANDLE; @@ -626,7 +651,7 @@ typedef struct ivas_dirac_dec_binaural_data_structure HANDLE_DIRAC_DECORR_STATE h_freq_domain_decorr_ap_state; } DIRAC_DEC_BIN_DATA, *DIRAC_DEC_BIN_HANDLE; - +#ifndef IVAS_FLOAT_FIXED typedef struct ivas_binaural_rendering_conv_module_struct { float ***filterTapsLeftReal; @@ -641,7 +666,23 @@ typedef struct ivas_binaural_rendering_conv_module_struct int16_t numTaps; } BINRENDERER_CONV_MODULE, *BINRENDERER_CONV_MODULE_HANDLE; +#else +typedef struct ivas_binaural_rendering_conv_module_struct_fx +{ + Word32 ***filterTapsLeftReal_fx; + Word32 ***filterTapsLeftImag_fx; + Word32 ***filterTapsRightReal_fx; + Word32 ***filterTapsRightImag_fx; + + Word32 ***filterStatesLeftReal_fx; + Word32 ***filterStatesLeftImag_fx; + Word16 ***Q_filterStatesLeft; + + int16_t numTapsArray[BINAURAL_CONVBANDS]; + int16_t numTaps; +} BINRENDERER_CONV_MODULE_FX, *BINRENDERER_CONV_MODULE_HANDLE_FX; +#endif /*----------------------------------------------------------------------------------* * EFAP structures @@ -1824,7 +1865,11 @@ typedef struct ivas_masa_external_rendering_struct REVERB_STRUCT_HANDLE hReverb; HRTFS_PARAMBIN_HANDLE hHrtfParambin; VBAP_HANDLE hVBAPdata; +#ifndef IVAS_FLOAT_FIXED float *hoa_dec_mtx; +#else + Word32 *hoa_dec_mtx; +#endif HANDLE_CLDFB_FILTER_BANK cldfbAnaRend[MASA_MAX_TRANSPORT_CHANNELS]; HANDLE_CLDFB_FILTER_BANK cldfbSynRend[MAX_OUTPUT_CHANNELS]; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index a4cd1a9fb..4b43af333 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -2667,7 +2667,11 @@ static ivas_error initSbaPanGainsForMcOut( { int16_t ambiOrderIn; int16_t chInIdx, chOutIdx; +#ifndef IVAS_FLOAT_FIXED float *tmpDecMtx, *readPtr; +#else + Word32 *tmpDecMtx, *readPtr; +#endif IVAS_OUTPUT_SETUP hOutSetup; ivas_error error; @@ -2721,7 +2725,11 @@ static ivas_error initSbaPanGainsForMcOut( { continue; /* nothing to be rendered to LFE */ } +#ifndef IVAS_FLOAT_FIXED inputSba->hoaDecMtx[chInIdx][chOutIdx] = *readPtr++; +#else + inputSba->hoaDecMtx[chInIdx][chOutIdx] = ( (float) *readPtr++ ) / ONE_IN_Q29; +#endif } } -- GitLab