From 4fbd8abcd4b3e379e9839f187c9dcbee762241fd Mon Sep 17 00:00:00 2001 From: rtyag Date: Mon, 15 Jan 2024 22:31:29 +1100 Subject: [PATCH 01/13] LCLD 5ms changes --- apps/decoder.c | 34 ++ lib_com/options.h | 3 + lib_dec/ivas_init_dec.c | 13 +- lib_dec/ivas_mc_paramupmix_dec.c | 30 +- lib_dec/ivas_stat_dec.h | 4 +- lib_dec/lib_dec.c | 90 +++- lib_rend/ivas_MSPred.c | 93 ---- lib_rend/ivas_PredDecoder.c | 234 ++++++++- lib_rend/ivas_PredEncoder.c | 544 ++++++++++++++++++++- lib_rend/ivas_RMSEnvGrouping.c | 225 ++++++++- lib_rend/ivas_lcld_decoder.c | 171 +++---- lib_rend/ivas_lcld_encoder.c | 713 +++++++++++++++++++++++----- lib_rend/ivas_lcld_prot.h | 94 +++- lib_rend/ivas_lcld_rom_tables.c | 2 + lib_rend/ivas_lcld_rom_tables.h | 12 +- lib_rend/ivas_prot_rend.h | 64 +++ lib_rend/ivas_splitRend_lcld_dec.c | 94 +++- lib_rend/ivas_splitRend_lcld_enc.c | 127 +++-- lib_rend/ivas_splitRendererPLC.c | 165 +++++-- lib_rend/ivas_splitRendererPre.c | 64 ++- lib_rend/ivas_splitRenderer_utils.c | 25 + lib_rend/ivas_stat_rend.h | 8 + lib_rend/lib_rend.c | 68 ++- 23 files changed, 2434 insertions(+), 443 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 54879bb30e..3d961ae833 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -456,9 +456,14 @@ int main( *------------------------------------------------------------------------------------------*/ #ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef SPLIT_REND_LCLD_5MS + asked_frame_size = arg.renderFramesize; +#endif if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { +#ifndef SPLIT_REND_LCLD_5MS asked_frame_size = arg.renderFramesize; +#endif if ( ( error = IVAS_DEC_EnableSplitRendering( hIvasDec ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nConfigure failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); @@ -471,10 +476,12 @@ int main( goto cleanup; } +#ifndef SPLIT_REND_LCLD_5MS if ( arg.renderFramesize != asked_frame_size ) { fprintf( stderr, "\nChanged render framesize, only 20ms are allowed for split rendering!\n" ); } +#endif arg.enableHeadRotation = true; } @@ -629,6 +636,7 @@ int main( } #ifdef SPLIT_REND_WITH_HEAD_ROT +#ifndef SPLIT_REND_LCLD_5MS if ( arg.renderFramesize == IVAS_RENDER_FRAMESIZE_5MS && ( renderConfig.split_rend_config.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE || renderConfig.split_rend_config.dof == 0 ) ) { @@ -645,6 +653,7 @@ int main( return error; } +#endif #endif if ( RenderConfigReader_read( renderConfigReader, arg.renderConfigFilename, &renderConfig ) != IVAS_ERR_OK ) @@ -659,6 +668,31 @@ int main( goto cleanup; } +#ifdef SPLIT_REND_LCLD_5MS +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( asked_frame_size == IVAS_RENDER_FRAMESIZE_5MS && ( renderConfig.split_rend_config.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE || + renderConfig.split_rend_config.dof == 0 ) ) + { + arg.renderFramesize = IVAS_RENDER_FRAMESIZE_5MS; + } + else + { + arg.renderFramesize = IVAS_RENDER_FRAMESIZE_20MS; + } + + if ( ( error = IVAS_DEC_SetRenderFramesize( hIvasDec, arg.renderFramesize ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( arg.renderFramesize != asked_frame_size ) + { + fprintf( stderr, "\nChanged render framesize, only 20ms are allowed for non-0dof split rendering!\n" ); + } + +#endif +#endif + if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, arg.acousticEnvironmentId, &renderConfig.roomAcoustics ) ) == IVAS_ERR_OK ) diff --git a/lib_com/options.h b/lib_com/options.h index fc6c6a06aa..b1215c8761 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -134,6 +134,8 @@ /*#define SPLIT_REND_WITH_HEAD_ROT_DEBUG*/ /* debugging switch for split rendering */ /*#define SPLIT_POSE_CORRECTION_DEBUG*/ /* debugging switch for split rendering pose correction */ /*#define SPLIT_MD_CODING_DEBUG*/ /* debugging switch for split rendering metadata coding */ +/*#define DEBUG_WRITE_PREDICTORS*/ /* debugging switch for LCDL predictors*/ +/*#define DEBUG_WRITE_MS_PRED*/ /* debugging switch for LCLD mid-side prediction*/ #endif /* DEBUGGING */ @@ -172,6 +174,7 @@ #define SPLIT_REND_HF_TUNING /* Dlb: issue 950: split rendering MD tuning change at high frequencies*/ #define SPLIT_REND_MC_FIX_LFE /* Dlb: issue 950: split rendering LFE fix for 7.1 and 5.1 MC mode*/ #define SPLIT_EXT_REND_FIX_LIMITER_POS /* Dlb: issue 950: fixing limiter position in split rendering mode in external renderer*/ +#define SPLIT_REND_LCLD_5MS /* Dlb: LCLD 5ms framing operation */ #endif /* ##################### End NON-BE switches ########################### */ diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index d24e043648..2aea345c36 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -247,10 +247,18 @@ static ivas_error ivas_dec_init_split_rend( } } +#ifdef SPLIT_REND_LCLD_5MS + if ( ( error = ivas_split_rend_choose_default_codec( &st_ivas->hRenderConfig->split_rend_config.codec, &st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, pcm_out_flag, st_ivas->hDecoderConfig->render_framesize == IVAS_RENDER_FRAMESIZE_5MS ) ) != IVAS_ERR_OK ) + { + return error; + } +#else if ( ( error = ivas_split_rend_choose_default_codec( &st_ivas->hRenderConfig->split_rend_config.codec, &st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, pcm_out_flag ) ) != IVAS_ERR_OK ) { return error; } +#endif + #ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ivas_format == SBA_ISM_FORMAT ) @@ -2477,7 +2485,9 @@ void ivas_initialize_handles_dec( st_ivas->hSplitBinRend.hMultiBinCldfbData = NULL; st_ivas->hSplitBinRend.hSplitRendBits = NULL; st_ivas->hSplitBinRend.hCldfbDataOut = NULL; +#ifndef SPLIT_REND_LCLD_5MS st_ivas->hSplitBinRend.tdDataOut = NULL; +#endif st_ivas->hSplitBinRend.numTdSamplesPerChannelCached = 0; ivas_init_split_rend_handles( &st_ivas->hSplitBinRend.splitrend ); #endif @@ -2627,11 +2637,12 @@ void ivas_destroy_dec( free( st_ivas->hSplitBinRend.hCldfbDataOut ); st_ivas->hSplitBinRend.hCldfbDataOut = NULL; } - +#ifndef SPLIT_REND_LCLD_5MS if ( st_ivas->hSplitBinRend.tdDataOut != NULL ) { free( st_ivas->hSplitBinRend.tdDataOut ); } +#endif #endif /* Parametric binaural renderer handle */ diff --git a/lib_dec/ivas_mc_paramupmix_dec.c b/lib_dec/ivas_mc_paramupmix_dec.c index fdbca9f546..5fc36b9e61 100644 --- a/lib_dec/ivas_mc_paramupmix_dec.c +++ b/lib_dec/ivas_mc_paramupmix_dec.c @@ -66,11 +66,15 @@ const int16_t MC_PARAMUPMIX_CHIDX2[MC_PARAMUPMIX_COMBINATIONS] = { 2, 3, 6, 7 }; static void ps_pred_process_sf( MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix, DECODER_TC_BUFFER_HANDLE hTcBuffer, float qmf_mod_re[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float qmf_mod_im[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float qmf_side_re[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float qmf_side_im[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float *param_interpol, const int16_t ch, const int16_t slots_rendered ); +#ifndef SPLIT_REND_LCLD_5MS #ifdef SPLIT_REND_WITH_HEAD_ROT static void ivas_mc_paramupmix_dec_sf( Decoder_Struct *st_ivas, float *output_f[MAX_OUTPUT_CHANNELS], const int16_t slot_index_start ); #else static void ivas_mc_paramupmix_dec_sf( Decoder_Struct *st_ivas, float *output_f[MAX_OUTPUT_CHANNELS] ); #endif +#else +static void ivas_mc_paramupmix_dec_sf( Decoder_Struct *st_ivas, float *output_f[MAX_OUTPUT_CHANNELS] ); +#endif static void ivas_param_upmix_dec_decorr_subframes( Decoder_Struct *st_ivas, const int16_t nSamplesForRendering ); @@ -208,8 +212,10 @@ void ivas_mc_paramupmix_dec_render( int16_t slots_to_render, first_sf, last_sf, subframe_idx; uint16_t slot_size, ch; float *output_f_local[MAX_OUTPUT_CHANNELS]; +#ifndef SPLIT_REND_LCLD_5MS #ifdef SPLIT_REND_WITH_HEAD_ROT int16_t slot_index_start; +#endif #endif MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix; @@ -251,18 +257,22 @@ void ivas_mc_paramupmix_dec_render( mvr2r( hMCParamUpmix->alpha_prev[ch], hMCParamUpmix->alpha_sf[ch], IVAS_MAX_NUM_BANDS ); mvr2r( hMCParamUpmix->beta_prev[ch], hMCParamUpmix->beta_sf[ch], IVAS_MAX_NUM_BANDS ); } - +#ifndef SPLIT_REND_LCLD_5MS #ifdef SPLIT_REND_WITH_HEAD_ROT slot_index_start = 0; +#endif #endif for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) { int16_t n_samples_sf = slot_size * st_ivas->hTcBuffer->subframe_nbslots[subframe_idx]; - +#ifndef SPLIT_REND_LCLD_5MS #ifdef SPLIT_REND_WITH_HEAD_ROT ivas_mc_paramupmix_dec_sf( st_ivas, output_f_local, slot_index_start ); slot_index_start += st_ivas->hTcBuffer->subframe_nbslots[subframe_idx]; +#else + ivas_mc_paramupmix_dec_sf( st_ivas, output_f_local ); +#endif #else ivas_mc_paramupmix_dec_sf( st_ivas, output_f_local ); #endif @@ -644,7 +654,7 @@ static void ps_pred_process_sf( return; } - +#ifndef SPLIT_REND_LCLD_5MS static void ivas_mc_paramupmix_dec_sf( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ #ifdef SPLIT_REND_WITH_HEAD_ROT @@ -654,6 +664,12 @@ static void ivas_mc_paramupmix_dec_sf( float *output_f[MAX_OUTPUT_CHANNELS] /* i/o: synthesized core-coder transport channels */ #endif ) +#else +static void ivas_mc_paramupmix_dec_sf( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + float *output_f[MAX_OUTPUT_CHANNELS] /* i/o: synthesized core-coder transport channels */ +) +#endif { int16_t i, ch, slot_idx, k; float *pPcm_temp[MC_PARAMUPMIX_COMBINATIONS * 2]; /* decorrelated and undecorrelated*/ @@ -668,6 +684,9 @@ static void ivas_mc_paramupmix_dec_sf( #ifdef SPLIT_REND_WITH_HEAD_ROT float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#ifdef SPLIT_REND_LCLD_5MS + int16_t slot_index_start; +#endif #else float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; @@ -677,6 +696,11 @@ static void ivas_mc_paramupmix_dec_sf( assert( hMCParamUpmix ); push_wmops( "ivas_mc_paramupmix_dec_sf" ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef SPLIT_REND_LCLD_5MS + slot_index_start = st_ivas->hTcBuffer->slots_rendered; +#endif +#endif for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) { pPcm_temp[2 * i] = output_f[i + 4]; /* un-decorrelated */ diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 81427d9cfa..c3ea6c9c57 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -979,7 +979,9 @@ typedef struct IVAS_SPLIT_REND_BITS_HANDLE hSplitRendBits; /*scratch buffer for frame by frame processing*/ SPLIT_REND_WRAPPER splitrend; IVAS_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE hCldfbDataOut; /*buffer to store cldfb data before binauralization*/ - float *tdDataOut; /*buffer to store TD data before binauralization*/ +#ifndef SPLIT_REND_LCLD_5MS + float *tdDataOut; /*buffer to store TD data before binauralization*/ +#endif int16_t numTdSamplesPerChannelCached; } IVAS_DEC_SPLIT_REND_WRAPPER; diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 4bf943351e..c80c593d02 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -1036,14 +1036,21 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( Decoder_Struct *st_ivas; AUDIO_CONFIG output_config; int32_t output_Fs; +#ifndef SPLIT_REND_LCLD_5MS float *writePtr; float *readPtr, *readEnd; +#endif float *pOutput[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES]; float output[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES][L_FRAME48k]; float pcmBuf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES * L_FRAME48k]; +#ifdef SPLIT_REND_LCLD_5MS + float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; +#else int16_t numSamplesPerChannelCacheSize; - int16_t numSamplesPerChannelToDecode; int16_t numSamplesPerChannelToSplitEncode; +#endif + int16_t numSamplesPerChannelToDecode; int16_t i, j; ivas_error error; IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend; @@ -1051,6 +1058,9 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( int16_t pcm_out_flag; int16_t td_input; int16_t numPoses; +#ifdef SPLIT_REND_LCLD_5MS + int16_t slots_rendered, slots_rendered_new; +#endif #ifdef SPLIT_REND_HF_TUNING int16_t ro_md_flag; #endif @@ -1071,6 +1081,14 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( numPoses = hSplitBinRend->splitrend.multiBinPoseData.num_poses; +#ifdef SPLIT_REND_LCLD_5MS + if ( st_ivas->hDecoderConfig->render_framesize == IVAS_RENDER_FRAMESIZE_5MS && + ( hIvasDec->st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE || + hIvasDec->st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) + { + numSamplesPerChannelToDecode = (int16_t) ( output_Fs / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ); + } +#else if ( st_ivas->hDecoderConfig->render_framesize == IVAS_RENDER_FRAMESIZE_5MS && hIvasDec->st_ivas->hRenderConfig->split_rend_config.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && ( hIvasDec->st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE || hIvasDec->st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) @@ -1092,12 +1110,29 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( numSamplesPerChannelToSplitEncode = (int16_t) ( output_Fs / FRAMES_PER_SEC ); numSamplesPerChannelCacheSize = 0; } - +#endif if ( output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { return IVAS_ERR_WRONG_PARAMS; } +#ifdef SPLIT_REND_LCLD_5MS + if ( st_ivas->hTcBuffer == NULL || hIvasDec->hasBeenFedFrame ) + { + slots_rendered = 0; + } + else + { + slots_rendered = st_ivas->hTcBuffer->n_samples_rendered / st_ivas->hTcBuffer->n_samples_granularity; + } + + + /* Decode and render */ + if ( ( error = IVAS_DEC_GetSamples( hIvasDec, numSamplesPerChannelToDecode, IVAS_DEC_PCM_FLOAT, pcmBuf, nOutSamples, needNewFrame ) ) != IVAS_ERR_OK ) + { + return error; + } +#else if ( numSamplesPerChannelToDecode == numSamplesPerChannelToSplitEncode || hSplitBinRend->numTdSamplesPerChannelCached == 0 ) { /* Decode and render */ @@ -1138,9 +1173,14 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( } hSplitBinRend->numTdSamplesPerChannelCached -= numSamplesPerChannelToSplitEncode; } +#endif - /* change buffer layout */ +/* change buffer layout */ +#ifdef SPLIT_REND_LCLD_5MS + for ( i = 0; i < numSamplesPerChannelToDecode; ++i ) +#else for ( i = 0; i < numSamplesPerChannelToSplitEncode; ++i ) +#endif { for ( j = 0; j < BINAURAL_CHANNELS * numPoses; ++j ) { @@ -1152,6 +1192,26 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( pOutput[i] = output[i]; } +#ifdef SPLIT_REND_LCLD_5MS + if ( st_ivas->hTcBuffer == NULL ) + { + slots_rendered_new = 0; + } + else + { + slots_rendered_new = st_ivas->hTcBuffer->n_samples_rendered / st_ivas->hTcBuffer->n_samples_granularity; + } + + for ( i = 0; i < BINAURAL_CHANNELS * numPoses; ++i ) + { + for ( j = slots_rendered; j < slots_rendered_new; ++j ) + { + mvr2r( hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[i][j], Cldfb_RealBuffer_Binaural[i][j - slots_rendered], CLDFB_NO_CHANNELS_MAX ); + mvr2r( hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[i][j], Cldfb_ImagBuffer_Binaural[i][j - slots_rendered], CLDFB_NO_CHANNELS_MAX ); + } + } +#endif + max_band = (int16_t) ( ( BINAURAL_MAXBANDS * output_Fs ) / 48000 ); pcm_out_flag = ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; td_input = st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM && st_ivas->renderer_type != RENDERER_STEREO_PARAMETRIC; @@ -1172,8 +1232,13 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( st_ivas->hRenderConfig->split_rend_config.codec, st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms, hSplitBinRend->hSplitRendBits, +#ifdef SPLIT_REND_LCLD_5MS + Cldfb_RealBuffer_Binaural, + Cldfb_ImagBuffer_Binaural, +#else hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural, hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural, +#endif max_band, pOutput, 1, !td_input, pcm_out_flag, ro_md_flag ) ) != IVAS_ERR_OK ) #else if ( ( error = ivas_renderMultiBinToSplitBinaural( &hSplitBinRend->splitrend, @@ -1182,8 +1247,13 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( st_ivas->hRenderConfig->split_rend_config.codec, st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms, hSplitBinRend->hSplitRendBits, +#ifdef SPLIT_REND_LCLD_5MS + Cldfb_RealBuffer_Binaural, + Cldfb_ImagBuffer_Binaural, +#else hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural, hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural, +#endif max_band, pOutput, 1, !td_input, pcm_out_flag ) ) != IVAS_ERR_OK ) #endif { @@ -1196,18 +1266,30 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( if ( st_ivas->hDecoderConfig->render_framesize == IVAS_RENDER_FRAMESIZE_5MS ) { #ifndef DISABLE_LIMITER +#ifdef SPLIT_REND_LCLD_5MS + ivas_limiter_dec( st_ivas->hLimiter, pOutput, st_ivas->hDecoderConfig->nchan_out, numSamplesPerChannelToDecode, st_ivas->BER_detect ); +#else ivas_limiter_dec( st_ivas->hLimiter, pOutput, st_ivas->hDecoderConfig->nchan_out, numSamplesPerChannelToSplitEncode, st_ivas->BER_detect ); +#endif #endif } else { +#ifdef SPLIT_REND_LCLD_5MS + ivas_limiter_dec( st_ivas->hLimiter, pOutput, st_ivas->hDecoderConfig->nchan_out, numSamplesPerChannelToDecode, st_ivas->BER_detect ); +#else ivas_limiter_dec( st_ivas->hLimiter, pOutput, st_ivas->hDecoderConfig->nchan_out, numSamplesPerChannelToSplitEncode, st_ivas->BER_detect ); +#endif } #ifdef DEBUGGING st_ivas->noClipping += #endif - ivas_syn_output( pOutput, numSamplesPerChannelToSplitEncode, st_ivas->hDecoderConfig->nchan_out, (int16_t *) pcmBuf_out ); +#ifdef SPLIT_REND_LCLD_5MS + ivas_syn_output( pOutput, numSamplesPerChannelToDecode, st_ivas->hDecoderConfig->nchan_out, (int16_t *) pcmBuf_out ); +#else + ivas_syn_output( pOutput, numSamplesPerChannelToSplitEncode, st_ivas->hDecoderConfig->nchan_out, (int16_t *) pcmBuf_out ); +#endif } free( st_ivas->hSplitBinRend.hMultiBinCldfbData ); diff --git a/lib_rend/ivas_MSPred.c b/lib_rend/ivas_MSPred.c index 4dcdbbb1cf..fcfb29a55c 100644 --- a/lib_rend/ivas_MSPred.c +++ b/lib_rend/ivas_MSPred.c @@ -61,15 +61,6 @@ static int32_t _round( int32_t quantPhase( float phase ) { -#ifdef SIMPLE_PHASE - int32_t phaseQ; - if ( phase < 0.0f ) - { - phase += 2.0f * _PI_; - } - phaseQ = _round( phase * SIMPLE_PHASE_QUANT_FACTOR ); - phaseQ = ( phaseQ > SIMPLE_PHASE_MAX_VAL ? SIMPLE_PHASE_MIN_VAL : phaseQ ); -#else int32_t phaseQ; phaseQ = _round( phase * PHASE_QUANT_FACTOR ); @@ -77,83 +68,9 @@ int32_t quantPhase( { phaseQ = PHASE_MIN_VAL; } -#endif return phaseQ; } -#ifdef SIMPLE_PHASE -/*-------------------------------------------------------------------* - * Function rot_pm_pi() - * - * - *-------------------------------------------------------------------*/ - -void rot_pm_pi( - float *pr, - float *pi ) -{ - /* (-1 + j0) */ - *pr = -( *pr ); - *pi = -( *pi ); - - return; -} - - -/*-------------------------------------------------------------------* - * Function ApplyInversePredictros() - * - * - *-------------------------------------------------------------------*/ - -void rot_p_pi_2( - float *pr, - float *pi ) -{ - /* (0 + j) */ - float r = *pr; - - *pr = -( *pi ); - *pi = r; - - return; -} - -/*-------------------------------------------------------------------* - * Function rot_zero() - * - * - *-------------------------------------------------------------------*/ - -void rot_zero( - float *pr, - float *pi ) -{ - *pr = *pr; - *pi = *pi; - - return; -} - -/*-------------------------------------------------------------------* - * Function rot_m_pi_2() - * - * - *-------------------------------------------------------------------*/ - -void rot_m_pi_2( - float *pr, - float *pi ) -{ - /* (0 - j) */ - float r = *pr; - - *pr = *pi; - *pi = -r; - - return; -} -#endif /*-------------------------------------------------------------------* * Function cplxmult() @@ -233,11 +150,7 @@ int32_t quantPred( float dequantPhase( const int32_t phaseQ ) { -#ifdef SIMPLE_PHASE - return (float) phaseQ / SIMPLE_PHASE_QUANT_FACTOR; -#else return (float) phaseQ / PHASE_QUANT_FACTOR; -#endif } @@ -468,9 +381,7 @@ int32_t CountMSBits( /* Differential Coding of Phase Data*/ PrepEncode( piPhaseCopy, piMSFlags, iNumBands ); PrepEncode( piPredCopy, piMSFlags, iNumBands ); -#ifndef SIMPLE_PHASE EncodePhase( piPhaseCopy, iNumMSBands, PHASE_DIFF_DIM ); -#endif EncodePredCoef( piPredCopy, iNumMSBands ); iBitsWritten += 1; /* iMSPredAll */ @@ -486,16 +397,12 @@ int32_t CountMSBits( iBitsWritten++; /*anyNonZero Phase*/ if ( anyNonZero ) { -#ifdef SIMPLE_PHASE - iBitsWritten += iNumMSBands * SIMPLE_PHASE_BITS; -#else iBitsWritten += PHASE_BAND0_BITS; for ( b = 1; b < iNumMSBands; b++ ) { int32_t tabIdx = piPhaseCopy[b] - ENV_DELTA_MIN; iBitsWritten += c_aaiRMSEnvHuffEnc[tabIdx][0]; } -#endif } anyNonZero = 0; /* prediction */ for ( b = 0; b < iNumMSBands; b++ ) diff --git a/lib_rend/ivas_PredDecoder.c b/lib_rend/ivas_PredDecoder.c index 914435e2fe..cc383160e2 100644 --- a/lib_rend/ivas_PredDecoder.c +++ b/lib_rend/ivas_PredDecoder.c @@ -40,6 +40,18 @@ #include "ivas_lcld_rom_tables.h" #include "wmc_auto.h" +#ifdef SPLIT_REND_LCLD_5MS +/*-------------------------------------------------------------------* + * Function get_bit() + * + * + *-------------------------------------------------------------------*/ + +static int get_bit( int state, int bit_id ) +{ + return ( state & ( 1 << bit_id ) ); +} +#endif /*-------------------------------------------------------------------* * Function CreatePredictionDecoder() @@ -53,6 +65,9 @@ ivas_error CreatePredictionDecoder( const int32_t iNumBlocks ) { int16_t n; +#ifdef SPLIT_REND_LCLD_5MS + int16_t m; +#endif PredictionDecoder *psPredictionDecoder = NULL; if ( ( psPredictionDecoder = (PredictionDecoder *) malloc( sizeof( PredictionDecoder ) ) ) == NULL ) @@ -62,11 +77,15 @@ ivas_error CreatePredictionDecoder( psPredictionDecoder->iChannels = iChannels; psPredictionDecoder->iNumBlocks = iNumBlocks; - +#ifdef SPLIT_REND_LCLD_5MS + psPredictionDecoder->iNumSubSets = LCLD_BLOCKS_PER_FRAME / psPredictionDecoder->iNumBlocks; + psPredictionDecoder->iSubSetId = 0; +#endif if ( ( psPredictionDecoder->piPredChanEnable = (int32_t *) malloc( sizeof( int32_t ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } +#ifndef SPLIT_REND_LCLD_5MS if ( ( psPredictionDecoder->piNumPredBands = (int32_t *) malloc( sizeof( int32_t ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); @@ -76,6 +95,7 @@ ivas_error CreatePredictionDecoder( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } +#endif if ( ( psPredictionDecoder->ppiPredBandEnable = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); @@ -96,17 +116,37 @@ ivas_error CreatePredictionDecoder( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } +#ifdef SPLIT_REND_LCLD_5MS + if ( ( psPredictionDecoder->ppfPredStateReal = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); + } + if ( ( psPredictionDecoder->ppfPredStateImag = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); + } +#endif for ( n = 0; n < psPredictionDecoder->iChannels; n++ ) { +#ifdef SPLIT_REND_LCLD_5MS + psPredictionDecoder->piPredChanEnable[n] = 0; +#else if ( ( psPredictionDecoder->ppfEstPredGain[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psPredictionDecoder->ppiPredBandEnable[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_BANDS ) ) == NULL ) +#endif + if ( ( psPredictionDecoder->ppiPredBandEnable[n] = (int32_t *) malloc( LCLD_BANDS * sizeof( int32_t ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } +#ifdef SPLIT_REND_LCLD_5MS + for ( m = 0; m < LCLD_BANDS; m++ ) + { + psPredictionDecoder->ppiPredBandEnable[n][m] = 0; + } +#endif if ( ( psPredictionDecoder->ppfA1Real[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); @@ -123,6 +163,23 @@ ivas_error CreatePredictionDecoder( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } +#ifdef SPLIT_REND_LCLD_5MS + if ( ( psPredictionDecoder->ppfPredStateReal[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionDecoder Module \n" ) ); + } + if ( ( psPredictionDecoder->ppfPredStateImag[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionDecoder Module \n" ) ); + } +#ifdef SPLIT_REND_LCLD_5MS + for ( m = 0; m < LCLD_BANDS; m++ ) + { + psPredictionDecoder->ppfPredStateReal[n][m] = 0; + psPredictionDecoder->ppfPredStateImag[n][m] = 0; + } +#endif +#endif } /* pre-define these tables? */ @@ -161,21 +218,33 @@ void DeletePredictionDecoder( for ( n = 0; n < psPredictionDecoder->iChannels; n++ ) { +#ifndef SPLIT_REND_LCLD_5MS free( psPredictionDecoder->ppfEstPredGain[n] ); +#endif free( psPredictionDecoder->ppiPredBandEnable[n] ); free( psPredictionDecoder->ppfA1Real[n] ); free( psPredictionDecoder->ppfA1Imag[n] ); free( psPredictionDecoder->ppiA1Mag[n] ); free( psPredictionDecoder->ppiA1Phase[n] ); +#ifdef SPLIT_REND_LCLD_5MS + free( psPredictionDecoder->ppfPredStateReal[n] ); + free( psPredictionDecoder->ppfPredStateImag[n] ); +#endif } free( psPredictionDecoder->piPredChanEnable ); +#ifndef SPLIT_REND_LCLD_5MS free( psPredictionDecoder->piNumPredBands ); free( psPredictionDecoder->ppfEstPredGain ); +#endif free( psPredictionDecoder->ppiPredBandEnable ); free( psPredictionDecoder->ppfA1Real ); free( psPredictionDecoder->ppfA1Imag ); free( psPredictionDecoder->ppiA1Mag ); free( psPredictionDecoder->ppiA1Phase ); +#ifdef SPLIT_REND_LCLD_5MS + free( psPredictionDecoder->ppfPredStateReal ); + free( psPredictionDecoder->ppfPredStateImag ); +#endif free( psPredictionDecoder ); psPredictionDecoder = NULL; @@ -183,7 +252,7 @@ void DeletePredictionDecoder( return; } - +#ifndef SPLIT_REND_LCLD_5MS #define USE_TABLE_LOOKUP /*-------------------------------------------------------------------* * Function ReadPredictors() @@ -286,7 +355,105 @@ int32_t ReadPredictors( return iBitsRead; } +#else +/*-------------------------------------------------------------------* + * Function ReadPredictors() + * + * + *-------------------------------------------------------------------*/ + +int32_t ReadPredictors( + PredictionDecoder *psPredictionDecoder, + IVAS_SPLIT_REND_BITS_HANDLE pBits ) +{ + int16_t iBitsRead = 0; + int32_t c; + int32_t b; + int16_t iNumPredBandBits = 6; + const int16_t iSubSetBits = ( LCLD_MAX_NUM_PRED_SUBSETS > 4 ? 3 : 2 ); + psPredictionDecoder->iNumSubSets = ivas_split_rend_bitstream_read_int32( pBits, iSubSetBits ) + 1; + iBitsRead += iSubSetBits; + + if ( psPredictionDecoder->iNumSubSets > 1 ) + { + psPredictionDecoder->iSubSetId = ivas_split_rend_bitstream_read_int32( pBits, iSubSetBits ); + iBitsRead += iSubSetBits; + iNumPredBandBits = ( psPredictionDecoder->iNumSubSets >= 4 ? 4 : 5 ); + } + else + { + psPredictionDecoder->iSubSetId = 0; + } + for ( c = 0; c < psPredictionDecoder->iChannels; c++ ) + { + psPredictionDecoder->piPredChanEnable[c] = ivas_split_rend_bitstream_read_int32( pBits, psPredictionDecoder->iNumSubSets ); + iBitsRead += (int16_t) psPredictionDecoder->iNumSubSets; + + if ( get_bit( psPredictionDecoder->piPredChanEnable[c], psPredictionDecoder->iSubSetId ) ) + { + int32_t b0 = psPredictionDecoder->iSubSetId; + int32_t bstep = psPredictionDecoder->iNumSubSets; + int32_t iNumPredBands; + + for ( b = b0; b < LCLD_BANDS; b += bstep ) + { + psPredictionDecoder->ppiPredBandEnable[c][b] = 0; + } + iNumPredBands = ivas_split_rend_bitstream_read_int32( pBits, iNumPredBandBits ); + iBitsRead += iNumPredBandBits; + iNumPredBands = iNumPredBands * psPredictionDecoder->iNumSubSets + b0; + + for ( b = b0; b < iNumPredBands; b += bstep ) + { + psPredictionDecoder->ppiPredBandEnable[c][b] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iBitsRead += 1; + + if ( psPredictionDecoder->ppiPredBandEnable[c][b] == 1 ) + { + int32_t iA1Mag; + int32_t iA1Phase; + float fA1Real; + float fA1Imag; + iA1Mag = ivas_split_rend_bitstream_read_int32( pBits, PRED_QUNAT_FILTER_MAG_BITS ); + iBitsRead += PRED_QUNAT_FILTER_MAG_BITS; + iA1Phase = ivas_split_rend_bitstream_read_int32( pBits, PRED_QUANT_FILTER_PHASE_BITS ); + iBitsRead += PRED_QUANT_FILTER_PHASE_BITS; + + psPredictionDecoder->ppiA1Mag[c][b] = iA1Mag; + psPredictionDecoder->ppiA1Phase[c][b] = iA1Phase + PRED_QUANT_FILTER_PHASE_MIN; + + fA1Real = psPredictionDecoder->pfMagLUT[iA1Mag] * psPredictionDecoder->pfP2RRealLUT[iA1Phase]; + fA1Imag = psPredictionDecoder->pfMagLUT[iA1Mag] * psPredictionDecoder->pfP2RImagLUT[iA1Phase]; + + psPredictionDecoder->ppfA1Real[c][b] = fA1Real; + psPredictionDecoder->ppfA1Imag[c][b] = fA1Imag; + } + } + } + } + + /* disable any inactive prediction bands */ + for ( c = 0; c < psPredictionDecoder->iChannels; c++ ) + { + int set; + for ( set = 0; set < psPredictionDecoder->iNumSubSets; set++ ) + { + if ( !get_bit( psPredictionDecoder->piPredChanEnable[c], set ) ) + { + for ( b = set; b < LCLD_BANDS; b += psPredictionDecoder->iNumSubSets ) + { + psPredictionDecoder->ppiPredBandEnable[c][b] = 0; + } + } + } + } + + return iBitsRead; +} +#endif + +#ifndef SPLIT_REND_LCLD_5MS /*-------------------------------------------------------------------* * Function ApplyInversePredictros() * @@ -332,4 +499,65 @@ void ApplyInversePredictros( return; } +#else +/*-------------------------------------------------------------------* + * Function ApplyInversePredictors() + * + * + *-------------------------------------------------------------------*/ + +void ApplyInversePredictors( + PredictionDecoder *psPredictionDecoder, + float ***pppfReal, + float ***pppfImag ) +{ + int32_t c; + for ( c = 0; c < psPredictionDecoder->iChannels; c++ ) + { + if ( psPredictionDecoder->piPredChanEnable[c] > 0 ) + { + int32_t b; + for ( b = 0; b < LCLD_BANDS; b++ ) + { + if ( psPredictionDecoder->ppiPredBandEnable[c][b] == 1 ) + { + int32_t n; + float fA1Real; + float fA1Imag; + float fPrevReal = 0.0f; + float fPrevImag = 0.0f; + int32_t iSubset = b % psPredictionDecoder->iNumSubSets; + + if ( iSubset != psPredictionDecoder->iSubSetId ) + { + fPrevReal = psPredictionDecoder->ppfPredStateReal[c][b]; + fPrevImag = psPredictionDecoder->ppfPredStateImag[c][b]; + } + + fA1Real = psPredictionDecoder->ppfA1Real[c][b]; + fA1Imag = psPredictionDecoder->ppfA1Imag[c][b]; + for ( n = 0; n < psPredictionDecoder->iNumBlocks; n++ ) + { + float fReal; + float fImag; + + fReal = pppfReal[c][n][b] - fA1Real * fPrevReal + fA1Imag * fPrevImag; + fImag = pppfImag[c][n][b] - fA1Real * fPrevImag - fA1Imag * fPrevReal; + + pppfReal[c][n][b] = fReal; + pppfImag[c][n][b] = fImag; + + fPrevReal = fReal; + fPrevImag = fImag; + } + psPredictionDecoder->ppfPredStateReal[c][b] = fPrevReal; + psPredictionDecoder->ppfPredStateImag[c][b] = fPrevImag; + } + } + } + } + + return; +} +#endif #endif diff --git a/lib_rend/ivas_PredEncoder.c b/lib_rend/ivas_PredEncoder.c index 804a00a6a1..b4fdc234af 100644 --- a/lib_rend/ivas_PredEncoder.c +++ b/lib_rend/ivas_PredEncoder.c @@ -40,6 +40,40 @@ #include "ivas_prot_rend.h" #include "wmc_auto.h" +#ifdef SPLIT_REND_LCLD_5MS + +/*-------------------------------------------------------------------* + * Function activate_bit() + * + * + *-------------------------------------------------------------------*/ +static void activate_bit( int *state, int bit_id ) +{ + ( *state ) |= ( 1 << bit_id ); +} + +/*-------------------------------------------------------------------* + * Function deactivate_bit() + * + * + *-------------------------------------------------------------------*/ + +static void deactivate_bit( int *state, int bit_id ) +{ + ( *state ) &= ( ~( 1 << bit_id ) ); +} + +/*-------------------------------------------------------------------* + * Function get_bit() + * + * + *-------------------------------------------------------------------*/ + +static int get_bit( int state, int bit_id ) +{ + return ( state & ( 1 << bit_id ) ); +} +#endif /*-------------------------------------------------------------------* * Function CreatePredictionEncoder() @@ -47,10 +81,19 @@ * *-------------------------------------------------------------------*/ +#ifdef SPLIT_REND_LCLD_5MS +ivas_error CreatePredictionEncoder( + PredictionEncoder **psPredictionEncoder_out, + const int32_t iChannels, + const int32_t iNumBlocks, + const int32_t iNumSubSets, + const int32_t iMaxNumPredBands ) +#else ivas_error CreatePredictionEncoder( PredictionEncoder **psPredictionEncoder_out, const int32_t iChannels, const int32_t iNumBlocks ) +#endif { int32_t k, n; PredictionEncoder *psPredictionEncoder = NULL; @@ -62,15 +105,33 @@ ivas_error CreatePredictionEncoder( psPredictionEncoder->iChannels = iChannels; psPredictionEncoder->iNumBlocks = iNumBlocks; - +#ifdef SPLIT_REND_LCLD_5MS + psPredictionEncoder->iSubSetId = 0; + psPredictionEncoder->iMaxNumPredBands = iMaxNumPredBands; + psPredictionEncoder->iNumSubSets = iNumSubSets; + if ( ( psPredictionEncoder->pfWindow = (float *) malloc( sizeof( float ) * LCLD_PRED_WIN_LEN ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } +#else if ( ( psPredictionEncoder->pfWindow = (float *) malloc( sizeof( float ) * iNumBlocks ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); } +#endif + +#ifdef SPLIT_REND_LCLD_5MS + for ( n = 0; n < LCLD_PRED_WIN_LEN; n++ ) + { + psPredictionEncoder->pfWindow[n] = 0.54f - 0.46f * cosf( 2.0f * M_PI * ( (float) n + 0.5f ) / (float) LCLD_PRED_WIN_LEN ); + } +#else for ( n = 0; n < iNumBlocks; n++ ) { psPredictionEncoder->pfWindow[n] = 0.54f - 0.46f * cosf( 2.0f * M_PI * ( (float) n + 0.5f ) / (float) iNumBlocks ); } +#endif + if ( ( psPredictionEncoder->piPredChanEnable = (int32_t *) malloc( sizeof( int32_t ) * iChannels ) ) == NULL ) { @@ -87,6 +148,60 @@ ivas_error CreatePredictionEncoder( psPredictionEncoder->piNumPredBands[n] = 40; // Will need to be set correctly } +#ifdef SPLIT_REND_LCLD_5MS + if ( ( psPredictionEncoder->ppiPredBandEnable = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfA1Real = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfA1Imag = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppiA1Mag = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppiA1Phase = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->pppfInpBufReal = (float ***) malloc( sizeof( float ** ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->pppfInpBufImag = (float ***) malloc( sizeof( float ** ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfInpPrevReal = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfInpPrevImag = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfPredStateReal = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfPredStateImag = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfPredStateRealTmp = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfPredStateImagTmp = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } +#else if ( ( psPredictionEncoder->ppfEstPredGain = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); @@ -116,8 +231,11 @@ ivas_error CreatePredictionEncoder( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); } +#endif + for ( n = 0; n < psPredictionEncoder->iChannels; n++ ) { +#ifndef SPLIT_REND_LCLD_5MS if ( ( psPredictionEncoder->ppfEstPredGain[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); @@ -126,6 +244,7 @@ ivas_error CreatePredictionEncoder( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); } +#endif if ( ( psPredictionEncoder->ppiPredBandEnable[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_BANDS ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); @@ -146,11 +265,72 @@ ivas_error CreatePredictionEncoder( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); } +#ifdef SPLIT_REND_LCLD_5MS + if ( ( psPredictionEncoder->pppfInpBufReal[n] = (float **) malloc( sizeof( float * ) * LCLD_PRED_WIN_LEN ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->pppfInpBufImag[n] = (float **) malloc( sizeof( float * ) * LCLD_PRED_WIN_LEN ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + for ( k = 0; k < LCLD_PRED_WIN_LEN; k++ ) + { + if ( ( psPredictionEncoder->pppfInpBufReal[n][k] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->pppfInpBufImag[n][k] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + set_zero( psPredictionEncoder->pppfInpBufReal[n][k], LCLD_BANDS ); + set_zero( psPredictionEncoder->pppfInpBufImag[n][k], LCLD_BANDS ); + } + if ( ( psPredictionEncoder->ppfPredStateReal[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfPredStateImag[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + set_zero( psPredictionEncoder->ppfPredStateReal[n], LCLD_BANDS ); + set_zero( psPredictionEncoder->ppfPredStateImag[n], LCLD_BANDS ); + + if ( ( psPredictionEncoder->ppfInpPrevReal[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfInpPrevImag[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + + set_zero( psPredictionEncoder->ppfInpPrevReal[n], LCLD_BANDS ); + set_zero( psPredictionEncoder->ppfInpPrevImag[n], LCLD_BANDS ); + + if ( ( psPredictionEncoder->ppfPredStateRealTmp[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfPredStateImagTmp[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + set_zero( psPredictionEncoder->ppfPredStateRealTmp[n], LCLD_BANDS ); + set_zero( psPredictionEncoder->ppfPredStateImagTmp[n], LCLD_BANDS ); +#endif for ( k = 0; k < LCLD_BANDS; k++ ) { psPredictionEncoder->ppiPredBandEnable[n][k] = 0; +#ifndef SPLIT_REND_LCLD_5MS psPredictionEncoder->ppfA1Real[n][k] = 0.0; psPredictionEncoder->ppfA1Imag[n][k] = 0.0; +#else + psPredictionEncoder->ppfA1Real[n][k] = 0.0f; + psPredictionEncoder->ppfA1Imag[n][k] = 0.0f; +#endif } } @@ -175,23 +355,55 @@ void DeletePredictionEncoder( for ( n = 0; n < psPredictionEncoder->iChannels; n++ ) { +#ifdef SPLIT_REND_LCLD_5MS + int32_t k; +#else free( psPredictionEncoder->ppfEstPredGain[n] ); free( psPredictionEncoder->ppfEstPredBitGain[n] ); +#endif free( psPredictionEncoder->ppiPredBandEnable[n] ); free( psPredictionEncoder->ppfA1Real[n] ); free( psPredictionEncoder->ppfA1Imag[n] ); free( psPredictionEncoder->ppiA1Mag[n] ); free( psPredictionEncoder->ppiA1Phase[n] ); +#ifdef SPLIT_REND_LCLD_5MS + for ( k = 0; k < LCLD_PRED_WIN_LEN; k++ ) + { + free( psPredictionEncoder->pppfInpBufReal[n][k] ); + free( psPredictionEncoder->pppfInpBufImag[n][k] ); + } + free( psPredictionEncoder->pppfInpBufReal[n] ); + free( psPredictionEncoder->pppfInpBufImag[n] ); + free( psPredictionEncoder->ppfInpPrevReal[n] ); + free( psPredictionEncoder->ppfInpPrevImag[n] ); + free( psPredictionEncoder->ppfPredStateReal[n] ); + free( psPredictionEncoder->ppfPredStateImag[n] ); + free( psPredictionEncoder->ppfPredStateRealTmp[n] ); + free( psPredictionEncoder->ppfPredStateImagTmp[n] ); +#endif } free( psPredictionEncoder->piPredChanEnable ); free( psPredictionEncoder->piNumPredBands ); +#ifndef SPLIT_REND_LCLD_5MS free( psPredictionEncoder->ppfEstPredGain ); free( psPredictionEncoder->ppfEstPredBitGain ); +#endif free( psPredictionEncoder->ppiPredBandEnable ); free( psPredictionEncoder->ppfA1Real ); free( psPredictionEncoder->ppfA1Imag ); free( psPredictionEncoder->ppiA1Mag ); free( psPredictionEncoder->ppiA1Phase ); +#ifdef SPLIT_REND_LCLD_5MS + free( psPredictionEncoder->pppfInpBufReal ); + free( psPredictionEncoder->pppfInpBufImag ); + free( psPredictionEncoder->ppfInpPrevReal ); + free( psPredictionEncoder->ppfInpPrevImag ); + free( psPredictionEncoder->ppfPredStateReal ); + free( psPredictionEncoder->ppfPredStateImag ); + free( psPredictionEncoder->ppfPredStateRealTmp ); + free( psPredictionEncoder->ppfPredStateImagTmp ); +#endif + free( psPredictionEncoder ); @@ -206,7 +418,216 @@ void DeletePredictionEncoder( * * *-------------------------------------------------------------------*/ +#ifdef SPLIT_REND_LCLD_5MS +void ComputePredictors( + PredictionEncoder *psPredictionEncoder, + float ***pppfReal, + float ***pppfImag ) +{ + int32_t c; + + int32_t b0 = psPredictionEncoder->iSubSetId; + int32_t bstep = psPredictionEncoder->iNumSubSets; + int32_t iNumBlocks = psPredictionEncoder->iNumBlocks; + float ***pppfRealBuf; + float ***pppfImagBuf; + float pfEstPredBitGain[LCLD_BANDS] = { 0 }; + + if ( iNumBlocks < LCLD_PRED_WIN_LEN ) + { + pppfRealBuf = psPredictionEncoder->pppfInpBufReal; + pppfImagBuf = psPredictionEncoder->pppfInpBufImag; + for ( c = 0; c < psPredictionEncoder->iChannels; c++ ) + { + int n; + for ( n = 0; n < LCLD_PRED_WIN_LEN - iNumBlocks; n++ ) + { + mvr2r( pppfRealBuf[c][n + iNumBlocks], pppfRealBuf[c][n], LCLD_BANDS ); + mvr2r( pppfImagBuf[c][n + iNumBlocks], pppfImagBuf[c][n], LCLD_BANDS ); + } + for ( n = 0; n < iNumBlocks; n++ ) + { + mvr2r( pppfReal[c][n], pppfRealBuf[c][n + LCLD_PRED_WIN_LEN - iNumBlocks], LCLD_BANDS ); + mvr2r( pppfImag[c][n], pppfImagBuf[c][n + LCLD_PRED_WIN_LEN - iNumBlocks], LCLD_BANDS ); + } + } + } + else + { + pppfRealBuf = pppfReal; + pppfImagBuf = pppfImag; + } + + for ( c = 0; c < psPredictionEncoder->iChannels; c++ ) + { + int32_t b; + psPredictionEncoder->piNumPredBands[c] = min( 50, psPredictionEncoder->iMaxNumPredBands ); + for ( b = b0; b < psPredictionEncoder->piNumPredBands[c]; b += bstep ) + { + int32_t n; + float fGain = 0.0; + float fBitGain = 0.0; + float *pfRxxReal; + float *pfRxxImag; + float fA1Real; + float fA1Imag; + int32_t iA1Mag; + int32_t iA1Phase; + + pfRxxReal = psPredictionEncoder->pfRxxReal; + pfRxxImag = psPredictionEncoder->pfRxxImag; + + pfRxxReal[0] = 0.0; + pfRxxImag[0] = 0.0; + for ( n = 0; n < LCLD_PRED_WIN_LEN; n++ ) + { +#ifdef USE_RXX_WINDOW + float fReal; + float fImag; + fReal = psPredictionEncoder->pfWindow[n] * pppfRealBuf[c][n][b]; + fImag = psPredictionEncoder->pfWindow[n] * pppfImagBuf[c][n][b]; + pfRxxReal[0] += ( fReal * fReal + fImag * fImag ); +#else + pfRxxReal[0] += ( pppfRealBuf[c][n][b] * pppfRealBuf[c][n][b] + pppfImagBuf[c][n][b] * pppfImagBuf[c][n][b] ); +#endif + } + + pfRxxReal[1] = 0.0; + pfRxxImag[1] = 0.0; + for ( n = 1; n < LCLD_PRED_WIN_LEN; n++ ) + { +#ifdef USE_RXX_WINDOW + float fReal1; + float fImag1; + float fReal2; + float fImag2; + fReal1 = psPredictionEncoder->pfWindow[n] * pppfRealBuf[c][n][b]; + fImag1 = psPredictionEncoder->pfWindow[n] * pppfImagBuf[c][n][b]; + fReal2 = psPredictionEncoder->pfWindow[n - 1] * pppfRealBuf[c][n - 1][b]; + fImag2 = psPredictionEncoder->pfWindow[n - 1] * pppfImagBuf[c][n - 1][b]; + pfRxxReal[1] += ( fReal1 * fReal2 + fImag1 * fImag2 ); + pfRxxImag[1] += ( fImag1 * fReal2 - fReal1 * fImag2 ); +#else + pfRxxReal[1] += ( pppfRealBuf[c][n][b] * pppfRealBuf[c][n - 1][b] + pppfImagBuf[c][n][b] * pppfImagBuf[c][n - 1][b] ); + pfRxxImag[1] += ( pppfImagBuf[c][n][b] * pppfRealBuf[c][n - 1][b] - pppfRealBuf[c][n][b] * pppfImagBuf[c][n - 1][b] ); +#endif + } + + if ( pfRxxReal[0] > 1e-12f ) + { + float fA1Mag; + float fA1Phase; + float fGain2; + float fBitGain2; + int iNumBlocksPerPredCoef = min( iNumBlocks * psPredictionEncoder->iNumSubSets, LCLD_PRED_WIN_LEN ); + + const float fMagScale = ( 2.0f * (float) ( 1 << ( PRED_QUNAT_FILTER_MAG_BITS ) ) + 1.0f ) / M_PI; + const float fInvMagScale = M_PI / ( 2.0f * (float) ( 1 << ( PRED_QUNAT_FILTER_MAG_BITS ) ) + 1.0f ); + const float fPhaseScale = (float) ( 1 << ( PRED_QUANT_FILTER_PHASE_BITS - 1 ) ) / M_PI; + const float fInvPhaseScale = M_PI / (float) ( 1 << ( PRED_QUANT_FILTER_PHASE_BITS - 1 ) ); + + /* Compute filter coefficeints */ + fA1Real = -pfRxxReal[1] / pfRxxReal[0]; + fA1Imag = -pfRxxImag[1] / pfRxxReal[0]; + + /* compute these before quant */ + /* Compute est coding gain based on quantized filter coefficients */ + fGain = 1.0f / ( 1.0f - fA1Real * fA1Real - fA1Imag * fA1Imag ); + fBitGain = 0.65f * log2f( fGain ) * (float) ( iNumBlocksPerPredCoef ) - (float) ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS ); // Wrong fix (iNumBlocks-1) + fA1Mag = sqrtf( fA1Real * fA1Real + fA1Imag * fA1Imag ); + fA1Mag = fMagScale * asinf( fA1Mag ); + iA1Mag = (int32_t) ( fA1Mag + 0.5f ); + iA1Mag = ( iA1Mag > PRED_QUANT_FILTER_MAG_MIN ) ? iA1Mag : PRED_QUANT_FILTER_MAG_MIN; + iA1Mag = ( iA1Mag < PRED_QUANT_FILTER_MAG_MAX ) ? iA1Mag : PRED_QUANT_FILTER_MAG_MAX; + fA1Mag = sinf( fInvMagScale * (float) iA1Mag ); + + fA1Phase = atan2f( fA1Imag, fA1Real ); + fA1Phase = fPhaseScale * fA1Phase; + iA1Phase = ( fA1Phase > 0.0f ) ? (int32_t) ( fA1Phase + 0.5f ) : (int32_t) ( fA1Phase - 0.5f ); + iA1Phase = ( iA1Phase > PRED_QUANT_FILTER_PHASE_MIN ) ? iA1Phase : PRED_QUANT_FILTER_PHASE_MIN; + iA1Phase = ( iA1Phase < PRED_QUANT_FILTER_PHASE_MAX ) ? iA1Phase : PRED_QUANT_FILTER_PHASE_MAX; // Is this the correct way to deal with this? should wrap? + fA1Phase = fInvPhaseScale * (float) iA1Phase; + + fA1Real = fA1Mag * cosf( fA1Phase ); + fA1Imag = fA1Mag * sinf( fA1Phase ); + fGain2 = 1.0f / ( 1.0f - fA1Real * fA1Real - fA1Imag * fA1Imag ); + fBitGain2 = 0.65f * log2f( fGain ) * (float) ( iNumBlocksPerPredCoef ) - (float) ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS ); // Wrong fix (iNumBlocks-1) + fGain = ( fGain < fGain2 ) ? fGain : fGain2; + fBitGain = ( fBitGain < fBitGain2 ) ? fBitGain : fBitGain2; + } + else + { + fA1Real = 0.0f; + fA1Imag = 0.0f; + iA1Mag = 0; + iA1Phase = 0; + fGain = -10.0f; // Fix this + } + + pfEstPredBitGain[b] = fBitGain; + psPredictionEncoder->ppiPredBandEnable[c][b] = ( fBitGain > 0.0f ); // Initial prediction enable + psPredictionEncoder->ppfA1Real[c][b] = fA1Real; + psPredictionEncoder->ppfA1Imag[c][b] = fA1Imag; + psPredictionEncoder->ppiA1Mag[c][b] = iA1Mag; + psPredictionEncoder->ppiA1Phase[c][b] = iA1Phase; + } + + { + float fBestCost; + int32_t iPredBands; + float fBitGain; + int32_t iPredChanEnable = 0; + + fBestCost = 0.0; + iPredBands = 0; + fBitGain = -7.0; + for ( b = b0; b < 50; b += bstep ) + { // still getting this decision wrong! + fBitGain -= 1.0; + if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) + { + fBitGain += pfEstPredBitGain[b]; + } + if ( fBitGain > fBestCost ) + { + fBestCost = fBitGain; + iPredBands = b; + iPredChanEnable = 1; + } + } + + if ( iPredChanEnable == 1 ) + { + for ( b = iPredBands + bstep; b < LCLD_BANDS; b += bstep ) + { + psPredictionEncoder->ppiPredBandEnable[c][b] = 0; + } + activate_bit( &psPredictionEncoder->piPredChanEnable[c], psPredictionEncoder->iSubSetId ); + psPredictionEncoder->piNumPredBands[c] = iPredBands + bstep; + } + else if ( iPredBands > 0 ) + { + for ( b = iPredBands; b < LCLD_BANDS; b += bstep ) + { + psPredictionEncoder->ppiPredBandEnable[c][b] = 0; + } + activate_bit( &psPredictionEncoder->piPredChanEnable[c], psPredictionEncoder->iSubSetId ); + psPredictionEncoder->piNumPredBands[c] = iPredBands; + } + else + { + for ( b = b0; b < LCLD_BANDS; b += bstep ) + { + psPredictionEncoder->ppiPredBandEnable[c][b] = 0; + } + deactivate_bit( &psPredictionEncoder->piPredChanEnable[c], psPredictionEncoder->iSubSetId ); + psPredictionEncoder->piNumPredBands[c] = 0; + } + } + } +} +#else int32_t ComputePredictors( PredictionEncoder *psPredictionEncoder, float ***pppfReal, @@ -425,6 +846,7 @@ int32_t ComputePredictors( return iPredictionBits; } +#endif /*-------------------------------------------------------------------* @@ -432,7 +854,61 @@ int32_t ComputePredictors( * * *-------------------------------------------------------------------*/ +#ifdef SPLIT_REND_LCLD_5MS +void ApplyForwardPredictors( + PredictionEncoder *psPredictionEncoder, + float ***pppfReal, + float ***pppfImag ) +{ + int32_t c; + for ( c = 0; c < psPredictionEncoder->iChannels; c++ ) + { + int32_t b; + if ( psPredictionEncoder->piPredChanEnable[c] > 0 ) + { + for ( b = 0; b < LCLD_BANDS; b++ ) + { + if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) + { + int32_t n; + float fOldReal = 0.0f; + float fOldImag = 0.0f; + float fA1Real; + float fA1Imag; + int32_t iSubset = b % psPredictionEncoder->iNumSubSets; + if ( iSubset != psPredictionEncoder->iSubSetId ) + { + fOldReal = psPredictionEncoder->ppfInpPrevReal[c][b]; + fOldImag = psPredictionEncoder->ppfInpPrevImag[c][b]; + } + psPredictionEncoder->ppfInpPrevReal[c][b] = pppfReal[c][psPredictionEncoder->iNumBlocks - 1][b]; + psPredictionEncoder->ppfInpPrevImag[c][b] = pppfImag[c][psPredictionEncoder->iNumBlocks - 1][b]; + + fA1Real = psPredictionEncoder->ppfA1Real[c][b]; + fA1Imag = psPredictionEncoder->ppfA1Imag[c][b]; + for ( n = 0; n < psPredictionEncoder->iNumBlocks; n++ ) + { + float fReal; + float fImag; + + fReal = pppfReal[c][n][b] + fA1Real * fOldReal - fA1Imag * fOldImag; + fImag = pppfImag[c][n][b] + fA1Real * fOldImag + fA1Imag * fOldReal; + + fOldReal = pppfReal[c][n][b]; + fOldImag = pppfImag[c][n][b]; + + pppfReal[c][n][b] = fReal; + pppfImag[c][n][b] = fImag; + } + } + } + } + } + + return; +} +#else void ApplyForwardPredictors( PredictionEncoder *psPredictionEncoder, float ***pppfReal, @@ -479,6 +955,7 @@ void ApplyForwardPredictors( return; } +#endif /*-------------------------------------------------------------------* @@ -486,7 +963,71 @@ void ApplyForwardPredictors( * * *-------------------------------------------------------------------*/ +#ifdef SPLIT_REND_LCLD_5MS +int32_t WritePredictors( + PredictionEncoder *psPredictionEncoder, + IVAS_SPLIT_REND_BITS_HANDLE pBits ) +{ + int32_t iBitsWritten = 0; + int32_t c; + int32_t iNumSubSets = psPredictionEncoder->iNumSubSets; + int32_t iSubSetId = psPredictionEncoder->iSubSetId; + int32_t iNumPredBandBits = 6; + const int16_t iSubSetBits = ( LCLD_MAX_NUM_PRED_SUBSETS > 4 ? 3 : 2 ); + + /* number of subsets */ + ivas_split_rend_bitstream_write_int32( pBits, iNumSubSets - 1, iSubSetBits ); /* otherwise use default */ + iBitsWritten += iSubSetBits; + + if ( iNumSubSets > 1 ) + { + /* write current subset */ + ivas_split_rend_bitstream_write_int32( pBits, iSubSetId, iSubSetBits ); + iBitsWritten += iSubSetBits; + iNumPredBandBits = ( iNumSubSets >= 4 ? 4 : 5 ); + } + + for ( c = 0; c < psPredictionEncoder->iChannels; c++ ) + { + int32_t b; + int32_t b0 = iSubSetId; + + ivas_split_rend_bitstream_write_int32( pBits, psPredictionEncoder->piPredChanEnable[c], iNumSubSets ); + iBitsWritten += iNumSubSets; + if ( get_bit( psPredictionEncoder->piPredChanEnable[c], iSubSetId ) ) + { + int32_t iNumPredBands = ( psPredictionEncoder->piNumPredBands[c] - b0 ) / iNumSubSets; + + ivas_split_rend_bitstream_write_int32( pBits, iNumPredBands, iNumPredBandBits ); + iBitsWritten += iNumPredBandBits; + + for ( b = b0; b < psPredictionEncoder->piNumPredBands[c]; b += iNumSubSets ) + { + ivas_split_rend_bitstream_write_int32( pBits, psPredictionEncoder->ppiPredBandEnable[c][b], 1 ); + iBitsWritten += 1; + + if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) + { + int32_t iA1Mag; + int32_t iA1Phase; + + iA1Mag = psPredictionEncoder->ppiA1Mag[c][b]; + iA1Phase = psPredictionEncoder->ppiA1Phase[c][b] - PRED_QUANT_FILTER_PHASE_MIN; + + ivas_split_rend_bitstream_write_int32( pBits, iA1Mag, PRED_QUNAT_FILTER_MAG_BITS ); + iBitsWritten += PRED_QUNAT_FILTER_MAG_BITS; + + ivas_split_rend_bitstream_write_int32( pBits, iA1Phase, PRED_QUANT_FILTER_PHASE_BITS ); + iBitsWritten += PRED_QUANT_FILTER_PHASE_BITS; + } + } + } + } + + return iBitsWritten; +} +#else int32_t WritePredictors( PredictionEncoder *psPredictionEncoder, IVAS_SPLIT_REND_BITS_HANDLE pBits ) @@ -529,3 +1070,4 @@ int32_t WritePredictors( return iBitsWritten; } #endif +#endif diff --git a/lib_rend/ivas_RMSEnvGrouping.c b/lib_rend/ivas_RMSEnvGrouping.c index edbde3cb01..1d8ef2593f 100644 --- a/lib_rend/ivas_RMSEnvGrouping.c +++ b/lib_rend/ivas_RMSEnvGrouping.c @@ -276,6 +276,108 @@ static void ComputeBandEnergy( } +#ifdef SPLIT_REND_LCLD_5MS +/*-------------------------------------------------------------------* + * Function TryMerge() + * + * + *-------------------------------------------------------------------*/ + +/* THis is temporary cost function */ +static float TryMerge( + const int32_t iNumBands, + const int32_t iStartBlock, + const int32_t iGroupLength, + const float fMaxAllowedDiffdB, + float **ppfBandEnergy, + float **ppfBandEnergydB, +#ifdef APPLY_WEIGHT + float **ppfWeight, +#endif + float *pfMegredEnergydB ) +{ + int32_t b; + int32_t n; + float fMeanCost; + float fMaxCost; + float fMinDiffCost; + float fMaxDiffCost; + float fInvGroupSize = 1.0f / (float) iGroupLength; + float fInvNumBands = 1.0f / (float) iNumBands; + + for ( b = 0; b < iNumBands; b++ ) + { + float fGroupEnergy; + + + fGroupEnergy = 0.0; + for ( n = iStartBlock; n < ( iStartBlock + iGroupLength ); n++ ) + { + fGroupEnergy += ppfBandEnergy[n][b]; + } + fGroupEnergy *= fInvGroupSize; + fGroupEnergy = 10.0f * log10f( fGroupEnergy ); // Note epsolon was added when computing BandEnergy; + + pfMegredEnergydB[b] = fGroupEnergy; + } + + fMeanCost = 0.0; + fMaxCost = 0.0; + fMinDiffCost = 0.0; + fMaxDiffCost = 0.0; + for ( n = iStartBlock; n < ( iStartBlock + iGroupLength ); n++ ) + { + float fMeanAbsDiff; + float fMaxAbsDiff; + float fMaxDiff; + float fMinDiff; + + fMeanAbsDiff = 0.0; + fMaxAbsDiff = 0.0; + fMaxDiff = 0.0; + fMinDiff = 0.0; + for ( b = 0; b < iNumBands; b++ ) + { + float fDiff; + float fAbsDiff; + + fDiff = pfMegredEnergydB[b] - ppfBandEnergydB[n][b]; // Changed the order of this + fAbsDiff = fabsf( fDiff ); +#ifdef APPLY_WEIGHT + fAbsDiff *= ppfWeight[n][b]; +#endif + + fMeanAbsDiff += fAbsDiff; + fMaxAbsDiff = ( fMaxAbsDiff > fAbsDiff ) ? fMaxAbsDiff : fAbsDiff; + + + fMaxDiff = ( fMaxDiff > fDiff ) ? fMaxDiff : fDiff; + fMinDiff = ( fMinDiff < fDiff ) ? fMinDiff : fDiff; + } + fMeanAbsDiff *= fInvNumBands; + + fMeanCost = ( fMeanCost > fMeanAbsDiff ) ? fMeanCost : fMeanAbsDiff; + fMaxCost = ( fMaxCost > fMaxAbsDiff ) ? fMaxCost : fMaxAbsDiff; + + fMaxDiffCost = ( fMaxDiffCost > fMaxDiff ) ? fMaxDiffCost : fMaxDiff; + fMinDiffCost = ( fMinDiffCost < fMinDiff ) ? fMinDiffCost : fMinDiff; + } + + // printf("%f\t%f\t%f\t%f\n",fMeanCost,fMaxCost,fMaxDiffCost,fMinDiffCost); + + /*if(fMinDiffCost < -9.0){ // This prevents cliping + fMeanCost = 1e12; //Some large value + }*/ + + if ( fMaxCost > fMaxAllowedDiffdB ) + { + fMeanCost = 1e12f; // Some large value + } + + return fMeanCost; +} +#endif + /*-------------------------------------------------------------------* * Function ComputeMergeRMS() * @@ -487,6 +589,121 @@ static float TryMerge2( return fMergedCost; } +#ifdef SPLIT_REND_LCLD_5MS +/*-------------------------------------------------------------------* + * Function ComputeGreedyGroups() + * + * + *-------------------------------------------------------------------*/ + +static void ComputeGreedyGroups( + RMSEnvelopeGrouping *psRMSEnvelopeGrouping, + const int32_t iChannels, + const int32_t iNumBands, + const float fMeanAllowedDiffdB, + const float fMaxAllowedDiffdB ) +{ + float fBestMeanCost; + + fBestMeanCost = 0.0; + while ( fBestMeanCost < fMeanAllowedDiffdB ) + { + GMNode *psGMNode; + GMNode *psBestGMNode; + + fBestMeanCost = fMeanAllowedDiffdB; + psGMNode = &psRMSEnvelopeGrouping->psGMNodes[0]; + psBestGMNode = NULL; + while ( psGMNode->psNext != NULL ) + { + float fMeanCost; + int32_t iGroupLength; + + iGroupLength = psGMNode->iGroupLength + psGMNode->psNext->iGroupLength; + + fMeanCost = TryMerge( iNumBands * iChannels, + psGMNode->iGroupStart, + iGroupLength, // psGMNode->iGroupLength, //Fix this bug + fMaxAllowedDiffdB, + psRMSEnvelopeGrouping->ppfBandEnergy, + psRMSEnvelopeGrouping->ppfBandEnergydB, +#ifdef APPLY_WEIGHT + psRMSEnvelopeGrouping->ppfWeight, +#endif + psGMNode->pfMergedEnergydB ); + + + if ( fMeanCost < fBestMeanCost ) + { + fBestMeanCost = fMeanCost; + psBestGMNode = psGMNode; + } + + psGMNode = psGMNode->psNext; + } + + if ( fBestMeanCost < fMeanAllowedDiffdB && psBestGMNode != NULL && psBestGMNode->psNext != NULL ) + { + psBestGMNode->iGroupLength += psBestGMNode->psNext->iGroupLength; + psBestGMNode->psNext = psBestGMNode->psNext->psNext; + } + } + + return; +} + + +/*-------------------------------------------------------------------* + * Function ComputeGreedyGroups2() + * + * + *-------------------------------------------------------------------*/ + +static void ComputeGreedyGroups2( + RMSEnvelopeGrouping *psRMSEnvelopeGrouping, + const int32_t iChannels, + const int32_t iNumBands, + const int32_t *piBandwidths ) +{ + float fBestMergeCost; + // int32_t iDone = 0; + fBestMergeCost = -1.0; + + while ( fBestMergeCost < 0.0 ) + { + GMNode *psGMNode; + GMNode *psBestGMNode; + + fBestMergeCost = 0.0; + psGMNode = &psRMSEnvelopeGrouping->psGMNodes[0]; + psBestGMNode = NULL; + while ( psGMNode->psNext != NULL ) + { + float fMergeCost; + + fMergeCost = TryMerge2( iChannels, iNumBands, piBandwidths, psRMSEnvelopeGrouping->ppfBandEnergy, psRMSEnvelopeGrouping->ppfBandEnergydB, psGMNode, psGMNode->psNext ); + + if ( fMergeCost < fBestMergeCost ) + { + fBestMergeCost = fMergeCost; + psBestGMNode = psGMNode; + } + + psGMNode = psGMNode->psNext; + } + + if ( fBestMergeCost < 0.0 && psBestGMNode != NULL && psBestGMNode->psNext != NULL ) + { + psBestGMNode->iGroupLength += psBestGMNode->psNext->iGroupLength; + psBestGMNode->iGroupRMSEnvelopeCost = -1; + psBestGMNode->fGroupSNRPenalty = -1.0; + psBestGMNode->psNext = psBestGMNode->psNext->psNext; + } + } + + return; +} +#endif /*-------------------------------------------------------------------* * Function ComputeGreedyGroups3() @@ -700,9 +917,13 @@ void ComputeEnvelopeGrouping( psRMSEnvelopeGrouping->psGMNodes[n].psNext = NULL; } - /* Perform grouping via Greedy Merge */ - /* Allows control over max groups can call using 16 if want same as previous call */ +/* Perform grouping via Greedy Merge */ +/* Allows control over max groups can call using 16 if want same as previous call */ +#ifdef SPLIT_REND_LCLD_5MS + ComputeGreedyGroups3( psRMSEnvelopeGrouping, iChannels, iNumBands, piBandwidths, psRMSEnvelopeGrouping->iNumBlocks ); +#else ComputeGreedyGroups3( psRMSEnvelopeGrouping, iChannels, iNumBands, piBandwidths, LCLD_BLOCKS_PER_FRAME ); +#endif /* Calc Groups from Merge Results */ *piNumGroups = 0; diff --git a/lib_rend/ivas_lcld_decoder.c b/lib_rend/ivas_lcld_decoder.c index 8aafcb1fa8..d989797a29 100644 --- a/lib_rend/ivas_lcld_decoder.c +++ b/lib_rend/ivas_lcld_decoder.c @@ -83,9 +83,6 @@ struct LCLD_DECODER uint32_t num_decode_table[2 * ALLOC_TABLE_SIZE]; int32_t piMSPredCoefs[MAX_BANDS]; int32_t piLRPhaseDiffs[MAX_BANDS]; -#ifdef ENABLE_PMOD_ADJUST - int32_t **ppiHiSMRFlags; -#endif int32_t iCommonGrouping; int32_t *piNumGroups; int32_t **ppiGroupLengths; @@ -344,10 +341,18 @@ static void CreateDecodeTable( LCLDDecoder *psLCLDDecoder, int32_t num, const ui * *------------------------------------------------------------------------------------------*/ +#ifndef SPLIT_REND_LCLD_5MS ivas_error CreateLCLDDecoder( LCLDDecoder **psLCLDDecoder_out, const int32_t iSampleRate, const int32_t iChannels ) +#else +ivas_error CreateLCLDDecoder( + LCLDDecoder **psLCLDDecoder_out, + const int32_t iSampleRate, + const int32_t iChannels, + const int32_t iNumBlocks ) +#endif { int32_t n; int32_t read_length; @@ -355,17 +360,27 @@ ivas_error CreateLCLDDecoder( LCLDDecoder *psLCLDDecoder = NULL; assert( iSampleRate == 48000 ); // Fix - +#ifdef SPLIT_REND_LCLD_5MS + assert( iNumBlocks == 16 || iNumBlocks == 8 || iNumBlocks == 4 ); +#endif if ( ( psLCLDDecoder = (LCLDDecoder *) malloc( sizeof( LCLDDecoder ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } psLCLDDecoder->iSampleRate = iSampleRate; psLCLDDecoder->iChannels = iChannels; +#ifdef SPLIT_REND_LCLD_5MS + psLCLDDecoder->iNumBlocks = iNumBlocks; +#else psLCLDDecoder->iNumBlocks = LCLD_BLOCKS_PER_FRAME; +#endif psLCLDDecoder->iAllocOffset = 0; - psLCLDDecoder->iNumBands = MAX_BANDS_48; // Fix +#ifdef SPLIT_REND_LCLD_5MS + psLCLDDecoder->iNumBands = 0; // read from bitstream +#else + psLCLDDecoder->iNumBands = MAX_BANDS_48; // Fix +#endif psLCLDDecoder->piBandwidths = c_aiBandwidths48; // Fix psLCLDDecoder->iMSMode = 0; @@ -378,10 +393,6 @@ ivas_error CreateLCLDDecoder( psLCLDDecoder->piLRPhaseDiffs[n] = 0; psLCLDDecoder->piMSPredCoefs[n] = 0; } -#ifdef ENABLE_PMOD_ADJUST - psLCLDDecoder->ppiHiSMRFlags = - (int32_t **) malloc( psLCLDDecoder->iChannels * sizeof( int32_t * ) ); -#endif psLCLDDecoder->iCommonGrouping = 1; /* Common grouping always on only impacts stereo */ if ( ( psLCLDDecoder->piNumGroups = (int32_t *) malloc( psLCLDDecoder->iChannels * sizeof( int32_t ) ) ) == NULL ) @@ -429,11 +440,6 @@ ivas_error CreateLCLDDecoder( for ( n = 0; n < iChannels; n++ ) { int16_t k; -#ifdef ENABLE_PMOD_ADJUST - psLCLDDecoder->ppiHiSMRFlags[n] = - (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ); - ; -#endif if ( ( psLCLDDecoder->ppiGroupLengths[n] = (int32_t *) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( int32_t ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); @@ -606,16 +612,6 @@ void DeleteLCLDDecoder( LCLDDecoder *psLCLDDecoder ) free( psLCLDDecoder->pppiExcitation ); } -#ifdef ENABLE_PMOD_ADJUST - if ( psLCLDDecoder->ppiHiSMRFlags != NULL ) - { - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) - { - free( psLCLDDecoder->ppiHiSMRFlags[n] ); - } - free( psLCLDDecoder->ppiHiSMRFlags ); - } -#endif if ( psLCLDDecoder->pppiAlloc != NULL ) { @@ -768,9 +764,6 @@ int32_t DecodeLCLDFrame( ReadRMSEnvelope( psLCLDDecoder->iChannels, (const int32_t *) psLCLDDecoder->piNumGroups, psLCLDDecoder->iNumBands, psLCLDDecoder->pppiRMSEnvelope, pBits ); -#ifdef ENABLE_PMOD_ADJUST - ReadPmodInformation( psLCLDDecoder->ppiHiSMRFlags, pBits, psLCLDDecoder->iChannels, psLCLDDecoder->iNumBands ); -#endif ReadAllocInformation( &psLCLDDecoder->iAllocOffset, pBits ); @@ -831,8 +824,26 @@ int32_t DecodeLCLDFrame( psLCLDDecoder->pppiLCLDSignImag[n], pppfLCLDReal[n], pppfLCLDImag[n] ); } +#ifdef DEBUG_WRITE_PREDICTORS + { + static FILE *fid; + if ( !fid ) + fid = fopen( "pred_dec.txt", "wt" ); + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + int b; + for ( b = 0; b < 60; b++ ) + fprintf( fid, "%.5f ", (float) psLCLDDecoder->psPredictionDecoder->ppiPredBandEnable[n][b] * psLCLDDecoder->psPredictionDecoder->ppfA1Imag[n][b] ); + } + fprintf( fid, "%d %d\n", psLCLDDecoder->psPredictionDecoder->iSubSetId, psLCLDDecoder->psPredictionDecoder->piPredChanEnable[n] ); + } +#endif +#ifdef SPLIT_REND_LCLD_5MS + ApplyInversePredictors( psLCLDDecoder->psPredictionDecoder, pppfLCLDReal, pppfLCLDImag ); +#else ApplyInversePredictros( psLCLDDecoder->psPredictionDecoder, pppfLCLDReal, pppfLCLDImag ); +#endif for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) { @@ -1020,9 +1031,10 @@ static void InvMSCoding( { int32_t b; int32_t iFBOffset; +#ifdef SPLIT_REND_LCLD_5MS + int32_t bMSPred = 0; +#else int32_t bms = 0; -#if defined SIMPLE_PHASE - void( *pFuncPhaseRotateOptions[4] ) = { &rot_zero, &rot_m_pi_2, &rot_pm_pi, &rot_p_pi_2 }; #endif iFBOffset = 0; @@ -1031,9 +1043,11 @@ static void InvMSCoding( if ( piMSFlags[b] == 1 ) { int32_t n; -#if defined SIMPLE_PHASE - void ( *pFuncPhaseRotate )( float *, float * ) = - pFuncPhaseRotateOptions[piLRPhaseDiffs[bms]]; +#ifdef SPLIT_REND_LCLD_5MS + int32_t phaseIdx; + float fPred; + phaseIdx = piLRPhaseDiffs[bMSPred] - PHASE_MIN_VAL; + fPred = dequantPred( piMSPredCoefs[bMSPred] ); #endif for ( n = 0; n < piBandwidths[b]; n++ ) { @@ -1047,8 +1061,10 @@ static void InvMSCoding( if ( iMSMode == 3 ) { +#ifndef SPLIT_REND_LCLD_5MS float fPred; fPred = dequantPred( piMSPredCoefs[bms] ); +#endif pppfReal[1][k][iFBOffset] += fPred * pppfReal[0][k][iFBOffset]; pppfImag[1][k][iFBOffset] += fPred * pppfImag[0][k][iFBOffset]; } @@ -1060,13 +1076,11 @@ static void InvMSCoding( if ( iMSMode == 3 ) { -#ifdef SIMPLE_PHASE - ( *pFuncPhaseRotate )( &fRightReal, &fRightImag ); -#else +#ifndef SPLIT_REND_LCLD_5MS int32_t phaseIdx; phaseIdx = piLRPhaseDiffs[bms] - PHASE_MIN_VAL; - cplxmult( &fRightReal, &fRightImag, c_afRotRealImag[phaseIdx][0], -c_afRotRealImag[phaseIdx][1] ); #endif + cplxmult( &fRightReal, &fRightImag, c_afRotRealImag[phaseIdx][0], -c_afRotRealImag[phaseIdx][1] ); } pppfReal[0][k][iFBOffset] = fLeftReal; @@ -1076,8 +1090,11 @@ static void InvMSCoding( } iFBOffset++; } - +#ifdef SPLIT_REND_LCLD_5MS + bMSPred++; +#else bms++; +#endif } else { @@ -1175,13 +1192,6 @@ static int32_t ReadMSInformation( anyNonZero = ivas_split_rend_bitstream_read_int32( pBits, 1 ); if ( anyNonZero ) { -#ifdef SIMPLE_PHASE - for ( n = 0; n < iNumMSPredBands; n++ ) - { - piLRPhaseDiffs[n] = ivas_split_rend_bitstream_read_int32( pBits, SIMPLE_PHASE_BITS ); - iBitsRead += SIMPLE_PHASE_BITS; - } -#else piLRPhaseDiffs[0] = ivas_split_rend_bitstream_read_int32( pBits, PHASE_BAND0_BITS ); piLRPhaseDiffs[0] += PHASE_MIN_VAL; iBitsRead += PHASE_BAND0_BITS; @@ -1192,7 +1202,6 @@ static int32_t ReadMSInformation( piLRPhaseDiffs[n] = tabIdx + ENV_DELTA_MIN; } DecodePhase( piLRPhaseDiffs, iNumMSPredBands, PHASE_DIFF_DIM ); -#endif } else { @@ -1224,11 +1233,9 @@ static int32_t ReadMSInformation( } #ifdef DEBUG_WRITE_MS_PRED { - static FILE *fid = 0; + static FILE *fid; if ( !fid ) - { - fid = fopen( "ms_mode_dec.txt", "wt" ); - } + fid = fopen( "ms_pred_dec.txt", "wt" ); writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSPredBands, iNumBands, fid, piMSFlags ); } #endif @@ -1241,6 +1248,12 @@ static int32_t ReadMSInformation( return iBitsRead; } +#ifdef SPLIT_REND_LCLD_5MS +int32_t GetNumPredSubSets( LCLDDecoder *psLCLDDecoder ) +{ + return psLCLDDecoder->psPredictionDecoder->iNumSubSets; +} +#endif static int32_t ReadGroupInformation( const int32_t iChannels, @@ -1430,66 +1443,6 @@ static int32_t ReadRMSEnvelope( } -#ifdef ENABLE_PMOD_ADJUST -static int32_t ReadPmodInformation( - int32_t **ppiHiSMRFlags, - IVAS_SPLIT_REND_BITS_HANDLE pBits, - int32_t iChannels, - int32_t iNumBands ) -{ - int32_t iBitsRead; - int32_t c; - iBitsRead = 0; - for ( c = 0; c < iChannels; c++ ) - { - int32_t b; - int32_t iFlags = ivas_split_rend_bitstream_read_int32( pBits, 1 ); - iBitsRead += 1; - if ( iFlags ) - { - for ( b = 0; b < iNumBands; b++ ) - { - ppiHiSMRFlags[c][b] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); - iBitsRead += 1; - } - } - else - { - for ( b = 0; b < iNumBands; b++ ) - { - ppiHiSMRFlags[c][b] = 0; - } - } - } -#ifdef WRITE_HISMR_FLAGS - { - static FILE *fid = 0; - if ( !fid ) - { - fid = fopen( "hismr_dec.txt", "wt" ); - } - for ( c = 0; c < iChannels; c++ ) - { - int32_t b; - for ( b = 0; b < iNumBands; b++ ) - { - if ( c == iChannels - 1 && b == iNumBands - 1 ) - { - fprintf( fid, "%d\n", ppiHiSMRFlags[c][b] ); - } - else - { - fprintf( fid, "%d ", ppiHiSMRFlags[c][b] ); - } - } - } - } -#endif - return iBitsRead; -} -#endif - - static int32_t ReadAllocInformation( int32_t *piAllocOffset, IVAS_SPLIT_REND_BITS_HANDLE pBits ) diff --git a/lib_rend/ivas_lcld_encoder.c b/lib_rend/ivas_lcld_encoder.c index 8052edee4a..3d64e6012e 100644 --- a/lib_rend/ivas_lcld_encoder.c +++ b/lib_rend/ivas_lcld_encoder.c @@ -39,9 +39,6 @@ #include "ivas_lcld_rom_tables.h" #include "prot.h" #include "ivas_prot_rend.h" -#ifdef ENABLE_PMOD_ADJUST -#include "ton_corr.h" -#endif #include "wmc_auto.h" /*------------------------------------------------------------------------------------------* @@ -55,7 +52,9 @@ struct LCLD_ENCODER int32_t iNumBlocks; int32_t iTargetBitRate; +#ifndef SPLIT_REND_LCLD_5MS int32_t iTargetBitsPerFrame; +#endif int32_t iNumBands; const int32_t *piBandwidths; @@ -66,9 +65,6 @@ struct LCLD_ENCODER int32_t piLRPhaseDiffs[MAX_BANDS]; int32_t iAllowSidePred; -#ifdef ENABLE_PMOD_ADJUST - int32_t **ppiHiSMRFlags; -#endif RMSEnvelopeGrouping *psRMSEnvelopeGrouping; @@ -92,6 +88,38 @@ struct LCLD_ENCODER PredictionEncoder *psPredictionEncoder; }; +#ifdef SPLIT_REND_LCLD_5MS +static int Quantize( float fVal, float fScale, int *iSign, int iMaxVal ) +{ + int iVal; + if ( fVal > 0.0f ) + { + iVal = (int) ( fScale * fVal + 0.5f ); + *iSign = 0; + } + else + { + iVal = (int) ( -fScale * fVal + 0.5f ); + *iSign = 1; + } + iVal = ( iVal < iMaxVal ) ? iVal : iMaxVal; + + return iVal; +} +static float UnQuantize( int iVal, float fScale, int iSign ) +{ + float fVal; + if ( iSign == 0 ) + { + fVal = fScale * (float) iVal; + } + else + { + fVal = -fScale * (float) iVal; + } + return fVal; +} +#endif /*------------------------------------------------------------------------------------------* * Function CreateLCLDEncoder() @@ -99,18 +127,36 @@ struct LCLD_ENCODER * *------------------------------------------------------------------------------------------*/ +#ifdef SPLIT_REND_LCLD_5MS +ivas_error CreateLCLDEncoder( + LCLDEncoder **psLCLDEncoder_out, + const int32_t iSampleRate, + const int32_t iChannels, + const int32_t iTargetBitRate, + const int32_t iAllowSidePred, + const int32_t iNumBlocks, + const int32_t iNumSubSets ) +#else ivas_error CreateLCLDEncoder( LCLDEncoder **psLCLDEncoder_out, const int32_t iSampleRate, const int32_t iChannels, const int32_t iTargetBitRate, const int32_t iAllowSidePred ) +#endif { int32_t n; LCLDEncoder *psLCLDEncoder; ivas_error error; +#ifdef SPLIT_REND_LCLD_5MS + int32_t iMaxNumPredBands = 0; +#endif assert( iSampleRate == 48000 ); // Fix +#ifdef SPLIT_REND_LCLD_5MS + assert( iNumBlocks == 16 || iNumBlocks == 8 || iNumBlocks == 4 ); + assert( iNumSubSets > 0 && iNumSubSets <= LCLD_MAX_NUM_PRED_SUBSETS ); +#endif if ( ( psLCLDEncoder = (LCLDEncoder *) malloc( sizeof( LCLDEncoder ) ) ) == NULL ) { @@ -119,14 +165,29 @@ ivas_error CreateLCLDEncoder( psLCLDEncoder->iSampleRate = iSampleRate; psLCLDEncoder->iChannels = iChannels; +#ifdef SPLIT_REND_LCLD_5MS + psLCLDEncoder->iNumBlocks = iNumBlocks; +#else psLCLDEncoder->iNumBlocks = LCLD_BLOCKS_PER_FRAME; +#endif psLCLDEncoder->iAllocOffset = 0; psLCLDEncoder->iTargetBitRate = iTargetBitRate; +#ifndef SPLIT_REND_LCLD_5MS psLCLDEncoder->iTargetBitsPerFrame = iTargetBitRate * LCLD_BLOCKS_PER_FRAME * LCLD_BANDS / iSampleRate; +#endif + + psLCLDEncoder->piBandwidths = c_aiBandwidths48; +#ifdef SPLIT_REND_LCLD_5MS + psLCLDEncoder->iNumBands = DEF_BANDS_48; /* 22 bands = 50 CLDFB bands (rather than 23 bands) */ + for ( n = 0; n < psLCLDEncoder->iNumBands; n++ ) + { + iMaxNumPredBands += psLCLDEncoder->piBandwidths[n]; + } +#else + psLCLDEncoder->iNumBands = MAX_BANDS_48; +#endif - psLCLDEncoder->iNumBands = MAX_BANDS_48; // Fix - psLCLDEncoder->piBandwidths = c_aiBandwidths48; // Fix psLCLDEncoder->iMSMode = 0; if ( ( psLCLDEncoder->piMSFlags = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) @@ -194,23 +255,11 @@ ivas_error CreateLCLDEncoder( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } -#ifdef ENABLE_PMOD_ADJUST - if ( ( psLCLDEncoder->ppiHiSMRFlags = (int32_t **) malloc( psLCLDEncoder->iChannels * sizeof( int32_t * ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); - } -#endif for ( n = 0; n < iChannels; n++ ) { int32_t k; -#ifdef ENABLE_PMOD_ADJUST - if ( ( psLCLDEncoder->ppiHiSMRFlags[n] = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); - } -#endif if ( ( psLCLDEncoder->ppiGroupLengths[n] = (int32_t *) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( int32_t ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); @@ -302,10 +351,17 @@ ivas_error CreateLCLDEncoder( } } +#ifdef SPLIT_REND_LCLD_5MS + if ( ( error = CreatePredictionEncoder( &( psLCLDEncoder->psPredictionEncoder ), iChannels, psLCLDEncoder->iNumBlocks, iNumSubSets, iMaxNumPredBands ) ) != IVAS_ERR_OK ) + { + return error; + } +#else if ( ( error = CreatePredictionEncoder( &( psLCLDEncoder->psPredictionEncoder ), iChannels, psLCLDEncoder->iNumBlocks ) ) != IVAS_ERR_OK ) { return error; } +#endif *psLCLDEncoder_out = psLCLDEncoder; @@ -350,16 +406,6 @@ void DeleteLCLDEncoder( } free( psLCLDEncoder->ppiGroupLengths ); } -#ifdef ENABLE_PMOD_ADJUST - if ( psLCLDEncoder->ppiHiSMRFlags != NULL ) - { - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) - { - free( psLCLDEncoder->ppiHiSMRFlags[n] ); - } - free( psLCLDEncoder->ppiHiSMRFlags ); - } -#endif if ( psLCLDEncoder->pppiRMSEnvelope != NULL ) { for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) @@ -483,10 +529,6 @@ static int32_t CountLCLDBits( const int32_t iNumGroups, const int32_t *piGroupLe static int32_t WriteHeaderInformation( const int32_t iNumBands, IVAS_SPLIT_REND_BITS_HANDLE pBits ); -#ifdef ENABLE_PMOD_ADJUST -static int32_t WritePmodInformation( const int32_t **ppiHiSMRFlags, IVAS_SPLIT_REND_BITS_HANDLE pBits, int32_t iChannels, int32_t iNumBands ); -#endif - static int32_t WriteMSInformation( const int32_t iNumBands, const int32_t iMSMode, const int32_t *piMSFlags, const int32_t *piLRPhaseDiffs, const int32_t *piMSPredCoefs, int32_t iNumMSPredBands, IVAS_SPLIT_REND_BITS_HANDLE pBits ); static int32_t WriteGroupInformation( const int32_t iChannels, const int32_t iCommonGrouping, const int32_t *piNumGroups, int32_t **ppiGroupLengths, IVAS_SPLIT_REND_BITS_HANDLE pBits ); @@ -497,8 +539,11 @@ static int32_t WriteAllocInformation( const int32_t iAllocOffset, IVAS_SPLIT_REN static int32_t WriteLCLDData( const int32_t iNumGroups, const int32_t *piGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, const int32_t *piPredEnable, int32_t **ppiAlloc, int32_t **ppiSignReal, int32_t **ppiSignImag, int32_t **ppiQReal, int32_t **ppiQImag, IVAS_SPLIT_REND_BITS_HANDLE pBits ); +#ifdef SPLIT_REND_LCLD_5MS +static int32_t ComputeAllocation( const int32_t iChannels, const int32_t *piNumGroups, int32_t **ppiGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, float ***pppfReal, float ***pppfImag, int32_t ***pppiSMR, const int32_t iAvailableBits, int32_t *piAllocOffset, int32_t ***pppiAlloc, int32_t ***pppiQReal, int32_t ***pppiQImag, int32_t ***pppiSignReal, int32_t ***pppiSignImag, PredictionEncoder *psPredictionEncoder ); +#else static int32_t ComputeAllocation( const int32_t iChannels, const int32_t *piNumGroups, int32_t **ppiGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, float ***pppfReal, float ***pppfImag, int32_t ***pppiSMR, const int32_t iAvailableBits, int32_t *piAllocOffset, int32_t ***pppiAlloc, int32_t ***pppiQReal, int32_t ***pppiQImag, int32_t ***pppiSignReal, int32_t ***pppiSignImag, int32_t **ppiPredEnable, float **ppfA1Real, float **ppfA1Imag ); - +#endif /*------------------------------------------------------------------------------------------* * Function EncodeLCLDFrame() @@ -519,6 +564,9 @@ int32_t EncodeLCLDFrame( int32_t iNumMSBands = 0; iAvailableBits = available_bits; // HCBR for now iBitsWritten = 0; +#ifdef SPLIT_REND_LCLD_5MS + assert( available_bits <= pBits->buf_len * 8 ); +#endif /* Do MS calc here */ if ( psLCLDEncoder->iChannels == 2 ) @@ -540,9 +588,6 @@ int32_t EncodeLCLDFrame( } } -#ifdef ENABLE_PMOD_ADJUST - CalcTonQuotas( psLCLDEncoder->iChannels, psLCLDEncoder->iNumBands, psLCLDEncoder->piBandwidths, pppfLCLDReal, pppfLCLDImag, psLCLDEncoder->ppiHiSMRFlags ); -#endif /* Compute Grouping and RMS Envelopes */ if ( psLCLDEncoder->iChannels == 2 && psLCLDEncoder->iCommonGrouping == 1 ) @@ -612,12 +657,6 @@ int32_t EncodeLCLDFrame( iBitsWritten += WriteRMSEnvelope( psLCLDEncoder->iChannels, (const int32_t *) psLCLDEncoder->piNumGroups, psLCLDEncoder->iNumBands, psLCLDEncoder->pppiRMSEnvelope, pBits ); -#ifdef ENABLE_PMOD_ADJUST - iBitsWritten += WritePmodInformation( psLCLDEncoder->ppiHiSMRFlags, - pBits, - psLCLDEncoder->iChannels, - psLCLDEncoder->iNumBands ); -#endif if ( psLCLDEncoder->iChannels == 2 && psLCLDEncoder->iCommonGrouping == 1 ) { @@ -648,7 +687,20 @@ int32_t EncodeLCLDFrame( } } } - +#ifdef DEBUG_WRITE_PREDICTORS + { + static FILE *fid; + if ( !fid ) + fid = fopen( "pred_enc.txt", "wt" ); + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + int b; + for ( b = 0; b < 60; b++ ) + fprintf( fid, "%.5f ", (float) psLCLDEncoder->psPredictionEncoder->ppiPredBandEnable[n][b] * psLCLDEncoder->psPredictionEncoder->ppfA1Imag[n][b] ); + } + fprintf( fid, "%d %d\n", psLCLDEncoder->psPredictionEncoder->iSubSetId, psLCLDEncoder->psPredictionEncoder->piPredChanEnable[n] ); + } +#endif iAvailableBits -= iBitsWritten; ComputeAllocation( psLCLDEncoder->iChannels, (const int32_t *) psLCLDEncoder->piNumGroups, @@ -665,10 +717,15 @@ int32_t EncodeLCLDFrame( psLCLDEncoder->pppiQLCLDImag, psLCLDEncoder->pppiLCLDSignReal, psLCLDEncoder->pppiLCLDSignImag, +#ifdef SPLIT_REND_LCLD_5MS + psLCLDEncoder->psPredictionEncoder ); +#else psLCLDEncoder->psPredictionEncoder->ppiPredBandEnable, psLCLDEncoder->psPredictionEncoder->ppfA1Real, psLCLDEncoder->psPredictionEncoder->ppfA1Imag ); +#endif + iBitsWritten += WriteAllocInformation( psLCLDEncoder->iAllocOffset, pBits ); @@ -710,6 +767,344 @@ int32_t GetNumGroups( LCLDEncoder *psLCLDEncoder ) * *------------------------------------------------------------------------------------------*/ +#ifdef SPLIT_REND_LCLD_5MS +enum MSPred_Types +{ + MS_PHASE_AND_PRED = 0, /* LR phase alignment + real-valued M/S prediction */ + MS_PRED_ONLY = 1, /* real-valued M/S prediction */ + MS_PHASE_ONLY = 2 /* LR phase alignment + M/S */ +}; + +enum MS_BS_TYPES +{ + MS_OFF = 0, + MS_ALL = 1, + MS_SOME = 2, + MS_PRED = 3 +}; + +static int32_t MSModeCalculation( + const int32_t iNumBlocks, + const int32_t iNumBands, + const int32_t *piBandwidths, + float ***pppfReal, + float ***pppfImag, + int32_t *piMSMode, + int32_t *piLRPhaseDiffs, + int32_t *piMSPredCoefs, + const int32_t iAllowSidePred, + int32_t *piMSFlags ) +{ + int32_t b; + int32_t iFBOffset; + int32_t iNumMSBands; + int32_t iMSPredType; + float fMSBitGain = 0.0f; + float pfMSPredBitGain[3] = { 0.0f }; + float fPred; + int32_t piMSPredFlags0[MAX_BANDS] = { 0 }; + int32_t piMSPredFlags1[MAX_BANDS] = { 0 }; + int32_t piMSPredFlags2[MAX_BANDS] = { 0 }; + int32_t *ppiMSPredFlags[3]; + int32_t piMSPredCoefs0[MAX_BANDS] = { 0 }; + int32_t piMSPredCoefs1[MAX_BANDS] = { 0 }; + int32_t piMSPredCoefs2[MAX_BANDS] = { 0 }; + int32_t *ppiMSPredCoefs[3]; + int32_t piMSPredPhase0[MAX_BANDS] = { 0 }; + int32_t piMSPredPhase1[MAX_BANDS] = { 0 }; + int32_t piMSPredPhase2[MAX_BANDS] = { 0 }; + int32_t *ppiMSPredPhase[3]; + int32_t iMsInfoBits; + int32_t piMsPredInfoBits[3] = { 0 }; + + const float feps = 1e-12f; + float fBitsFactor = 3.32192809488736f; /* = 1/log10(2), from dB/10 to bits assuming 1 bit per log2(SNR) or 1 bit per 3dB SNR */ + if ( iNumBlocks < LCLD_BLOCKS_PER_FRAME ) + { + fBitsFactor *= ( 0.7f + (float) ( iNumBlocks - 4 ) / (float) ( LCLD_BLOCKS_PER_FRAME - 4 ) * ( 1.0f - 0.7f ) ); /* Tuning for relatively higher side rate due to shorter frame length */ + } + + ppiMSPredFlags[0] = piMSPredFlags0; + ppiMSPredFlags[1] = piMSPredFlags1; + ppiMSPredFlags[2] = piMSPredFlags2; + + ppiMSPredCoefs[0] = piMSPredCoefs0; + ppiMSPredCoefs[1] = piMSPredCoefs1; + ppiMSPredCoefs[2] = piMSPredCoefs2; + + ppiMSPredPhase[0] = piMSPredPhase0; + ppiMSPredPhase[1] = piMSPredPhase1; + ppiMSPredPhase[2] = piMSPredPhase2; + + *piMSMode = MS_OFF; + iFBOffset = 0; + iNumMSBands = 0; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t n; + float fLeftEnergy; + float fRightEnergy; + float fMidEnergy; + float fSideEnergy; + float fLRRatio; + float fMSRatio; + float pfMSPredRatio[3] = { 0.0f }; + float fMidEnergyPred; + float fSideEnergyPred; + float fLRCovReal = 0.0f; + float fLRCovImag = 0.0f; + int32_t iPhase; + int32_t iPred; + int32_t tabIdx = 0; + float fNumLines = (float) ( iNumBlocks * piBandwidths[b] * 2 ); /* per band per channel */ + float fLevelToSMRdBFactor = (float) c_aiDefaultTheta48[b] / (float) ( 1 << PERCEPTUAL_MODEL_SLGAIN_SHIFT ); /* frequency dependent SMR slope in psy model */ +#ifndef SPLIT_REND_LCLD_5MS + fLevelToSMRdBFactor = (float) c_aiDefaultTheta48[b] / 16.0f; /* this is a bug due to a change of PERCEPTUAL_MODEL_SLGAIN_SHIFT */ +#endif + fLeftEnergy = 0.0f; + fRightEnergy = 0.0f; + fMidEnergy = 0.0f; + fSideEnergy = 0.0f; + + for ( n = 0; n < piBandwidths[b]; n++ ) + { + int32_t k; + for ( k = 0; k < iNumBlocks; k++ ) + { + float fMidReal; + float fMidImag; + float fSideReal; + float fSideImag; + + fMidReal = 0.5f * ( pppfReal[0][k][iFBOffset] + pppfReal[1][k][iFBOffset] ); + fMidImag = 0.5f * ( pppfImag[0][k][iFBOffset] + pppfImag[1][k][iFBOffset] ); + fSideReal = 0.5f * ( pppfReal[0][k][iFBOffset] - pppfReal[1][k][iFBOffset] ); + fSideImag = 0.5f * ( pppfImag[0][k][iFBOffset] - pppfImag[1][k][iFBOffset] ); + + fLeftEnergy += ( pppfReal[0][k][iFBOffset] * pppfReal[0][k][iFBOffset] + pppfImag[0][k][iFBOffset] * pppfImag[0][k][iFBOffset] ); + fRightEnergy += ( pppfReal[1][k][iFBOffset] * pppfReal[1][k][iFBOffset] + pppfImag[1][k][iFBOffset] * pppfImag[1][k][iFBOffset] ); + fMidEnergy += ( fMidReal * fMidReal + fMidImag * fMidImag ); + fSideEnergy += ( fSideReal * fSideReal + fSideImag * fSideImag ); + + fLRCovReal += ( pppfReal[0][k][iFBOffset] * pppfReal[1][k][iFBOffset] + pppfImag[0][k][iFBOffset] * pppfImag[1][k][iFBOffset] ); + fLRCovImag += ( pppfImag[0][k][iFBOffset] * pppfReal[1][k][iFBOffset] - pppfImag[1][k][iFBOffset] * pppfReal[0][k][iFBOffset] ); + } + + iFBOffset++; + } + + /* M/S prediction without phase alignment*/ + fPred = 0.25f * ( fLeftEnergy - fRightEnergy ) / ( fMidEnergy + feps ); + iPred = quantPred( fPred ); + fPred = dequantPred( iPred ); + fSideEnergyPred = fSideEnergy + ( fPred * fPred * fMidEnergy - 2.0f * fPred * 0.25f * ( fLeftEnergy - fRightEnergy ) ); + + ppiMSPredCoefs[MS_PRED_ONLY][b] = iPred; + ppiMSPredPhase[MS_PRED_ONLY][b] = 0; + pfMSPredRatio[MS_PRED_ONLY] = log10f( ( fMidEnergy + feps ) / ( fSideEnergyPred + feps ) ); + + /* Phase alignment*/ + iPhase = 0; + if ( fLRCovReal * fLRCovReal + fLRCovImag * fLRCovImag > 0.5f * fLeftEnergy * fRightEnergy ) + { + float fPhase = atan2f( fLRCovImag, fLRCovReal ); + iPhase = quantPhase( fPhase ); + } + + /* adjust covariance */ + tabIdx = iPhase - PHASE_MIN_VAL; + cplxmult( &fLRCovReal, &fLRCovImag, c_afRotRealImag[tabIdx][0], -c_afRotRealImag[tabIdx][1] ); + + /* compute MS prediction coefficient based on adjusted covariance */ + fMidEnergyPred = 0.25f * ( fLeftEnergy + fRightEnergy + 2.0f * fLRCovReal ); + fSideEnergyPred = 0.25f * ( fLeftEnergy + fRightEnergy - 2.0f * fLRCovReal ); + + /* M/S with LR phase alignment but without prediction */ + ppiMSPredCoefs[MS_PHASE_ONLY][b] = 0; + ppiMSPredPhase[MS_PHASE_ONLY][b] = iPhase; + pfMSPredRatio[MS_PHASE_ONLY] = log10f( ( fMidEnergyPred + feps ) / ( fSideEnergyPred + feps ) ); + + /* M/S with LR phase alignment and prediction */ + fPred = fMidEnergyPred == 0.0f ? 0.0f : 0.25f * ( fLeftEnergy - fRightEnergy ) / fMidEnergyPred; + iPred = quantPred( fPred ); + fPred = dequantPred( iPred ); + fSideEnergyPred += ( fPred * fPred * fMidEnergyPred - 2.0f * fPred * 0.25f * ( fLeftEnergy - fRightEnergy ) ); + /* -= fPred * fPred * fMidEnergyPred doesn't work because fPred is quantized and does not match MS/MM exactly */ + ppiMSPredCoefs[MS_PHASE_AND_PRED][b] = iPred; + ppiMSPredPhase[MS_PHASE_AND_PRED][b] = iPhase; + pfMSPredRatio[MS_PHASE_AND_PRED] = log10f( ( fMidEnergyPred + feps ) / ( fSideEnergyPred + feps ) ); + + /* Plain M/S */ + fLeftEnergy = log10f( fLeftEnergy + feps ); + fRightEnergy = log10f( fRightEnergy + feps ); + fMidEnergy = log10f( fMidEnergy + feps ); + fSideEnergy = log10f( fSideEnergy + feps ); + + fLRRatio = ( fLeftEnergy > fRightEnergy ? fLeftEnergy - fRightEnergy : fRightEnergy - fLeftEnergy ); + fMSRatio = ( fMidEnergy > fSideEnergy ? fMidEnergy - fSideEnergy : fSideEnergy - fMidEnergy ); + + if ( fMSRatio > fLRRatio ) + { + iNumMSBands++; + piMSFlags[b] = 1; + fMSBitGain += fNumLines * ( fMSRatio - fLRRatio ) * fLevelToSMRdBFactor * fBitsFactor; + } + else + { + piMSFlags[b] = 0; + } + piLRPhaseDiffs[b] = 0; + piMSPredCoefs[b] = 0; + + /* MSPred bit gains based on increase of level ratio compared to L/R ratio and the level dependent psy-model */ + for ( iMSPredType = 0; iMSPredType < 3; iMSPredType++ ) + { + if ( pfMSPredRatio[iMSPredType] > fLRRatio ) + { + ppiMSPredFlags[iMSPredType][b] = 1; + pfMSPredBitGain[iMSPredType] += fNumLines * ( pfMSPredRatio[iMSPredType] - fLRRatio ) * fLevelToSMRdBFactor * fBitsFactor; + } + } + } + + /* remove signalling cost from bit gains */ + for ( iMSPredType = 0; iMSPredType < 3; iMSPredType++ ) + { + piMsPredInfoBits[iMSPredType] = CountMSBits( iNumBands, MS_PRED, ppiMSPredFlags[iMSPredType], ppiMSPredPhase[iMSPredType], ppiMSPredCoefs[iMSPredType] ); + pfMSPredBitGain[iMSPredType] = max( pfMSPredBitGain[iMSPredType] - piMsPredInfoBits[iMSPredType], 0.0f ); + } + + /* find the best M/S Pred type */ + iMSPredType = MS_PHASE_AND_PRED; +#ifdef SPLIT_REND_LCLD_5MS + iMSPredType = ( pfMSPredBitGain[MS_PRED_ONLY] > pfMSPredBitGain[iMSPredType] ? MS_PRED_ONLY : iMSPredType ); + iMSPredType = ( pfMSPredBitGain[MS_PHASE_ONLY] > pfMSPredBitGain[iMSPredType] ? MS_PHASE_ONLY : iMSPredType ); +#endif + + /* plain M/S */ + iMsInfoBits = CountMSBits( iNumBands, MS_SOME, piMSFlags, NULL, NULL ); + fMSBitGain = max( fMSBitGain - iMsInfoBits, 0.0f ); + if ( iAllowSidePred && pfMSPredBitGain[iMSPredType] > 1.1f * fMSBitGain ) + { + *piMSMode = MS_PRED; + iNumMSBands = 0; + for ( b = 0; b < iNumBands; b++ ) + { + piMSFlags[b] = ppiMSPredFlags[iMSPredType][b]; + if ( piMSFlags[b] == 1 ) + { + piMSPredCoefs[b] = ppiMSPredCoefs[iMSPredType][b]; + piLRPhaseDiffs[b] = ppiMSPredPhase[iMSPredType][b]; + iNumMSBands++; + } + else + { + piMSPredCoefs[b] = 0; + piLRPhaseDiffs[b] = 0; + } + } + } + else if ( iNumMSBands == iNumBands ) + { + *piMSMode = MS_ALL; + } + else if ( iNumMSBands > 0 ) + { + *piMSMode = MS_SOME; + } + else + { + *piMSMode = MS_OFF; + } +#ifdef DEBUG_WRITE_MS_PRED + { + static FILE *fid; + int32_t iActualInfoBits = CountMSBits( iNumBands, *piMSMode, piMSFlags, piLRPhaseDiffs, piMSPredCoefs ); + if ( !fid ) + fid = fopen( "ms_info_bits.txt", "wt" ); + fprintf( fid, "%d %d %d %d %d\n", iMsInfoBits, piMsPredInfoBits[MS_PHASE_AND_PRED], piMsPredInfoBits[MS_PRED_ONLY], piMsPredInfoBits[MS_PHASE_ONLY], iActualInfoBits ); + } +#endif + if ( *piMSMode != MS_OFF ) + { + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { + if ( piMSFlags[b] == 1 ) + { + int32_t n; + int32_t phaseIdx; + phaseIdx = piLRPhaseDiffs[b] - PHASE_MIN_VAL; + fPred = dequantPred( piMSPredCoefs[b] ); + for ( n = 0; n < piBandwidths[b]; n++ ) + { + int32_t k; + for ( k = 0; k < iNumBlocks; k++ ) + { + float fMidReal; + float fMidImag; + float fSideReal; + float fSideImag; + + if ( *piMSMode == MS_PRED ) + { + cplxmult( &pppfReal[1][k][iFBOffset], &pppfImag[1][k][iFBOffset], c_afRotRealImag[phaseIdx][0], c_afRotRealImag[phaseIdx][1] ); + } + + fMidReal = 0.5f * ( pppfReal[0][k][iFBOffset] + pppfReal[1][k][iFBOffset] ); + fMidImag = 0.5f * ( pppfImag[0][k][iFBOffset] + pppfImag[1][k][iFBOffset] ); + fSideReal = 0.5f * ( pppfReal[0][k][iFBOffset] - pppfReal[1][k][iFBOffset] ); + fSideImag = 0.5f * ( pppfImag[0][k][iFBOffset] - pppfImag[1][k][iFBOffset] ); + + if ( *piMSMode == MS_PRED ) + { + fSideReal -= fPred * fMidReal; + fSideImag -= fPred * fMidImag; + } + + pppfReal[0][k][iFBOffset] = fMidReal; + pppfReal[1][k][iFBOffset] = fSideReal; + pppfImag[0][k][iFBOffset] = fMidImag; + pppfImag[1][k][iFBOffset] = fSideImag; + } + iFBOffset++; + } + } + else + { + iFBOffset += piBandwidths[b]; + } + } + } +#ifdef DEBUG_WRITE_MS_PRED + { + static FILE *fid; + if ( !fid ) + fid = fopen( "ms_enc.txt", "wt" ); + writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSBands, iNumBands, fid, piMSFlags ); + } +#endif + if ( *piMSMode == MS_PRED ) + { + /* Differential Coding of Phase Data*/ + PrepEncode( piLRPhaseDiffs, piMSFlags, iNumBands ); + PrepEncode( piMSPredCoefs, piMSFlags, iNumBands ); +#ifdef DEBUG_WRITE_MS_PRED + { + static FILE *fid; + if ( !fid ) + fid = fopen( "ms_pred_enc.txt", "wt" ); + writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSBands, iNumBands, fid, piMSFlags ); + } +#endif + /* Differential Coding*/ + EncodePhase( piLRPhaseDiffs, iNumMSBands, PHASE_DIFF_DIM ); + EncodePredCoef( piMSPredCoefs, iNumMSBands ); + } + + return iNumMSBands; +} +#else static int32_t MSModeCalculation( const int32_t iNumBlocks, const int32_t iNumBands, @@ -1018,6 +1413,7 @@ static int32_t MSModeCalculation( return iNumMSBands; } +#endif static void RemoveRMSEnvelope( @@ -1057,7 +1453,119 @@ static void RemoveRMSEnvelope( return; } +#ifdef SPLIT_REND_LCLD_5MS +static void QuantizeSpectrumDPCM_Opt( + const int32_t iNumGroups, + const int32_t *piGroupLengths, + const int32_t iNumBands, + const int32_t *piBandwidths, + int32_t **ppiAlloc, + float **ppfReal, + float **ppfImag, + int32_t **ppiQReal, + int32_t **ppiQImag, + int32_t **ppiSignReal, + int32_t **ppiSignImag, + int32_t iNumSubSets, + int32_t iSubSetId, + int32_t *piPredEnable, + float *pfA1Real, + float *pfA1Imag, + float *pfPredStateReal, + float *pfPredStateImag ) +{ + int32_t b, n; + int32_t iFBOffset; + int32_t k, iAlloc, iMaxQuantVal; + float fSCFGain, fInvSCFGain; + + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t m; + for ( m = 0; m < piBandwidths[b]; m++ ) + { + int32_t iBlockOffset = 0; + if ( piPredEnable[iFBOffset] == 1 ) + { + float fReal; + float fImag; + int32_t iSubset = iFBOffset % iNumSubSets; + float fPrevReal = 0.0f; + float fPrevImag = 0.0f; + if ( iSubset != iSubSetId ) + { + /* run predictors across sub-frames */ + fPrevReal = pfPredStateReal[iFBOffset]; + fPrevImag = pfPredStateImag[iFBOffset]; + } + for ( n = 0; n < iNumGroups; n++ ) + { + iAlloc = ppiAlloc[n][b]; + iMaxQuantVal = c_aiQuantMaxValues[iAlloc]; + fSCFGain = c_afScaleFactor[iAlloc]; + fInvSCFGain = c_afInvScaleFactor[iAlloc]; + for ( k = 0; k < piGroupLengths[n]; k++ ) + { + /* prediction */ + fReal = pfA1Real[iFBOffset] * fPrevReal - pfA1Imag[iFBOffset] * fPrevImag; + fImag = pfA1Real[iFBOffset] * fPrevImag + pfA1Imag[iFBOffset] * fPrevReal; + + ppiQReal[iBlockOffset][iFBOffset] = Quantize( ppfReal[iBlockOffset][iFBOffset] + fReal, /* quantize residual */ + fSCFGain, + &ppiSignReal[iBlockOffset][iFBOffset], + iMaxQuantVal ); + + ppiQImag[iBlockOffset][iFBOffset] = Quantize( ppfImag[iBlockOffset][iFBOffset] + fImag, + fSCFGain, + &ppiSignImag[iBlockOffset][iFBOffset], + iMaxQuantVal ); + + fPrevReal = UnQuantize( ppiQReal[iBlockOffset][iFBOffset], + fInvSCFGain, + ppiSignReal[iBlockOffset][iFBOffset] ) - + fReal; /* add prediction to quantized residual = reconstructed sample */ + + fPrevImag = UnQuantize( ppiQImag[iBlockOffset][iFBOffset], + fInvSCFGain, + ppiSignImag[iBlockOffset][iFBOffset] ) - + fImag; + + iBlockOffset++; + } /* group length */ + } /* groups */ + pfPredStateReal[iFBOffset] = fPrevReal; + pfPredStateImag[iFBOffset] = fPrevImag; + } /* predEnable */ + else + { /* no prediction */ + for ( n = 0; n < iNumGroups; n++ ) + { + iAlloc = ppiAlloc[n][b]; + iMaxQuantVal = c_aiQuantMaxValues[iAlloc]; + fSCFGain = c_afScaleFactor[iAlloc]; + fInvSCFGain = c_afInvScaleFactor[iAlloc]; + for ( k = 0; k < piGroupLengths[n]; k++ ) + { + ppiQReal[iBlockOffset][iFBOffset] = Quantize( ppfReal[iBlockOffset][iFBOffset], + fSCFGain, + &ppiSignReal[iBlockOffset][iFBOffset], + iMaxQuantVal ); + ppiQImag[iBlockOffset][iFBOffset] = Quantize( ppfImag[iBlockOffset][iFBOffset], + fSCFGain, + &ppiSignImag[iBlockOffset][iFBOffset], + iMaxQuantVal ); + + iBlockOffset++; + } /* group length */ + } /* groups */ + } /* predEnable */ + iFBOffset++; + } /* bandwidth */ + } /* bands */ +} +#else static void QuantizeSpectrumDPCM_Opt( const int32_t iNumGroups, const int32_t *piGroupLengths, @@ -1199,7 +1707,7 @@ static void QuantizeSpectrumDPCM_Opt( return; } - +#endif static int32_t CountLCLDBits( const int32_t iNumGroups, @@ -1362,13 +1870,6 @@ static int32_t WriteMSInformation( if ( anyNonZero ) { -#ifdef SIMPLE_PHASE - for ( b = 0; b < iNumMSPredBands; b++ ) - { - ivas_split_rend_bitstream_write_int32( pBits, piLRPhaseDiff[b], SIMPLE_PHASE_BITS ); - iBitsWritten += SIMPLE_PHASE_BITS; - } -#else ivas_split_rend_bitstream_write_int32( pBits, piLRPhaseDiff[0] - PHASE_MIN_VAL, PHASE_BAND0_BITS ); iBitsWritten += PHASE_BAND0_BITS; for ( b = 1; b < iNumMSPredBands; b++ ) @@ -1377,7 +1878,6 @@ static int32_t WriteMSInformation( ivas_split_rend_bitstream_write_int32( pBits, c_aaiRMSEnvHuffEnc[tabIdx][1], c_aaiRMSEnvHuffEnc[tabIdx][0] ); iBitsWritten += c_aaiRMSEnvHuffEnc[tabIdx][0]; } -#endif } anyNonZero = 0; @@ -1540,70 +2040,6 @@ static int32_t WriteRMSEnvelope( } -#ifdef ENABLE_PMOD_ADJUST -static int32_t WritePmodInformation( - const int32_t **ppiHiSMRFlags, - IVAS_SPLIT_REND_BITS_HANDLE pBits, - int32_t iChannels, - int32_t iNumBands ) -{ - int32_t iBitsWritten, c, b; - - iBitsWritten = 0; - - for ( c = 0; c < iChannels; c++ ) - { - int32_t anyNonZero = 0; - const int32_t *flags = ppiHiSMRFlags[c]; - for ( b = 0; b < iNumBands; b++ ) - { - if ( flags[b] ) - { - anyNonZero = 1; - break; - } - } - ivas_split_rend_bitstream_write_int32( pBits, anyNonZero, 1 ); - iBitsWritten += 1; - if ( anyNonZero ) - { - for ( b = 0; b < iNumBands; b++ ) - { - ivas_split_rend_bitstream_write_int32( pBits, flags[b], 1 ); - iBitsWritten += 1; - } - } - } -#ifdef WRITE_HISMR_FLAGS - { - static FILE *fid = 0; - if ( !fid ) - { - fid = fopen( "hismr_enc.txt", "wt" ); - } - for ( c = 0; c < iChannels; c++ ) - { - int32_t b; - for ( b = 0; b < iNumBands; b++ ) - { - if ( c == iChannels - 1 && b == iNumBands - 1 ) - { - fprintf( fid, "%d\n", ppiHiSMRFlags[c][b] ); - } - else - { - fprintf( fid, "%d ", ppiHiSMRFlags[c][b] ); - } - } - } - } -#endif - - return iBitsWritten; -} -#endif - - static int32_t WriteAllocInformation( const int32_t iAllocOffset, IVAS_SPLIT_REND_BITS_HANDLE pBits ) @@ -1764,9 +2200,13 @@ static int32_t ComputeAllocation( int32_t ***pppiQImag, int32_t ***pppiSignReal, int32_t ***pppiSignImag, +#ifdef SPLIT_REND_LCLD_5MS + PredictionEncoder *psPredictionEncoder ) +#else int32_t **ppiPredEnable, float **ppfA1Real, float **ppfA1Imag ) +#endif { int32_t iBitsUsed, iDone, iDelta; int32_t b, k, n; @@ -1800,6 +2240,14 @@ static int32_t ComputeAllocation( } } +#ifdef SPLIT_REND_LCLD_5MS + if ( psPredictionEncoder->iNumSubSets > 1 ) + { + mvr2r( psPredictionEncoder->ppfPredStateReal[n], psPredictionEncoder->ppfPredStateRealTmp[n], LCLD_BANDS ); + mvr2r( psPredictionEncoder->ppfPredStateImag[n], psPredictionEncoder->ppfPredStateImagTmp[n], LCLD_BANDS ); + } +#endif + QuantizeSpectrumDPCM_Opt( piNumGroups[n], (const int32_t *) ppiGroupLengths[n], iNumBands, @@ -1811,15 +2259,29 @@ static int32_t ComputeAllocation( pppiQImag[n], pppiSignReal[n], pppiSignImag[n], +#ifdef SPLIT_REND_LCLD_5MS + psPredictionEncoder->iNumSubSets, + psPredictionEncoder->iSubSetId, + psPredictionEncoder->ppiPredBandEnable[n], + psPredictionEncoder->ppfA1Real[n], + psPredictionEncoder->ppfA1Imag[n], + psPredictionEncoder->ppfPredStateRealTmp[n], + psPredictionEncoder->ppfPredStateImagTmp[n] ); +#else ppiPredEnable[n], ppfA1Real[n], ppfA1Imag[n] ); +#endif iBitsUsed += CountLCLDBits( piNumGroups[n], (const int32_t *) ppiGroupLengths[n], iNumBands, piBandwidths, +#ifdef SPLIT_REND_LCLD_5MS + (const int32_t *) psPredictionEncoder->ppiPredBandEnable[n], +#else (const int32_t *) ppiPredEnable[n], +#endif pppiAlloc[n], pppiQReal[n], pppiQImag[n] ); @@ -1866,6 +2328,21 @@ static int32_t ComputeAllocation( } } +#ifdef SPLIT_REND_LCLD_5MS + if ( psPredictionEncoder->iNumSubSets > 1 ) + { + for ( n = 0; n < iChannels; n++ ) + { + mvr2r( psPredictionEncoder->ppfPredStateRealTmp[n], psPredictionEncoder->ppfPredStateReal[n], LCLD_BANDS ); + mvr2r( psPredictionEncoder->ppfPredStateImagTmp[n], psPredictionEncoder->ppfPredStateImag[n], LCLD_BANDS ); + } + if ( ++psPredictionEncoder->iSubSetId == psPredictionEncoder->iNumSubSets ) + { + psPredictionEncoder->iSubSetId = 0; + } + } +#endif + // printf("%d\n",*piAllocOffset); // printf("%d\t%d\t%d\n",pppiAlloc[0][0][0],pppiAlloc[0][0][1],pppiAlloc[0][0][22]); diff --git a/lib_rend/ivas_lcld_prot.h b/lib_rend/ivas_lcld_prot.h index 2af8355c97..08daf79c05 100644 --- a/lib_rend/ivas_lcld_prot.h +++ b/lib_rend/ivas_lcld_prot.h @@ -42,12 +42,23 @@ typedef struct LCLD_ENCODER LCLDEncoder; +#ifdef SPLIT_REND_LCLD_5MS +ivas_error CreateLCLDEncoder( + LCLDEncoder **psLCLDEncoder_out, + const int32_t iSampleRate, + const int32_t iChannels, + const int32_t iTargetBitRate, + const int32_t iAllowSidePred, + const int32_t iNumBlocks, + const int32_t iNumSubSets ); +#else ivas_error CreateLCLDEncoder( LCLDEncoder **psLCLDEncoder, const int32_t iSampleRate, const int32_t iChannels, const int32_t iTargetBitRate, const int32_t iAllowSidePred ); +#endif void DeleteLCLDEncoder( LCLDEncoder *psLCLDEncoder @@ -68,10 +79,22 @@ int32_t GetNumGroups( typedef struct LCLD_DECODER LCLDDecoder; +#ifndef SPLIT_REND_LCLD_5MS ivas_error CreateLCLDDecoder( LCLDDecoder **psLCLDDecoder_out, const int32_t iSampleRate, const int32_t iChannels ); +#else +int32_t GetNumPredSubSets( + LCLDDecoder *psLCLDDecoder +); + +ivas_error CreateLCLDDecoder( + LCLDDecoder **psLCLDDecoder_out, + const int32_t iSampleRate, + const int32_t iChannels, + const int32_t iNumBlocks ); +#endif void DeleteLCLDDecoder( LCLDDecoder *psLCLDDecoder @@ -100,25 +123,6 @@ void cplxmult( float i2 ); -#ifdef SIMPLE_PHASE -void rot_pm_pi( - float *pr, - float *pi ); - -void rot_p_pi_2( - float *pr, - float *pi -); - -void rot_m_pi_2( - float *pr, - float *pi ); - -void rot_zero( - float *pr, - float *pi -); -#endif int32_t requantPhase( int32_t phaseQ @@ -195,6 +199,11 @@ typedef struct NOISE_GEN float *pfNoiseBuffer; } NoiseGen; +#ifdef SPLIT_REND_LCLD_5MS +NoiseGen *CreateNoiseGen( + void +); +#endif void DeleteNoiseGen( NoiseGen *psNoiseGen @@ -244,15 +253,30 @@ typedef struct PREDICTION_ENCODER int32_t iChannels; int32_t iNumBlocks; +#ifdef SPLIT_REND_LCLD_5MS + int32_t iSubSetId; + int32_t iNumSubSets; + int32_t iMaxNumPredBands; + float ***pppfInpBufReal; /* channels, LCLD_PRED_WIN_LEN, bands */ + float ***pppfInpBufImag; + float **ppfPredStateReal; /* channels, bands */ + float **ppfPredStateImag; + float **ppfPredStateRealTmp; + float **ppfPredStateImagTmp; + float **ppfInpPrevReal; /* channels, bands */ + float **ppfInpPrevImag; +#endif + float *pfWindow; float pfRxxReal[2]; float pfRxxImag[2]; int32_t *piPredChanEnable; int32_t *piNumPredBands; - +#ifndef SPLIT_REND_LCLD_5MS float **ppfEstPredGain; float **ppfEstPredBitGain; +#endif int32_t **ppiPredBandEnable; float **ppfA1Real; @@ -262,21 +286,39 @@ typedef struct PREDICTION_ENCODER int32_t **ppiA1Phase; } PredictionEncoder; +#ifdef SPLIT_REND_LCLD_5MS +ivas_error CreatePredictionEncoder( + PredictionEncoder **psPredictionEncoder_out, + const int32_t iChannels, + const int32_t iNumBlocks, + const int32_t iNumSubSets, + const int32_t iMaxNumPredBands +); +#else ivas_error CreatePredictionEncoder( PredictionEncoder **psPredictionEncoder_out, const int32_t iChannels, const int32_t iNumBlocks ); +#endif void DeletePredictionEncoder( PredictionEncoder *psPredictionEncoder ); +#ifdef SPLIT_REND_LCLD_5MS +void ComputePredictors( + PredictionEncoder *psPredictionEncoder, + float ***pppfReal, + float ***pppfImag +); +#else int32_t ComputePredictors( PredictionEncoder *psPredictionEncoder, float ***pppfReal, float ***pppfImag ); +#endif void ApplyForwardPredictors( PredictionEncoder *psPredictionEncoder, @@ -293,11 +335,19 @@ typedef struct PREDICTION_DECODER { int32_t iChannels; int32_t iNumBlocks; + #ifdef SPLIT_REND_LCLD_5MS + int32_t iSubSetId; + int32_t iNumSubSets; + float **ppfPredStateReal; + float **ppfPredStateImag; + #endif int32_t *piPredChanEnable; + #ifndef SPLIT_REND_LCLD_5MS int32_t *piNumPredBands; float **ppfEstPredGain; + #endif int32_t **ppiPredBandEnable; float **ppfA1Real; @@ -327,7 +377,11 @@ int32_t ReadPredictors( IVAS_SPLIT_REND_BITS_HANDLE pBits ); +#ifdef SPLIT_REND_LCLD_5MS +void ApplyInversePredictors( +#else void ApplyInversePredictros( +#endif PredictionDecoder *psPredictionDecoder, float ***pppfReal, float ***pppfImag diff --git a/lib_rend/ivas_lcld_rom_tables.c b/lib_rend/ivas_lcld_rom_tables.c index 144c44718d..58fd22ff5c 100644 --- a/lib_rend/ivas_lcld_rom_tables.c +++ b/lib_rend/ivas_lcld_rom_tables.c @@ -39,12 +39,14 @@ /* clang-format off */ +#ifndef SPLIT_REND_LCLD_5MS const float c_afRotRealImagSimple[SIMPLE_PHASE_MAX_VAL + 1][2] = { { 1.0f, 0.0f }, /* zero */ { 0.0f, 1.0f }, /* pi/2 */ { -1.0f, 0.0f }, /* pi */ { 0.0f, -1.0f }, /* 3*pi/2 */ }; +#endif /* phi = (-12:12)'/12 *pi; tmp = [cos(phi),sin(phi)]; tmp = tmp';sprintf('{%.8ff, %.8ff},\n',tmp(:)) */ const float c_afRotRealImag[PHASE_MAX_VAL - PHASE_MIN_VAL + 1][2] = diff --git a/lib_rend/ivas_lcld_rom_tables.h b/lib_rend/ivas_lcld_rom_tables.h index 132f52addf..8e9de87606 100644 --- a/lib_rend/ivas_lcld_rom_tables.h +++ b/lib_rend/ivas_lcld_rom_tables.h @@ -45,9 +45,16 @@ #define LCLD_BLOCKS_PER_FRAME ( 16 ) #define LCLD_MAX_BLOCKS_PER_FRAME ( 16 ) #define LCLD_BANDS ( 60 ) +#ifdef SPLIT_REND_LCLD_5MS +#define LCLD_PRED_WIN_LEN ( 16 ) +#define LCLD_MAX_NUM_PRED_SUBSETS ( 8 ) +#endif #define MAX_BANDS ( 23 ) #define MAX_BANDS_48 ( 23 ) +#ifdef SPLIT_REND_LCLD_5MS +#define DEF_BANDS_48 ( 22 ) +#endif #define ENV_MIN ( -64 ) #define ENV_MAX ( 64 ) @@ -88,6 +95,7 @@ #define PHASE_DIFF_DIM ( 2 ) #define PHASE_BAND0_BITS ( 5 ) +#ifndef SPLIT_REND_LCLD_5MS #define SIMPLE_PHASE_MAX_VAL ( 3 ) #define SIMPLE_PHASE_MIN_VAL ( 0 ) #define SIMPLE_PHASE_BITS ( 2 ) @@ -95,7 +103,7 @@ #define TON_QUOTA_ABS_THRESHOLD ( 8.0f ) #define TON_QUOTA_INC_THRESHOLD ( 4.0f ) - +#endif #define PERCEPTUAL_MODEL_SLGAIN_SHIFT ( 8 ) //#define USE_DEMOD_TABLES @@ -103,7 +111,9 @@ #define HUFF_DEC_TABLE_SIZE ( 16 ) extern const float c_afRotRealImag[PRED_MAX_VAL - PRED_MIN_VAL + 1][2]; +#ifndef SPLIT_REND_LCLD_5MS extern const float c_afRotRealImagSimple[SIMPLE_PHASE_MAX_VAL + 1][2]; +#endif extern const int32_t c_aiDefaultTheta48[MAX_BANDS_48]; extern const float c_afScaleFactor[ALLOC_TABLE_SIZE]; diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index bb120dcafa..3438c693d0 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -1486,12 +1486,23 @@ void ivas_split_renderer_close( SPLIT_REND_WRAPPER *hSplitBinRend ); +#ifdef SPLIT_REND_LCLD_5MS +ivas_error ivas_splitBinLCLDEncOpen( + BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc, + const int32_t iSampleRate, + const int16_t iChannels, + const int32_t iDataRate, + const int32_t iNumBlocks, + const int32_t iNumIterations +); +#else ivas_error ivas_splitBinLCLDEncOpen( BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc, const int32_t iSampleRate, const int16_t iChannels, const int32_t iDataRate ); +#endif void ivas_splitBinLCLDEncClose( BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc @@ -1505,11 +1516,21 @@ void ivas_splitBinLCLDEncProcess( IVAS_SPLIT_REND_BITS_HANDLE pBits ); +#ifdef SPLIT_REND_LCLD_5MS +ivas_error ivas_splitBinLCLDDecOpen( + BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec, + const int32_t iSampleRate, + const int16_t iChannels, + const int16_t iNumBlocks, + const int16_t iNumIterations +); +#else ivas_error ivas_splitBinLCLDDecOpen( BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec, const int32_t iSampleRate, const int16_t iChannels ); +#endif void ivas_splitBinLCLDDecClose( BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec @@ -1650,26 +1671,59 @@ void ivas_splitBinRendPLCClose( SPLIT_REND_PLC_HANDLE* phSplitRendPLC ); +#ifdef SPLIT_REND_LCLD_5MS +void ivas_splitBinRendPLCsaveState( + SPLIT_REND_PLC_HANDLE hSplitRendPLC, + float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t num_chs, + const int16_t iNumBlocks, + const int16_t iNumIterations +); +#else void ivas_splitBinRendPLCsaveState( SPLIT_REND_PLC_HANDLE hSplitRendPLC, float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const int16_t num_chs ); +#endif +#ifdef SPLIT_REND_LCLD_5MS +void ivas_splitBinRendPLC_xf( + SPLIT_REND_PLC_HANDLE hSplitRendPLC, + float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t num_chs, + const int16_t iNumBlocks, + const int16_t iNumIterations +); +#else void ivas_splitBinRendPLC_xf( SPLIT_REND_PLC_HANDLE hSplitRendPLC, float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const int16_t num_chs ); +#endif +#ifdef SPLIT_REND_LCLD_5MS +void ivas_splitBinRendPLC( + SPLIT_REND_PLC_HANDLE hSplitRendPLC, + float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t num_chs, + const int16_t iNumBlocks, + const int16_t iNumIterations +); +#else void ivas_splitBinRendPLC( SPLIT_REND_PLC_HANDLE hSplitRendPLC, float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const int16_t num_chs ); +#endif #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG void ivas_log_cldfb2wav_data( @@ -2011,12 +2065,22 @@ void ivas_split_rend_get_quant_params( int16_t *num_complex_bands ); +#ifdef SPLIT_REND_LCLD_5MS +ivas_error ivas_split_rend_choose_default_codec( + IVAS_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */ + int16_t *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */ + const int16_t cldfb_in_flag, /* i : flag indicating rendering in TD */ + const int16_t pcm_out_flag, /* i : flag to indicate PCM output */ + const int16_t is_5ms_frame /* i : flag to indicate 5ms framing */ +); +#else ivas_error ivas_split_rend_choose_default_codec( IVAS_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */ int16_t *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */ const int16_t cldfb_in_flag, /* i : flag indicating rendering in CLDFB */ const int16_t pcm_out_flag /* i : flag to indicate PCM output */ ); +#endif #endif diff --git a/lib_rend/ivas_splitRend_lcld_dec.c b/lib_rend/ivas_splitRend_lcld_dec.c index 1d81dfebc9..3ca53e513d 100644 --- a/lib_rend/ivas_splitRend_lcld_dec.c +++ b/lib_rend/ivas_splitRend_lcld_dec.c @@ -47,11 +47,19 @@ * * *------------------------------------------------------------------------*/ - +#ifdef SPLIT_REND_LCLD_5MS +ivas_error ivas_splitBinLCLDDecOpen( + BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec, + const int32_t iSampleRate, + const int16_t iChannels, + const int16_t iNumBlocks, + const int16_t iNumIterations ) +#else ivas_error ivas_splitBinLCLDDecOpen( BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec, const int32_t iSampleRate, const int16_t iChannels ) +#endif { int16_t n; BIN_HR_SPLIT_LCLD_DEC_HANDLE splitBinLCLDDec; @@ -65,10 +73,17 @@ ivas_error ivas_splitBinLCLDDecOpen( splitBinLCLDDec->pLcld_dec = NULL; /* place holder for CLDFB decoder handle */ splitBinLCLDDec->iChannels = iChannels; +#ifndef SPLIT_REND_LCLD_5MS if ( ( error = CreateLCLDDecoder( &splitBinLCLDDec->psLCLDDecoder, iSampleRate, iChannels ) ) != IVAS_ERR_OK ) { return error; } +#else + if ( ( error = CreateLCLDDecoder( &splitBinLCLDDec->psLCLDDecoder, iSampleRate, iChannels, iNumBlocks ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif if ( ( splitBinLCLDDec->pppfDecLCLDReal = (float ***) malloc( iChannels * sizeof( float ** ) ) ) == NULL ) { @@ -108,6 +123,10 @@ ivas_error ivas_splitBinLCLDDecOpen( { return error; } +#ifdef SPLIT_REND_LCLD_5MS + splitBinLCLDDec->iNumBlocks = iNumBlocks; + splitBinLCLDDec->iNumIterations = iNumIterations; +#endif *hSplitBinLCLDDec = splitBinLCLDDec; @@ -171,7 +190,9 @@ void ivas_splitBinLCLDDecProcess( const int16_t bfi ) { int16_t k, n; - +#ifdef SPLIT_REND_LCLD_5MS + int16_t itr; +#endif push_wmops( "ivas_splitBinLCLDDecProcess" ); assert( hSplitBinLCLDDec != NULL ); @@ -184,9 +205,22 @@ void ivas_splitBinLCLDDecProcess( #endif if ( !bfi ) { - /* Initialized with zeros....... */ - for ( n = 0; n < hSplitBinLCLDDec->iChannels; n++ ) +#ifdef SPLIT_REND_LCLD_5MS + for ( itr = 0; itr < hSplitBinLCLDDec->iNumIterations; itr++ ) { +#endif + /* Initialized with zeros....... */ + for ( n = 0; n < hSplitBinLCLDDec->iChannels; n++ ) + { +#ifdef SPLIT_REND_LCLD_5MS + for ( k = 0; k < hSplitBinLCLDDec->iNumBlocks; k++ ) + { + hSplitBinLCLDDec->pppfDecLCLDReal[n][k] = Cldfb_Out_Real[n][hSplitBinLCLDDec->iNumBlocks * itr + k]; + hSplitBinLCLDDec->pppfDecLCLDImag[n][k] = Cldfb_Out_Imag[n][hSplitBinLCLDDec->iNumBlocks * itr + k]; + set_f( hSplitBinLCLDDec->pppfDecLCLDReal[n][k], 0, CLDFB_NO_CHANNELS_MAX ); + set_f( hSplitBinLCLDDec->pppfDecLCLDImag[n][k], 0, CLDFB_NO_CHANNELS_MAX ); + } +#else for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) { hSplitBinLCLDDec->pppfDecLCLDReal[n][k] = Cldfb_Out_Real[n][k]; @@ -194,43 +228,59 @@ void ivas_splitBinLCLDDecProcess( set_f( hSplitBinLCLDDec->pppfDecLCLDReal[n][k], 0, CLDFB_NO_CHANNELS_MAX ); set_f( hSplitBinLCLDDec->pppfDecLCLDImag[n][k], 0, CLDFB_NO_CHANNELS_MAX ); } - } +#endif + } - DecodeLCLDFrame( hSplitBinLCLDDec->psLCLDDecoder, pBits, hSplitBinLCLDDec->pppfDecLCLDReal, hSplitBinLCLDDec->pppfDecLCLDImag ); + DecodeLCLDFrame( hSplitBinLCLDDec->psLCLDDecoder, pBits, hSplitBinLCLDDec->pppfDecLCLDReal, hSplitBinLCLDDec->pppfDecLCLDImag ); #ifdef CLDFB_DEBUG - printf( "Frame Decoded = %d\n", ++hSplitBinLCLDDec->numFrame ); - int16_t writeByte = 0; - for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) - { - for ( int16_t b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ ) + printf( "Frame Decoded = %d\n", ++hSplitBinLCLDDec->numFrame ); + int16_t writeByte = 0; + for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) { - for ( n = 0; n < hSplitBinLCLDDec->iChannels; n++ ) + for ( int16_t b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ ) { - writeByte = fwrite( &hSplitBinLCLDDec->pppfDecLCLDReal[n][k][b], sizeof( float ), 1, hSplitBinLCLDDec->cldfbOut ); - if ( writeByte != 1 ) - exit( -1 ); - writeByte = fwrite( &hSplitBinLCLDDec->pppfDecLCLDImag[n][k][b], sizeof( float ), 1, hSplitBinLCLDDec->cldfbOut ); - if ( writeByte != 1 ) - exit( -1 ); + for ( n = 0; n < hSplitBinLCLDDec->iChannels; n++ ) + { + writeByte = fwrite( &hSplitBinLCLDDec->pppfDecLCLDReal[n][k][b], sizeof( float ), 1, hSplitBinLCLDDec->cldfbOut ); + if ( writeByte != 1 ) + exit( -1 ); + writeByte = fwrite( &hSplitBinLCLDDec->pppfDecLCLDImag[n][k][b], sizeof( float ), 1, hSplitBinLCLDDec->cldfbOut ); + if ( writeByte != 1 ) + exit( -1 ); + } } } - } #endif - if ( hSplitBinLCLDDec->hSplitRendPLC->prev_bfi != 0 ) - { - /* cross-fade recovered frame into good frame */ + if ( hSplitBinLCLDDec->hSplitRendPLC->prev_bfi != 0 ) + { + /* cross-fade recovered frame into good frame */ +#ifdef SPLIT_REND_LCLD_5MS + ivas_splitBinRendPLC_xf( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations ); +#else ivas_splitBinRendPLC_xf( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels ); +#endif + } +#ifdef SPLIT_REND_LCLD_5MS } +#endif } else { /* do PLC for lost split renderer frame */ +#ifdef SPLIT_REND_LCLD_5MS + ivas_splitBinRendPLC( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations ); +#else ivas_splitBinRendPLC( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels ); +#endif } /* save PLC state */ +#ifdef SPLIT_REND_LCLD_5MS + ivas_splitBinRendPLCsaveState( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations ); +#else ivas_splitBinRendPLCsaveState( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels ); +#endif pop_wmops(); diff --git a/lib_rend/ivas_splitRend_lcld_enc.c b/lib_rend/ivas_splitRend_lcld_enc.c index a0789d63a8..83a60a8710 100644 --- a/lib_rend/ivas_splitRend_lcld_enc.c +++ b/lib_rend/ivas_splitRend_lcld_enc.c @@ -47,11 +47,21 @@ * *------------------------------------------------------------------------*/ +#ifdef SPLIT_REND_LCLD_5MS +ivas_error ivas_splitBinLCLDEncOpen( + BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc, + const int32_t iSampleRate, + const int16_t iChannels, + const int32_t iDataRate, + const int32_t iNumBlocks, + const int32_t iNumIterations ) +#else ivas_error ivas_splitBinLCLDEncOpen( BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc, const int32_t iSampleRate, const int16_t iChannels, const int32_t iDataRate ) +#endif { BIN_HR_SPLIT_LCLD_ENC_HANDLE splitBinLCLDEnc; ivas_error error; @@ -64,10 +74,17 @@ ivas_error ivas_splitBinLCLDEncOpen( splitBinLCLDEnc->pLcld_enc = NULL; // place holder for CLDFB encoder handle splitBinLCLDEnc->iChannels = iChannels; +#ifdef SPLIT_REND_LCLD_5MS + if ( ( error = CreateLCLDEncoder( &( splitBinLCLDEnc->psLCLDEncoder ), iSampleRate, iChannels, iDataRate, 1, iNumBlocks, CLDFB_NO_COL_MAX / iNumBlocks ) ) != IVAS_ERR_OK ) + { + return error; + } +#else if ( ( error = CreateLCLDEncoder( &( splitBinLCLDEnc->psLCLDEncoder ), iSampleRate, iChannels, iDataRate, 1 ) ) != IVAS_ERR_OK ) { return error; } +#endif if ( ( splitBinLCLDEnc->pppfLCLDReal = (float ***) malloc( iChannels * sizeof( float ** ) ) ) == NULL ) { @@ -90,6 +107,11 @@ ivas_error ivas_splitBinLCLDEncOpen( } } +#ifdef SPLIT_REND_LCLD_5MS + splitBinLCLDEnc->iNumIterations = iNumIterations; + splitBinLCLDEnc->iNumBlocks = iNumBlocks; +#endif + #ifdef CLDFB_DEBUG splitBinLCLDEnc->numFrame = 0; char cldfbFilename[50] = "cldfb_in_ref.qmf"; @@ -158,16 +180,37 @@ void ivas_splitBinLCLDEncProcess( const int32_t available_bits, IVAS_SPLIT_REND_BITS_HANDLE pBits ) { +#ifdef SPLIT_REND_LCLD_5MS + int32_t iBitsWritten, itr, available_bits_itr, rem_itr, available_bits_local; +#else int32_t iBitsWritten; - +#endif push_wmops( "ivas_splitBinLCLDEncProcess" ); assert( hSplitBinLCLDEnc != NULL ); assert( Cldfb_In_Real != NULL ); assert( Cldfb_In_Imag != NULL ); assert( pBits != NULL ); - +#ifdef SPLIT_REND_LCLD_5MS + available_bits_local = available_bits; +#endif /* A conversion is needed for the 3d pointer interface here ........ */ +#ifdef SPLIT_REND_LCLD_5MS + for ( itr = 0; itr < hSplitBinLCLDEnc->iNumIterations; itr++ ) + { + + rem_itr = hSplitBinLCLDEnc->iNumIterations - itr; + available_bits_itr = available_bits_local / rem_itr; + + for ( int32_t n = 0; n < hSplitBinLCLDEnc->iChannels; n++ ) + { + for ( int32_t k = 0; k < hSplitBinLCLDEnc->iNumBlocks; k++ ) + { + hSplitBinLCLDEnc->pppfLCLDReal[n][k] = Cldfb_In_Real[n][hSplitBinLCLDEnc->iNumBlocks * itr + k]; + hSplitBinLCLDEnc->pppfLCLDImag[n][k] = Cldfb_In_Imag[n][hSplitBinLCLDEnc->iNumBlocks * itr + k]; + } + } +#else for ( int32_t n = 0; n < hSplitBinLCLDEnc->iChannels; n++ ) { for ( int32_t k = 0; k < CLDFB_NO_COL_MAX; k++ ) @@ -176,55 +219,83 @@ void ivas_splitBinLCLDEncProcess( hSplitBinLCLDEnc->pppfLCLDImag[n][k] = Cldfb_In_Imag[n][k]; } } +#endif #ifdef CLDFB_DEBUG - int16_t readByte = 0; - for ( int16_t k = 0; k < CLDFB_NO_COL_MAX; k++ ) - { - for ( int16_t b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ ) + int16_t readByte = 0; +#ifdef SPLIT_REND_LCLD_5MS + for ( int16_t k = 0; k < hSplitBinLCLDEnc->iNumBlocks; k++ ) +#else + for ( int16_t k = 0; k < CLDFB_NO_COL_MAX; k++ ) +#endif { - for ( int16_t n = 0; n < hSplitBinLCLDEnc->iChannels; n++ ) + for ( int16_t b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ ) { - readByte = fread( &Cldfb_In_Real[n][k][b], sizeof( float ), 1, hSplitBinLCLDEnc->cldfbIn ); - if ( readByte != 1 ) - break; - readByte = fread( &Cldfb_In_Imag[n][k][b], sizeof( float ), 1, hSplitBinLCLDEnc->cldfbIn ); + for ( int16_t n = 0; n < hSplitBinLCLDEnc->iChannels; n++ ) + { +#ifdef SPLIT_REND_LCLD_5MS + readByte = fread( &hSplitBinLCLDEnc->pppfLCLDReal[n][k][b], sizeof( float ), 1, hSplitBinLCLDEnc->cldfbIn ); + if ( readByte != 1 ) + break; + readByte = fread( &hSplitBinLCLDEnc->pppfLCLDReal[n][k][b], sizeof( float ), 1, hSplitBinLCLDEnc->cldfbIn ); +#else + readByte = fread( &Cldfb_In_Real[n][k][b], sizeof( float ), 1, hSplitBinLCLDEnc->cldfbIn ); + if ( readByte != 1 ) + break; + readByte = fread( &Cldfb_In_Imag[n][k][b], sizeof( float ), 1, hSplitBinLCLDEnc->cldfbIn ); +#endif + } } } - } - if ( readByte == 1 ) - { - printf( "Frame Read = %d\n", ++hSplitBinLCLDEnc->numFrame ); - } - else - { - printf( "Writing zeroes...\n" ); - for ( int16_T k = 0; k < CLDFB_NO_COL_MAX; k++ ) + if ( readByte == 1 ) { - for ( int16_t b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ ) + printf( "Frame Read = %d\n", ++hSplitBinLCLDEnc->numFrame ); + } + else + { + printf( "Writing zeroes...\n" ); +#ifdef SPLIT_REND_LCLD_5MS + for ( int16_T k = 0; k < hSplitBinLCLDEnc->iNumBlocks; k++ ) +#else + for ( int16_T k = 0; k < CLDFB_NO_COL_MAX; k++ ) +#endif { - for ( int16_t n = 0; n < hSplitBinLCLDEnc->iChannels; n++ ) + for ( int16_t b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ ) { - hSplitBinLCLDEnc->pppfLCLDReal[n][k][b] = 0.f; - hSplitBinLCLDEnc->pppfLCLDImag[n][k][b] = 0.f; + for ( int16_t n = 0; n < hSplitBinLCLDEnc->iChannels; n++ ) + { + hSplitBinLCLDEnc->pppfLCLDReal[n][k][b] = 0.f; + hSplitBinLCLDEnc->pppfLCLDImag[n][k][b] = 0.f; + } } } } - } #endif - +#ifdef SPLIT_REND_LCLD_5MS + EncodeLCLDFrame( hSplitBinLCLDEnc->psLCLDEncoder, hSplitBinLCLDEnc->pppfLCLDReal, hSplitBinLCLDEnc->pppfLCLDImag, &iBitsWritten, available_bits_itr, pBits ); +#else EncodeLCLDFrame( hSplitBinLCLDEnc->psLCLDEncoder, hSplitBinLCLDEnc->pppfLCLDReal, hSplitBinLCLDEnc->pppfLCLDImag, &iBitsWritten, available_bits, pBits ); +#endif +#ifdef SPLIT_REND_LCLD_5MS + available_bits_local -= iBitsWritten; +#ifdef DEBUGGING + assert( available_bits_local >= 0 ); +#endif +#else #ifdef DEBUGGING if ( iBitsWritten > available_bits ) assert( iBitsWritten <= available_bits ); #endif +#endif #ifdef CLDFB_DEBUG - printf( "Bits written = %d\n", iBitsWritten ); + printf( "Bits written = %d\n", iBitsWritten ); +#endif +#ifdef SPLIT_REND_LCLD_5MS + } #endif - pop_wmops(); return; diff --git a/lib_rend/ivas_splitRendererPLC.c b/lib_rend/ivas_splitRendererPLC.c index 0c75b55eb6..459827bd56 100644 --- a/lib_rend/ivas_splitRendererPLC.c +++ b/lib_rend/ivas_splitRendererPLC.c @@ -74,6 +74,10 @@ static void adaptive_polar_ext_plc( float xf_alp[CLDFB_PLC_XF], float xf_bet[CLDFB_PLC_XF] #endif +#ifdef SPLIT_REND_LCLD_5MS + , + const int16_t iNumCols +#endif ) { float uth[CLDFB_NO_COL_MAX], uthu[CLDFB_NO_COL_MAX], urh[CLDFB_NO_COL_MAX]; @@ -82,6 +86,10 @@ static void adaptive_polar_ext_plc( float start_real, start_imag, abs_fac, abs_fac_powj, comp_fac, fac_powj_real, fac_powj_imag, temp, abs2inv; float fac_ph_real, fac_ph_imag, rat_real, rat_imag, abs_temp; int32_t k, j; +#ifndef SPLIT_REND_LCLD_5MS + int16_t iNumCols; + iNumCols = CLDFB_NO_COL_MAX; +#endif /* reset of accumulators */ ph_adj = 0.0f; @@ -91,7 +99,7 @@ static void adaptive_polar_ext_plc( sth = 0.0f; /* calculate per-sample phase and magnitude evolution in preceding frame */ - for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) + for ( k = 0; k < iNumCols; k++ ) { urh[k] = sqrtf( prev_imag[k] * prev_imag[k] + prev_real[k] * prev_real[k] ); if ( urh[k] < EPSILON ) @@ -134,14 +142,14 @@ static void adaptive_polar_ext_plc( } } - if ( k == CLDFB_NO_COL_MAX ) + if ( k == iNumCols ) { /* mean and stdev of per-sample magnitude ratios */ - drho *= 1.0f / ( CLDFB_NO_COL_MAX - 1 ); - temp = srho - ( CLDFB_NO_COL_MAX - 1 ) * SQR( drho ); + drho *= 1.0f / ( iNumCols - 1 ); + temp = srho - ( iNumCols - 1 ) * SQR( drho ); if ( temp > 0 ) { - srho = sqrtf( temp * ( 1.0f / ( CLDFB_NO_COL_MAX - 2 ) ) ); + srho = sqrtf( temp * ( 1.0f / ( iNumCols - 2 ) ) ); } else { @@ -149,11 +157,11 @@ static void adaptive_polar_ext_plc( } /* mean and stdev of per-sample phase differences */ - dth *= 1.0f / ( CLDFB_NO_COL_MAX - 1 ); - temp = sth - ( CLDFB_NO_COL_MAX - 1 ) * SQR( dth ); + dth *= 1.0f / ( iNumCols - 1 ); + temp = sth - ( iNumCols - 1 ) * SQR( dth ); if ( temp > 0 ) { - sth = sqrtf( temp * ( 1.0f / ( CLDFB_NO_COL_MAX - 2 ) ) ); + sth = sqrtf( temp * ( 1.0f / ( iNumCols - 2 ) ) ); } else { @@ -173,12 +181,12 @@ static void adaptive_polar_ext_plc( /* Calculate start value for evolution from last samples of previous frame */ fac_powj_real = fac_real; fac_powj_imag = fac_imag; - start_real = prev_real[CLDFB_NO_COL_MAX - 1]; - start_imag = prev_imag[CLDFB_NO_COL_MAX - 1]; + start_real = prev_real[iNumCols - 1]; + start_imag = prev_imag[iNumCols - 1]; for ( j = 1; j < START_VAL_AVG_LEN; j++ ) { - start_real += fac_powj_real * prev_real[CLDFB_NO_COL_MAX - j - 1] - fac_powj_imag * prev_imag[CLDFB_NO_COL_MAX - j - 1]; - start_imag += fac_powj_imag * prev_real[CLDFB_NO_COL_MAX - j - 1] + fac_powj_real * prev_imag[CLDFB_NO_COL_MAX - j - 1]; + start_real += fac_powj_real * prev_real[iNumCols - j - 1] - fac_powj_imag * prev_imag[iNumCols - j - 1]; + start_imag += fac_powj_imag * prev_real[iNumCols - j - 1] + fac_powj_real * prev_imag[iNumCols - j - 1]; temp = fac_powj_real * fac_real - fac_powj_imag * fac_imag; fac_powj_imag = fac_powj_imag * fac_real + fac_powj_real * fac_imag; fac_powj_real = temp; @@ -187,8 +195,8 @@ static void adaptive_polar_ext_plc( start_imag *= 1.0f / START_VAL_AVG_LEN; #else /* take last sample of previous frame as start value */ - start_real = prev_real[CLDFB_NO_COL_MAX - 1]; - start_imag = prev_imag[CLDFB_NO_COL_MAX - 1]; + start_real = prev_real[iNumCols - 1]; + start_imag = prev_imag[iNumCols - 1]; #endif #if DO_PERTURB != 0 @@ -211,7 +219,7 @@ static void adaptive_polar_ext_plc( /* apply complex evolution for first substitution sample */ rec_real[0] = rat_real * start_real - rat_imag * start_imag; rec_imag[0] = rat_imag * start_real + rat_real * start_imag; - for ( j = 2; j < CLDFB_NO_COL_MAX; j++ ) + for ( j = 2; j < iNumCols; j++ ) { /* make evolution less static: apply per samples differences as in preceding frame */ rat_real = ( prev_real[j] * prev_real[j - 1] + prev_imag[j] * prev_imag[j - 1] ); @@ -244,13 +252,13 @@ static void adaptive_polar_ext_plc( #endif rat_real *= abs2inv; rat_imag *= abs2inv; - rec_real[j + CLDFB_NO_COL_MAX - 2] = rat_real * rec_real[j + CLDFB_NO_COL_MAX - 3] - rat_imag * rec_imag[j + CLDFB_NO_COL_MAX - 3]; - rec_imag[j + CLDFB_NO_COL_MAX - 2] = rat_imag * rec_real[j + CLDFB_NO_COL_MAX - 3] + rat_real * rec_imag[j + CLDFB_NO_COL_MAX - 3]; + rec_real[j + iNumCols - 2] = rat_real * rec_real[j + iNumCols - 3] - rat_imag * rec_imag[j + iNumCols - 3]; + rec_imag[j + iNumCols - 2] = rat_imag * rec_real[j + iNumCols - 3] + rat_real * rec_imag[j + iNumCols - 3]; } #else rec_real[0] = fac_real * start_real - fac_imag * start_imag; rec_imag[0] = fac_imag * start_real + fac_real * start_imag; - for ( j = 1; j < CLDFB_NO_COL_MAX + CLDFB_PLC_XF; j++ ) + for ( j = 1; j < iNumCols + CLDFB_PLC_XF; j++ ) { rec_real[j] = fac_real * rec_real[j - 1] - fac_imag * rec_imag[j - 1]; rec_imag[j] = fac_imag * rec_real[j - 1] + fac_real * rec_imag[j - 1]; @@ -261,8 +269,8 @@ static void adaptive_polar_ext_plc( /* apply crossfade */ for ( j = 0; j < CLDFB_PLC_XF; j++ ) { - rec_real[CLDFB_NO_COL_MAX + j] *= xf_alp[j]; - rec_imag[CLDFB_NO_COL_MAX + j] *= xf_alp[j]; + rec_real[iNumCols + j] *= xf_alp[j]; + rec_imag[iNumCols + j] *= xf_alp[j]; xf_bet[j] = 1 - xf_alp[j]; } #endif @@ -273,7 +281,7 @@ static void adaptive_polar_ext_plc( Ruu_real[0] = SQR( prev_real[0] ) + SQR( prev_imag[0] ); Ruu_real[1] = 0; Ruu_imag[1] = 0; - for ( j = 1; j < CLDFB_NO_COL_MAX; j++ ) + for ( j = 1; j < iNumCols; j++ ) { Ruu_real[0] += SQR( prev_real[j] ) + SQR( prev_imag[j] ); Ruu_real[1] += prev_real[j] * prev_real[j - 1] + prev_imag[j] * prev_imag[j - 1]; @@ -296,12 +304,12 @@ static void adaptive_polar_ext_plc( fac_powj_imag = fac_imag; abs_fac = sqrtf( SQR( fac_real ) + SQR( fac_imag ) ); abs_fac_powj = abs_fac; - for ( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + for ( j = 0; j < iNumCols; j++ ) { comp_fac = 1 - abs_fac_powj; - rec_real[j] = prev_real[CLDFB_NO_COL_MAX - 1] * fac_powj_real - prev_imag[CLDFB_NO_COL_MAX - 1] * fac_powj_imag + + rec_real[j] = prev_real[iNumCols - 1] * fac_powj_real - prev_imag[iNumCols - 1] * fac_powj_imag + prev_real[j] * comp_fac; - rec_imag[j] = prev_real[CLDFB_NO_COL_MAX - 1] * fac_powj_imag + prev_imag[CLDFB_NO_COL_MAX - 1] * fac_powj_real + + rec_imag[j] = prev_real[iNumCols - 1] * fac_powj_imag + prev_imag[iNumCols - 1] * fac_powj_real + prev_imag[j] * comp_fac; abs_fac_powj = abs_fac_powj * abs_fac; temp = fac_powj_real * fac_real - fac_powj_imag * fac_imag; @@ -317,8 +325,8 @@ static void adaptive_polar_ext_plc( for ( j = 0; j < CLDFB_PLC_XF; j++ ) { xf_bet[j] = 1 - abs_fac_powj; - rec_real[j + CLDFB_NO_COL_MAX] = rec_real[CLDFB_NO_COL_MAX - 1] * fac_powj_real - rec_imag[CLDFB_NO_COL_MAX - 1] * fac_powj_imag; - rec_imag[j + CLDFB_NO_COL_MAX] = rec_real[CLDFB_NO_COL_MAX - 1] * fac_powj_imag + rec_imag[CLDFB_NO_COL_MAX - 1] * fac_powj_real; + rec_real[j + iNumCols] = rec_real[iNumCols - 1] * fac_powj_real - rec_imag[iNumCols - 1] * fac_powj_imag; + rec_imag[j + iNumCols] = rec_real[iNumCols - 1] * fac_powj_imag + rec_imag[iNumCols - 1] * fac_powj_real; abs_fac_powj = abs_fac_powj * abs_fac; temp = fac_powj_real * fac_real - fac_powj_imag * fac_imag; fac_powj_imag = fac_powj_real * fac_imag + fac_powj_imag * fac_real; @@ -329,7 +337,7 @@ static void adaptive_polar_ext_plc( } else { - for ( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + for ( j = 0; j < iNumCols; j++ ) { rec_real[j] = prev_real[j]; rec_imag[j] = prev_imag[j]; @@ -338,8 +346,8 @@ static void adaptive_polar_ext_plc( for ( j = 0; j < CLDFB_PLC_XF; j++ ) { xf_bet[j] = 1; - rec_real[j + CLDFB_NO_COL_MAX] = 0; - rec_imag[j + CLDFB_NO_COL_MAX] = 0; + rec_real[j + iNumCols] = 0; + rec_imag[j + iNumCols] = 0; } #endif } @@ -401,16 +409,30 @@ void ivas_splitBinRendPLCClose( * *------------------------------------------------------------------------*/ +#ifdef SPLIT_REND_LCLD_5MS +void ivas_splitBinRendPLCsaveState( + SPLIT_REND_PLC_HANDLE hSplitRendPLC, + float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t num_chs, + const int16_t iNumBlocks, + const int16_t iNumIterations ) +#else void ivas_splitBinRendPLCsaveState( SPLIT_REND_PLC_HANDLE hSplitRendPLC, float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const int16_t num_chs ) +#endif { int16_t k, n; - /* Save Cldfb frame */ +/* Save Cldfb frame */ +#ifdef SPLIT_REND_LCLD_5MS + for ( k = 0; k < ( iNumBlocks * iNumIterations ); k++ ) +#else for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) +#endif { for ( n = 0; n < num_chs; n++ ) { @@ -429,11 +451,21 @@ void ivas_splitBinRendPLCsaveState( * Cross-fade of preceding bad frame into good frame *------------------------------------------------------------------------*/ +#ifdef SPLIT_REND_LCLD_5MS +void ivas_splitBinRendPLC_xf( + SPLIT_REND_PLC_HANDLE hSplitRendPLC, + float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t num_chs, + const int16_t iNumBlocks, + const int16_t iNumIterations ) +#else void ivas_splitBinRendPLC_xf( SPLIT_REND_PLC_HANDLE hSplitRendPLC, float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const int16_t num_chs ) +#endif { int16_t n, i, k; @@ -452,8 +484,13 @@ void ivas_splitBinRendPLC_xf( #if CLDFB_PLC_XF > 0 for ( k = 0; k < CLDFB_PLC_XF; k++ ) { +#ifdef SPLIT_REND_LCLD_5MS + Cldfb_RealBuffer_Binaural[n][k][i] = hSplitRendPLC->CldfbPLC_state.xf_bet[n][i][k] * Cldfb_RealBuffer_Binaural[n][k][i] + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k + ( iNumBlocks * iNumIterations )][i]; + Cldfb_ImagBuffer_Binaural[n][k][i] = hSplitRendPLC->CldfbPLC_state.xf_bet[n][i][k] * Cldfb_ImagBuffer_Binaural[n][k][i] + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k + ( iNumBlocks * iNumIterations )][i]; +#else Cldfb_RealBuffer_Binaural[n][k][i] = hSplitRendPLC->CldfbPLC_state.xf_bet[n][i][k] * Cldfb_RealBuffer_Binaural[n][k][i] + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k + CLDFB_NO_COL_MAX][i]; Cldfb_ImagBuffer_Binaural[n][k][i] = hSplitRendPLC->CldfbPLC_state.xf_bet[n][i][k] * Cldfb_ImagBuffer_Binaural[n][k][i] + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k + CLDFB_NO_COL_MAX][i]; +#endif } #endif } @@ -469,11 +506,21 @@ void ivas_splitBinRendPLC_xf( * Conceal bad frame *------------------------------------------------------------------------*/ +#ifdef SPLIT_REND_LCLD_5MS +void ivas_splitBinRendPLC( + SPLIT_REND_PLC_HANDLE hSplitRendPLC, + float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t num_chs, + const int16_t iNumBlocks, + const int16_t iNumIterations ) +#else void ivas_splitBinRendPLC( SPLIT_REND_PLC_HANDLE hSplitRendPLC, float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const int16_t num_chs ) +#endif { int32_t i, n, k; float fade_fac; @@ -481,6 +528,11 @@ void ivas_splitBinRendPLC( #if CLDFB_PLC_XF > 0 float xf_alp[CLDFB_PLC_XF]; #endif +#ifdef SPLIT_REND_LCLD_5MS + int16_t iNumCols, fade_start_cntr, mute_cntr, fade_val; + + iNumCols = iNumBlocks * iNumIterations; +#endif /* Indicate that next transition will be from a bad frame */ hSplitRendPLC->prev_bfi = 1; @@ -497,7 +549,11 @@ void ivas_splitBinRendPLC( { for ( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) { +#ifdef SPLIT_REND_LCLD_5MS + for ( k = 0; k < iNumCols; k++ ) +#else for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) +#endif { prev_real[k] = hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k][i]; prev_imag[k] = hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k][i]; @@ -507,10 +563,18 @@ void ivas_splitBinRendPLC( #if CLDFB_PLC_XF > 0 , xf_alp, hSplitRendPLC->CldfbPLC_state.xf_bet[n][i] +#endif +#ifdef SPLIT_REND_LCLD_5MS + , + iNumCols #endif ); +#ifdef SPLIT_REND_LCLD_5MS + for ( k = 0; k < iNumCols; k++ ) +#else for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) +#endif { Cldfb_RealBuffer_Binaural[n][k][i] = rec_real[k]; hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k][i] = rec_real[k]; @@ -519,7 +583,11 @@ void ivas_splitBinRendPLC( } #if CLDFB_PLC_XF > 0 +#ifdef SPLIT_REND_LCLD_5MS + for ( k = iNumCols; k < iNumCols + CLDFB_PLC_XF; k++ ) +#else for ( k = CLDFB_NO_COL_MAX; k < CLDFB_NO_COL_MAX + CLDFB_PLC_XF; k++ ) +#endif { hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k][i] = rec_real[k]; hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k][i] = rec_imag[k]; @@ -529,7 +597,41 @@ void ivas_splitBinRendPLC( } - /* Check bf counter */ +/* Check bf counter */ +#ifdef SPLIT_REND_LCLD_5MS + fade_start_cntr = SR_PLC_FADE_START * CLDFB_NO_COL_MAX / iNumCols; + mute_cntr = SR_PLC_MUTE * CLDFB_NO_COL_MAX / iNumCols; + + if ( hSplitRendPLC->bf_count++ >= fade_start_cntr ) + { + if ( hSplitRendPLC->bf_count < mute_cntr ) + { + fade_val = ( ( hSplitRendPLC->bf_count - fade_start_cntr ) * iNumCols ) / CLDFB_NO_COL_MAX; + fade_fac = powf( 10, ( hSplitRendPLC->bf_count - fade_start_cntr ) * SR_PLC_FADE_DEGREE / 20.0f ); + + for ( n = 0; n < num_chs; n++ ) + { + for ( k = 0; k < iNumCols; k++ ) + { + v_multc( &Cldfb_RealBuffer_Binaural[n][k][0], fade_fac, &Cldfb_RealBuffer_Binaural[n][k][0], (int16_t) CLDFB_NO_CHANNELS_MAX ); + v_multc( &Cldfb_ImagBuffer_Binaural[n][k][0], fade_fac, &Cldfb_ImagBuffer_Binaural[n][k][0], (int16_t) CLDFB_NO_CHANNELS_MAX ); + } + } + } + else + { + for ( n = 0; n < num_chs; n++ ) + { + for ( k = 0; k < iNumCols; k++ ) + { + set_zero( &Cldfb_RealBuffer_Binaural[n][k][0], (int16_t) CLDFB_NO_CHANNELS_MAX ); + set_zero( &Cldfb_ImagBuffer_Binaural[n][k][0], (int16_t) CLDFB_NO_CHANNELS_MAX ); + } + } + hSplitRendPLC->bf_count = mute_cntr; + } + } +#else if ( hSplitRendPLC->bf_count++ >= SR_PLC_FADE_START ) { if ( hSplitRendPLC->bf_count < SR_PLC_MUTE ) @@ -545,6 +647,7 @@ void ivas_splitBinRendPLC( hSplitRendPLC->bf_count = SR_PLC_MUTE; } } +#endif return; } diff --git a/lib_rend/ivas_splitRendererPre.c b/lib_rend/ivas_splitRendererPre.c index 973432ec50..e25e7fc5de 100644 --- a/lib_rend/ivas_splitRendererPre.c +++ b/lib_rend/ivas_splitRendererPre.c @@ -2025,10 +2025,20 @@ ivas_error ivas_split_renderer_open( } else { +#ifdef SPLIT_REND_LCLD_5MS + int16_t iNumBlocksPerFrame; + iNumBlocksPerFrame = ( CLDFB_NO_COL_MAX * pSplitRendConfig->codec_frame_size_ms ) / 20; + + if ( ( error = ivas_splitBinLCLDEncOpen( &hSplitRendWrapper->hSplitBinLCLDEnc, OutSampleRate, BINAURAL_CHANNELS, ivas_get_lcld_bitrate( pSplitRendConfig->splitRendBitRate, hSplitRendWrapper->multiBinPoseData.poseCorrectionMode ), iNumBlocksPerFrame, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } +#else if ( ( error = ivas_splitBinLCLDEncOpen( &hSplitRendWrapper->hSplitBinLCLDEnc, OutSampleRate, BINAURAL_CHANNELS, ivas_get_lcld_bitrate( pSplitRendConfig->splitRendBitRate, hSplitRendWrapper->multiBinPoseData.poseCorrectionMode ) ) ) != IVAS_ERR_OK ) { return error; } +#endif } } @@ -2233,10 +2243,12 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( actual_md_bits = pBits->bits_written; if ( ( hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) || ( !useLc3plus && !pcm_out_flag ) ) { +#ifndef SPLIT_REND_LCLD_5MS if ( !useLc3plus && codec_frame_size_ms != 20 && !pcm_out_flag ) { return IVAS_ERROR( IVAS_ERR_INVALID_INPUT_BUFFER_SIZE, "Unsupported framing for LCLD codec!" ); } +#endif num_cldfb_bands = hSplitBin->hCldfbHandles->cldfbAna[0]->no_channels; /* CLDFB Analysis*/ @@ -2260,7 +2272,11 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( #endif for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { +#ifdef SPLIT_REND_LCLD_5MS + for ( slot_idx = 0; slot_idx < hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations; slot_idx++ ) +#else for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) +#endif { cldfbAnalysis_ts( &( in_delayed[pos_idx * BINAURAL_CHANNELS + ch][num_cldfb_bands * slot_idx] ), Cldfb_In_BinReal[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinImag[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], @@ -2289,10 +2305,17 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( if ( !useLc3plus ) { +#ifdef SPLIT_REND_LCLD_5MS + available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); + actual_md_bits = pBits->bits_written - actual_md_bits; + available_bits -= actual_md_bits; + pBits->codec_frame_size_ms = codec_frame_size_ms; +#else available_bits = SplitRendBitRate * L_FRAME48k / 48000; actual_md_bits = pBits->bits_written - actual_md_bits; available_bits -= actual_md_bits; pBits->codec_frame_size_ms = 20; +#endif ivas_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal, Cldfb_In_BinImag, available_bits, pBits ); } @@ -2319,7 +2342,11 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( { if ( !useLc3plus ) { +#ifdef SPLIT_REND_LCLD_5MS + bit_len = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); +#else bit_len = SplitRendBitRate / FRAMES_PER_SEC; +#endif } else { @@ -2455,10 +2482,18 @@ ivas_error ivas_renderMultiBinToSplitBinaural( /* Needs to be done at runtime. If this was in another API function, * there would be no guarantee that the user did not change * the split rendering config before calling the main rendering function */ +#ifdef SPLIT_REND_LCLD_5MS + if ( ( error = ivas_split_rend_choose_default_codec( &splitCodec, &codec_frame_size_ms, cldfb_in_flag, pcm_out_flag, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } +#else if ( ( error = ivas_split_rend_choose_default_codec( &splitCodec, &codec_frame_size_ms, cldfb_in_flag, pcm_out_flag ) ) != IVAS_ERR_OK ) { return error; } +#endif + if ( cldfb_in_flag == 0 ) { @@ -2500,31 +2535,49 @@ ivas_error ivas_renderMultiBinToSplitBinaural( if ( splitCodec == IVAS_SPLIT_REND_CODEC_LCLD ) { +#ifdef SPLIT_REND_LCLD_5MS + available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); + actual_md_bits = pBits->bits_written - actual_md_bits; + available_bits -= actual_md_bits; + pBits->codec_frame_size_ms = codec_frame_size_ms; +#else available_bits = SplitRendBitRate * L_FRAME48k / 48000; actual_md_bits = pBits->bits_written - actual_md_bits; available_bits -= actual_md_bits; - +#endif ivas_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal, Cldfb_In_BinImag, available_bits, pBits ); } else { +#ifdef SPLIT_REND_LCLD_5MS + int16_t ch, slot_idx, num_slots, ivas_fs; + ivas_fs = (int16_t) hSplitBin->hLc3plusEnc->config.ivas_frame_duration_us / 1000; + num_slots = (int16_t) ( CLDFB_NO_COL_MAX * ivas_fs ) / 20; +#else int16_t ch, slot_idx; - +#endif /* CLDFB synthesis of main pose */ for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { float *Cldfb_In_BinReal_p[CLDFB_NO_COL_MAX]; float *Cldfb_In_BinImag_p[CLDFB_NO_COL_MAX]; - +#ifdef SPLIT_REND_LCLD_5MS + for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ ) +#else for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) +#endif { Cldfb_In_BinReal_p[slot_idx] = Cldfb_In_BinReal[ch][slot_idx]; Cldfb_In_BinImag_p[slot_idx] = Cldfb_In_BinImag[ch][slot_idx]; } #ifndef SPLIT_REND_WITH_HEAD_ROT cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbAna[0]->no_channels * CLDFB_NO_COL_MAX, hSplitBin->hCldfbHandles->cldfbAna[ch] ); +#else +#ifdef SPLIT_REND_LCLD_5MS + cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * num_slots, hSplitBin->hCldfbHandles->cldfbSyn[ch] ); #else cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * CLDFB_NO_COL_MAX, hSplitBin->hCldfbHandles->cldfbSyn[ch] ); +#endif #endif } @@ -2561,7 +2614,6 @@ ivas_error ivas_renderMultiBinToSplitBinaural( } /*zero pad*/ - /*TODO: do this inside the LCLD ENC codec */ if ( pcm_out_flag ) { bit_len = SplitRendBitRate / FRAMES_PER_SEC; @@ -2570,7 +2622,11 @@ ivas_error ivas_renderMultiBinToSplitBinaural( { if ( splitCodec == IVAS_SPLIT_REND_CODEC_LCLD ) { +#ifdef SPLIT_REND_LCLD_5MS + bit_len = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); +#else bit_len = SplitRendBitRate / FRAMES_PER_SEC; +#endif } else { diff --git a/lib_rend/ivas_splitRenderer_utils.c b/lib_rend/ivas_splitRenderer_utils.c index daf6eb6f28..f3f3cad2a3 100644 --- a/lib_rend/ivas_splitRenderer_utils.c +++ b/lib_rend/ivas_splitRenderer_utils.c @@ -724,7 +724,11 @@ ivas_error ivas_split_rend_validate_config( if ( pSplitRendConfig->codec_frame_size_ms != 0 ) /* 0 means "default for current codec", will be set to actual value at a later stage */ { +#ifdef SPLIT_REND_LCLD_5MS + if ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LCLD && pSplitRendConfig->codec_frame_size_ms != 5 && pSplitRendConfig->codec_frame_size_ms != 10 && pSplitRendConfig->codec_frame_size_ms != 20 ) +#else if ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LCLD && pSplitRendConfig->codec_frame_size_ms != 20 ) +#endif { return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Invalid framing for LCLD codec" ); } @@ -1049,12 +1053,22 @@ void ivas_init_multi_bin_pose_data( * *------------------------------------------------------------------------*/ +#ifdef SPLIT_REND_LCLD_5MS +ivas_error ivas_split_rend_choose_default_codec( + IVAS_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */ + int16_t *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */ + const int16_t cldfb_in_flag, /* i : flag indicating rendering in TD */ + const int16_t pcm_out_flag, /* i : flag to indicate PCM output */ + const int16_t is_5ms_frame /* i : flag to indicate 5ms framing */ +) +#else ivas_error ivas_split_rend_choose_default_codec( IVAS_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */ int16_t *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */ const int16_t cldfb_in_flag, /* i : flag indicating rendering in TD */ const int16_t pcm_out_flag /* i : flag to indicate PCM output */ ) +#endif { if ( pcm_out_flag == 0 ) { @@ -1073,7 +1087,18 @@ ivas_error ivas_split_rend_choose_default_codec( switch ( *pCodec ) { case IVAS_SPLIT_REND_CODEC_LCLD: +#ifdef SPLIT_REND_LCLD_5MS + if ( is_5ms_frame ) + { + *pCodec_frame_size_ms = 5; + } + else + { + *pCodec_frame_size_ms = 20; + } +#else *pCodec_frame_size_ms = 20; +#endif break; case IVAS_SPLIT_REND_CODEC_LC3PLUS: case IVAS_SPLIT_REND_CODEC_NONE: diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index ec5d5efa4a..c4e042f429 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -1438,6 +1438,10 @@ typedef struct ivas_binaural_head_rot_split_rendering_lcld_enc_struct FILE *cldfbIn; int16_t numFrame; #endif +#ifdef SPLIT_REND_LCLD_5MS + int32_t iNumIterations; + int32_t iNumBlocks; +#endif } BIN_HR_SPLIT_LCLD_ENC, *BIN_HR_SPLIT_LCLD_ENC_HANDLE; @@ -1471,6 +1475,10 @@ typedef struct ivas_binaural_head_rot_split_rendering_lcld_dec_struct int16_t numFrame; #endif SPLIT_REND_PLC_HANDLE hSplitRendPLC; +#ifdef SPLIT_REND_LCLD_5MS + int16_t iNumBlocks; + int16_t iNumIterations; +#endif } BIN_HR_SPLIT_LCLD_DEC, *BIN_HR_SPLIT_LCLD_DEC_HANDLE; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 947889e837..1bd89d4084 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -3916,10 +3916,17 @@ ivas_error IVAS_REND_AddInput( int16_t cldfb_in_flag; cldfb_in_flag = getCldfbRendFlag( hIvasRend, getAudioConfigType( inConfig ) ); +#ifdef SPLIT_REND_LCLD_5MS + if ( ( error = ivas_split_rend_choose_default_codec( &hIvasRend->hRendererConfig->split_rend_config.codec, &hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, ( hIvasRend->num_subframes == 1 ) ? 1 : 0 ) ) != IVAS_ERR_OK ) + { + return error; + } +#else if ( ( error = ivas_split_rend_choose_default_codec( &hIvasRend->hRendererConfig->split_rend_config.codec, &hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) != IVAS_ERR_OK ) { return error; } +#endif if ( ( error = initSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, ( hIvasRend->num_subframes == 1 ) ? 1 : 0 ) ) != IVAS_ERR_OK ) { @@ -4797,10 +4804,17 @@ int16_t IVAS_REND_FeedRenderConfig( cldfb_in_flag = getCldfbRendFlag( hIvasRend, IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN ); closeSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer ); +#ifdef SPLIT_REND_LCLD_5MS + if ( ( error = ivas_split_rend_choose_default_codec( &hIvasRend->hRendererConfig->split_rend_config.codec, &hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, ( hIvasRend->num_subframes == 1 ) ? 1 : 0 ) ) != IVAS_ERR_OK ) + { + return error; + } +#else if ( ( error = ivas_split_rend_choose_default_codec( &hIvasRend->hRendererConfig->split_rend_config.codec, &hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) != IVAS_ERR_OK ) { return error; } +#endif if ( ( error = initSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, ( hIvasRend->num_subframes == 1 ) ? 1 : 0 ) ) != IVAS_ERR_OK ) { @@ -6993,6 +7007,10 @@ static ivas_error renderSplitBinauralWithPostRot( int16_t outBufNumSamplesPerChannel, outBufNumColPerChannel; int16_t numSamplesPerChannelCacheSize, numColPerChannelCacheSize; float *readPtr, *writePtr; +#ifdef SPLIT_REND_LCLD_5MS + LC3PLUS_CONFIG config; + int16_t iNumBlocksPerFrame, iNumLCLDIterationsPerFrame; +#endif isPostRendInputCldfb = 0; push_wmops( "renderSplitBinauralWithPostRot" ); @@ -7002,15 +7020,43 @@ static ivas_error renderSplitBinauralWithPostRot( hSplitBin = &splitBinInput->splitPostRendWrapper; convertBitsBufferToInternalBitsBuff( *splitBinInput->hBits, &bits ); +#ifdef SPLIT_REND_LCLD_5MS + config.lc3plus_frame_duration_us = bits.codec_frame_size_ms * 1000; + if ( pCombinedOrientationData->num_subframes == 1 ) + { + config.ivas_frame_duration_us = ( bits.pose_correction == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ? config.lc3plus_frame_duration_us : 20000; + iNumLCLDIterationsPerFrame = 1; + } + else + { + config.ivas_frame_duration_us = 20000; + } + + iNumLCLDIterationsPerFrame = (int16_t) config.ivas_frame_duration_us / ( 1000 * bits.codec_frame_size_ms ); + iNumLCLDIterationsPerFrame = max( 1, iNumLCLDIterationsPerFrame ); + iNumBlocksPerFrame = CLDFB_NO_COL_MAX * bits.codec_frame_size_ms / 20; + + config.channels = BINAURAL_CHANNELS; + config.samplerate = *splitBinInput->base.ctx.pOutSampleRate; +#endif + if ( bits.codec == IVAS_SPLIT_REND_CODEC_LCLD && splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec == NULL ) { +#ifdef SPLIT_REND_LCLD_5MS + if ( ( error = ivas_splitBinLCLDDecOpen( &splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec, *splitBinInput->base.ctx.pOutSampleRate, BINAURAL_CHANNELS, iNumBlocksPerFrame, iNumLCLDIterationsPerFrame ) ) != IVAS_ERR_OK ) + { + return error; + } +#else if ( ( error = ivas_splitBinLCLDDecOpen( &splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec, *splitBinInput->base.ctx.pOutSampleRate, BINAURAL_CHANNELS ) ) != IVAS_ERR_OK ) { return error; } +#endif } else if ( bits.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && splitBinInput->splitPostRendWrapper.hLc3plusDec == NULL ) { +#ifndef SPLIT_REND_LCLD_5MS LC3PLUS_CONFIG config; if ( outAudio.config.numSamplesPerChannel == 240 ) @@ -7026,6 +7072,7 @@ static ivas_error renderSplitBinauralWithPostRot( config.channels = BINAURAL_CHANNELS; config.samplerate = *splitBinInput->base.ctx.pOutSampleRate; +#endif if ( ( error = IVAS_LC3PLUS_DEC_Open( config, &splitBinInput->splitPostRendWrapper.hLc3plusDec ) ) != IVAS_ERR_OK ) { @@ -7069,13 +7116,20 @@ static ivas_error renderSplitBinauralWithPostRot( { isPostRendInputCldfb = 1; } - +#ifdef SPLIT_REND_LCLD_5MS + preRendFrameSize_ms = (int16_t) ( config.ivas_frame_duration_us ) / 1000; +#else preRendFrameSize_ms = bits.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS ? (int16_t) ( hSplitBin->hLc3plusDec->config.ivas_frame_duration_us ) / 1000 : 20; +#endif numSamplesPerChannelCacheSize = (int16_t) ( *splitBinInput->base.ctx.pOutSampleRate * ( preRendFrameSize_ms - bits.codec_frame_size_ms ) / 1000 ); outBufNumColPerChannel = MAX_PARAM_SPATIAL_SUBFRAMES; +#ifdef SPLIT_REND_LCLD_5MS + numColPerChannelCacheSize = ( iNumBlocksPerFrame * iNumLCLDIterationsPerFrame ) - outBufNumColPerChannel; +#else numColPerChannelCacheSize = CLDFB_NO_COL_MAX - outBufNumColPerChannel; +#endif for ( sf_idx = 0; sf_idx < pCombinedOrientationData->num_subframes; sf_idx++ ) { @@ -7098,7 +7152,11 @@ static ivas_error renderSplitBinauralWithPostRot( /* cache the remaining 15ms */ splitBinInput->numCachedSamples = numColPerChannelCacheSize; writePtr = splitBinInput->bufferData; +#ifdef SPLIT_REND_LCLD_5MS + for ( slotIdx = CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slotIdx < ( iNumBlocksPerFrame * iNumLCLDIterationsPerFrame ); ++slotIdx ) +#else for ( slotIdx = CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slotIdx < CLDFB_NO_COL_MAX; ++slotIdx ) +#endif { for ( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) { @@ -8549,12 +8607,18 @@ ivas_error IVAS_REND_GetSplitBinauralBitstream( cldfb_in_flag = getCldfbRendFlag( hIvasRend, IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN ); hIvasRend->splitRendEncBuffer.config.is_cldfb = cldfb_in_flag; - +#ifdef SPLIT_REND_LCLD_5MS + if ( hIvasRend->hRendererConfig->split_rend_config.dof == 0 || hIvasRend->hRendererConfig->split_rend_config.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) + { + hIvasRend->splitRendEncBuffer.config.numSamplesPerChannel = outAudio.config.numSamplesPerChannel; + } +#else if ( hIvasRend->hRendererConfig->split_rend_config.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && ( hIvasRend->hRendererConfig->split_rend_config.dof == 0 || hIvasRend->hRendererConfig->split_rend_config.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ) { hIvasRend->splitRendEncBuffer.config.numSamplesPerChannel = hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms * hIvasRend->num_subframes * (int16_t) ( hIvasRend->sampleRateOut / 1000 ); } +#endif else { hIvasRend->splitRendEncBuffer.config.numSamplesPerChannel = (int16_t) ( hIvasRend->sampleRateOut / FRAMES_PER_SEC ); -- GitLab From f00dd9a2363065f7bcfb924d7f9ca839e9493066 Mon Sep 17 00:00:00 2001 From: rtyag Date: Mon, 15 Jan 2024 22:59:10 +1100 Subject: [PATCH 02/13] warning fixes --- lib_rend/ivas_RMSEnvGrouping.c | 2 +- lib_rend/ivas_splitRendererPLC.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_rend/ivas_RMSEnvGrouping.c b/lib_rend/ivas_RMSEnvGrouping.c index 1d8ef2593f..7dc34714bf 100644 --- a/lib_rend/ivas_RMSEnvGrouping.c +++ b/lib_rend/ivas_RMSEnvGrouping.c @@ -589,7 +589,7 @@ static float TryMerge2( return fMergedCost; } -#ifdef SPLIT_REND_LCLD_5MS +#ifndef SPLIT_REND_LCLD_5MS /*-------------------------------------------------------------------* * Function ComputeGreedyGroups() * diff --git a/lib_rend/ivas_splitRendererPLC.c b/lib_rend/ivas_splitRendererPLC.c index 459827bd56..c63715a230 100644 --- a/lib_rend/ivas_splitRendererPLC.c +++ b/lib_rend/ivas_splitRendererPLC.c @@ -607,7 +607,7 @@ void ivas_splitBinRendPLC( if ( hSplitRendPLC->bf_count < mute_cntr ) { fade_val = ( ( hSplitRendPLC->bf_count - fade_start_cntr ) * iNumCols ) / CLDFB_NO_COL_MAX; - fade_fac = powf( 10, ( hSplitRendPLC->bf_count - fade_start_cntr ) * SR_PLC_FADE_DEGREE / 20.0f ); + fade_fac = powf( 10, fade_val * SR_PLC_FADE_DEGREE / 20.0f ); for ( n = 0; n < num_chs; n++ ) { -- GitLab From 027ccdbcb2fc94d8a412b7df511016b7da0b615c Mon Sep 17 00:00:00 2001 From: rtyag Date: Tue, 16 Jan 2024 09:44:06 +1100 Subject: [PATCH 03/13] remove unused functions --- lib_rend/ivas_RMSEnvGrouping.c | 219 --------------------------------- 1 file changed, 219 deletions(-) diff --git a/lib_rend/ivas_RMSEnvGrouping.c b/lib_rend/ivas_RMSEnvGrouping.c index 7dc34714bf..f7174b6526 100644 --- a/lib_rend/ivas_RMSEnvGrouping.c +++ b/lib_rend/ivas_RMSEnvGrouping.c @@ -275,109 +275,6 @@ static void ComputeBandEnergy( return; } - -#ifdef SPLIT_REND_LCLD_5MS -/*-------------------------------------------------------------------* - * Function TryMerge() - * - * - *-------------------------------------------------------------------*/ - -/* THis is temporary cost function */ -static float TryMerge( - const int32_t iNumBands, - const int32_t iStartBlock, - const int32_t iGroupLength, - const float fMaxAllowedDiffdB, - float **ppfBandEnergy, - float **ppfBandEnergydB, -#ifdef APPLY_WEIGHT - float **ppfWeight, -#endif - float *pfMegredEnergydB ) -{ - int32_t b; - int32_t n; - float fMeanCost; - float fMaxCost; - float fMinDiffCost; - float fMaxDiffCost; - float fInvGroupSize = 1.0f / (float) iGroupLength; - float fInvNumBands = 1.0f / (float) iNumBands; - - for ( b = 0; b < iNumBands; b++ ) - { - float fGroupEnergy; - - - fGroupEnergy = 0.0; - for ( n = iStartBlock; n < ( iStartBlock + iGroupLength ); n++ ) - { - fGroupEnergy += ppfBandEnergy[n][b]; - } - fGroupEnergy *= fInvGroupSize; - fGroupEnergy = 10.0f * log10f( fGroupEnergy ); // Note epsolon was added when computing BandEnergy; - - pfMegredEnergydB[b] = fGroupEnergy; - } - - fMeanCost = 0.0; - fMaxCost = 0.0; - fMinDiffCost = 0.0; - fMaxDiffCost = 0.0; - for ( n = iStartBlock; n < ( iStartBlock + iGroupLength ); n++ ) - { - float fMeanAbsDiff; - float fMaxAbsDiff; - float fMaxDiff; - float fMinDiff; - - fMeanAbsDiff = 0.0; - fMaxAbsDiff = 0.0; - fMaxDiff = 0.0; - fMinDiff = 0.0; - for ( b = 0; b < iNumBands; b++ ) - { - float fDiff; - float fAbsDiff; - - fDiff = pfMegredEnergydB[b] - ppfBandEnergydB[n][b]; // Changed the order of this - fAbsDiff = fabsf( fDiff ); -#ifdef APPLY_WEIGHT - fAbsDiff *= ppfWeight[n][b]; -#endif - - fMeanAbsDiff += fAbsDiff; - fMaxAbsDiff = ( fMaxAbsDiff > fAbsDiff ) ? fMaxAbsDiff : fAbsDiff; - - - fMaxDiff = ( fMaxDiff > fDiff ) ? fMaxDiff : fDiff; - fMinDiff = ( fMinDiff < fDiff ) ? fMinDiff : fDiff; - } - fMeanAbsDiff *= fInvNumBands; - - fMeanCost = ( fMeanCost > fMeanAbsDiff ) ? fMeanCost : fMeanAbsDiff; - fMaxCost = ( fMaxCost > fMaxAbsDiff ) ? fMaxCost : fMaxAbsDiff; - - fMaxDiffCost = ( fMaxDiffCost > fMaxDiff ) ? fMaxDiffCost : fMaxDiff; - fMinDiffCost = ( fMinDiffCost < fMinDiff ) ? fMinDiffCost : fMinDiff; - } - - // printf("%f\t%f\t%f\t%f\n",fMeanCost,fMaxCost,fMaxDiffCost,fMinDiffCost); - - /*if(fMinDiffCost < -9.0){ // This prevents cliping - fMeanCost = 1e12; //Some large value - }*/ - - if ( fMaxCost > fMaxAllowedDiffdB ) - { - fMeanCost = 1e12f; // Some large value - } - - return fMeanCost; -} -#endif - /*-------------------------------------------------------------------* * Function ComputeMergeRMS() * @@ -589,122 +486,6 @@ static float TryMerge2( return fMergedCost; } -#ifndef SPLIT_REND_LCLD_5MS -/*-------------------------------------------------------------------* - * Function ComputeGreedyGroups() - * - * - *-------------------------------------------------------------------*/ - -static void ComputeGreedyGroups( - RMSEnvelopeGrouping *psRMSEnvelopeGrouping, - const int32_t iChannels, - const int32_t iNumBands, - const float fMeanAllowedDiffdB, - const float fMaxAllowedDiffdB ) -{ - float fBestMeanCost; - - fBestMeanCost = 0.0; - while ( fBestMeanCost < fMeanAllowedDiffdB ) - { - GMNode *psGMNode; - GMNode *psBestGMNode; - - fBestMeanCost = fMeanAllowedDiffdB; - psGMNode = &psRMSEnvelopeGrouping->psGMNodes[0]; - psBestGMNode = NULL; - while ( psGMNode->psNext != NULL ) - { - float fMeanCost; - int32_t iGroupLength; - - iGroupLength = psGMNode->iGroupLength + psGMNode->psNext->iGroupLength; - - fMeanCost = TryMerge( iNumBands * iChannels, - psGMNode->iGroupStart, - iGroupLength, // psGMNode->iGroupLength, //Fix this bug - fMaxAllowedDiffdB, - psRMSEnvelopeGrouping->ppfBandEnergy, - psRMSEnvelopeGrouping->ppfBandEnergydB, -#ifdef APPLY_WEIGHT - psRMSEnvelopeGrouping->ppfWeight, -#endif - psGMNode->pfMergedEnergydB ); - - - if ( fMeanCost < fBestMeanCost ) - { - fBestMeanCost = fMeanCost; - psBestGMNode = psGMNode; - } - - psGMNode = psGMNode->psNext; - } - - if ( fBestMeanCost < fMeanAllowedDiffdB && psBestGMNode != NULL && psBestGMNode->psNext != NULL ) - { - psBestGMNode->iGroupLength += psBestGMNode->psNext->iGroupLength; - psBestGMNode->psNext = psBestGMNode->psNext->psNext; - } - } - - return; -} - - -/*-------------------------------------------------------------------* - * Function ComputeGreedyGroups2() - * - * - *-------------------------------------------------------------------*/ - -static void ComputeGreedyGroups2( - RMSEnvelopeGrouping *psRMSEnvelopeGrouping, - const int32_t iChannels, - const int32_t iNumBands, - const int32_t *piBandwidths ) -{ - float fBestMergeCost; - // int32_t iDone = 0; - fBestMergeCost = -1.0; - - while ( fBestMergeCost < 0.0 ) - { - GMNode *psGMNode; - GMNode *psBestGMNode; - - fBestMergeCost = 0.0; - psGMNode = &psRMSEnvelopeGrouping->psGMNodes[0]; - psBestGMNode = NULL; - while ( psGMNode->psNext != NULL ) - { - float fMergeCost; - - fMergeCost = TryMerge2( iChannels, iNumBands, piBandwidths, psRMSEnvelopeGrouping->ppfBandEnergy, psRMSEnvelopeGrouping->ppfBandEnergydB, psGMNode, psGMNode->psNext ); - - if ( fMergeCost < fBestMergeCost ) - { - fBestMergeCost = fMergeCost; - psBestGMNode = psGMNode; - } - - psGMNode = psGMNode->psNext; - } - - if ( fBestMergeCost < 0.0 && psBestGMNode != NULL && psBestGMNode->psNext != NULL ) - { - psBestGMNode->iGroupLength += psBestGMNode->psNext->iGroupLength; - psBestGMNode->iGroupRMSEnvelopeCost = -1; - psBestGMNode->fGroupSNRPenalty = -1.0; - psBestGMNode->psNext = psBestGMNode->psNext->psNext; - } - } - - return; -} -#endif - /*-------------------------------------------------------------------* * Function ComputeGreedyGroups3() * -- GitLab From 61e1be5ba6ef498184c8039be361407d7d5c4614 Mon Sep 17 00:00:00 2001 From: rtyag Date: Tue, 16 Jan 2024 10:45:16 +1100 Subject: [PATCH 04/13] avoid division by 0 --- lib_rend/lib_rend.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 1bd89d4084..28fd9850f3 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -7032,9 +7032,17 @@ static ivas_error renderSplitBinauralWithPostRot( config.ivas_frame_duration_us = 20000; } - iNumLCLDIterationsPerFrame = (int16_t) config.ivas_frame_duration_us / ( 1000 * bits.codec_frame_size_ms ); - iNumLCLDIterationsPerFrame = max( 1, iNumLCLDIterationsPerFrame ); - iNumBlocksPerFrame = CLDFB_NO_COL_MAX * bits.codec_frame_size_ms / 20; + if ( bits.codec_frame_size_ms > 0 ) + { + iNumLCLDIterationsPerFrame = (int16_t) config.ivas_frame_duration_us / ( 1000 * bits.codec_frame_size_ms ); + iNumLCLDIterationsPerFrame = max( 1, iNumLCLDIterationsPerFrame ); + iNumBlocksPerFrame = CLDFB_NO_COL_MAX * bits.codec_frame_size_ms / 20; + } + else + { + iNumLCLDIterationsPerFrame = 1; + iNumBlocksPerFrame = CLDFB_NO_COL_MAX; + } config.channels = BINAURAL_CHANNELS; config.samplerate = *splitBinInput->base.ctx.pOutSampleRate; -- GitLab From 5604d3b788574be75aefb9def2763fae7eb416cf Mon Sep 17 00:00:00 2001 From: rtyag Date: Tue, 16 Jan 2024 12:11:42 +1100 Subject: [PATCH 05/13] crash fix with TD to CLDFB conversion in pre renderer --- lib_rend/ivas_splitRendererPre.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib_rend/ivas_splitRendererPre.c b/lib_rend/ivas_splitRendererPre.c index e25e7fc5de..d0c5ca4e76 100644 --- a/lib_rend/ivas_splitRendererPre.c +++ b/lib_rend/ivas_splitRendererPre.c @@ -2211,6 +2211,9 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( uint8_t useLc3plus; float *in_delayed[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; int16_t i; +#ifdef SPLIT_REND_LCLD_5MS + int32_t num_slots; +#endif push_wmops( "ivas_renderMultiTDBinToSplitBinaural" ); @@ -2248,6 +2251,8 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( { return IVAS_ERROR( IVAS_ERR_INVALID_INPUT_BUFFER_SIZE, "Unsupported framing for LCLD codec!" ); } +#else + num_slots = ( hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ? CLDFB_NO_COL_MAX : ( hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ); #endif num_cldfb_bands = hSplitBin->hCldfbHandles->cldfbAna[0]->no_channels; @@ -2273,7 +2278,7 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { #ifdef SPLIT_REND_LCLD_5MS - for ( slot_idx = 0; slot_idx < hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations; slot_idx++ ) + for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ ) #else for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) #endif -- GitLab From c26c2f3b5b65d116086657577efc5eb4508e4bbb Mon Sep 17 00:00:00 2001 From: rtyag Date: Mon, 22 Jan 2024 23:49:22 +1100 Subject: [PATCH 06/13] fixes for 5ms PCM modes --- apps/renderer.c | 19 +++++++++++++++++++ lib_rend/lib_rend.c | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/apps/renderer.c b/apps/renderer.c index 449df94dca..968cee37f2 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -1928,8 +1928,26 @@ int main( #ifdef SPLIT_REND_WITH_HEAD_ROT for ( i = 0; i < args.inConfig.numBinBuses; ++i ) { +#ifdef SPLIT_REND_LCLD_5MS + if ( numSamplesRead > 0 ) + { + if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, splitBinIds[i], &numChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + IVAS_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, (int16_t) args.inConfig.binBuses[i].inputChannelIndex, numChannels ); + + if ( ( error = IVAS_REND_FeedInputAudio( hIvasRend, splitBinIds[i], tmpBuffer ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } +#endif if ( splitBinNeedsNewFrame ) { +#ifndef SPLIT_REND_LCLD_5MS if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, splitBinIds[i], &numChannels ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); @@ -1942,6 +1960,7 @@ int main( fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } +#endif if ( ( error = IVAS_REND_FeedSplitBinauralBitstream( hIvasRend, splitBinIds[i], &bitsBuffer ) ) != IVAS_ERR_OK ) { diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 28fd9850f3..09872dcbae 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -4413,6 +4413,12 @@ ivas_error IVAS_REND_GetDelay( { latency_ns += IVAS_FB_DEC_DELAY_NS; } +#ifdef SPLIT_REND_LCLD_5MS + else if ( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hSplitBinLCLDDec != NULL ) + { + latency_ns += IVAS_FB_DEC_DELAY_NS; + } +#endif max_latency_ns = max( max_latency_ns, latency_ns ); } } @@ -7232,6 +7238,19 @@ static ivas_error renderSplitBinauralWithPostRot( else { copyBufferTo2dArray( splitBinInput->base.inputBuffer, tmpCrendBuffer ); +#ifdef SPLIT_REND_LCLD_5MS + if ( splitBinInput->numCachedSamples == 0 ) + { + preRendFrameSize_ms = (int16_t) ( config.ivas_frame_duration_us ) / 1000; + numSamplesPerChannelCacheSize = (int16_t) ( *splitBinInput->base.ctx.pOutSampleRate * preRendFrameSize_ms / 1000 ); + numSamplesPerChannelCacheSize -= outAudio.config.numSamplesPerChannel; + splitBinInput->numCachedSamples = numSamplesPerChannelCacheSize; + } + else + { + splitBinInput->numCachedSamples -= outAudio.config.numSamplesPerChannel; + } +#endif } /* apply pose correction if enabled */ -- GitLab From 487a5ebde712d3e42a2e60eb0618f697c2648a8c Mon Sep 17 00:00:00 2001 From: rtyag Date: Mon, 5 Feb 2024 22:00:21 +1100 Subject: [PATCH 07/13] change int to int32_t --- lib_rend/ivas_PredDecoder.c | 15 +-------------- lib_rend/ivas_PredEncoder.c | 19 ++++--------------- lib_rend/ivas_lcld_decoder.c | 2 +- lib_rend/ivas_lcld_encoder.c | 12 ++++++------ lib_rend/ivas_prot_rend.h | 5 +++++ lib_rend/ivas_splitRenderer_utils.c | 14 ++++++++++++++ 6 files changed, 31 insertions(+), 36 deletions(-) diff --git a/lib_rend/ivas_PredDecoder.c b/lib_rend/ivas_PredDecoder.c index cc383160e2..4e528141ac 100644 --- a/lib_rend/ivas_PredDecoder.c +++ b/lib_rend/ivas_PredDecoder.c @@ -40,19 +40,6 @@ #include "ivas_lcld_rom_tables.h" #include "wmc_auto.h" -#ifdef SPLIT_REND_LCLD_5MS -/*-------------------------------------------------------------------* - * Function get_bit() - * - * - *-------------------------------------------------------------------*/ - -static int get_bit( int state, int bit_id ) -{ - return ( state & ( 1 << bit_id ) ); -} -#endif - /*-------------------------------------------------------------------* * Function CreatePredictionDecoder() * @@ -436,7 +423,7 @@ int32_t ReadPredictors( /* disable any inactive prediction bands */ for ( c = 0; c < psPredictionDecoder->iChannels; c++ ) { - int set; + int32_t set; for ( set = 0; set < psPredictionDecoder->iNumSubSets; set++ ) { if ( !get_bit( psPredictionDecoder->piPredChanEnable[c], set ) ) diff --git a/lib_rend/ivas_PredEncoder.c b/lib_rend/ivas_PredEncoder.c index b4fdc234af..e41099bc53 100644 --- a/lib_rend/ivas_PredEncoder.c +++ b/lib_rend/ivas_PredEncoder.c @@ -47,7 +47,7 @@ * * *-------------------------------------------------------------------*/ -static void activate_bit( int *state, int bit_id ) +static void activate_bit( int32_t *state, int32_t bit_id ) { ( *state ) |= ( 1 << bit_id ); } @@ -58,21 +58,10 @@ static void activate_bit( int *state, int bit_id ) * *-------------------------------------------------------------------*/ -static void deactivate_bit( int *state, int bit_id ) +static void deactivate_bit( int32_t *state, int32_t bit_id ) { ( *state ) &= ( ~( 1 << bit_id ) ); } - -/*-------------------------------------------------------------------* - * Function get_bit() - * - * - *-------------------------------------------------------------------*/ - -static int get_bit( int state, int bit_id ) -{ - return ( state & ( 1 << bit_id ) ); -} #endif /*-------------------------------------------------------------------* @@ -439,7 +428,7 @@ void ComputePredictors( pppfImagBuf = psPredictionEncoder->pppfInpBufImag; for ( c = 0; c < psPredictionEncoder->iChannels; c++ ) { - int n; + int32_t n; for ( n = 0; n < LCLD_PRED_WIN_LEN - iNumBlocks; n++ ) { mvr2r( pppfRealBuf[c][n + iNumBlocks], pppfRealBuf[c][n], LCLD_BANDS ); @@ -519,7 +508,7 @@ void ComputePredictors( float fA1Phase; float fGain2; float fBitGain2; - int iNumBlocksPerPredCoef = min( iNumBlocks * psPredictionEncoder->iNumSubSets, LCLD_PRED_WIN_LEN ); + int32_t iNumBlocksPerPredCoef = min( iNumBlocks * psPredictionEncoder->iNumSubSets, LCLD_PRED_WIN_LEN ); const float fMagScale = ( 2.0f * (float) ( 1 << ( PRED_QUNAT_FILTER_MAG_BITS ) ) + 1.0f ) / M_PI; const float fInvMagScale = M_PI / ( 2.0f * (float) ( 1 << ( PRED_QUNAT_FILTER_MAG_BITS ) ) + 1.0f ); diff --git a/lib_rend/ivas_lcld_decoder.c b/lib_rend/ivas_lcld_decoder.c index d989797a29..094f082c74 100644 --- a/lib_rend/ivas_lcld_decoder.c +++ b/lib_rend/ivas_lcld_decoder.c @@ -831,7 +831,7 @@ int32_t DecodeLCLDFrame( fid = fopen( "pred_dec.txt", "wt" ); for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) { - int b; + int16_t b; for ( b = 0; b < 60; b++ ) fprintf( fid, "%.5f ", (float) psLCLDDecoder->psPredictionDecoder->ppiPredBandEnable[n][b] * psLCLDDecoder->psPredictionDecoder->ppfA1Imag[n][b] ); } diff --git a/lib_rend/ivas_lcld_encoder.c b/lib_rend/ivas_lcld_encoder.c index 3d64e6012e..7958a4f345 100644 --- a/lib_rend/ivas_lcld_encoder.c +++ b/lib_rend/ivas_lcld_encoder.c @@ -89,24 +89,24 @@ struct LCLD_ENCODER }; #ifdef SPLIT_REND_LCLD_5MS -static int Quantize( float fVal, float fScale, int *iSign, int iMaxVal ) +static int32_t Quantize( float fVal, float fScale, int32_t *iSign, int32_t iMaxVal ) { - int iVal; + int32_t iVal; if ( fVal > 0.0f ) { - iVal = (int) ( fScale * fVal + 0.5f ); + iVal = (int32_t) ( fScale * fVal + 0.5f ); *iSign = 0; } else { - iVal = (int) ( -fScale * fVal + 0.5f ); + iVal = (int32_t) ( -fScale * fVal + 0.5f ); *iSign = 1; } iVal = ( iVal < iMaxVal ) ? iVal : iMaxVal; return iVal; } -static float UnQuantize( int iVal, float fScale, int iSign ) +static float UnQuantize( int32_t iVal, float fScale, int32_t iSign ) { float fVal; if ( iSign == 0 ) @@ -694,7 +694,7 @@ int32_t EncodeLCLDFrame( fid = fopen( "pred_enc.txt", "wt" ); for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) { - int b; + int16_t b; for ( b = 0; b < 60; b++ ) fprintf( fid, "%.5f ", (float) psLCLDEncoder->psPredictionEncoder->ppiPredBandEnable[n][b] * psLCLDEncoder->psPredictionEncoder->ppfA1Imag[n][b] ); } diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 5c3f7b168a..6b6a3881ac 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -1973,6 +1973,11 @@ int32_t ivas_split_rend_bitstream_read_int32( const int32_t bits ); +#ifdef SPLIT_REND_LCLD_5MS +int32_t get_bit( const int32_t state, + const int32_t bit_id +); +#endif void ivas_rend_closeCldfbRend( CLDFB_REND_WRAPPER *pCldfbRend diff --git a/lib_rend/ivas_splitRenderer_utils.c b/lib_rend/ivas_splitRenderer_utils.c index f3f3cad2a3..1336ffc4d9 100644 --- a/lib_rend/ivas_splitRenderer_utils.c +++ b/lib_rend/ivas_splitRenderer_utils.c @@ -1112,3 +1112,17 @@ ivas_error ivas_split_rend_choose_default_codec( return IVAS_ERR_OK; } #endif + +#ifdef SPLIT_REND_LCLD_5MS +/*-------------------------------------------------------------------* + * Function get_bit() + * + * + *-------------------------------------------------------------------*/ + +int32_t get_bit( const int32_t state, + const int32_t bit_id ) +{ + return ( state & ( 1 << bit_id ) ); +} +#endif -- GitLab From 44617da954f9c9e1ddde3828ec58d27f498e362f Mon Sep 17 00:00:00 2001 From: rtyag Date: Mon, 5 Feb 2024 22:25:01 +1100 Subject: [PATCH 08/13] address formating related comments --- lib_dec/ivas_init_dec.c | 1 - lib_rend/ivas_PredEncoder.c | 47 ++---------------------------- lib_rend/ivas_lcld_decoder.c | 12 ++++---- lib_rend/ivas_lcld_encoder.c | 8 ++--- lib_rend/ivas_lcld_prot.h | 4 +-- lib_rend/ivas_prot_rend.h | 6 ++-- lib_rend/ivas_splitRend_lcld_enc.c | 8 ++--- lib_rend/ivas_stat_rend.h | 4 +-- 8 files changed, 24 insertions(+), 66 deletions(-) diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 2aea345c36..c67ab7aa7e 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -259,7 +259,6 @@ static ivas_error ivas_dec_init_split_rend( } #endif - #ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ivas_format == SBA_ISM_FORMAT ) { diff --git a/lib_rend/ivas_PredEncoder.c b/lib_rend/ivas_PredEncoder.c index e41099bc53..250368c6be 100644 --- a/lib_rend/ivas_PredEncoder.c +++ b/lib_rend/ivas_PredEncoder.c @@ -400,13 +400,12 @@ void DeletePredictionEncoder( } -//#define USE_RXX_WINDOW - /*-------------------------------------------------------------------* * Function ComputePredictors() * * *-------------------------------------------------------------------*/ + #ifdef SPLIT_REND_LCLD_5MS void ComputePredictors( PredictionEncoder *psPredictionEncoder, @@ -470,36 +469,15 @@ void ComputePredictors( pfRxxImag[0] = 0.0; for ( n = 0; n < LCLD_PRED_WIN_LEN; n++ ) { -#ifdef USE_RXX_WINDOW - float fReal; - float fImag; - fReal = psPredictionEncoder->pfWindow[n] * pppfRealBuf[c][n][b]; - fImag = psPredictionEncoder->pfWindow[n] * pppfImagBuf[c][n][b]; - pfRxxReal[0] += ( fReal * fReal + fImag * fImag ); -#else pfRxxReal[0] += ( pppfRealBuf[c][n][b] * pppfRealBuf[c][n][b] + pppfImagBuf[c][n][b] * pppfImagBuf[c][n][b] ); -#endif } pfRxxReal[1] = 0.0; pfRxxImag[1] = 0.0; for ( n = 1; n < LCLD_PRED_WIN_LEN; n++ ) { -#ifdef USE_RXX_WINDOW - float fReal1; - float fImag1; - float fReal2; - float fImag2; - fReal1 = psPredictionEncoder->pfWindow[n] * pppfRealBuf[c][n][b]; - fImag1 = psPredictionEncoder->pfWindow[n] * pppfImagBuf[c][n][b]; - fReal2 = psPredictionEncoder->pfWindow[n - 1] * pppfRealBuf[c][n - 1][b]; - fImag2 = psPredictionEncoder->pfWindow[n - 1] * pppfImagBuf[c][n - 1][b]; - pfRxxReal[1] += ( fReal1 * fReal2 + fImag1 * fImag2 ); - pfRxxImag[1] += ( fImag1 * fReal2 - fReal1 * fImag2 ); -#else pfRxxReal[1] += ( pppfRealBuf[c][n][b] * pppfRealBuf[c][n - 1][b] + pppfImagBuf[c][n][b] * pppfImagBuf[c][n - 1][b] ); pfRxxImag[1] += ( pppfImagBuf[c][n][b] * pppfRealBuf[c][n - 1][b] - pppfRealBuf[c][n][b] * pppfImagBuf[c][n - 1][b] ); -#endif } if ( pfRxxReal[0] > 1e-12f ) @@ -651,36 +629,15 @@ int32_t ComputePredictors( pfRxxImag[0] = 0.0; for ( n = 0; n < iNumBlocks; n++ ) { -#ifdef USE_RXX_WINDOW - float fReal; - float fImag; - fReal = psPredictionEncoder->pfWindow[n] * pppfReal[c][n][b]; - fImag = psPredictionEncoder->pfWindow[n] * pppfImag[c][n][b]; - pfRxxReal[0] += ( fReal * fReal + fImag * fImag ); -#else pfRxxReal[0] += ( pppfReal[c][n][b] * pppfReal[c][n][b] + pppfImag[c][n][b] * pppfImag[c][n][b] ); -#endif } pfRxxReal[1] = 0.0; pfRxxImag[1] = 0.0; for ( n = 1; n < iNumBlocks; n++ ) { -#ifdef USE_RXX_WINDOW - float fReal1; - float fImag1; - float fReal2; - float fImag2; - fReal1 = psPredictionEncoder->pfWindow[n] * pppfReal[c][n][b]; - fImag1 = psPredictionEncoder->pfWindow[n] * pppfImag[c][n][b]; - fReal2 = psPredictionEncoder->pfWindow[n - 1] * pppfReal[c][n - 1][b]; - fImag2 = psPredictionEncoder->pfWindow[n - 1] * pppfImag[c][n - 1][b]; - pfRxxReal[1] += ( fReal1 * fReal2 + fImag1 * fImag2 ); - pfRxxImag[1] += ( fImag1 * fReal2 - fReal1 * fImag2 ); -#else pfRxxReal[1] += ( pppfReal[c][n][b] * pppfReal[c][n - 1][b] + pppfImag[c][n][b] * pppfImag[c][n - 1][b] ); pfRxxImag[1] += ( pppfImag[c][n][b] * pppfReal[c][n - 1][b] - pppfReal[c][n][b] * pppfImag[c][n - 1][b] ); -#endif } if ( pfRxxReal[0] > 1e-12f ) @@ -843,6 +800,7 @@ int32_t ComputePredictors( * * *-------------------------------------------------------------------*/ + #ifdef SPLIT_REND_LCLD_5MS void ApplyForwardPredictors( PredictionEncoder *psPredictionEncoder, @@ -952,6 +910,7 @@ void ApplyForwardPredictors( * * *-------------------------------------------------------------------*/ + #ifdef SPLIT_REND_LCLD_5MS int32_t WritePredictors( PredictionEncoder *psPredictionEncoder, diff --git a/lib_rend/ivas_lcld_decoder.c b/lib_rend/ivas_lcld_decoder.c index 094f082c74..0ede821e21 100644 --- a/lib_rend/ivas_lcld_decoder.c +++ b/lib_rend/ivas_lcld_decoder.c @@ -359,7 +359,7 @@ ivas_error CreateLCLDDecoder( ivas_error error; LCLDDecoder *psLCLDDecoder = NULL; - assert( iSampleRate == 48000 ); // Fix + assert( iSampleRate == 48000 ); /* Fix */ #ifdef SPLIT_REND_LCLD_5MS assert( iNumBlocks == 16 || iNumBlocks == 8 || iNumBlocks == 4 ); #endif @@ -377,11 +377,11 @@ ivas_error CreateLCLDDecoder( psLCLDDecoder->iAllocOffset = 0; #ifdef SPLIT_REND_LCLD_5MS - psLCLDDecoder->iNumBands = 0; // read from bitstream + psLCLDDecoder->iNumBands = 0; /* read from bitstream*/ #else - psLCLDDecoder->iNumBands = MAX_BANDS_48; // Fix + psLCLDDecoder->iNumBands = MAX_BANDS_48; /* Fix */ #endif - psLCLDDecoder->piBandwidths = c_aiBandwidths48; // Fix + psLCLDDecoder->piBandwidths = c_aiBandwidths48; /* Fix */ psLCLDDecoder->iMSMode = 0; if ( ( psLCLDDecoder->piMSFlags = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) @@ -535,7 +535,7 @@ ivas_error CreateLCLDDecoder( { return error; } - psLCLDDecoder->psNoiseGen = NULL; // CreateNoiseGen(); // No noise fill for now + psLCLDDecoder->psNoiseGen = NULL; /* CreateNoiseGen(); No noise fill for now*/ *psLCLDDecoder_out = psLCLDDecoder; return IVAS_ERR_OK; @@ -783,7 +783,7 @@ int32_t DecodeLCLDFrame( else { for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) - { // This will be updated to support multiple sample rates + { /* This will be updated to support multiple sample rates*/ for ( k = 0; k < psLCLDDecoder->piNumGroups[n]; k++ ) { PerceptualModel( psLCLDDecoder->iNumBands, psLCLDDecoder->pppiRMSEnvelope[n][k], psLCLDDecoder->pppiExcitation[n][k], psLCLDDecoder->pppiSMR[n][k] ); diff --git a/lib_rend/ivas_lcld_encoder.c b/lib_rend/ivas_lcld_encoder.c index 7958a4f345..e6b8f6b543 100644 --- a/lib_rend/ivas_lcld_encoder.c +++ b/lib_rend/ivas_lcld_encoder.c @@ -134,8 +134,8 @@ ivas_error CreateLCLDEncoder( const int32_t iChannels, const int32_t iTargetBitRate, const int32_t iAllowSidePred, - const int32_t iNumBlocks, - const int32_t iNumSubSets ) + const int16_t iNumBlocks, + const int16_t iNumSubSets ) #else ivas_error CreateLCLDEncoder( LCLDEncoder **psLCLDEncoder_out, @@ -166,7 +166,7 @@ ivas_error CreateLCLDEncoder( psLCLDEncoder->iSampleRate = iSampleRate; psLCLDEncoder->iChannels = iChannels; #ifdef SPLIT_REND_LCLD_5MS - psLCLDEncoder->iNumBlocks = iNumBlocks; + psLCLDEncoder->iNumBlocks = (int32_t) iNumBlocks; #else psLCLDEncoder->iNumBlocks = LCLD_BLOCKS_PER_FRAME; #endif @@ -352,7 +352,7 @@ ivas_error CreateLCLDEncoder( } #ifdef SPLIT_REND_LCLD_5MS - if ( ( error = CreatePredictionEncoder( &( psLCLDEncoder->psPredictionEncoder ), iChannels, psLCLDEncoder->iNumBlocks, iNumSubSets, iMaxNumPredBands ) ) != IVAS_ERR_OK ) + if ( ( error = CreatePredictionEncoder( &( psLCLDEncoder->psPredictionEncoder ), iChannels, psLCLDEncoder->iNumBlocks, (int32_t) iNumSubSets, iMaxNumPredBands ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_rend/ivas_lcld_prot.h b/lib_rend/ivas_lcld_prot.h index 08daf79c05..54d1f771bb 100644 --- a/lib_rend/ivas_lcld_prot.h +++ b/lib_rend/ivas_lcld_prot.h @@ -49,8 +49,8 @@ ivas_error CreateLCLDEncoder( const int32_t iChannels, const int32_t iTargetBitRate, const int32_t iAllowSidePred, - const int32_t iNumBlocks, - const int32_t iNumSubSets ); + const int16_t iNumBlocks, + const int16_t iNumSubSets ); #else ivas_error CreateLCLDEncoder( LCLDEncoder **psLCLDEncoder, diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 6b6a3881ac..9ee5f9615e 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -1492,8 +1492,8 @@ ivas_error ivas_splitBinLCLDEncOpen( const int32_t iSampleRate, const int16_t iChannels, const int32_t iDataRate, - const int32_t iNumBlocks, - const int32_t iNumIterations + const int16_t iNumBlocks, + const int16_t iNumIterations ); #else ivas_error ivas_splitBinLCLDEncOpen( @@ -2035,7 +2035,7 @@ ivas_error ivas_split_rend_choose_default_codec( int16_t *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */ const int16_t cldfb_in_flag, /* i : flag indicating rendering in TD */ const int16_t pcm_out_flag, /* i : flag to indicate PCM output */ - const int16_t is_5ms_frame /* i : flag to indicate 5ms framing */ + const int16_t is_5ms_frame /* i : flag to indicate 5ms framing */ ); #else ivas_error ivas_split_rend_choose_default_codec( diff --git a/lib_rend/ivas_splitRend_lcld_enc.c b/lib_rend/ivas_splitRend_lcld_enc.c index 83a60a8710..54674c80bb 100644 --- a/lib_rend/ivas_splitRend_lcld_enc.c +++ b/lib_rend/ivas_splitRend_lcld_enc.c @@ -53,8 +53,8 @@ ivas_error ivas_splitBinLCLDEncOpen( const int32_t iSampleRate, const int16_t iChannels, const int32_t iDataRate, - const int32_t iNumBlocks, - const int32_t iNumIterations ) + const int16_t iNumBlocks, + const int16_t iNumIterations ) #else ivas_error ivas_splitBinLCLDEncOpen( BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc, @@ -71,11 +71,11 @@ ivas_error ivas_splitBinLCLDEncOpen( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - splitBinLCLDEnc->pLcld_enc = NULL; // place holder for CLDFB encoder handle + splitBinLCLDEnc->pLcld_enc = NULL; /* place holder for CLDFB encoder handle*/ splitBinLCLDEnc->iChannels = iChannels; #ifdef SPLIT_REND_LCLD_5MS - if ( ( error = CreateLCLDEncoder( &( splitBinLCLDEnc->psLCLDEncoder ), iSampleRate, iChannels, iDataRate, 1, iNumBlocks, CLDFB_NO_COL_MAX / iNumBlocks ) ) != IVAS_ERR_OK ) + if ( ( error = CreateLCLDEncoder( &( splitBinLCLDEnc->psLCLDEncoder ), iSampleRate, iChannels, iDataRate, 1, iNumBlocks, (int16_t) CLDFB_NO_COL_MAX / iNumBlocks ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index ac7e994607..59343f6e92 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -1449,8 +1449,8 @@ typedef struct ivas_binaural_head_rot_split_rendering_lcld_enc_struct int16_t numFrame; #endif #ifdef SPLIT_REND_LCLD_5MS - int32_t iNumIterations; - int32_t iNumBlocks; + int16_t iNumIterations; + int16_t iNumBlocks; #endif } BIN_HR_SPLIT_LCLD_ENC, *BIN_HR_SPLIT_LCLD_ENC_HANDLE; -- GitLab From 59eadb4ddc6ac5d6282f09083aa3d9f31435b30d Mon Sep 17 00:00:00 2001 From: rtyag Date: Tue, 6 Feb 2024 15:35:11 +1100 Subject: [PATCH 09/13] replace is_5msframe with num_subframes --- apps/decoder.c | 6 +++--- lib_dec/ivas_init_dec.c | 2 +- lib_rend/ivas_prot_rend.h | 2 +- lib_rend/ivas_splitRenderer_utils.c | 11 ++--------- lib_rend/lib_rend.c | 4 ++-- 5 files changed, 9 insertions(+), 16 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 580ee42afe..b902d9ea21 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -673,10 +673,10 @@ int main( #ifdef SPLIT_REND_LCLD_5MS #ifdef SPLIT_REND_WITH_HEAD_ROT - if ( asked_frame_size == IVAS_RENDER_FRAMESIZE_5MS && ( renderConfig.split_rend_config.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE || - renderConfig.split_rend_config.dof == 0 ) ) + if ( asked_frame_size != IVAS_RENDER_FRAMESIZE_20MS && ( renderConfig.split_rend_config.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE || + renderConfig.split_rend_config.dof == 0 ) ) { - arg.renderFramesize = IVAS_RENDER_FRAMESIZE_5MS; + arg.renderFramesize = asked_frame_size; } else { diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index eee9c74d93..ff32ad7cc7 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -248,7 +248,7 @@ static ivas_error ivas_dec_init_split_rend( } #ifdef SPLIT_REND_LCLD_5MS - if ( ( error = ivas_split_rend_choose_default_codec( &st_ivas->hRenderConfig->split_rend_config.codec, &st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, pcm_out_flag, st_ivas->hDecoderConfig->render_framesize == IVAS_RENDER_FRAMESIZE_5MS ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_split_rend_choose_default_codec( &st_ivas->hRenderConfig->split_rend_config.codec, &st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, pcm_out_flag, (int16_t) st_ivas->hDecoderConfig->render_framesize ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index cb5b78b892..ac7defb345 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -2086,7 +2086,7 @@ ivas_error ivas_split_rend_choose_default_codec( int16_t *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */ const int16_t cldfb_in_flag, /* i : flag indicating rendering in TD */ const int16_t pcm_out_flag, /* i : flag to indicate PCM output */ - const int16_t is_5ms_frame /* i : flag to indicate 5ms framing */ + const int16_t num_subframes /* i : number of subframes */ ); #else ivas_error ivas_split_rend_choose_default_codec( diff --git a/lib_rend/ivas_splitRenderer_utils.c b/lib_rend/ivas_splitRenderer_utils.c index 1336ffc4d9..e18e4b6628 100644 --- a/lib_rend/ivas_splitRenderer_utils.c +++ b/lib_rend/ivas_splitRenderer_utils.c @@ -1059,7 +1059,7 @@ ivas_error ivas_split_rend_choose_default_codec( int16_t *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */ const int16_t cldfb_in_flag, /* i : flag indicating rendering in TD */ const int16_t pcm_out_flag, /* i : flag to indicate PCM output */ - const int16_t is_5ms_frame /* i : flag to indicate 5ms framing */ + const int16_t num_subframes /* i : number of subframes */ ) #else ivas_error ivas_split_rend_choose_default_codec( @@ -1088,14 +1088,7 @@ ivas_error ivas_split_rend_choose_default_codec( { case IVAS_SPLIT_REND_CODEC_LCLD: #ifdef SPLIT_REND_LCLD_5MS - if ( is_5ms_frame ) - { - *pCodec_frame_size_ms = 5; - } - else - { - *pCodec_frame_size_ms = 20; - } + *pCodec_frame_size_ms = num_subframes * 5; #else *pCodec_frame_size_ms = 20; #endif diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index e890a9f9b9..72c87b873a 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -4016,7 +4016,7 @@ ivas_error IVAS_REND_AddInput( cldfb_in_flag = getCldfbRendFlag( hIvasRend, getAudioConfigType( inConfig ) ); #ifdef SPLIT_REND_LCLD_5MS - if ( ( error = ivas_split_rend_choose_default_codec( &hIvasRend->hRendererConfig->split_rend_config.codec, &hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, ( hIvasRend->num_subframes == 1 ) ? 1 : 0 ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_split_rend_choose_default_codec( &hIvasRend->hRendererConfig->split_rend_config.codec, &hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) { return error; } @@ -4913,7 +4913,7 @@ int16_t IVAS_REND_FeedRenderConfig( closeSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer ); #ifdef SPLIT_REND_LCLD_5MS - if ( ( error = ivas_split_rend_choose_default_codec( &hIvasRend->hRendererConfig->split_rend_config.codec, &hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, ( hIvasRend->num_subframes == 1 ) ? 1 : 0 ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_split_rend_choose_default_codec( &hIvasRend->hRendererConfig->split_rend_config.codec, &hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) { return error; } -- GitLab From 9baaf8941ca54d7a2cb07456739693e3c144f404 Mon Sep 17 00:00:00 2001 From: rtyag Date: Tue, 6 Feb 2024 15:53:45 +1100 Subject: [PATCH 10/13] formatting fixes --- lib_rend/ivas_lcld_decoder.c | 4 ++-- lib_rend/ivas_lcld_encoder.c | 22 ++++++++++++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/lib_rend/ivas_lcld_decoder.c b/lib_rend/ivas_lcld_decoder.c index 0ede821e21..64848af700 100644 --- a/lib_rend/ivas_lcld_decoder.c +++ b/lib_rend/ivas_lcld_decoder.c @@ -359,7 +359,7 @@ ivas_error CreateLCLDDecoder( ivas_error error; LCLDDecoder *psLCLDDecoder = NULL; - assert( iSampleRate == 48000 ); /* Fix */ + assert( iSampleRate == 48000 ); #ifdef SPLIT_REND_LCLD_5MS assert( iNumBlocks == 16 || iNumBlocks == 8 || iNumBlocks == 4 ); #endif @@ -381,7 +381,7 @@ ivas_error CreateLCLDDecoder( #else psLCLDDecoder->iNumBands = MAX_BANDS_48; /* Fix */ #endif - psLCLDDecoder->piBandwidths = c_aiBandwidths48; /* Fix */ + psLCLDDecoder->piBandwidths = c_aiBandwidths48; psLCLDDecoder->iMSMode = 0; if ( ( psLCLDDecoder->piMSFlags = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) diff --git a/lib_rend/ivas_lcld_encoder.c b/lib_rend/ivas_lcld_encoder.c index e6b8f6b543..80f484d338 100644 --- a/lib_rend/ivas_lcld_encoder.c +++ b/lib_rend/ivas_lcld_encoder.c @@ -89,7 +89,16 @@ struct LCLD_ENCODER }; #ifdef SPLIT_REND_LCLD_5MS -static int32_t Quantize( float fVal, float fScale, int32_t *iSign, int32_t iMaxVal ) +/*------------------------------------------------------------------------------------------* + * Function Quantize() + * + * + *------------------------------------------------------------------------------------------*/ + +static int32_t Quantize( const float fVal, + const float fScale, + int32_t *iSign, + const int32_t iMaxVal ) { int32_t iVal; if ( fVal > 0.0f ) @@ -106,7 +115,16 @@ static int32_t Quantize( float fVal, float fScale, int32_t *iSign, int32_t iMaxV return iVal; } -static float UnQuantize( int32_t iVal, float fScale, int32_t iSign ) + +/*------------------------------------------------------------------------------------------* + * Function UnQuantize() + * + * + *------------------------------------------------------------------------------------------*/ + +static float UnQuantize( const int32_t iVal, + const float fScale, + const int32_t iSign ) { float fVal; if ( iSign == 0 ) -- GitLab From 396a290fee865faed9d393960c6f40499fd4b00d Mon Sep 17 00:00:00 2001 From: rtyag Date: Tue, 6 Feb 2024 17:57:15 +1100 Subject: [PATCH 11/13] fix 10ms framesize issues --- lib_dec/ivas_init_dec.c | 5 +++- lib_dec/lib_dec.c | 3 ++- lib_rend/ivas_prot_rend.h | 11 ++++++++ lib_rend/ivas_splitRendererPre.c | 32 +++++++++++++++++++++-- lib_rend/lib_rend.c | 45 ++++++++++++++++++++++++++++---- 5 files changed, 87 insertions(+), 9 deletions(-) diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index ff32ad7cc7..dd72f45426 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -266,8 +266,11 @@ static ivas_error ivas_dec_init_split_rend( } #endif +#ifdef SPLIT_REND_LCLD_5MS + error = ivas_split_renderer_open( &st_ivas->hSplitBinRend.splitrend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hDecoderConfig->output_Fs, cldfb_in_flag, pcm_out_flag, (int16_t) st_ivas->hDecoderConfig->render_framesize ); +#else error = ivas_split_renderer_open( &st_ivas->hSplitBinRend.splitrend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hDecoderConfig->output_Fs, cldfb_in_flag, pcm_out_flag, st_ivas->hDecoderConfig->render_framesize == IVAS_RENDER_FRAMESIZE_5MS ); - +#endif return error; } #endif diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 2f9a5ae595..9ce0c12a87 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -1081,11 +1081,12 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( numPoses = hSplitBinRend->splitrend.multiBinPoseData.num_poses; #ifdef SPLIT_REND_LCLD_5MS - if ( st_ivas->hDecoderConfig->render_framesize == IVAS_RENDER_FRAMESIZE_5MS && + if ( st_ivas->hDecoderConfig->render_framesize != IVAS_RENDER_FRAMESIZE_20MS && ( hIvasDec->st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE || hIvasDec->st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) { numSamplesPerChannelToDecode = (int16_t) ( output_Fs / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ); + numSamplesPerChannelToDecode *= (int16_t) st_ivas->hDecoderConfig->render_framesize; } #else if ( st_ivas->hDecoderConfig->render_framesize == IVAS_RENDER_FRAMESIZE_5MS && hIvasDec->st_ivas->hRenderConfig->split_rend_config.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index ac7defb345..87fe0c34a8 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -1524,6 +1524,16 @@ void ivas_init_split_post_rend_handles( SPLIT_POST_REND_WRAPPER *hSplitRendWrapper ); +#ifdef SPLIT_REND_LCLD_5MS +ivas_error ivas_split_renderer_open( + SPLIT_REND_WRAPPER *hSplitBinRend, + const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, + const int32_t output_Fs, + const int16_t cldfb_in_flag, + const int16_t pcm_out_flag, + const int16_t num_subframes +); +#else ivas_error ivas_split_renderer_open( SPLIT_REND_WRAPPER *hSplitBinRend, const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, @@ -1532,6 +1542,7 @@ ivas_error ivas_split_renderer_open( const int16_t pcm_out_flag, const int16_t is_5ms_frame ); +#endif void ivas_split_renderer_close( SPLIT_REND_WRAPPER *hSplitBinRend diff --git a/lib_rend/ivas_splitRendererPre.c b/lib_rend/ivas_splitRendererPre.c index 6154a15f79..bbe0cd9a85 100644 --- a/lib_rend/ivas_splitRendererPre.c +++ b/lib_rend/ivas_splitRendererPre.c @@ -1794,17 +1794,27 @@ void ivas_init_split_rend_handles( * * *------------------------------------------------------------------------*/ - +#ifdef SPLIT_REND_LCLD_5MS +static ivas_error split_renderer_open_lc3plus( + SPLIT_REND_WRAPPER *hSplitRendWrapper, + const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, + const int32_t OutSampleRate, + const int16_t num_subframes ) +#else static ivas_error split_renderer_open_lc3plus( SPLIT_REND_WRAPPER *hSplitRendWrapper, const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, const int32_t OutSampleRate, const int16_t is_5ms_frame ) +#endif { ivas_error error; int16_t i, delayBufferLength; LC3PLUS_CONFIG config; - +#ifdef SPLIT_REND_LCLD_5MS + config.lc3plus_frame_duration_us = pSplitRendConfig->codec_frame_size_ms * 1000; + config.ivas_frame_duration_us = ( pSplitRendConfig->dof == 0 ) ? config.lc3plus_frame_duration_us * num_subframes : 20000; +#else if ( is_5ms_frame ) { config.lc3plus_frame_duration_us = pSplitRendConfig->codec_frame_size_ms * 1000; @@ -1815,6 +1825,7 @@ static ivas_error split_renderer_open_lc3plus( config.lc3plus_frame_duration_us = 5000; config.ivas_frame_duration_us = 20000; } +#endif config.samplerate = OutSampleRate; config.channels = BINAURAL_CHANNELS; @@ -1872,6 +1883,15 @@ static ivas_error split_renderer_open_lc3plus( * *------------------------------------------------------------------------*/ +#ifdef SPLIT_REND_LCLD_5MS +ivas_error ivas_split_renderer_open( + SPLIT_REND_WRAPPER *hSplitRendWrapper, + const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, + const int32_t OutSampleRate, + const int16_t cldfb_in_flag, + const int16_t pcm_out_flag, + const int16_t num_subframes ) +#else ivas_error ivas_split_renderer_open( SPLIT_REND_WRAPPER *hSplitRendWrapper, const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, @@ -1879,6 +1899,7 @@ ivas_error ivas_split_renderer_open( const int16_t cldfb_in_flag, const int16_t pcm_out_flag, const int16_t is_5ms_frame ) +#endif { ivas_error error, ch, num_ch; #ifndef SPLIT_REND_WITH_HEAD_ROT @@ -1985,10 +2006,17 @@ ivas_error ivas_split_renderer_open( { if ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LC3PLUS ) { +#ifdef SPLIT_REND_LCLD_5MS + if ( ( error = split_renderer_open_lc3plus( hSplitRendWrapper, pSplitRendConfig, OutSampleRate, num_subframes ) ) != IVAS_ERR_OK ) + { + return error; + } +#else if ( ( error = split_renderer_open_lc3plus( hSplitRendWrapper, pSplitRendConfig, OutSampleRate, is_5ms_frame ) ) != IVAS_ERR_OK ) { return error; } +#endif } else { diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 72c87b873a..a07fc170cb 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -3240,8 +3240,18 @@ static void clearInputMasa( return; } - #ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef SPLIT_REND_LCLD_5MS +static ivas_error initSplitRend( + SPLIT_REND_WRAPPER *pSplitRendWrapper, + IVAS_REND_AudioBuffer *pSplitRendEncBuffer, + const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, + IVAS_REND_HeadRotData headRotData, + const int32_t outputSampleRate, + const AUDIO_CONFIG outConfig, + const int16_t cldfb_in_flag, + const int16_t num_subframes ) +#else static ivas_error initSplitRend( SPLIT_REND_WRAPPER *pSplitRendWrapper, IVAS_REND_AudioBuffer *pSplitRendEncBuffer, @@ -3251,6 +3261,7 @@ static ivas_error initSplitRend( const AUDIO_CONFIG outConfig, const int16_t cldfb_in_flag, const int16_t is_5ms_frame ) +#endif { ivas_error error; IVAS_REND_AudioBufferConfig bufConfig; @@ -3266,10 +3277,17 @@ static ivas_error initSplitRend( ivas_renderSplitUpdateNoCorrectionPoseData( pSplit_rend_config, &pSplitRendWrapper->multiBinPoseData ); } +#ifdef SPLIT_REND_LCLD_5MS + if ( ( error = ivas_split_renderer_open( pSplitRendWrapper, pSplit_rend_config, outputSampleRate, cldfb_in_flag, outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, num_subframes ) ) != IVAS_ERR_OK ) + { + return error; + } +#else if ( ( error = ivas_split_renderer_open( pSplitRendWrapper, pSplit_rend_config, outputSampleRate, cldfb_in_flag, outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, is_5ms_frame ) ) != IVAS_ERR_OK ) { return error; } +#endif /*allocate for CLDFB in and change to TD during process if needed*/ bufConfig.numSamplesPerChannel = MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL; @@ -4020,17 +4038,22 @@ ivas_error IVAS_REND_AddInput( { return error; } + + if ( ( error = initSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) + { + return error; + } #else if ( ( error = ivas_split_rend_choose_default_codec( &hIvasRend->hRendererConfig->split_rend_config.codec, &hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) != IVAS_ERR_OK ) { return error; } -#endif if ( ( error = initSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, ( hIvasRend->num_subframes == 1 ) ? 1 : 0 ) ) != IVAS_ERR_OK ) { return error; } +#endif } #endif @@ -4917,17 +4940,22 @@ int16_t IVAS_REND_FeedRenderConfig( { return error; } + + if ( ( error = initSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) + { + return error; + } #else if ( ( error = ivas_split_rend_choose_default_codec( &hIvasRend->hRendererConfig->split_rend_config.codec, &hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) != IVAS_ERR_OK ) { return error; } -#endif if ( ( error = initSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, ( hIvasRend->num_subframes == 1 ) ? 1 : 0 ) ) != IVAS_ERR_OK ) { return error; } +#endif } #endif @@ -7128,9 +7156,16 @@ static ivas_error renderSplitBinauralWithPostRot( #ifdef SPLIT_REND_LCLD_5MS config.lc3plus_frame_duration_us = bits.codec_frame_size_ms * 1000; - if ( pCombinedOrientationData->num_subframes == 1 ) + if ( pCombinedOrientationData->num_subframes != MAX_PARAM_SPATIAL_SUBFRAMES ) { - config.ivas_frame_duration_us = ( bits.pose_correction == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ? config.lc3plus_frame_duration_us : 20000; + if ( bits.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS ) + { + config.ivas_frame_duration_us = ( bits.pose_correction == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ? config.lc3plus_frame_duration_us * pCombinedOrientationData->num_subframes : 20000; + } + else + { + config.ivas_frame_duration_us = ( bits.pose_correction == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ? config.lc3plus_frame_duration_us : 20000; + } iNumLCLDIterationsPerFrame = 1; } else -- GitLab From 4188ad0b31add2ffa7f07091eef6ca5c4d85fc03 Mon Sep 17 00:00:00 2001 From: rtyag Date: Thu, 8 Feb 2024 14:45:19 +1100 Subject: [PATCH 12/13] sanitizer fixes --- apps/renderer.c | 4 ++++ lib_dec/lib_dec.c | 7 ++++++ lib_rend/ivas_crend.c | 4 +++- lib_rend/ivas_lcld_decoder.c | 46 +++++++++++++++++++++++++++++++++++- 4 files changed, 59 insertions(+), 2 deletions(-) diff --git a/apps/renderer.c b/apps/renderer.c index e0e0c411c8..a3da5b6d09 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -2280,6 +2280,10 @@ cleanup: RotationFileReader_close( &headRotReader ); RotationFileReader_close( &externalOrientationFileReader ); RotationFileReader_close( &referenceRotReader ); +#ifdef SPLIT_REND_LCLD_5MS + SplitRendBFIFileReader_close( &splitRendBFIReader ); +#endif + Vector3PairFileReader_close( &referenceVectorReader ); #ifndef NONBE_FIX_BINARY_BINAURAL_READING hrtfFileReader_close( &hrtfFileReader ); diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 9ce0c12a87..d94d9958b7 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -3735,6 +3735,13 @@ ivas_error IVAS_DEC_GetSplitRendBits( splitRendBits->pose_correction = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->pose_correction; splitRendBits->codec_frame_size_ms = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->codec_frame_size_ms; +#ifdef SPLIT_REND_LCLD_5MS + /* data consumed, free it */ + free( hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits ); + hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits = NULL; +#endif + + return IVAS_ERR_OK; } diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index fedb722b4e..c7d7b7e5eb 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1806,7 +1806,9 @@ void ivas_rend_closeCldfbRend( } ivas_binRenderer_close( &pCldfbRend->hCldfbRend ); - +#ifdef SPLIT_REND_LCLD_5MS + ivas_binaural_hrtf_close( &pCldfbRend->hHrtfFastConv ); +#endif ivas_HRTF_fastconv_binary_close( &pCldfbRend->hHrtfFastConv ); return; diff --git a/lib_rend/ivas_lcld_decoder.c b/lib_rend/ivas_lcld_decoder.c index 64848af700..ab434b2d41 100644 --- a/lib_rend/ivas_lcld_decoder.c +++ b/lib_rend/ivas_lcld_decoder.c @@ -713,7 +713,11 @@ void DeleteLCLDDecoder( LCLDDecoder *psLCLDDecoder ) static void ApplyRMSEnvelope( const int32_t iNumBands, const int32_t *piBandwidths, const int32_t iNumGroups, const int32_t *piGroupLengths, int32_t **ppiRMSEnvelope, float **ppfReal, float **ppfImag ); +#ifdef SPLIT_REND_LCLD_5MS +static void ReplaceSign( const int32_t iNumBlocks, const int32_t iNumLCLDBands, int32_t **ppiSignReal, int32_t **ppiSignImag, float **ppfReal, float **ppfImag, const int32_t *piBandwidths ); +#else static void ReplaceSign( const int32_t iNumBlocks, const int32_t iNumLCLDBands, int32_t **ppiSignReal, int32_t **ppiSignImag, float **ppfReal, float **ppfImag ); +#endif static void InvQuantizeSpectrum( const int32_t iNumGroups, const int32_t *piGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, int32_t **ppiAlloc, int32_t **ppiQReal, int32_t **ppiQImag, float **ppfReal, float **ppfImag, NoiseGen *psNoiseGen ); @@ -819,10 +823,17 @@ int32_t DecodeLCLDFrame( pppfLCLDReal[n], pppfLCLDImag[n], psLCLDDecoder->psNoiseGen ); +#ifdef SPLIT_REND_LCLD_5MS + ReplaceSign( psLCLDDecoder->iNumBlocks, psLCLDDecoder->iNumBands, + psLCLDDecoder->pppiLCLDSignReal[n], + psLCLDDecoder->pppiLCLDSignImag[n], + pppfLCLDReal[n], pppfLCLDImag[n], psLCLDDecoder->piBandwidths ); +#else ReplaceSign( psLCLDDecoder->iNumBlocks, LCLD_BANDS, psLCLDDecoder->pppiLCLDSignReal[n], psLCLDDecoder->pppiLCLDSignImag[n], pppfLCLDReal[n], pppfLCLDImag[n] ); +#endif } #ifdef DEBUG_WRITE_PREDICTORS { @@ -915,7 +926,16 @@ static void ApplyRMSEnvelope( return; } - +#ifdef SPLIT_REND_LCLD_5MS +static void ReplaceSign( + const int32_t iNumBlocks, + const int32_t iNumLCLDBands, + int32_t **ppiSignReal, + int32_t **ppiSignImag, + float **ppfReal, + float **ppfImag, + const int32_t *piBandwidths ) +#else static void ReplaceSign( const int32_t iNumBlocks, const int32_t iNumLCLDBands, @@ -923,11 +943,34 @@ static void ReplaceSign( int32_t **ppiSignImag, float **ppfReal, float **ppfImag ) +#endif { int32_t b, n; +#ifdef SPLIT_REND_LCLD_5MS + int32_t m, idx; +#endif for ( n = 0; n < iNumBlocks; n++ ) { +#ifdef SPLIT_REND_LCLD_5MS + idx = 0; + for ( b = 0; b < iNumLCLDBands; b++ ) + { + for ( m = 0; m < piBandwidths[b]; m++ ) + { + if ( ppiSignReal[n][idx] == 1 ) + { + ppfReal[n][idx] = -ppfReal[n][idx]; + } + + if ( ppiSignImag[n][idx] == 1 ) + { + ppfImag[n][idx] = -ppfImag[n][idx]; + } + idx++; + } + } +#else for ( b = 0; b < iNumLCLDBands; b++ ) { if ( ppiSignReal[n][b] == 1 ) @@ -940,6 +983,7 @@ static void ReplaceSign( ppfImag[n][b] = -ppfImag[n][b]; } } +#endif } return; -- GitLab From 217f68d6e049a63e1c8bab2b80191a15ef051656 Mon Sep 17 00:00:00 2001 From: rtyag Date: Tue, 13 Feb 2024 11:52:01 +1100 Subject: [PATCH 13/13] fix for formatting issues --- apps/decoder.c | 3 --- apps/renderer.c | 7 +++---- lib_rend/ivas_PredEncoder.c | 8 ++++++-- lib_rend/ivas_lcld_decoder.c | 7 ------- lib_rend/ivas_lcld_encoder.c | 16 +++++++++------- lib_rend/ivas_lcld_prot.h | 10 ---------- lib_rend/ivas_prot_rend.h | 5 +++-- lib_rend/ivas_splitRend_lcld_dec.c | 2 ++ lib_rend/ivas_splitRend_lcld_enc.c | 1 + lib_rend/ivas_splitRendererPre.c | 3 +++ lib_rend/ivas_splitRenderer_utils.c | 5 +++-- 11 files changed, 30 insertions(+), 37 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 3e539f5123..e93eb594f5 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -483,7 +483,6 @@ int main( fprintf( stderr, "\nChanged render framesize, only 20ms are allowed for split rendering!\n" ); } #endif - arg.enableHeadRotation = true; } #endif @@ -656,7 +655,6 @@ int main( #endif #endif - if ( RenderConfigReader_read( renderConfigReader, arg.renderConfigFilename, &renderConfig ) != IVAS_ERR_OK ) { fprintf( stderr, "Failed to read renderer configuration from file %s\n\n", arg.renderConfigFilename ); @@ -690,7 +688,6 @@ int main( { fprintf( stderr, "\nChanged render framesize, only 20ms are allowed for non-0dof split rendering!\n" ); } - #endif #endif diff --git a/apps/renderer.c b/apps/renderer.c index 68307833c5..5e3f692608 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -1936,7 +1936,6 @@ int main( exit( -1 ); } #endif - if ( ( error = IVAS_REND_FeedSplitBinauralBitstream( hIvasRend, splitBinIds[i], &bitsBuffer ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); @@ -2236,6 +2235,9 @@ cleanup: } split_rend_reader_writer_close( &hSplitRendFileReadWrite ); +#ifdef SPLIT_REND_LCLD_5MS + SplitRendBFIFileReader_close( &splitRendBFIReader ); +#endif #endif for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) @@ -2248,9 +2250,6 @@ cleanup: RotationFileReader_close( &headRotReader ); RotationFileReader_close( &externalOrientationFileReader ); RotationFileReader_close( &referenceRotReader ); -#ifdef SPLIT_REND_LCLD_5MS - SplitRendBFIFileReader_close( &splitRendBFIReader ); -#endif Vector3PairFileReader_close( &referenceVectorReader ); destroy_td_hrtf( hHrtfTD ); diff --git a/lib_rend/ivas_PredEncoder.c b/lib_rend/ivas_PredEncoder.c index 250368c6be..747e652cf5 100644 --- a/lib_rend/ivas_PredEncoder.c +++ b/lib_rend/ivas_PredEncoder.c @@ -47,7 +47,9 @@ * * *-------------------------------------------------------------------*/ -static void activate_bit( int32_t *state, int32_t bit_id ) +static void activate_bit( + int32_t *state, + const int32_t bit_id ) { ( *state ) |= ( 1 << bit_id ); } @@ -58,7 +60,9 @@ static void activate_bit( int32_t *state, int32_t bit_id ) * *-------------------------------------------------------------------*/ -static void deactivate_bit( int32_t *state, int32_t bit_id ) +static void deactivate_bit( + int32_t *state, + const int32_t bit_id ) { ( *state ) &= ( ~( 1 << bit_id ) ); } diff --git a/lib_rend/ivas_lcld_decoder.c b/lib_rend/ivas_lcld_decoder.c index ab434b2d41..c3710f9cca 100644 --- a/lib_rend/ivas_lcld_decoder.c +++ b/lib_rend/ivas_lcld_decoder.c @@ -1292,13 +1292,6 @@ static int32_t ReadMSInformation( return iBitsRead; } -#ifdef SPLIT_REND_LCLD_5MS -int32_t GetNumPredSubSets( LCLDDecoder *psLCLDDecoder ) -{ - return psLCLDDecoder->psPredictionDecoder->iNumSubSets; -} -#endif - static int32_t ReadGroupInformation( const int32_t iChannels, const int32_t iNumBlocks, diff --git a/lib_rend/ivas_lcld_encoder.c b/lib_rend/ivas_lcld_encoder.c index 80f484d338..811572e185 100644 --- a/lib_rend/ivas_lcld_encoder.c +++ b/lib_rend/ivas_lcld_encoder.c @@ -95,10 +95,11 @@ struct LCLD_ENCODER * *------------------------------------------------------------------------------------------*/ -static int32_t Quantize( const float fVal, - const float fScale, - int32_t *iSign, - const int32_t iMaxVal ) +static int32_t Quantize( + const float fVal, + const float fScale, + int32_t *iSign, + const int32_t iMaxVal ) { int32_t iVal; if ( fVal > 0.0f ) @@ -122,9 +123,10 @@ static int32_t Quantize( const float fVal, * *------------------------------------------------------------------------------------------*/ -static float UnQuantize( const int32_t iVal, - const float fScale, - const int32_t iSign ) +static float UnQuantize( + const int32_t iVal, + const float fScale, + const int32_t iSign ) { float fVal; if ( iSign == 0 ) diff --git a/lib_rend/ivas_lcld_prot.h b/lib_rend/ivas_lcld_prot.h index 54d1f771bb..1353868980 100644 --- a/lib_rend/ivas_lcld_prot.h +++ b/lib_rend/ivas_lcld_prot.h @@ -85,10 +85,6 @@ ivas_error CreateLCLDDecoder( const int32_t iSampleRate, const int32_t iChannels ); #else -int32_t GetNumPredSubSets( - LCLDDecoder *psLCLDDecoder -); - ivas_error CreateLCLDDecoder( LCLDDecoder **psLCLDDecoder_out, const int32_t iSampleRate, @@ -199,12 +195,6 @@ typedef struct NOISE_GEN float *pfNoiseBuffer; } NoiseGen; -#ifdef SPLIT_REND_LCLD_5MS -NoiseGen *CreateNoiseGen( - void -); -#endif - void DeleteNoiseGen( NoiseGen *psNoiseGen ); diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 87fe0c34a8..8a3237c2ff 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -2036,8 +2036,9 @@ int32_t ivas_split_rend_bitstream_read_int32( ); #ifdef SPLIT_REND_LCLD_5MS -int32_t get_bit( const int32_t state, - const int32_t bit_id +int32_t get_bit( + const int32_t state, + const int32_t bit_id ); #endif diff --git a/lib_rend/ivas_splitRend_lcld_dec.c b/lib_rend/ivas_splitRend_lcld_dec.c index 3ca53e513d..6e53411e2b 100644 --- a/lib_rend/ivas_splitRend_lcld_dec.c +++ b/lib_rend/ivas_splitRend_lcld_dec.c @@ -47,6 +47,7 @@ * * *------------------------------------------------------------------------*/ + #ifdef SPLIT_REND_LCLD_5MS ivas_error ivas_splitBinLCLDDecOpen( BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec, @@ -73,6 +74,7 @@ ivas_error ivas_splitBinLCLDDecOpen( splitBinLCLDDec->pLcld_dec = NULL; /* place holder for CLDFB decoder handle */ splitBinLCLDDec->iChannels = iChannels; + #ifndef SPLIT_REND_LCLD_5MS if ( ( error = CreateLCLDDecoder( &splitBinLCLDDec->psLCLDDecoder, iSampleRate, iChannels ) ) != IVAS_ERR_OK ) { diff --git a/lib_rend/ivas_splitRend_lcld_enc.c b/lib_rend/ivas_splitRend_lcld_enc.c index 54674c80bb..85dd1e2442 100644 --- a/lib_rend/ivas_splitRend_lcld_enc.c +++ b/lib_rend/ivas_splitRend_lcld_enc.c @@ -191,6 +191,7 @@ void ivas_splitBinLCLDEncProcess( assert( Cldfb_In_Real != NULL ); assert( Cldfb_In_Imag != NULL ); assert( pBits != NULL ); + #ifdef SPLIT_REND_LCLD_5MS available_bits_local = available_bits; #endif diff --git a/lib_rend/ivas_splitRendererPre.c b/lib_rend/ivas_splitRendererPre.c index bbe0cd9a85..0a9cdb237c 100644 --- a/lib_rend/ivas_splitRendererPre.c +++ b/lib_rend/ivas_splitRendererPre.c @@ -1794,6 +1794,7 @@ void ivas_init_split_rend_handles( * * *------------------------------------------------------------------------*/ + #ifdef SPLIT_REND_LCLD_5MS static ivas_error split_renderer_open_lc3plus( SPLIT_REND_WRAPPER *hSplitRendWrapper, @@ -1811,6 +1812,7 @@ static ivas_error split_renderer_open_lc3plus( ivas_error error; int16_t i, delayBufferLength; LC3PLUS_CONFIG config; + #ifdef SPLIT_REND_LCLD_5MS config.lc3plus_frame_duration_us = pSplitRendConfig->codec_frame_size_ms * 1000; config.ivas_frame_duration_us = ( pSplitRendConfig->dof == 0 ) ? config.lc3plus_frame_duration_us * num_subframes : 20000; @@ -2521,6 +2523,7 @@ ivas_error ivas_renderMultiBinToSplitBinaural( { float *Cldfb_In_BinReal_p[CLDFB_NO_COL_MAX]; float *Cldfb_In_BinImag_p[CLDFB_NO_COL_MAX]; + #ifdef SPLIT_REND_LCLD_5MS for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ ) #else diff --git a/lib_rend/ivas_splitRenderer_utils.c b/lib_rend/ivas_splitRenderer_utils.c index e18e4b6628..74fd854b24 100644 --- a/lib_rend/ivas_splitRenderer_utils.c +++ b/lib_rend/ivas_splitRenderer_utils.c @@ -1113,8 +1113,9 @@ ivas_error ivas_split_rend_choose_default_codec( * *-------------------------------------------------------------------*/ -int32_t get_bit( const int32_t state, - const int32_t bit_id ) +int32_t get_bit( + const int32_t state, + const int32_t bit_id ) { return ( state & ( 1 << bit_id ) ); } -- GitLab