Loading apps/renderer.c +105 −3 Original line number Diff line number Diff line Loading @@ -643,6 +643,7 @@ int main( #ifdef IVAS_FLOAT_FIXED Word32 *outInt32Buffer; Word32 *inInt32Buffer; Word32 gain_fx; #endif float *outFloatBuffer; IVAS_REND_AudioBuffer inBuffer; Loading Loading @@ -933,7 +934,9 @@ int main( } IVAS_REND_LfePanMtx lfePanMatrix; #ifdef IVAS_FLOAT_FIXED IVAS_REND_LfePanMtx_fx lfePanMatrix_fx; #endif /* parse input LFE panning matrix */ if ( args.lfeCustomRoutingEnabled && !isEmptyString( args.inLfePanningMatrixFile ) ) { Loading Loading @@ -968,6 +971,7 @@ int main( for ( i = 0; i < args.inConfig.numMultiChannelBuses; ++i ) { #ifndef IVAS_FLOAT_FIXED if ( ( error = IVAS_REND_AddInput( hIvasRend, args.inConfig.multiChannelBuses[i].audioConfig, &mcIds[i] ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); Loading @@ -979,6 +983,21 @@ int main( fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } #else IF( ( error = IVAS_REND_AddInput_fx( hIvasRend, args.inConfig.multiChannelBuses[i].audioConfig, &mcIds[i] ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } gain_fx = (Word32) ( ( args.inputGainGlobal * dBToLin( args.inConfig.multiChannelBuses[i].gain_dB ) ) * ( 1u << 30 ) ); IF ((error = IVAS_REND_SetInputGain_fx(hIvasRend, mcIds[i], gain_fx)) != IVAS_ERR_OK) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } #endif if ( args.inConfig.multiChannelBuses[i].audioConfig == IVAS_AUDIO_CONFIG_LS_CUSTOM ) { Loading @@ -998,7 +1017,16 @@ int main( args.lfePanningEnabled = false; } #ifdef IVAS_FLOAT_FIXED FOR( Word16 k = 0; k < IVAS_MAX_OUTPUT_CHANNELS; k++ ) { ( *lfePanMatrix_fx )[k] = (Word32) ( ( *lfePanMatrix )[k] * ( 1u << 31 ) ); } IF ( ( error = IVAS_REND_SetInputLfeMtx_fx( hIvasRend, mcIds[i], (const IVAS_REND_LfePanMtx_fx *) &lfePanMatrix_fx ) ) != IVAS_ERR_OK ) #else if ( ( error = IVAS_REND_SetInputLfeMtx( hIvasRend, mcIds[i], (const IVAS_REND_LfePanMtx *) &lfePanMatrix ) ) != IVAS_ERR_OK ) #endif // IVAS_FLOAT_FIXED { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); Loading @@ -1007,7 +1035,12 @@ int main( /* set panning gains for input LFE */ else if ( args.lfePanningEnabled ) { #ifdef IVAS_FLOAT_FIXED Word32 inputGain = (Word32) ( args.lfeConfigGain * ( 1u << 31 ) ); IF( ( error = IVAS_REND_SetInputLfePos_fx( hIvasRend, mcIds[i], inputGain, (Word16) args.lfeConfigAzimuth, (Word16) args.lfeConfigElevation ) ) != IVAS_ERR_OK ) #else if ( ( error = IVAS_REND_SetInputLfePos( hIvasRend, mcIds[i], args.lfeConfigGain, args.lfeConfigAzimuth, args.lfeConfigElevation ) ) != IVAS_ERR_OK ) #endif // IVAS_FLOAT_FIXED { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); Loading @@ -1027,7 +1060,16 @@ int main( exit( -1 ); } #ifdef IVAS_FLOAT_FIXED FOR( Word16 k = 0; k < IVAS_MAX_OUTPUT_CHANNELS; k++ ) { ( *lfePanMatrix_fx )[k] = (Word32) ( ( *lfePanMatrix )[k] * ( 1u << 31 ) ); } if ( ( error = IVAS_REND_SetInputLfeMtx_fx( hIvasRend, mcIds[i], (const IVAS_REND_LfePanMtx_fx *) &lfePanMatrix_fx ) ) != IVAS_ERR_OK ) #else if ( ( error = IVAS_REND_SetInputLfeMtx( hIvasRend, mcIds[i], (const IVAS_REND_LfePanMtx *) &lfePanMatrix ) ) != IVAS_ERR_OK ) #endif // IVAS_FLOAT_FIXED { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); Loading @@ -1036,7 +1078,12 @@ int main( /* set position based gains */ else { #ifdef IVAS_FLOAT_FIXED Word32 inputGain = (Word32) ( lfeRoutingConfigs[i]->lfe_gain_dB * ( 1u << 31 ) ); IF( ( error = IVAS_REND_SetInputLfePos_fx( hIvasRend, mcIds[i], inputGain, (Word16) lfeRoutingConfigs[i]->lfe_azi, (Word16) lfeRoutingConfigs[i]->lfe_ele ) ) != IVAS_ERR_OK ) #else if ( ( error = IVAS_REND_SetInputLfePos( hIvasRend, mcIds[i], lfeRoutingConfigs[i]->lfe_gain_dB, lfeRoutingConfigs[i]->lfe_azi, lfeRoutingConfigs[i]->lfe_ele ) ) != IVAS_ERR_OK ) #endif // IVAS_FLOAT_FIXED { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); Loading @@ -1046,6 +1093,7 @@ int main( } } #ifndef IVAS_FLOAT_FIXED for ( i = 0; i < args.inConfig.numAudioObjects; ++i ) { if ( ( error = IVAS_REND_AddInput( hIvasRend, IVAS_AUDIO_CONFIG_OBA, &ismIds[i] ) ) != IVAS_ERR_OK ) Loading Loading @@ -1082,7 +1130,6 @@ int main( } } for ( i = 0; i < args.inConfig.numMasaBuses; ++i ) { if ( ( error = IVAS_REND_AddInput( hIvasRend, args.inConfig.masaBuses[i].audioConfig, &masaIds[i] ) ) != IVAS_ERR_OK ) Loading @@ -1097,6 +1144,61 @@ int main( exit( -1 ); } } #else FOR ( i = 0; i < args.inConfig.numAudioObjects; ++i ) { IF( ( error = IVAS_REND_AddInput_fx( hIvasRend, IVAS_AUDIO_CONFIG_OBA, &ismIds[i] ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } gain_fx = (Word32) ( args.inputGainGlobal * dBToLin( args.inConfig.audioObjects[i].gain_dB ) * ( 1u << 30 ) ); IF( ( error = IVAS_REND_SetInputGain_fx( hIvasRend, ismIds[i], gain_fx) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } /* With MASA output, all objects are handled at once, so add only one input having all objects in it */ IF ( EQ_32(args.outConfig.audioConfig, IVAS_AUDIO_CONFIG_MASA1) || EQ_32(args.outConfig.audioConfig, IVAS_AUDIO_CONFIG_MASA2) ) { BREAK; } } FOR ( i = 0; i < args.inConfig.numAmbisonicsBuses; ++i ) { IF( ( error = IVAS_REND_AddInput_fx( hIvasRend, args.inConfig.ambisonicsBuses[i].audioConfig, &sbaIds[i] ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } gain_fx = (Word32) ( args.inputGainGlobal * dBToLin( args.inConfig.ambisonicsBuses[i].gain_dB ) * ( 1u << 30 ) ); IF ( ( error = IVAS_REND_SetInputGain_fx( hIvasRend, sbaIds[i], gain_fx ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } } FOR ( i = 0; i < args.inConfig.numMasaBuses; ++i ) { IF( ( error = IVAS_REND_AddInput_fx( hIvasRend, args.inConfig.masaBuses[i].audioConfig, &masaIds[i] ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } gain_fx = (Word32) ( ( args.inputGainGlobal * dBToLin( args.inConfig.masaBuses[i].gain_dB ) ) * ( 1u << 30 ) ); IF ( ( error = IVAS_REND_SetInputGain_fx( hIvasRend, masaIds[i], gain_fx) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } } #endif // !IVAS_FLOAT_FIXED const int16_t totalNumInChannels = getTotalNumInChannels( hIvasRend, mcIds, ismIds, sbaIds, masaIds ); Loading lib_com/fft_fx.c +18 −0 Original line number Diff line number Diff line Loading @@ -5467,6 +5467,24 @@ Word16 L_norm_arr( Word32 *arr, Word16 size ) return q; } Word16 get_min_scalefactor( Word32 x, Word32 y ) { Word16 scf = Q31; IF( EQ_32( x, 0 ) && EQ_32( y, 0 ) ) { return 0; } IF( NE_32( x, 0 ) ) { scf = s_min( scf, norm_l( x ) ); } IF( NE_32( y, 0 ) ) { scf = s_min( scf, norm_l( y ) ); } return scf; } #if 0 /* Functions are already in fixed point and available in fft.c file */ Loading lib_com/ivas_prot.h +6 −1 Original line number Diff line number Diff line Loading @@ -6451,10 +6451,15 @@ void ivas_spar_param_to_masa_param_mapping_fx( /*---------------------------------------------------------------------------------* * Binaural FastConv Renderer Prototypes *-----------------------------------------------------------------------------------*/ #ifdef IVAS_FLOAT_FIXED ivas_error ivas_binRenderer_open_fx( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ); #else ivas_error ivas_binRenderer_open( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ); #endif void ivas_binRenderer_close( BINAURAL_RENDERER_HANDLE *hBinRenderer /* i/o: decoder binaural renderer handle */ Loading lib_com/prot_fx2.h +2 −0 Original line number Diff line number Diff line Loading @@ -4254,6 +4254,8 @@ Word16 find_guarded_bits_fx(Word32 n); Word16 L_norm_arr(Word32* arr, Word16 size); Word16 get_min_scalefactor( Word32 x, Word32 y ); void edct2_fx_ivas( const Word16 n, const Word16 isgn, Loading lib_dec/ivas_binRenderer_internal.c +188 −13 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ #ifdef IVAS_FLOAT_FIXED #include "prot_fx1.h" #include "prot_fx2.h" #include "ivas_rom_com_fx.h" #include "debug.h" #define float_to_fix( n, factor ) ( round( n * ( 1 << factor ) ) ) #define float_to_fixQ29( n ) float_to_fix( n, Q29 ) Loading Loading @@ -1601,8 +1602,8 @@ static void ivas_binaural_obtain_DMX_fx( * * Open fastconv binaural renderer handle *-------------------------------------------------------------------------*/ ivas_error ivas_binRenderer_open( #ifdef IVAS_FLOAT_FIXED ivas_error ivas_binRenderer_open_fx( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ) { Loading Loading @@ -1683,7 +1684,7 @@ ivas_error ivas_binRenderer_open( 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_fx( out_setup, &st_ivas->hoa_dec_mtx, st_ivas->hIntSetup.ambisonics_order ) ) != IVAS_ERR_OK ) { return error; } Loading Loading @@ -1746,11 +1747,7 @@ ivas_error ivas_binRenderer_open( { 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 } } } Loading @@ -1767,17 +1764,13 @@ ivas_error ivas_binRenderer_open( { 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], hBinRenderer->hReverb->foa_enc_fx[k], 1 ); ivas_dirac_dec_get_response_fixed( (Word16) L_shr_r( ls_azimuth_CICP19_fx[k], 22 ), (Word16) L_shr_r( ls_elevation_CICP19_fx[k], 22 ), 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 ) ) { 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_fx( &( st_ivas->hEFAPdata ), st_ivas->hIntSetup.ls_azimuth_fx, st_ivas->hIntSetup.ls_elevation_fx, st_ivas->hIntSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) { return error; } Loading @@ -1792,7 +1785,189 @@ ivas_error ivas_binRenderer_open( return error; } #else ivas_error ivas_binRenderer_open( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ) { BINAURAL_RENDERER_HANDLE hBinRenderer; int16_t convBand, chIdx, k; ivas_error error; error = IVAS_ERR_OK; /*-----------------------------------------------------------------* * prepare library opening *-----------------------------------------------------------------*/ 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" ) ); } hBinRenderer->hInputSetup = &st_ivas->hIntSetup; /* 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 ) { hBinRenderer->rotInCldfb = 1; } /* 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 ) { hBinRenderer->ivas_format = MC_FORMAT; } else { hBinRenderer->ivas_format = SBA_FORMAT; } hBinRenderer->max_band = (int16_t) ( ( BINAURAL_MAXBANDS * st_ivas->hDecoderConfig->output_Fs ) / 48000 ); convBand = hBinRenderer->max_band; hBinRenderer->timeSlots = MAX_PARAM_SPATIAL_SUBFRAMES; /* Corresponds to 5 msec sound to motion latency */ if ( convBand > BINAURAL_CONVBANDS ) { hBinRenderer->conv_band = BINAURAL_CONVBANDS; } else { hBinRenderer->conv_band = convBand; } /*LFE rendering switched off by default*/ hBinRenderer->render_lfe = 0; 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 ) { return error; } 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 ) { return error; } ivas_output_init( &out_setup, IVAS_AUDIO_CONFIG_7_1_4 ); 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 ) { return error; } } hBinRenderer->hoa_dec_mtx = st_ivas->hoa_dec_mtx; st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_BRIR_latency_s * 1000000000.f ); } 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 ) { return error; } if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) { 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 ) { st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_HOA3_latency_s * 1000000000.f ); } 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 ) { st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_FOA_latency_s * 1000000000.f ); } else { return IVAS_ERR_INVALID_INPUT_FORMAT; } } } else { /* same value for MC or HOA both use MC BRIR*/ st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_BRIR_latency_s * 1000000000.f ); } } /* 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 ( ( 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 ( k = 0; k < hBinRenderer->nInChannels; k++ ) { hBinRenderer->hReverb->dmxmtx[chIdx][k] = dmxmtx_table[chIdx][k]; } } } else { hBinRenderer->hReverb = NULL; } hBinRenderer->hEFAPdata = NULL; if ( hBinRenderer->hReverb != NULL ) { if ( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 ) { for ( k = 0; k < 11; k++ ) { ivas_dirac_dec_get_response( (int16_t) ls_azimuth_CICP19[k], (int16_t) ls_elevation_CICP19[k], hBinRenderer->hReverb->foa_enc[k], 1 ); } } 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 ) { return error; } /* Copy handles to bin renderer handle*/ hBinRenderer->hEFAPdata = st_ivas->hEFAPdata; } } /* Copy the handles to main handle */ st_ivas->hBinRenderer = hBinRenderer; return error; } #endif /*------------------------------------------------------------------------- * ivas_binRenderer_convModuleClose() Loading Loading
apps/renderer.c +105 −3 Original line number Diff line number Diff line Loading @@ -643,6 +643,7 @@ int main( #ifdef IVAS_FLOAT_FIXED Word32 *outInt32Buffer; Word32 *inInt32Buffer; Word32 gain_fx; #endif float *outFloatBuffer; IVAS_REND_AudioBuffer inBuffer; Loading Loading @@ -933,7 +934,9 @@ int main( } IVAS_REND_LfePanMtx lfePanMatrix; #ifdef IVAS_FLOAT_FIXED IVAS_REND_LfePanMtx_fx lfePanMatrix_fx; #endif /* parse input LFE panning matrix */ if ( args.lfeCustomRoutingEnabled && !isEmptyString( args.inLfePanningMatrixFile ) ) { Loading Loading @@ -968,6 +971,7 @@ int main( for ( i = 0; i < args.inConfig.numMultiChannelBuses; ++i ) { #ifndef IVAS_FLOAT_FIXED if ( ( error = IVAS_REND_AddInput( hIvasRend, args.inConfig.multiChannelBuses[i].audioConfig, &mcIds[i] ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); Loading @@ -979,6 +983,21 @@ int main( fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } #else IF( ( error = IVAS_REND_AddInput_fx( hIvasRend, args.inConfig.multiChannelBuses[i].audioConfig, &mcIds[i] ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } gain_fx = (Word32) ( ( args.inputGainGlobal * dBToLin( args.inConfig.multiChannelBuses[i].gain_dB ) ) * ( 1u << 30 ) ); IF ((error = IVAS_REND_SetInputGain_fx(hIvasRend, mcIds[i], gain_fx)) != IVAS_ERR_OK) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } #endif if ( args.inConfig.multiChannelBuses[i].audioConfig == IVAS_AUDIO_CONFIG_LS_CUSTOM ) { Loading @@ -998,7 +1017,16 @@ int main( args.lfePanningEnabled = false; } #ifdef IVAS_FLOAT_FIXED FOR( Word16 k = 0; k < IVAS_MAX_OUTPUT_CHANNELS; k++ ) { ( *lfePanMatrix_fx )[k] = (Word32) ( ( *lfePanMatrix )[k] * ( 1u << 31 ) ); } IF ( ( error = IVAS_REND_SetInputLfeMtx_fx( hIvasRend, mcIds[i], (const IVAS_REND_LfePanMtx_fx *) &lfePanMatrix_fx ) ) != IVAS_ERR_OK ) #else if ( ( error = IVAS_REND_SetInputLfeMtx( hIvasRend, mcIds[i], (const IVAS_REND_LfePanMtx *) &lfePanMatrix ) ) != IVAS_ERR_OK ) #endif // IVAS_FLOAT_FIXED { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); Loading @@ -1007,7 +1035,12 @@ int main( /* set panning gains for input LFE */ else if ( args.lfePanningEnabled ) { #ifdef IVAS_FLOAT_FIXED Word32 inputGain = (Word32) ( args.lfeConfigGain * ( 1u << 31 ) ); IF( ( error = IVAS_REND_SetInputLfePos_fx( hIvasRend, mcIds[i], inputGain, (Word16) args.lfeConfigAzimuth, (Word16) args.lfeConfigElevation ) ) != IVAS_ERR_OK ) #else if ( ( error = IVAS_REND_SetInputLfePos( hIvasRend, mcIds[i], args.lfeConfigGain, args.lfeConfigAzimuth, args.lfeConfigElevation ) ) != IVAS_ERR_OK ) #endif // IVAS_FLOAT_FIXED { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); Loading @@ -1027,7 +1060,16 @@ int main( exit( -1 ); } #ifdef IVAS_FLOAT_FIXED FOR( Word16 k = 0; k < IVAS_MAX_OUTPUT_CHANNELS; k++ ) { ( *lfePanMatrix_fx )[k] = (Word32) ( ( *lfePanMatrix )[k] * ( 1u << 31 ) ); } if ( ( error = IVAS_REND_SetInputLfeMtx_fx( hIvasRend, mcIds[i], (const IVAS_REND_LfePanMtx_fx *) &lfePanMatrix_fx ) ) != IVAS_ERR_OK ) #else if ( ( error = IVAS_REND_SetInputLfeMtx( hIvasRend, mcIds[i], (const IVAS_REND_LfePanMtx *) &lfePanMatrix ) ) != IVAS_ERR_OK ) #endif // IVAS_FLOAT_FIXED { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); Loading @@ -1036,7 +1078,12 @@ int main( /* set position based gains */ else { #ifdef IVAS_FLOAT_FIXED Word32 inputGain = (Word32) ( lfeRoutingConfigs[i]->lfe_gain_dB * ( 1u << 31 ) ); IF( ( error = IVAS_REND_SetInputLfePos_fx( hIvasRend, mcIds[i], inputGain, (Word16) lfeRoutingConfigs[i]->lfe_azi, (Word16) lfeRoutingConfigs[i]->lfe_ele ) ) != IVAS_ERR_OK ) #else if ( ( error = IVAS_REND_SetInputLfePos( hIvasRend, mcIds[i], lfeRoutingConfigs[i]->lfe_gain_dB, lfeRoutingConfigs[i]->lfe_azi, lfeRoutingConfigs[i]->lfe_ele ) ) != IVAS_ERR_OK ) #endif // IVAS_FLOAT_FIXED { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); Loading @@ -1046,6 +1093,7 @@ int main( } } #ifndef IVAS_FLOAT_FIXED for ( i = 0; i < args.inConfig.numAudioObjects; ++i ) { if ( ( error = IVAS_REND_AddInput( hIvasRend, IVAS_AUDIO_CONFIG_OBA, &ismIds[i] ) ) != IVAS_ERR_OK ) Loading Loading @@ -1082,7 +1130,6 @@ int main( } } for ( i = 0; i < args.inConfig.numMasaBuses; ++i ) { if ( ( error = IVAS_REND_AddInput( hIvasRend, args.inConfig.masaBuses[i].audioConfig, &masaIds[i] ) ) != IVAS_ERR_OK ) Loading @@ -1097,6 +1144,61 @@ int main( exit( -1 ); } } #else FOR ( i = 0; i < args.inConfig.numAudioObjects; ++i ) { IF( ( error = IVAS_REND_AddInput_fx( hIvasRend, IVAS_AUDIO_CONFIG_OBA, &ismIds[i] ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } gain_fx = (Word32) ( args.inputGainGlobal * dBToLin( args.inConfig.audioObjects[i].gain_dB ) * ( 1u << 30 ) ); IF( ( error = IVAS_REND_SetInputGain_fx( hIvasRend, ismIds[i], gain_fx) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } /* With MASA output, all objects are handled at once, so add only one input having all objects in it */ IF ( EQ_32(args.outConfig.audioConfig, IVAS_AUDIO_CONFIG_MASA1) || EQ_32(args.outConfig.audioConfig, IVAS_AUDIO_CONFIG_MASA2) ) { BREAK; } } FOR ( i = 0; i < args.inConfig.numAmbisonicsBuses; ++i ) { IF( ( error = IVAS_REND_AddInput_fx( hIvasRend, args.inConfig.ambisonicsBuses[i].audioConfig, &sbaIds[i] ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } gain_fx = (Word32) ( args.inputGainGlobal * dBToLin( args.inConfig.ambisonicsBuses[i].gain_dB ) * ( 1u << 30 ) ); IF ( ( error = IVAS_REND_SetInputGain_fx( hIvasRend, sbaIds[i], gain_fx ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } } FOR ( i = 0; i < args.inConfig.numMasaBuses; ++i ) { IF( ( error = IVAS_REND_AddInput_fx( hIvasRend, args.inConfig.masaBuses[i].audioConfig, &masaIds[i] ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } gain_fx = (Word32) ( ( args.inputGainGlobal * dBToLin( args.inConfig.masaBuses[i].gain_dB ) ) * ( 1u << 30 ) ); IF ( ( error = IVAS_REND_SetInputGain_fx( hIvasRend, masaIds[i], gain_fx) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } } #endif // !IVAS_FLOAT_FIXED const int16_t totalNumInChannels = getTotalNumInChannels( hIvasRend, mcIds, ismIds, sbaIds, masaIds ); Loading
lib_com/fft_fx.c +18 −0 Original line number Diff line number Diff line Loading @@ -5467,6 +5467,24 @@ Word16 L_norm_arr( Word32 *arr, Word16 size ) return q; } Word16 get_min_scalefactor( Word32 x, Word32 y ) { Word16 scf = Q31; IF( EQ_32( x, 0 ) && EQ_32( y, 0 ) ) { return 0; } IF( NE_32( x, 0 ) ) { scf = s_min( scf, norm_l( x ) ); } IF( NE_32( y, 0 ) ) { scf = s_min( scf, norm_l( y ) ); } return scf; } #if 0 /* Functions are already in fixed point and available in fft.c file */ Loading
lib_com/ivas_prot.h +6 −1 Original line number Diff line number Diff line Loading @@ -6451,10 +6451,15 @@ void ivas_spar_param_to_masa_param_mapping_fx( /*---------------------------------------------------------------------------------* * Binaural FastConv Renderer Prototypes *-----------------------------------------------------------------------------------*/ #ifdef IVAS_FLOAT_FIXED ivas_error ivas_binRenderer_open_fx( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ); #else ivas_error ivas_binRenderer_open( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ); #endif void ivas_binRenderer_close( BINAURAL_RENDERER_HANDLE *hBinRenderer /* i/o: decoder binaural renderer handle */ Loading
lib_com/prot_fx2.h +2 −0 Original line number Diff line number Diff line Loading @@ -4254,6 +4254,8 @@ Word16 find_guarded_bits_fx(Word32 n); Word16 L_norm_arr(Word32* arr, Word16 size); Word16 get_min_scalefactor( Word32 x, Word32 y ); void edct2_fx_ivas( const Word16 n, const Word16 isgn, Loading
lib_dec/ivas_binRenderer_internal.c +188 −13 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ #ifdef IVAS_FLOAT_FIXED #include "prot_fx1.h" #include "prot_fx2.h" #include "ivas_rom_com_fx.h" #include "debug.h" #define float_to_fix( n, factor ) ( round( n * ( 1 << factor ) ) ) #define float_to_fixQ29( n ) float_to_fix( n, Q29 ) Loading Loading @@ -1601,8 +1602,8 @@ static void ivas_binaural_obtain_DMX_fx( * * Open fastconv binaural renderer handle *-------------------------------------------------------------------------*/ ivas_error ivas_binRenderer_open( #ifdef IVAS_FLOAT_FIXED ivas_error ivas_binRenderer_open_fx( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ) { Loading Loading @@ -1683,7 +1684,7 @@ ivas_error ivas_binRenderer_open( 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_fx( out_setup, &st_ivas->hoa_dec_mtx, st_ivas->hIntSetup.ambisonics_order ) ) != IVAS_ERR_OK ) { return error; } Loading Loading @@ -1746,11 +1747,7 @@ ivas_error ivas_binRenderer_open( { 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 } } } Loading @@ -1767,17 +1764,13 @@ ivas_error ivas_binRenderer_open( { 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], hBinRenderer->hReverb->foa_enc_fx[k], 1 ); ivas_dirac_dec_get_response_fixed( (Word16) L_shr_r( ls_azimuth_CICP19_fx[k], 22 ), (Word16) L_shr_r( ls_elevation_CICP19_fx[k], 22 ), 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 ) ) { 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_fx( &( st_ivas->hEFAPdata ), st_ivas->hIntSetup.ls_azimuth_fx, st_ivas->hIntSetup.ls_elevation_fx, st_ivas->hIntSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) { return error; } Loading @@ -1792,7 +1785,189 @@ ivas_error ivas_binRenderer_open( return error; } #else ivas_error ivas_binRenderer_open( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ) { BINAURAL_RENDERER_HANDLE hBinRenderer; int16_t convBand, chIdx, k; ivas_error error; error = IVAS_ERR_OK; /*-----------------------------------------------------------------* * prepare library opening *-----------------------------------------------------------------*/ 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" ) ); } hBinRenderer->hInputSetup = &st_ivas->hIntSetup; /* 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 ) { hBinRenderer->rotInCldfb = 1; } /* 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 ) { hBinRenderer->ivas_format = MC_FORMAT; } else { hBinRenderer->ivas_format = SBA_FORMAT; } hBinRenderer->max_band = (int16_t) ( ( BINAURAL_MAXBANDS * st_ivas->hDecoderConfig->output_Fs ) / 48000 ); convBand = hBinRenderer->max_band; hBinRenderer->timeSlots = MAX_PARAM_SPATIAL_SUBFRAMES; /* Corresponds to 5 msec sound to motion latency */ if ( convBand > BINAURAL_CONVBANDS ) { hBinRenderer->conv_band = BINAURAL_CONVBANDS; } else { hBinRenderer->conv_band = convBand; } /*LFE rendering switched off by default*/ hBinRenderer->render_lfe = 0; 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 ) { return error; } 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 ) { return error; } ivas_output_init( &out_setup, IVAS_AUDIO_CONFIG_7_1_4 ); 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 ) { return error; } } hBinRenderer->hoa_dec_mtx = st_ivas->hoa_dec_mtx; st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_BRIR_latency_s * 1000000000.f ); } 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 ) { return error; } if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) { 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 ) { st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_HOA3_latency_s * 1000000000.f ); } 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 ) { st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_FOA_latency_s * 1000000000.f ); } else { return IVAS_ERR_INVALID_INPUT_FORMAT; } } } else { /* same value for MC or HOA both use MC BRIR*/ st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_BRIR_latency_s * 1000000000.f ); } } /* 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 ( ( 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 ( k = 0; k < hBinRenderer->nInChannels; k++ ) { hBinRenderer->hReverb->dmxmtx[chIdx][k] = dmxmtx_table[chIdx][k]; } } } else { hBinRenderer->hReverb = NULL; } hBinRenderer->hEFAPdata = NULL; if ( hBinRenderer->hReverb != NULL ) { if ( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 ) { for ( k = 0; k < 11; k++ ) { ivas_dirac_dec_get_response( (int16_t) ls_azimuth_CICP19[k], (int16_t) ls_elevation_CICP19[k], hBinRenderer->hReverb->foa_enc[k], 1 ); } } 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 ) { return error; } /* Copy handles to bin renderer handle*/ hBinRenderer->hEFAPdata = st_ivas->hEFAPdata; } } /* Copy the handles to main handle */ st_ivas->hBinRenderer = hBinRenderer; return error; } #endif /*------------------------------------------------------------------------- * ivas_binRenderer_convModuleClose() Loading