From 1e12de6f9b31ff98c74c378b18ac6e390c6face3 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 16 May 2024 08:36:16 +0530 Subject: [PATCH] lib_rend functions conversion, MSAN fixes in SBA path [x] renderism functions conversion [x] SBA path MSAN error fixes [x] ivas_masa_merge.c BASOP changes --- apps/renderer.c | 12 +- lib_com/cnst.h | 8 + lib_com/common_api_types.h | 4 + lib_com/ivas_cnst.h | 2 + lib_dec/acelp_core_dec_ivas_fx.c | 12 + lib_dec/ivas_jbm_dec.c | 62 +++- lib_rend/ivas_dirac_rend.c | 12 +- lib_rend/ivas_masa_merge.c | 116 +++++- lib_rend/ivas_prot_rend.h | 19 +- lib_rend/ivas_rotation.c | 114 ++++++ lib_rend/lib_rend.c | 586 ++++++++++++++++++++----------- lib_rend/lib_rend.h | 1 + 12 files changed, 736 insertions(+), 212 deletions(-) diff --git a/apps/renderer.c b/apps/renderer.c index af75bcb68..5667a3042 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -1433,8 +1433,11 @@ int main( if ( i == 0 ) { IVAS_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, (int16_t) args.inConfig.audioObjects[i].inputChannelIndex, args.inConfig.numAudioObjects ); - +#ifdef IVAS_FLOAT_FIXED + if ( ( error = IVAS_REND_FeedInputAudio_fx( hIvasRend, ismIds[i], tmpBuffer ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_REND_FeedInputAudio( hIvasRend, ismIds[i], tmpBuffer ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); @@ -1450,9 +1453,12 @@ int main( else { IVAS_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, (int16_t) args.inConfig.audioObjects[i].inputChannelIndex, 1 ); - +#ifdef IVAS_FLOAT_FIXED + if ( ( error = IVAS_REND_FeedInputAudio_fx( hIvasRend, ismIds[i], tmpBuffer ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_REND_FeedInputAudio( hIvasRend, ismIds[i], tmpBuffer ) ) != IVAS_ERR_OK ) - { +#endif + { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 9cf45d203..3d49d2738 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -44,10 +44,18 @@ /* clang-format off */ #ifdef IVAS_FLOAT_FIXED #define MATRIX_CONSTANT (759250113) +#define NUM_SAMPLES_960 (960) +#define NUM_SAMPLES_720 (720) +#define NUM_SAMPLES_320 (320) +#define NUM_SAMPLES_160 (160) #define L_SUBFRAME_48k (240) #define L_SUBFRAME_32k (180) #define L_SUBFRAME_16k (80) #define L_SUBFRAME_8k (40) +#define Q31_BY_NUM_SAMPLES_960 ( 2239294 ) +#define Q31_BY_NUM_SAMPLES_720 ( 2986764 ) +#define Q31_BY_NUM_SAMPLES_320 ( 6731924 ) +#define Q31_BY_NUM_SAMPLES_160 ( 13506186 ) #define Q31_BY_SUB_FRAME_240 ( 8985287 ) #define Q31_BY_SUB_FRAME_180 ( 11997115 ) #define Q31_BY_SUB_FRAME_80 ( 27183337 ) diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index d61457a11..563c51d6d 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -118,6 +118,10 @@ typedef struct _IVAS_ENC_CHANNEL_AWARE_CONFIG typedef struct _IVAS_ISM_METADATA { +#ifdef IVAS_FLOAT_FIXED + Word32 azimuth_fx; + Word32 elevation_fx; +#endif float azimuth; float elevation; float radius; diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index a786807cb..c7b930a31 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -49,6 +49,8 @@ #define _180_OVER_PI ( 180.0f / EVS_PI ) #ifdef IVAS_FLOAT_FIXED #define _180_OVER_PI_Q25 1922527233 +#define _180_IN_Q22 (754974720) +#define _360_IN_Q22 (1509949440) #define _180_OVER_PI_FX (Word32) (( 180.0f / EVS_PI ) *ONE_IN_Q10) #define PI_OVER_180_Q15 ( 572 ) #define _180_OVER_PI_Q9 ( 29335 ) diff --git a/lib_dec/acelp_core_dec_ivas_fx.c b/lib_dec/acelp_core_dec_ivas_fx.c index fea2a55ac..4b1940cff 100644 --- a/lib_dec/acelp_core_dec_ivas_fx.c +++ b/lib_dec/acelp_core_dec_ivas_fx.c @@ -1577,7 +1577,11 @@ ivas_error acelp_core_dec_ivas_fx( q_bpf_error_signal = Q6; +#ifdef MSAN_FIX + Copy_Scale_sig_16_32(bpf_error_signal_16fx, tmp_bpf_error_signal_fx, st->L_frame, q_bpf_error_signal - st->Q_syn); // Q6 +#else Copy_Scale_sig_16_32(bpf_error_signal_16fx, tmp_bpf_error_signal_fx, L_FRAME16k, q_bpf_error_signal - st->Q_syn); // Q6 +#endif for (i = 0; i < CLDFB_NO_COL_MAX; i++) { Scale_sig32(realBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, -Q7); //Q0 @@ -1855,12 +1859,20 @@ ivas_error acelp_core_dec_ivas_fx( ( EQ_16( st->extl, -1 ) || EQ_16( st->extl, SWB_CNG ) || ( EQ_16( st->extl, WB_BWE ) && st->extl_brate == 0 && NE_16( st->coder_type, AUDIO ) ) ) ) ) { Word16 tmp_exp = 0; +#ifdef MSAN_FIX + Copy_Scale_sig_32_16(synth_fx, synth_fx16, output_frame, 0); +#else Copy_Scale_sig_32_16(synth_fx, synth_fx16, L_FRAME48k, 0); +#endif hf_synth_ivas_fx( st->hBWE_zero, st->core_brate, output_frame, Aq_fx, exc_fx, psyn_fx, synth_fx16, st->Q_exc, st->Q_syn2, st->hBWE_zero->delay_syn_hf_fx, &tmp_exp, st->hBWE_zero->mem_hp_interp_fx, st->extl, st->CNG_mode, st->element_mode ); +#ifdef MSAN_FIX + Copy_Scale_sig_16_32(synth_fx16, synth_fx, 0, output_frame); +#else Copy_Scale_sig_16_32(synth_fx16, synth_fx, 0, L_FRAME48k); +#endif IF( st->hBWE_FD != NULL ) { diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index b40f30bc6..8b335e463 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -641,7 +641,36 @@ ivas_error ivas_jbm_dec_tc( } IF( hCPE->hStereoDft != NULL ) { -#ifndef MSAN_FIX_ +#ifdef MSAN_FIX + IF( LE_16( st_ivas->nchan_transport, 1 ) ) + { + st = hCPE->hCoreCoder[0]; + IF( st->core == TCX_20_CORE || st->core == TCX_10_CORE || st->core == HQ_CORE || ( st->bfi == 1 && st->core == ACELP_CORE && st->con_tcx == 1 ) ) + { + IF( ( ( st->last_core != ACELP_CORE || ( st->prev_bfi == 1 && st->last_core == ACELP_CORE && st->last_con_tcx == 1 ) ) && st->last_core != AMR_WB_CORE ) || ( st_ivas->sba_dirac_stereo_flag && st->cng_type == FD_CNG ) ) /* TCX / HQ-CORE -> TCX / HQ-CORE */ + { + scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( hCPE->hCoreCoder[0]->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); + } + ELSE IF( st->core == TCX_20_CORE || st->core == TCX_10_CORE || st->core == HQ_CORE ) /* ACELP -> TCX/HQ */ + { + IF( !st->tcxonly ) + { + scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( hCPE->hCoreCoder[0]->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); + } + } + } + ELSE /* ACELP core */ + { + IF( st->last_core == TCX_20_CORE || st->last_core == TCX_10_CORE || st->last_core == HQ_CORE ) /* TCX/HQ -> ACELP */ + { + IF( ( st->last_L_frame <= L_FRAME16k && st->L_frame <= L_FRAME16k ) || ( st_ivas->sba_dirac_stereo_flag && st->core_brate == SID_2k40 && st->cng_type == FD_CNG ) ) + { + scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( hCPE->hCoreCoder[0]->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); + } + } + } + } +#else scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( 16000, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); #endif scale_sig32( hCPE->hStereoDft->ap_delay_mem_fx, NS2SA( 16000, DELAY_BWE_TOTAL_NS ), sub( hCPE->hStereoDft->q_dft, hCPE->hStereoDft->q_ap_fade_mem_fx ) ); @@ -699,7 +728,36 @@ ivas_error ivas_jbm_dec_tc( } IF( hCPE->hStereoDft != NULL ) { -#ifndef MSAN_FIX_ +#ifdef MSAN_FIX + IF( LE_16( st_ivas->nchan_transport, 1 ) ) + { + st = hCPE->hCoreCoder[0]; + IF( st->core == TCX_20_CORE || st->core == TCX_10_CORE || st->core == HQ_CORE || ( st->bfi == 1 && st->core == ACELP_CORE && st->con_tcx == 1 ) ) + { + IF( ( ( st->last_core != ACELP_CORE || ( st->prev_bfi == 1 && st->last_core == ACELP_CORE && st->last_con_tcx == 1 ) ) && st->last_core != AMR_WB_CORE ) || ( st_ivas->sba_dirac_stereo_flag && st->cng_type == FD_CNG ) ) /* TCX / HQ-CORE -> TCX / HQ-CORE */ + { + scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( hCPE->hCoreCoder[0]->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); + } + ELSE IF( st->core == TCX_20_CORE || st->core == TCX_10_CORE || st->core == HQ_CORE ) /* ACELP -> TCX/HQ */ + { + IF( !st->tcxonly ) + { + scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( hCPE->hCoreCoder[0]->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); + } + } + } + ELSE /* ACELP core */ + { + IF( st->last_core == TCX_20_CORE || st->last_core == TCX_10_CORE || st->last_core == HQ_CORE ) /* TCX/HQ -> ACELP */ + { + IF( ( st->last_L_frame <= L_FRAME16k && st->L_frame <= L_FRAME16k ) || ( st_ivas->sba_dirac_stereo_flag && st->core_brate == SID_2k40 && st->cng_type == FD_CNG ) ) + { + scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( hCPE->hCoreCoder[0]->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); + } + } + } + } +#else scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( 16000, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); #endif scale_sig32( hCPE->hStereoDft->ap_delay_mem_fx, NS2SA( 16000, DELAY_BWE_TOTAL_NS ), sub( Q11, hCPE->hStereoDft->q_ap_fade_mem_fx ) ); diff --git a/lib_rend/ivas_dirac_rend.c b/lib_rend/ivas_dirac_rend.c index ecd3571db..036b71754 100644 --- a/lib_rend/ivas_dirac_rend.c +++ b/lib_rend/ivas_dirac_rend.c @@ -1767,11 +1767,17 @@ ivas_error ivas_dirac_alloc_mem( hDirACRend->h_output_synthesis_psd_state.direct_power_factor = hDirAC_mem->direct_power_factor; hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor = hDirAC_mem->diffuse_power_factor; + set_zero( hDirACRend->h_output_synthesis_psd_state.direct_power_factor, size_pf ); + set_zero( hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor, size_pf ); #ifdef IVAS_FLOAT_FIXED hDirACRend->h_output_synthesis_psd_state.direct_power_factor_fx = hDirAC_mem->direct_power_factor_fx; hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor_fx = hDirAC_mem->diffuse_power_factor_fx; - set_zero(hDirACRend->h_output_synthesis_psd_state.direct_power_factor , size_pf); - set_zero(hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor, size_pf); + set_zero_fx( hDirACRend->h_output_synthesis_psd_state.direct_power_factor_fx, size_pf ); + set_zero_fx( hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor_fx, size_pf ); + hDirACRend->h_output_synthesis_psd_state.direct_power_factor_q = Q31; + move16(); + hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor_q = Q31; + move16(); #endif hDirAC_mem->reference_power = NULL; @@ -1806,6 +1812,7 @@ ivas_error ivas_dirac_alloc_mem( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) ); } #ifdef MSAN_FIX + set_zero( hDirAC_mem->onset_filter, num_outputs_diff * num_freq_bands); set_zero_fx( hDirAC_mem->onset_filter_fx, num_outputs_diff * num_freq_bands ); #endif #endif @@ -1840,6 +1847,7 @@ ivas_error ivas_dirac_alloc_mem( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) ); } #ifdef MSAN_FIX + set_zero( hDirAC_mem->onset_filter, 2 * num_freq_bands ); set_zero_fx( hDirAC_mem->onset_filter_fx, 2 * num_freq_bands ); #endif #endif diff --git a/lib_rend/ivas_masa_merge.c b/lib_rend/ivas_masa_merge.c index 43bead2e1..cce11afee 100644 --- a/lib_rend/ivas_masa_merge.c +++ b/lib_rend/ivas_masa_merge.c @@ -48,12 +48,24 @@ * Local function prototypes *---------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void copy_masa_meta_tile_fx( MASA_DECODER_EXT_OUT_META_HANDLE outMeta, MASA_DECODER_EXT_OUT_META_HANDLE inMeta, const UWord8 sf, const UWord8 band ); +#else static void copy_masa_meta_tile( MASA_DECODER_EXT_OUT_META_HANDLE outMeta, MASA_DECODER_EXT_OUT_META_HANDLE inMeta, const uint8_t sf, const uint8_t band ); +#endif #ifdef IVAS_FLOAT_FIXED static void full_stream_merge_fx( MASA_DECODER_EXT_OUT_META_HANDLE outMeta, MASA_DECODER_EXT_OUT_META_HANDLE inMeta1, Word32 inEne1[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], Word16 *inEne1_e, MASA_DECODER_EXT_OUT_META_HANDLE inMeta2, Word32 inEne2[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], Word16 *inEne2_e ); -static void diffuse_meta_merge_1x1_fx( MASA_DECODER_EXT_OUT_META_HANDLE outMeta, MASA_DECODER_EXT_OUT_META_HANDLE inMeta, Word32 inEne[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], Word16 *inEne1_e, MASA_DECODER_EXT_OUT_META_HANDLE inMetaISM, Word32 inEneISM[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], Word16 *inEne2_e); +static void diffuse_meta_merge_1x1_fx( + MASA_DECODER_EXT_OUT_META_HANDLE outMeta, /* o : Merged metadata output */ + MASA_DECODER_EXT_OUT_META_HANDLE inMeta, /* i : Input metadata 1 */ + Word32 inEne_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : TF-energy of input 1 */ + Word16 *inEne_e, /* i : TF-energy of input 1 */ + MASA_DECODER_EXT_OUT_META_HANDLE inMetaISM, /* i : Input metadata 2 */ + Word32 inEneISM_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : TF-energy of input 2 */ + Word16 *inEneISM_e /* i : TF-energy of input 2 */ +); #else static void full_stream_merge( MASA_DECODER_EXT_OUT_META_HANDLE outMeta, MASA_DECODER_EXT_OUT_META_HANDLE inMeta1, float inEne1[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], MASA_DECODER_EXT_OUT_META_HANDLE inMeta2, float inEne2[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS] ); @@ -67,6 +79,41 @@ static void diffuse_meta_merge_1x1( MASA_DECODER_EXT_OUT_META_HANDLE outMeta, MA * *---------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void copy_masa_meta_tile_fx( + MASA_DECODER_EXT_OUT_META_HANDLE outMeta, /* o : metadata to be written */ + MASA_DECODER_EXT_OUT_META_HANDLE inMeta, /* i : input metadata */ + const UWord8 sf, /* i : sub-frame index */ + const UWord8 band /* i : band index */ +) +{ + outMeta->directionIndex[0][sf][band] = inMeta->directionIndex[0][sf][band]; + move16(); + outMeta->directToTotalRatio[0][sf][band] = inMeta->directToTotalRatio[0][sf][band]; + outMeta->spreadCoherence[0][sf][band] = inMeta->spreadCoherence[0][sf][band]; + + outMeta->surroundCoherence[sf][band] = inMeta->surroundCoherence[sf][band]; + outMeta->diffuseToTotalRatio[sf][band] = inMeta->diffuseToTotalRatio[sf][band]; + + IF ( inMeta->descriptiveMeta.numberOfDirections == 1 ) + { + outMeta->directionIndex[1][sf][band] = inMeta->directionIndex[1][sf][band]; + move16(); + outMeta->directToTotalRatio[1][sf][band] = inMeta->directToTotalRatio[1][sf][band]; + outMeta->spreadCoherence[1][sf][band] = inMeta->spreadCoherence[1][sf][band]; + } + ELSE + { + /* make sure the output has zeroed data in the second direction */ + outMeta->directionIndex[1][sf][band] = SPH_IDX_FRONT; + move16(); + outMeta->directToTotalRatio[1][sf][band] = 0u; + outMeta->spreadCoherence[1][sf][band] = 0u; + } + + return; +} +#else void copy_masa_meta_tile( MASA_DECODER_EXT_OUT_META_HANDLE outMeta, /* o : metadata to be written */ MASA_DECODER_EXT_OUT_META_HANDLE inMeta, /* i : input metadata */ @@ -97,7 +144,7 @@ void copy_masa_meta_tile( return; } - +#endif /*---------------------------------------------------------------------* * copy_masa_descriptive_meta() @@ -105,6 +152,28 @@ void copy_masa_meta_tile( * *---------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void copy_masa_descriptive_meta( + MASA_DECRIPTIVE_META *outMeta, /* o : metadata to be written */ + MASA_DECRIPTIVE_META *inMeta /* i : input metadata */ +) +{ + UWord8 char_idx; + FOR ( char_idx = 0; char_idx < 8; char_idx++ ) + { + outMeta->formatDescriptor[char_idx] = inMeta->formatDescriptor[char_idx]; + } + outMeta->numberOfDirections = inMeta->numberOfDirections; + outMeta->numberOfChannels = inMeta->numberOfChannels; + outMeta->sourceFormat = inMeta->sourceFormat; + outMeta->transportDefinition = inMeta->transportDefinition; + outMeta->channelAngle = inMeta->channelAngle; + outMeta->channelDistance = inMeta->channelDistance; + outMeta->channelLayout = inMeta->channelLayout; + + return; +} +#else void copy_masa_descriptive_meta( MASA_DECRIPTIVE_META *outMeta, /* o : metadata to be written */ MASA_DECRIPTIVE_META *inMeta /* i : input metadata */ @@ -125,7 +194,7 @@ void copy_masa_descriptive_meta( return; } - +#endif /*---------------------------------------------------------------------* * diffuse_meta_merge_1x1() @@ -133,6 +202,7 @@ void copy_masa_descriptive_meta( * *---------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED void diffuse_meta_merge_1x1( MASA_DECODER_EXT_OUT_META_HANDLE outMeta, /* o : Merged metadata output */ MASA_DECODER_EXT_OUT_META_HANDLE inMeta, /* i : Input metadata 1 */ @@ -205,6 +275,7 @@ void diffuse_meta_merge_1x1( return; } +#endif #ifdef IVAS_FLOAT_FIXED @@ -332,6 +403,7 @@ void diffuse_meta_merge_1x1_fx( * *---------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED void full_stream_merge( MASA_DECODER_EXT_OUT_META_HANDLE outMeta, /* o : Merged metadata output */ MASA_DECODER_EXT_OUT_META_HANDLE inMeta1, /* i : Input metadata 1 */ @@ -396,6 +468,7 @@ void full_stream_merge( return; } +#endif #ifdef IVAS_FLOAT_FIXED void full_stream_merge_fx( @@ -451,11 +524,11 @@ void full_stream_merge_fx( IF (BASOP_Util_Cmp_Mant32Exp( dir_nrg_1_fx, dir_nrg_1_e, dir_nrg_2_fx, dir_nrg_2_e ) > 1 ) { - copy_masa_meta_tile( outMeta, inMeta1, sf, band ); + copy_masa_meta_tile_fx( outMeta, inMeta1, sf, band ); } ELSE { - copy_masa_meta_tile( outMeta, inMeta2, sf, band ); + copy_masa_meta_tile_fx( outMeta, inMeta2, sf, band ); } inEne1_fx[sf][band] = BASOP_Util_Add_Mant32Exp(inEne1_fx[sf][band], inEne1_e[sf], inEne2_fx[sf][band], inEne2_e[sf], &in1_e[band]); @@ -505,6 +578,7 @@ void full_stream_merge_fx( * *---------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED void ivas_prerend_merge_masa_metadata( MASA_DECODER_EXT_OUT_META_HANDLE outMeta, /* o : Merged metadata output */ MASA_DECODER_EXT_OUT_META_HANDLE inMeta1, /* i : Input metadata 1 */ @@ -533,6 +607,7 @@ void ivas_prerend_merge_masa_metadata( return; } +#endif #ifdef IVAS_FLOAT_FIXED void ivas_prerend_merge_masa_metadata_fx( @@ -627,7 +702,7 @@ ivas_error masaPrerendOpen( } #else -ivas_error masaPrerendOpen( +ivas_error masaPrerendOpen_fx( MASA_PREREND_HANDLE *hMasaPrerendPtr, /* o : handle to the opened prerenderer */ Word16 numTransports, /* i : number of transport channels */ Word32 input_Fs /* i : signal sampling rate */ @@ -685,6 +760,34 @@ ivas_error masaPrerendOpen( * *---------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void masaPrerendClose_fx( + MASA_PREREND_HANDLE *hMasaPrerendPtr /* i/o: prerenderer handle to be closed */ +) +{ + Word16 i; + + IF ( hMasaPrerendPtr == NULL || *hMasaPrerendPtr == NULL ) + { + return; + } + + FOR ( i = 0; i < ( *hMasaPrerendPtr )->num_Cldfb_instances; i++ ) + { + deleteCldfb_ivas( &( ( *hMasaPrerendPtr )->cldfbAnaEnc[i] ) ); + } + + free( ( *hMasaPrerendPtr )->hMasaOut ); + ( *hMasaPrerendPtr )->hMasaOut = NULL; + free( ( *hMasaPrerendPtr )->sph_grid16 ); + ( *hMasaPrerendPtr )->sph_grid16 = NULL; + + free( ( *hMasaPrerendPtr ) ); + ( *hMasaPrerendPtr ) = NULL; + + return; +} +#else void masaPrerendClose( MASA_PREREND_HANDLE *hMasaPrerendPtr /* i/o: prerenderer handle to be closed */ ) @@ -711,3 +814,4 @@ void masaPrerendClose( return; } +#endif \ No newline at end of file diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 91e724491..ea57f5e9e 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -2309,6 +2309,15 @@ void rotateAziEle_fx( const Word16 isPlanar /* i : is roation planar and elevation meaningless? */ ); +void rotateAziEle_fx_frac_az_el( + Word32 azi_in, /* i : output elevation */ + Word32 ele_in, /* i : input elevation */ + Word32 *azi, /* o : rotated azimuth */ + Word32 *ele, /* o : rotated elevation */ + Word32 Rmat[3][3], /* i : real-space rotation matrix */ + const Word16 isPlanar /* i : is roation planar and elevation meaningless? */ +); + void rotateAziEle_fixed( Word16 azi_in, /* i : output elevation */ Word16 ele_in, /* i : input elevation */ @@ -2780,6 +2789,7 @@ void ivas_dirac_ana_close( ); #endif +#ifndef IVAS_FLOAT_FIXED void ivas_prerend_merge_masa_metadata( MASA_DECODER_EXT_OUT_META_HANDLE outMeta, /* o : Merged metadata output */ MASA_DECODER_EXT_OUT_META_HANDLE inMeta1, /* i : Input metadata 1 */ @@ -2789,6 +2799,7 @@ void ivas_prerend_merge_masa_metadata( IVAS_REND_AudioConfigType inType2, /* i : Type of input 2 */ float inEne2[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS] /* i : TF-energy of input 2 */ ); +#endif #ifdef IVAS_FLOAT_FIXED void ivas_prerend_merge_masa_metadata_fx( @@ -2817,15 +2828,21 @@ ivas_error masaPrerendOpen( ); #else -ivas_error masaPrerendOpen( +ivas_error masaPrerendOpen_fx( MASA_PREREND_HANDLE *hMasaPrerendPtr, /* o : handle to the opened prerenderer */ Word16 numTransports, /* i : number of transport channels */ Word32 input_Fs /* i : signal sampling rate */ ); #endif +#ifndef IVAS_FLOAT_FIXED void masaPrerendClose( MASA_PREREND_HANDLE *hMasaPrerendPtr /* i/o: prerenderer handle to be closed */ ); +#else +void masaPrerendClose_fx( + MASA_PREREND_HANDLE *hMasaPrerendPtr /* i/o: prerenderer handle to be closed */ +); +#endif /* clang-format on */ diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index 20043875f..41dc6a502 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -567,6 +567,120 @@ void rotateAziEle_fx( return; } +/*------------------------------------------------------------------------- + * rotateAziEle_fx_frac_az_el() + * + * Apply rotation to direction parameters azimuth and elevation + *------------------------------------------------------------------------*/ +void rotateAziEle_fx_frac_az_el( + Word32 azi_in, /* i : output elevation */ + Word32 ele_in, /* i : input elevation */ + Word32 *azi, /* o : rotated azimuth */ + Word32 *ele, /* o : rotated elevation */ + Word32 Rmat_fx[3][3], /* i : real-space rotation matrix */ + const Word16 isPlanar /* i : is rotation planar and elevation meaningless? */ +) +{ + Word16 n, radian; // temp_16; + Word32 dv_fx[3], dv_r_fx[3]; + Word16 w_fx; + Word32 temp; + Word32 y, x, sqrt_fx; + Word32 angle; + Word16 azi_in_q13, ele_in_q13; + /*Conversion spherical to cartesian coordinates*/ + IF( GT_32( abs( azi_in ), _180_IN_Q22 ) ) + { + azi_in = GT_32( azi_in, 0 ) ? ( azi_in - _360_IN_Q22 ) : ( azi_in + _360_IN_Q22 ); + move32(); + } + azi_in_q13 = (Word16)L_shr( Mpy_32_32( azi_in, PI_OVER_180_FX ), Q9 ); + ele_in_q13 = (Word16)L_shr( Mpy_32_32( ele_in, PI_OVER_180_FX ), Q9 ); + w_fx = getCosWord16( ele_in_q13 ); // Q14 + dv_fx[0] = L_mult( w_fx, getCosWord16( azi_in_q13 ) ); + IF( EQ_32( dv_fx[0], ONE_IN_Q29 ) ) + { + move32(); + dv_fx[0] = ONE_IN_Q31; + } + ELSE + { + dv_fx[0] = L_shl( dv_fx[0], 2 ); + } + dv_fx[1] = L_mult( w_fx, getSinWord16( azi_in_q13 ) ); + IF( EQ_32( dv_fx[1], ONE_IN_Q30 ) ) + { + move32(); + dv_fx[1] = ONE_IN_Q31; + } + ELSE + { + dv_fx[1] = L_shl( dv_fx[1], 1 ); + } + dv_fx[2] = (Word32) getSinWord16( ele_in_q13 ); + IF( EQ_32( dv_fx[2], ONE_IN_Q15 ) ) + { + move32(); + dv_fx[2] = ONE_IN_Q31; + } + ELSE + { + dv_fx[2] = L_shl( dv_fx[2], 16 ); + } + + /*Rotation mtx multiplication*/ + FOR( n = 0; n < 3; n++ ) + { + temp = L_add( Mpy_32_32( dv_fx[0], Rmat_fx[n][0] ), Mpy_32_32( dv_fx[1], Rmat_fx[n][1] ) ); + dv_r_fx[n] = L_add( Mpy_32_32( dv_fx[2], Rmat_fx[n][2] ), temp ); // Q30 + } + + /*Conversion cartesian to spherical coordinates*/ + move32(); + y = dv_r_fx[1]; + move32(); + x = dv_r_fx[0]; + radian = BASOP_util_atan2( y, x, 0 ); // Q13 + + angle = ( Mpy_32_16_1( _180_OVER_PI_Q25, radian ) >> 1 ); // Q22 + + + *azi = (Word32) ( max( L_shl( -180, 22 ), min( L_shl( 180, 22 ), angle ) ) ); // Q22 + *azi = ( L_add( *azi, ONE_IN_Q21 ) >> Q22 ) << Q22; + IF( LT_32( abs( *azi ), ONE_IN_Q22 ) ) + { + move32(); + *azi = 0; + } + IF( EQ_16( isPlanar, 0 ) ) + { + sqrt_fx = L_Frac_sqrtQ31( L_add( Mpy_32_32( dv_r_fx[0], dv_r_fx[0] ), Mpy_32_32( dv_r_fx[1], dv_r_fx[1] ) ) ); + y = dv_r_fx[2]; + move32(); + x = sqrt_fx; + move32(); + radian = BASOP_util_atan2( y, x, 0 ); + + angle = ( Mpy_32_16_1( _180_OVER_PI_Q25, radian ) >> 1 ); // Q22 + + + *ele = (Word32) ( max( L_shl( -90, 22 ), min( L_shl( 90, 22 ), angle ) ) ); // Q22 + *ele = ( L_add( *ele, ONE_IN_Q21 ) >> Q22 ) << Q22; + IF( LT_32( abs( *ele ), ONE_IN_Q22 ) ) + { + *ele = 0; + move32(); + } + } + ELSE + { + *ele = 0; + move32(); + } + + return; +} + /*------------------------------------------------------------------------- * rotateAziEle() * diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index f0d024b31..d5a90e28a 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -155,7 +155,7 @@ typedef struct TDREND_WRAPPER tdRendWrapper; CREND_WRAPPER_HANDLE crendWrapper; REVERB_HANDLE hReverb; - rotation_matrix rot_mat_prev; + rotation_matrix_fx rot_mat_prev; #ifdef IVAS_FLOAT_FIXED pan_vector_fx prev_pan_gains_fx; rotation_matrix_fx rot_mat_prev_fx; @@ -163,8 +163,12 @@ typedef struct pan_vector prev_pan_gains; int8_t firstFrameRendered; float *bufferData; + Word32 *bufferData_fx; Word16 nonDiegeticPan; float nonDiegeticPanGain; +#ifdef IVAS_FLOAT_FIXED + Word32 nonDiegeticPanGain_fx; +#endif OMASA_ANA_HANDLE hOMasa; uint16_t total_num_objects; float ism_metadata_delay_ms; @@ -1968,39 +1972,39 @@ static void closeHeadRotation( } #endif -#ifdef IVAS_FLOAT_FIXED -static void initRotMatrix_fx( - rotation_matrix_fx rot_mat_fx) +static void initRotMatrix( + rotation_matrix rot_mat ) { - Word16 i; + int16_t i; /* Initialize rotation matrices */ - FOR (i = 0; i < 3; i++) + for ( i = 0; i < 3; i++ ) { - set32_fx(rot_mat_fx[i], 0, 3); - rot_mat_fx[i][i] = ONE_IN_Q30; + set_zero( rot_mat[i], 3 ); + rot_mat[i][i] = 1.f; } return; } -#endif -static void initRotMatrix( - rotation_matrix rot_mat ) +#ifdef IVAS_FLOAT_FIXED + +static void initRotMatrix_fx( + rotation_matrix_fx rot_mat ) { - int16_t i; + Word16 i; /* Initialize rotation matrices */ - for ( i = 0; i < 3; i++ ) + FOR( i = 0; i < 3; i++ ) { - set_zero( rot_mat[i], 3 ); - rot_mat[i][i] = 1.f; + set_zero_fx( rot_mat[i], 3 ); + rot_mat[i][i] = ONE_IN_Q30; + move32(); } return; } -#ifdef IVAS_FLOAT_FIXED static void initRotGains_fx( rotation_gains_fx rot_gains ) { @@ -2123,6 +2127,15 @@ static int8_t checkObjectPositionChanged( fabs( currentPos->elevation - previousPos->elevation ) < EPSILON ); } +#ifdef IVAS_FLOAT_FIXED +static Word8 checkObjectPositionChanged_fx( + IVAS_ISM_METADATA *currentPos, + IVAS_ISM_METADATA *previousPos ) +{ + return !( LT_32( abs( L_sub( currentPos->azimuth_fx, previousPos->azimuth_fx ) ), EPSILLON_FX ) && + LT_32( abs( L_sub( currentPos->elevation_fx, previousPos->elevation_fx ) ), EPSILLON_FX ) ); +} +#endif static rendering_context getRendCtx( IVAS_REND_HANDLE hIvasRend ) @@ -2258,6 +2271,13 @@ static ivas_error setRendInputActiveIsm( return error; } initRendInputBase( &inputIsm->base, inConfig, id, rendCtx, inputIsm->bufferData, MAX_BUFFER_LENGTH ); +#ifdef IVAS_FLOAT_FIXED + if ( ( error = allocateInputBaseBufferData_fx( &inputIsm->bufferData_fx, MAX_BUFFER_LENGTH ) ) != IVAS_ERR_OK ) + { + return error; + } + initRendInputBase_fx( &inputIsm->base, inConfig, id, rendCtx, inputIsm->bufferData_fx, MAX_BUFFER_LENGTH ); +#endif inputIsm->firstFrameRendered = FALSE; @@ -2266,12 +2286,16 @@ static ivas_error setRendInputActiveIsm( inputIsm->crendWrapper = NULL; inputIsm->hReverb = NULL; inputIsm->tdRendWrapper = defaultTdRendWrapper(); -#ifdef IVAS_FLOAT_FIXED - initRotMatrix_fx(inputIsm->rot_mat_prev_fx); -#endif + +#ifndef IVAS_FLOAT_FIXED initRotMatrix( inputIsm->rot_mat_prev ); +#else + initRotMatrix_fx( inputIsm->rot_mat_prev ); +#endif set_zero( inputIsm->prev_pan_gains, MAX_OUTPUT_CHANNELS ); - +#ifdef IVAS_FLOAT_FIXED + set_zero_fx( inputIsm->prev_pan_gains_fx, MAX_OUTPUT_CHANNELS ); +#endif inputIsm->hOMasa = NULL; @@ -2364,6 +2388,10 @@ static void clearInputIsm( freeInputBaseBufferData( &inputIsm->base.inputBuffer.data ); initRendInputBase( &inputIsm->base, IVAS_AUDIO_CONFIG_INVALID, 0, rendCtx, NULL, 0 ); +#ifdef IVAS_FLOAT_FIXED + freeInputBaseBufferData_fx( &inputIsm->base.inputBuffer.data_fx ); + initRendInputBase_fx( &inputIsm->base, IVAS_AUDIO_CONFIG_INVALID, 0, rendCtx, NULL, 0 ); +#endif /* Free input's internal handles */ ivas_rend_closeCrend( &inputIsm->crendWrapper ); @@ -5031,7 +5059,7 @@ static ivas_error setRendInputActiveMasa( IF ( getAudioConfigType( outConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_MASA ) { inputMasa->metadataHasBeenFed = false; - IF ( ( error = masaPrerendOpen( &inputMasa->hMasaPrerend, EQ_16(inputMasa->base.inConfig , IVAS_AUDIO_CONFIG_MASA1) ? 1 : 2, *( inputMasa->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) + IF ( ( error = masaPrerendOpen_fx( &inputMasa->hMasaPrerend, EQ_16(inputMasa->base.inConfig , IVAS_AUDIO_CONFIG_MASA1) ? 1 : 2, *( inputMasa->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) { return error; } @@ -5077,7 +5105,7 @@ static void clearInputMasa( freeInputBaseBufferData( &inputMasa->bufferData ); - masaPrerendClose( &inputMasa->hMasaPrerend ); + masaPrerendClose_fx( &inputMasa->hMasaPrerend ); freeMasaExtRenderer( &inputMasa->hMasaExtRend ); initRendInputBase( &inputMasa->base, IVAS_AUDIO_CONFIG_INVALID, 0, rendCtx, NULL, 0 ); @@ -5175,7 +5203,9 @@ ivas_error IVAS_REND_Open( for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) { initRendInputBase( &hIvasRend->inputsIsm[i].base, IVAS_AUDIO_CONFIG_INVALID, 0, getRendCtx( hIvasRend ), NULL, 0 ); - +#ifdef IVAS_FLOAT_FIXED + initRendInputBase_fx( &hIvasRend->inputsIsm[i].base, IVAS_AUDIO_CONFIG_INVALID, 0, getRendCtx( hIvasRend ), NULL, 0 ); +#endif hIvasRend->inputsIsm[i].crendWrapper = NULL; hIvasRend->inputsIsm[i].hReverb = NULL; hIvasRend->inputsIsm[i].tdRendWrapper.hBinRendererTd = NULL; @@ -5183,6 +5213,9 @@ ivas_error IVAS_REND_Open( hIvasRend->inputsIsm[i].nonDiegeticPan = nonDiegeticPan; hIvasRend->inputsIsm[i].nonDiegeticPanGain = nonDiegeticPanGain; hIvasRend->inputsIsm[i].hOMasa = NULL; +#ifdef IVAS_FLOAT_FIXED + hIvasRend->inputsIsm[i].bufferData_fx = NULL; +#endif } for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) @@ -7801,7 +7834,7 @@ static void renderBufferChannelLerp_fx( /* Set output pointer to first output channel sample */ outSmpl = getSmplPtr_fx( outAudio, outChnlIdx, 0 ); - IF( gainsPrev == NULL || LE_32( abs( L_sub( previousGain, currentGain ) ), EPSILON_FX ) ) + IF( gainsPrev == NULL || LE_32( abs( L_sub( L_shr(previousGain,1), L_shr(currentGain,1) ) ), EPSILON_FX ) ) { /* If no interpolation from previous frame, apply current gain */ DO @@ -7818,6 +7851,18 @@ static void renderBufferChannelLerp_fx( Word32 tmp = Q31_BY_SUB_FRAME_240; SWITCH( outAudio.config.numSamplesPerChannel ) { + case NUM_SAMPLES_960: + tmp = Q31_BY_NUM_SAMPLES_960; + BREAK; + case NUM_SAMPLES_720: + tmp = Q31_BY_NUM_SAMPLES_720; + BREAK; + case NUM_SAMPLES_320: + tmp = Q31_BY_NUM_SAMPLES_320; + BREAK; + case NUM_SAMPLES_160: + tmp = Q31_BY_NUM_SAMPLES_160; + BREAK; case L_SUBFRAME_48k: tmp = Q31_BY_SUB_FRAME_240; BREAK; @@ -8490,26 +8535,26 @@ static int16_t getNumSubframesInBuffer( #ifdef IVAS_FLOAT_FIXED static ivas_error renderIsmToBinauralRoom( input_ism *ismInput, - IVAS_REND_AudioBuffer outAudio ) + IVAS_REND_AudioBuffer outAudio, + Word16 *exp ) { - int16_t position_changed; - int16_t i, j; - int16_t azi_rot, ele_rot; - int16_t subframe_idx; - int16_t tmp; - rotation_matrix Rmat; - float tmpRendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + Word16 position_changed; + Word16 i, j; + Word32 azi_rot, ele_rot; + Word16 subframe_idx; + Word16 tmp; + rotation_matrix_fx Rmat; + Word32 tmpRendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; ivas_error error; - pan_vector currentPanGains; - pan_vector_fx currentPanGains_fx; + pan_vector_fx currentPanGains; IVAS_REND_AudioBuffer tmpMcBuffer; IVAS_ISM_METADATA rotatedPosPrev; IVAS_ISM_METADATA rotatedPos; const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData; - int8_t combinedOrientationEnabled; - float *p_tmpRendBuffer[MAX_OUTPUT_CHANNELS]; + Word8 combinedOrientationEnabled; + Word32 *p_tmpRendBuffer[MAX_OUTPUT_CHANNELS]; - for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) { p_tmpRendBuffer[i] = tmpRendBuffer[i]; } @@ -8521,147 +8566,143 @@ static ivas_error renderIsmToBinauralRoom( hCombinedOrientationData = ismInput->base.ctx.pCombinedOrientationData; combinedOrientationEnabled = 0; - if ( hCombinedOrientationData != NULL ) + IF( hCombinedOrientationData != NULL ) { - for ( subframe_idx = 0; subframe_idx < ( *hCombinedOrientationData )->num_subframes; subframe_idx++ ) + FOR( subframe_idx = 0; subframe_idx < ( *hCombinedOrientationData )->num_subframes; subframe_idx++ ) { - if ( ( *hCombinedOrientationData )->enableCombinedOrientation[subframe_idx] != 0 ) + IF( ( *hCombinedOrientationData )->enableCombinedOrientation[subframe_idx] != 0 ) { combinedOrientationEnabled = 1; - break; + BREAK; } } } - if ( combinedOrientationEnabled ) + IF( combinedOrientationEnabled ) { - for ( subframe_idx = 0; subframe_idx < 1; subframe_idx++ ) + FOR( subframe_idx = 0; subframe_idx < 1; subframe_idx++ ) { - for ( i = 0; i < 3; i++ ) + FOR( i = 0; i < 3; i++ ) { - if ( hCombinedOrientationData != NULL && ( *hCombinedOrientationData )->enableCombinedOrientation[subframe_idx] ) + IF( hCombinedOrientationData != NULL && ( *hCombinedOrientationData )->enableCombinedOrientation[subframe_idx] ) { - for ( j = 0; j < 3; j++ ) + FOR( j = 0; j < 3; j++ ) { - Rmat[i][j] = fixedToFloat_32( ( *hCombinedOrientationData )->Rmat_fx[subframe_idx][i][j], 30 ); + Rmat[i][j] = ( *hCombinedOrientationData )->Rmat_fx[subframe_idx][i][j]; + move32(); } } - else + ELSE { /* Set to identity */ - set_zero( Rmat[i], 3 ); - Rmat[i][i] = 1.0f; + set_zero_fx( Rmat[i], 3 ); + Rmat[i][i] = ONE_IN_Q30; + move32(); } } } } /* get previous position */ - if ( combinedOrientationEnabled ) + IF( combinedOrientationEnabled ) { - rotateAziEle( ismInput->previousPos.azimuth, ismInput->previousPos.elevation, &azi_rot, &ele_rot, ismInput->rot_mat_prev, 0 ); - rotatedPosPrev.azimuth = (float) azi_rot; - rotatedPosPrev.elevation = (float) ele_rot; + rotateAziEle_fx_frac_az_el( ismInput->previousPos.azimuth_fx, ismInput->previousPos.elevation_fx, &azi_rot, &ele_rot, ismInput->rot_mat_prev, 0 ); + rotatedPosPrev.azimuth_fx = azi_rot; + move32(); + rotatedPosPrev.elevation_fx = ele_rot; + move32(); } - else + ELSE { - rotatedPosPrev.azimuth = ismInput->previousPos.azimuth; - rotatedPosPrev.elevation = ismInput->previousPos.elevation; + rotatedPosPrev.azimuth_fx = ismInput->previousPos.azimuth_fx; + move32(); + rotatedPosPrev.elevation_fx = ismInput->previousPos.elevation_fx; + move32(); } /* get current position */ - if ( combinedOrientationEnabled ) + IF( combinedOrientationEnabled ) { - rotateAziEle( ismInput->currentPos.azimuth, ismInput->currentPos.elevation, &azi_rot, &ele_rot, Rmat, 0 ); - rotatedPos.azimuth = (float) azi_rot; - rotatedPos.elevation = (float) ele_rot; + rotateAziEle_fx_frac_az_el( ismInput->currentPos.azimuth_fx, ismInput->currentPos.elevation_fx, &azi_rot, &ele_rot, Rmat, 0 ); + rotatedPos.azimuth_fx = azi_rot; + move32(); + rotatedPos.elevation_fx = ele_rot; + move32(); } - else + ELSE { - rotatedPos.azimuth = ismInput->currentPos.azimuth; - rotatedPos.elevation = ismInput->currentPos.elevation; + rotatedPos.azimuth_fx = ismInput->currentPos.azimuth_fx; + move32(); + rotatedPos.elevation_fx = ismInput->currentPos.elevation_fx; + move32(); } - position_changed = !ismInput->firstFrameRendered || checkObjectPositionChanged( &rotatedPos, &rotatedPosPrev ); + position_changed = !ismInput->firstFrameRendered || checkObjectPositionChanged_fx( &rotatedPos, &rotatedPosPrev ); /* set previous gains if this is the first frame */ - /*float2fix to be removed*/ - Word32 azimuth_fx_tmp = floatToFixed( rotatedPosPrev.azimuth, Q22 ); - Word32 elevation_fx_tmp = floatToFixed( rotatedPosPrev.elevation, Q22 ); - if ( ( error = getEfapGains_fx( *ismInput->base.ctx.pEfapOutWrapper, azimuth_fx_tmp, elevation_fx_tmp, ismInput->prev_pan_gains_fx ) ) != IVAS_ERR_OK ) + IF( ( error = getEfapGains_fx( *ismInput->base.ctx.pEfapOutWrapper, rotatedPosPrev.azimuth_fx, rotatedPosPrev.elevation_fx, ismInput->prev_pan_gains_fx ) ) != IVAS_ERR_OK ) { return error; } - /* fix2float to be removed */ - fixedToFloat_arrL( ismInput->prev_pan_gains_fx, ismInput->prev_pan_gains, Q31, MAX_OUTPUT_CHANNELS ); + /* compute gains only if position changed */ - if ( position_changed ) + IF( position_changed ) { - /*float2fix to be removed*/ - azimuth_fx_tmp = floatToFixed( rotatedPos.azimuth, Q22 ); - elevation_fx_tmp = floatToFixed( rotatedPos.elevation, Q22 ); - if ( ( error = getEfapGains_fx( *ismInput->base.ctx.pEfapOutWrapper, - azimuth_fx_tmp, - elevation_fx_tmp, - currentPanGains_fx ) ) != IVAS_ERR_OK ) + IF( ( error = getEfapGains_fx( *ismInput->base.ctx.pEfapOutWrapper, + rotatedPos.azimuth_fx, + rotatedPos.elevation_fx, + currentPanGains ) ) != IVAS_ERR_OK ) { return error; } - /* fix2float to be removed */ - fixedToFloat_arrL( currentPanGains_fx, currentPanGains, Q31, MAX_OUTPUT_CHANNELS ); } /* intermediate rendering to 7_1_4 */ tmpMcBuffer = ismInput->base.inputBuffer; - if ( ( error = getAudioConfigNumChannels( IVAS_AUDIO_CONFIG_7_1_4, &tmp ) ) != IVAS_ERR_OK ) + IF( ( error = getAudioConfigNumChannels( IVAS_AUDIO_CONFIG_7_1_4, &tmp ) ) != IVAS_ERR_OK ) { return error; } tmpMcBuffer.config.numChannels = tmp; - tmpMcBuffer.data = malloc( tmpMcBuffer.config.numSamplesPerChannel * tmpMcBuffer.config.numChannels * sizeof( float ) ); - set_zero( tmpMcBuffer.data, tmpMcBuffer.config.numSamplesPerChannel * tmpMcBuffer.config.numChannels ); + move16(); + tmpMcBuffer.data_fx = malloc( tmpMcBuffer.config.numSamplesPerChannel * tmpMcBuffer.config.numChannels * sizeof( Word32 ) ); + set_zero_fx( tmpMcBuffer.data_fx, tmpMcBuffer.config.numSamplesPerChannel * tmpMcBuffer.config.numChannels ); - renderBufferChannelLerp( ismInput->base.inputBuffer, 0, - position_changed ? currentPanGains : ismInput->prev_pan_gains, - position_changed ? ismInput->prev_pan_gains : NULL, - tmpMcBuffer ); + renderBufferChannelLerp_fx( ismInput->base.inputBuffer, 0, + position_changed ? currentPanGains : ismInput->prev_pan_gains_fx, + position_changed ? ismInput->prev_pan_gains_fx : NULL, + tmpMcBuffer ); - copyBufferTo2dArray( tmpMcBuffer, tmpRendBuffer ); + copyBufferTo2dArray_fx( tmpMcBuffer, tmpRendBuffer ); /* save gains for next frame */ - for ( i = 0; i < 3; i++ ) + FOR( i = 0; i < 3; i++ ) { - mvr2r( Rmat[i], ismInput->rot_mat_prev[i], 3 ); + Copy32( Rmat[i], ismInput->rot_mat_prev[i], 3 ); } - if ( position_changed ) + IF( position_changed ) { - mvr2r( currentPanGains, ismInput->prev_pan_gains, MAX_OUTPUT_CHANNELS ); + Copy32( currentPanGains, ismInput->prev_pan_gains_fx, MAX_OUTPUT_CHANNELS ); } // Crend_process porting - Word16 nchan_out = 2, nchan_in = 12, subframe_len; + Word16 nchan_in = 12, subframe_len; + move16(); CREND_HANDLE hCrend; - Word32 output_buffer_fx[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - Word32 *output_fx[MAX_OUTPUT_CHANNELS]; hCrend = ismInput->crendWrapper->hCrend; subframe_len = (Word16) ( *ismInput->base.ctx.pOutSampleRate / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ); - Word16 gd_bits = find_guarded_bits_fx( subframe_len ); - Word16 exp = 15; - exp -= gd_bits; + move16(); Word16 nchan = nchan_in; - for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) - { - output_fx[i] = output_buffer_fx[i]; - } - if ( hCrend->reflections != NULL ) + move16(); + IF( hCrend->reflections != NULL ) { - if ( hCrend->reflections->use_er == 1 && hCrend->reflections->is_ready == 1 ) + IF( hCrend->reflections->use_er == 1 && hCrend->reflections->is_ready == 1 ) { - nchan = hCrend->reflections->shoebox_data.n_sources + 1; - for ( i = 0; i < 150; i++ ) + nchan = add( hCrend->reflections->shoebox_data.n_sources, 1 ); + FOR( i = 0; i < 150; i++ ) { hCrend->reflections->shoebox_data.gains.data_fx[i] = L_shl( hCrend->reflections->shoebox_data.gains.data_fx[i], 9 ); } @@ -8669,38 +8710,24 @@ static ivas_error renderIsmToBinauralRoom( } nchan = nchan_in; - for ( i = 0; i < nchan; i++ ) - { - for ( j = 0; j < L_FRAME48k; j++ ) - { + move16(); - output_fx[i][j] = (Word32) float_to_fix( p_tmpRendBuffer[i][j], exp ); - } - } /* render 7_1_4 with BRIRs */ - if ( ( error = ivas_rend_crendProcess( ismInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, - NULL, NULL, NULL, NULL, output_fx, *ismInput->base.ctx.pOutSampleRate, - getNumSubframesInBuffer( &outAudio, *ismInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) + IF( ( error = ivas_rend_crendProcess( ismInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, + NULL, NULL, NULL, NULL, p_tmpRendBuffer, *ismInput->base.ctx.pOutSampleRate, + getNumSubframesInBuffer( &outAudio, *ismInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) { return error; } - if ( hCrend->hReverb != NULL ) + IF( hCrend->hReverb != NULL ) { - exp -= 2; + *exp = sub( *exp, 2 ); } - for ( i = 0; i < nchan_out; i++ ) - { - - for ( j = 0; j < L_FRAME48k; j++ ) - { + accumulate2dArrayToBuffer_fx( tmpRendBuffer, &outAudio ); - p_tmpRendBuffer[i][j] = fix_to_float( output_fx[i][j], exp ); - } - } - accumulate2dArrayToBuffer( tmpRendBuffer, &outAudio ); + free( tmpMcBuffer.data_fx ); - free( tmpMcBuffer.data ); pop_wmops(); return IVAS_ERR_OK; @@ -8901,92 +8928,94 @@ static ivas_error renderIsmToMc( const IVAS_REND_AudioBuffer outAudio ) { int8_t position_changed; - pan_vector currentPanGains; pan_vector_fx currentPanGains_fx; ivas_error error; push_wmops( "renderIsmToMc" ); + ismInput->currentPos.azimuth_fx = L_shl( L_shr( L_add( ismInput->currentPos.azimuth_fx, ONE_IN_Q21 ), Q22 ), Q22 ); + ismInput->currentPos.elevation_fx = L_shl( L_shr( L_add( ismInput->currentPos.elevation_fx, ONE_IN_Q21 ), Q22 ), Q22 ); + ismInput->previousPos.azimuth_fx = L_shl( L_shr( L_add( ismInput->previousPos.azimuth_fx, ONE_IN_Q21 ), Q22 ), Q22 ); + ismInput->previousPos.elevation_fx = L_shl( L_shr( L_add( ismInput->previousPos.elevation_fx, ONE_IN_Q21 ), Q22 ), Q22 ); + position_changed = !ismInput->firstFrameRendered || checkObjectPositionChanged( &ismInput->currentPos, &ismInput->previousPos ); - if ( *ismInput->base.ctx.pOutConfig == IVAS_AUDIO_CONFIG_STEREO ) + IF ( *ismInput->base.ctx.pOutConfig == IVAS_AUDIO_CONFIG_STEREO ) { - if ( ismInput->nonDiegeticPan ) + IF ( ismInput->nonDiegeticPan ) { - ismInput->prev_pan_gains[0] = currentPanGains[0] = ( ismInput->nonDiegeticPanGain + 1.f ) * 0.5f; - ismInput->prev_pan_gains[1] = currentPanGains[1] = 1.f - currentPanGains[0]; + currentPanGains_fx[0] = L_add(L_shr(ismInput->nonDiegeticPanGain_fx,1),ONE_IN_Q30); + currentPanGains_fx[1] = L_sub(ONE_IN_Q31, currentPanGains_fx[0]); + ismInput->prev_pan_gains_fx[0] = currentPanGains_fx[0]; //Q31 + ismInput->prev_pan_gains_fx[1] = currentPanGains_fx[1]; //Q31 } - else + ELSE { - set_zero( currentPanGains, MAX_OUTPUT_CHANNELS ); + set32_fx( currentPanGains_fx, 0,MAX_OUTPUT_CHANNELS ); Word16 gains_fx[2]; - ivas_ism_get_stereo_gains_fx( (Word16) ismInput->currentPos.azimuth, (Word16) ismInput->currentPos.elevation, &gains_fx[0], &gains_fx[1] ); - currentPanGains[0] = (float) gains_fx[0] / 32768.f; - currentPanGains[1] = (float) gains_fx[1] / 32768.f; + Word16 azimuth_tmp, elevation_tmp; - set_zero( ismInput->prev_pan_gains, MAX_OUTPUT_CHANNELS ); - ivas_ism_get_stereo_gains_fx( (Word16) ismInput->previousPos.azimuth, (Word16) ismInput->previousPos.elevation, &gains_fx[0], &gains_fx[1] ); - ismInput->prev_pan_gains[0] = (float) gains_fx[0] / 32768.f; - ismInput->prev_pan_gains[1] = (float) gains_fx[1] / 32768.f; + azimuth_tmp = extract_l( L_shr( ismInput->currentPos.azimuth_fx, Q22 ) ); + elevation_tmp = extract_l( L_shr( ismInput->currentPos.elevation_fx, Q22 ) ); + + ivas_ism_get_stereo_gains_fx( azimuth_tmp, elevation_tmp, &gains_fx[0], &gains_fx[1] ); + currentPanGains_fx[0] = L_deposit_h( gains_fx[0] ); //Q31 + currentPanGains_fx[1] = L_deposit_h( gains_fx[1] ); //Q31 + + azimuth_tmp = extract_l( L_shr( ismInput->previousPos.azimuth_fx, Q22 ) ); + elevation_tmp = extract_l( L_shr( ismInput->previousPos.elevation_fx, Q22 ) ); + + set32_fx( ismInput->prev_pan_gains_fx, 0, MAX_OUTPUT_CHANNELS ); + ivas_ism_get_stereo_gains_fx( azimuth_tmp, elevation_tmp, &gains_fx[0], &gains_fx[1] ); + ismInput->prev_pan_gains_fx[0] = L_deposit_h( gains_fx[0] ); //Q31 + ismInput->prev_pan_gains_fx[1] = L_deposit_h( gains_fx[1] ); //Q31 } } - else + ELSE { /* compute gains only if position changed */ - if ( position_changed ) + IF ( position_changed ) { // TODO tmu review when #215 is resolved - /*float2fix to be removed*/ - Word32 azimuth_fx_tmp = (int16_t) floorf( ismInput->currentPos.azimuth + 0.5f ); - azimuth_fx_tmp = azimuth_fx_tmp << 22; - Word32 elevation_fx_tmp = (int16_t) floorf( ismInput->currentPos.elevation + 0.5f ); - elevation_fx_tmp = elevation_fx_tmp << 22; - if ( ( error = getEfapGains_fx( *ismInput->base.ctx.pEfapOutWrapper, - azimuth_fx_tmp, - elevation_fx_tmp, + IF ( ( error = getEfapGains_fx( *ismInput->base.ctx.pEfapOutWrapper, + ismInput->currentPos.azimuth_fx, + ismInput->currentPos.elevation_fx, currentPanGains_fx ) ) != IVAS_ERR_OK ) { return error; } - /* fix2float to be removed */ - fixedToFloat_arrL( currentPanGains_fx, currentPanGains, Q31, MAX_OUTPUT_CHANNELS ); } /* set previous gains if this is the first frame */ - if ( !ismInput->firstFrameRendered ) + IF( !ismInput->firstFrameRendered ) { // TODO tmu review when #215 is resolved - /*float2fix to be removed*/ - Word32 azimuth_fx_tmp = (int16_t) floorf( ismInput->previousPos.azimuth + 0.5f ); - azimuth_fx_tmp = azimuth_fx_tmp << 22; - Word32 elevation_fx_tmp = (int16_t) floorf( ismInput->previousPos.elevation + 0.5f ); - elevation_fx_tmp = elevation_fx_tmp << 22; - if ( ( error = getEfapGains_fx( *ismInput->base.ctx.pEfapOutWrapper, - azimuth_fx_tmp, - elevation_fx_tmp, + IF( ( error = getEfapGains_fx( *ismInput->base.ctx.pEfapOutWrapper, + ismInput->previousPos.azimuth_fx, + ismInput->previousPos.elevation_fx, ismInput->prev_pan_gains_fx ) ) != IVAS_ERR_OK ) { return error; } /* fix2float to be removed */ - fixedToFloat_arrL( ismInput->prev_pan_gains_fx, ismInput->prev_pan_gains, Q31, MAX_OUTPUT_CHANNELS ); } } /* Assume num channels in audio buffer to be 1. * This should have been validated in IVAS_REND_FeedInputAudio() */ - renderBufferChannelLerp( ismInput->base.inputBuffer, 0, - position_changed ? currentPanGains : ismInput->prev_pan_gains, - position_changed ? ismInput->prev_pan_gains : NULL, + renderBufferChannelLerp_fx( ismInput->base.inputBuffer, 0, + position_changed ? currentPanGains_fx : ismInput->prev_pan_gains_fx, + position_changed ? ismInput->prev_pan_gains_fx : NULL, outAudio ); - if ( position_changed ) + IF( position_changed ) { - mvr2r( currentPanGains, ismInput->prev_pan_gains, MAX_OUTPUT_CHANNELS ); + Copy32( currentPanGains_fx, ismInput->prev_pan_gains_fx, MAX_OUTPUT_CHANNELS ); } pop_wmops(); + return IVAS_ERR_OK; } #else @@ -9065,7 +9094,89 @@ static ivas_error renderIsmToMc( return IVAS_ERR_OK; } #endif +#ifdef IVAS_FLOAT_FIXED +static ivas_error renderIsmToSba( + input_ism *ismInput, + const AUDIO_CONFIG outConfig, + const IVAS_REND_AudioBuffer outAudio ) +{ + Word16 i; + Word8 position_changed; + Word16 ambiOrderOut; + Word16 numOutChannels; + pan_vector_fx currentPanGains_fx; + ivas_error error; + error = IVAS_ERR_OK; + + ismInput->currentPos.azimuth_fx = L_shl( L_shr( L_add( ismInput->currentPos.azimuth_fx, ONE_IN_Q21 ), Q22 ), Q22 ); + ismInput->currentPos.elevation_fx = L_shl( L_shr( L_add( ismInput->currentPos.elevation_fx, ONE_IN_Q21 ), Q22 ), Q22 ); + ismInput->previousPos.azimuth_fx = L_shl( L_shr( L_add( ismInput->previousPos.azimuth_fx, ONE_IN_Q21 ), Q22 ), Q22 ); + ismInput->previousPos.elevation_fx = L_shl( L_shr( L_add( ismInput->previousPos.elevation_fx, ONE_IN_Q21 ), Q22 ), Q22 ); + + push_wmops( "renderIsmToSba" ); + + IF ( ( error = getAudioConfigNumChannels( outConfig, &numOutChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + IF ( ( error = getAmbisonicsOrder( outConfig, &ambiOrderOut ) ) != IVAS_ERR_OK ) + { + return error; + } + + position_changed = !ismInput->firstFrameRendered || checkObjectPositionChanged( &ismInput->currentPos, &ismInput->previousPos ); + + /* set previous gains if this is the first frame */ + Word16 azimuth_tmp, elevation_tmp; + IF ( !ismInput->firstFrameRendered ) + { + // TODO tmu review when #215 is resolved + azimuth_tmp = extract_l(L_shr( ismInput->previousPos.azimuth_fx, Q22 )); + elevation_tmp = extract_l(L_shr( ismInput->previousPos.elevation_fx, Q22 )); + ivas_dirac_dec_get_response_fixed( azimuth_tmp, + elevation_tmp, + ismInput->prev_pan_gains_fx, + ambiOrderOut ); + FOR ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + ismInput->prev_pan_gains_fx[i] = L_shl_sat( ismInput->prev_pan_gains_fx[i], Q2 ); + } + } + + /* compute gains only if position changed */ + IF( position_changed ) + { + // TODO tmu review when #215 is resolved + azimuth_tmp = extract_l(L_shr( ismInput->currentPos.azimuth_fx, Q22 )); + elevation_tmp = extract_l(L_shr( ismInput->currentPos.elevation_fx, Q22 )); + ivas_dirac_dec_get_response_fixed( azimuth_tmp, + elevation_tmp, + currentPanGains_fx, + ambiOrderOut ); + FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + currentPanGains_fx[i] = L_shl_sat( currentPanGains_fx[i], Q2 ); + } + } + + /* Assume num channels in audio buffer to be 1. + * This should have been validated in IVAS_REND_FeedInputAudio() */ + renderBufferChannelLerp_fx( ismInput->base.inputBuffer, 0, + position_changed ? currentPanGains_fx : ismInput->prev_pan_gains_fx, + position_changed ? ismInput->prev_pan_gains_fx : NULL, + outAudio ); + + IF ( position_changed ) + { + Copy32( currentPanGains_fx, ismInput->prev_pan_gains_fx, MAX_OUTPUT_CHANNELS ); + //mvr2r( currentPanGains, ismInput->prev_pan_gains, MAX_OUTPUT_CHANNELS ); + } + pop_wmops(); + + return error; +} +#else static ivas_error renderIsmToSba( input_ism *ismInput, const AUDIO_CONFIG outConfig, @@ -9127,65 +9238,72 @@ static ivas_error renderIsmToSba( return error; } +#endif - +#ifdef IVAS_FLOAT_FIXED static void renderIsmToMasa( input_ism *ismInput, - IVAS_REND_AudioBuffer outAudio ) + IVAS_REND_AudioBuffer outAudio, + Word16 *exp ) { - float tmpRendBuffer[MAX_NUM_OBJECTS][L_FRAME48k]; -#ifdef IVAS_FLOAT_FIXED Word32 tmpRendBuffer_fx[MAX_NUM_OBJECTS][L_FRAME48k]; Word16 i, j; Word16 q_fact; -#endif push_wmops( "renderIsmToMasa" ); - copyBufferTo2dArray( ismInput->base.inputBuffer, tmpRendBuffer ); -#ifdef IVAS_FLOAT_FIXED + copyBufferTo2dArray_fx( ismInput->base.inputBuffer, tmpRendBuffer_fx ); Word16 input_e[MAX_NUM_OBJECTS], max_e; + FOR( i = 0; i < MAX_NUM_OBJECTS; i++ ) { - f2me_buf( tmpRendBuffer[i], tmpRendBuffer_fx[i], &input_e[i], L_FRAME48k ); + input_e[i] = sub( 31, add( getScaleFactor32( tmpRendBuffer_fx[i], L_FRAME48k ), 8 ) ); + move16(); } Word16 guard_bits = find_guarded_bits_fx( L_FRAME48k ); max_e = input_e[0]; - FOR ( i = 1; i < MAX_NUM_OBJECTS; i++) + FOR( Word16 i = 1; i < MAX_NUM_OBJECTS; i++ ) { IF( max_e < input_e[0] ) max_e = input_e[i]; + move16(); } FOR( i = 0; i < MAX_NUM_OBJECTS; i++ ) { FOR( j = 0; j < L_FRAME48k; j++ ) { - tmpRendBuffer_fx[i][j] = L_shr( tmpRendBuffer_fx[i][j], max_e - input_e[i] + guard_bits ); + tmpRendBuffer_fx[i][j] = L_shr( tmpRendBuffer_fx[i][j], add( sub( max_e, sub( 31, Q8 ) ), guard_bits ) ); + move32(); } } - max_e += guard_bits; - q_fact = 31 - max_e; -#endif -#ifdef IVAS_FLOAT_FIXED - ivas_omasa_ana_fx(ismInput->hOMasa, tmpRendBuffer_fx, &q_fact, ismInput->base.inputBuffer.config.numSamplesPerChannel, outAudio.config.numChannels, ismInput->base.inputBuffer.config.numChannels); + max_e = add( max_e, guard_bits ); + q_fact = sub( 31, max_e ); - FOR( Word16 block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ ) - { - FOR( Word16 band_m_idx = 0; band_m_idx < ismInput->hOMasa->nbands; band_m_idx++ ) - { - ismInput->hOMasa->energy[block_m_idx][band_m_idx] = fixedToFloat( ismInput->hOMasa->energy_fx[block_m_idx][band_m_idx], ismInput->hOMasa->energy_q ); - } - } - FOR( i = 0; i < ismInput->base.inputBuffer.config.numChannels; i++) { - fixedToFloat_arrL(tmpRendBuffer_fx[i], tmpRendBuffer[i], q_fact, L_FRAME48k ); - } + ivas_omasa_ana_fx( ismInput->hOMasa, tmpRendBuffer_fx, &q_fact, ismInput->base.inputBuffer.config.numSamplesPerChannel, outAudio.config.numChannels, ismInput->base.inputBuffer.config.numChannels ); + + *exp = q_fact; + accumulate2dArrayToBuffer_fx( tmpRendBuffer_fx, &outAudio ); + + pop_wmops(); + + return; +} #else +static void renderIsmToMasa( + input_ism *ismInput, + IVAS_REND_AudioBuffer outAudio ) +{ + float tmpRendBuffer[MAX_NUM_OBJECTS][L_FRAME48k]; + + push_wmops( "renderIsmToMasa" ); + + copyBufferTo2dArray( ismInput->base.inputBuffer, tmpRendBuffer ); + ivas_omasa_ana( ismInput->hOMasa, tmpRendBuffer, ismInput->base.inputBuffer.config.numSamplesPerChannel, outAudio.config.numChannels, ismInput->base.inputBuffer.config.numChannels ); -#endif accumulate2dArrayToBuffer( tmpRendBuffer, &outAudio ); @@ -9193,7 +9311,7 @@ static void renderIsmToMasa( return; } - +#endif static ivas_error renderInputIsm( input_ism *ismInput, @@ -9202,6 +9320,10 @@ static ivas_error renderInputIsm( { ivas_error error; IVAS_REND_AudioBuffer inAudio; +#ifdef IVAS_FLOAT_FIXED + Word16 exp = 8; + move16(); +#endif error = IVAS_ERR_OK; inAudio = ismInput->base.inputBuffer; @@ -9222,13 +9344,54 @@ static ivas_error renderInputIsm( /* set combined orientation subframe info to start info */ ivas_combined_orientation_set_to_start_index( *ismInput->base.ctx.pCombinedOrientationData ); +#ifdef IVAS_FLOAT_FIXED + ismInput->previousPos.azimuth_fx = (Word32) ( ismInput->previousPos.azimuth * ONE_IN_Q22 ); + move32(); + ismInput->previousPos.elevation_fx = (Word32) ( ismInput->previousPos.elevation * ONE_IN_Q22 ); + move32(); + ismInput->currentPos.azimuth_fx = (Word32) ( ismInput->currentPos.azimuth * ONE_IN_Q22 ); + move32(); + ismInput->currentPos.elevation_fx = (Word32) ( ismInput->currentPos.elevation * ONE_IN_Q22 ); + move32(); + + fixedToFloat_arrL(ismInput->base.inputBuffer.data_fx, ismInput->base.inputBuffer.data,Q8, ismInput->base.inputBuffer.config.numSamplesPerChannel*ismInput->base.inputBuffer.config.numChannels); + + floatToFixed_arrL( ismInput->prev_pan_gains, ismInput->prev_pan_gains_fx, Q31, MAX_OUTPUT_CHANNELS ); + ismInput->nonDiegeticPanGain_fx = floatToFixed_32( ismInput->nonDiegeticPanGain, Q31 ); + +#endif + switch ( getAudioConfigType( outConfig ) ) { case IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED: +#ifdef IVAS_FLOAT_FIXED + error = renderIsmToMc( ismInput, outAudio ); + FOR( Word32 i = 0; i < 16; i++ ) + { + ismInput->prev_pan_gains[i] = (float) ismInput->prev_pan_gains_fx[i] / ( ONE_IN_Q31 ); + } + FOR( Word32 i = 0; i < outAudio.config.numSamplesPerChannel * outAudio.config.numChannels; ++i ) + { + outAudio.data[i] = ( (float) outAudio.data_fx[i] / ONE_IN_Q8 ); + } +#else error = renderIsmToMc( ismInput, outAudio ); +#endif break; case IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS: +#ifdef IVAS_FLOAT_FIXED + error = renderIsmToSba( ismInput, outConfig, outAudio ); + FOR( Word32 i = 0; i < 16; i++ ) + { + ismInput->prev_pan_gains[i] = (float) ismInput->prev_pan_gains_fx[i] / ( ONE_IN_Q31 ); + } + FOR( Word32 i = 0; i < outAudio.config.numSamplesPerChannel * outAudio.config.numChannels; ++i ) + { + outAudio.data[i] = ( (float) outAudio.data_fx[i] / ONE_IN_Q8 ); + } +#else error = renderIsmToSba( ismInput, outConfig, outAudio ); +#endif break; case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: switch ( outConfig ) @@ -9237,7 +9400,19 @@ static ivas_error renderInputIsm( error = renderIsmToBinaural( ismInput, outAudio ); break; case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR: +#ifdef IVAS_FLOAT_FIXED + error = renderIsmToBinauralRoom( ismInput, outAudio, &exp ); + FOR( Word32 i = 0; i < 16; i++ ) + { + ismInput->prev_pan_gains[i] = (float) ismInput->prev_pan_gains_fx[i] / ( ONE_IN_Q31 ); + } + FOR( Word32 i = 0; i < outAudio.config.numSamplesPerChannel * outAudio.config.numChannels; ++i ) + { + outAudio.data[i] = ( (float) outAudio.data_fx[i] / ( 1 << exp ) ); + } +#else error = renderIsmToBinauralRoom( ismInput, outAudio ); +#endif break; case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: error = renderIsmToBinauralReverb( ismInput, outAudio ); @@ -9247,8 +9422,23 @@ static ivas_error renderInputIsm( } break; case IVAS_REND_AUDIO_CONFIG_TYPE_MASA: +#ifdef IVAS_FLOAT_FIXED + renderIsmToMasa( ismInput, outAudio, &exp ); + FOR( Word16 block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ ) + { + FOR( Word16 band_m_idx = 0; band_m_idx < ismInput->hOMasa->nbands; band_m_idx++ ) + { + ismInput->hOMasa->energy[block_m_idx][band_m_idx] = fixedToFloat( ismInput->hOMasa->energy_fx[block_m_idx][band_m_idx], ismInput->hOMasa->energy_q ); + } + } + FOR( Word32 i = 0; i < outAudio.config.numSamplesPerChannel * outAudio.config.numChannels; ++i ) + { + outAudio.data[i] = ( (float) outAudio.data_fx[i] / ( 1 << exp ) ); + } +#else renderIsmToMasa( ismInput, outAudio ); - break; +#endif + break; default: return IVAS_ERR_INVALID_OUTPUT_FORMAT; } diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index 9f5695c48..95a6dbfd5 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -84,6 +84,7 @@ typedef struct Word16 *pq_fact; float *data; Word32 *data_fx; + Word16 Q_data; } IVAS_REND_AudioBuffer; #endif -- GitLab