diff --git a/Workspace_msvc/lib_isar.vcxproj b/Workspace_msvc/lib_isar.vcxproj
index 5bee827041dc1972467edee3601f784b4573bba5..fceeb731ced2445a5434805d422d30654718782a 100644
--- a/Workspace_msvc/lib_isar.vcxproj
+++ b/Workspace_msvc/lib_isar.vcxproj
@@ -197,4 +197,4 @@
-
\ No newline at end of file
+
diff --git a/Workspace_msvc/lib_rend.vcxproj b/Workspace_msvc/lib_rend.vcxproj
index 27d4a19a693cf86f60b3ce654912c65b4a7cbaa6..1d55ed1942020a6c9b8e85bb05eb8bcd93cdd398 100644
--- a/Workspace_msvc/lib_rend.vcxproj
+++ b/Workspace_msvc/lib_rend.vcxproj
@@ -138,6 +138,7 @@
+
@@ -175,6 +176,7 @@
+
diff --git a/Workspace_msvc/lib_rend.vcxproj.filters b/Workspace_msvc/lib_rend.vcxproj.filters
index 63e83fc9b5938a8550c46a0c8ffb8fd79aa1f6eb..ebcb9060c5220e6778966be731913242dc30fdf0 100644
--- a/Workspace_msvc/lib_rend.vcxproj.filters
+++ b/Workspace_msvc/lib_rend.vcxproj.filters
@@ -116,6 +116,9 @@
rend_c
+
+ rend_c
+
diff --git a/apps/decoder.c b/apps/decoder.c
index a812a2a133cfa5b8bafb170fb1291c8926b14274..641445277586061a4bccca81e65d5d51c7aaa444 100644
--- a/apps/decoder.c
+++ b/apps/decoder.c
@@ -174,7 +174,11 @@ typedef struct
static bool parseCmdlIVAS_dec( int16_t argc, char **argv, DecArguments *arg );
static void usage_dec( void );
static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtfBinary, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ObjectEditFileReader *objectEditFileReader, ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf );
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtf, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ObjectEditFileReader *objectEditFileReader, ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf );
+#else
static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtfBinary, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ObjectEditFileReader *objectEditFileReader, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf );
+#endif
static ivas_error load_hrtf_from_file( IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtfBinary, IVAS_DEC_HANDLE hIvasDec, const IVAS_AUDIO_CONFIG OutputConfig, const int32_t output_Fs );
#ifdef DEBUGGING
static ivas_error printBitstreamInfoVoip( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HANDLE hIvasDec );
@@ -756,7 +760,11 @@ int main(
if ( arg.voipMode )
{
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ error = decodeVoIP( arg, hBsReader, &hHrtfBinary, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, objectEditFileReader, &splitRendBits, hIvasDec, pcmBuf );
+#else
error = decodeVoIP( arg, hBsReader, &hHrtfBinary, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, objectEditFileReader, hIvasDec, pcmBuf );
+#endif
}
else
{
@@ -1952,7 +1960,11 @@ static ivas_error initOnFirstGoodFrame(
for ( int16_t i = 0; i < numInitialBadFrames; ++i )
{
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ if ( isSplitRend )
+#else
if ( *splitRendWriter != NULL )
+#endif
{
ISAR_SPLIT_REND_BITS_DATA splitRendBitsZero;
splitRendBitsZero.bits_buf = NULL;
@@ -1970,7 +1982,12 @@ static ivas_error initOnFirstGoodFrame(
return error;
}
}
+
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ if ( !isSplitCoded )
+#else
else
+#endif
{
if ( *pRemainingDelayNumSamples < *numOutSamples )
{
@@ -2179,6 +2196,14 @@ static ivas_error decodeG192(
return error;
}
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ if ( !isSplitRend )
+ {
+ /* Ensure split rendering output struct is not used when not outputting to a split rendering output configuration */
+ splitRendBits = NULL;
+ }
+#endif
+
if ( ( error = IVAS_DEC_is_split_rendering_coded_out( hIvasDec, &isSplitCoded ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "\nError in IVAS_DEC_is_split_rendering_coded_out, code: %d\n", error );
@@ -2510,7 +2535,11 @@ static ivas_error decodeG192(
}
/* decode transport channels, do TSM and feed to renderer */
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ if ( ( error = IVAS_DEC_GetSamplesDecoder( hIvasDec, splitRendBits ) ) != IVAS_ERR_OK )
+#else
if ( ( error = IVAS_DEC_GetSamplesDecoder( hIvasDec, isSplitRend, splitRendBits ) ) != IVAS_ERR_OK )
+#endif
{
return error;
}
@@ -3060,6 +3089,9 @@ static ivas_error decodeVoIP(
RotFileReader *refRotReader,
Vector3PairFileReader *referenceVectorReader,
ObjectEditFileReader *objectEditFileReader,
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ ISAR_SPLIT_REND_BITS_DATA *splitRendBits,
+#endif
IVAS_DEC_HANDLE hIvasDec,
int16_t *pcmBuf )
{
@@ -3109,6 +3141,29 @@ static ivas_error decodeVoIP(
bool parametersAvailableForEditing = false;
uint16_t nSamplesRendered;
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ SplitFileReadWrite *splitRendWriter = NULL;
+ int16_t isSplitRend, isSplitCoded;
+
+ if ( ( error = IVAS_DEC_is_split_rendering_enabled( hIvasDec, &isSplitRend ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nError in IVAS_DEC_is_split_rendering_enabled, code: %d\n", error );
+ return error;
+ }
+
+ if ( !isSplitRend )
+ {
+ /* Ensure split rendering output struct is not used when not outputting to a split rendering format */
+ splitRendBits = NULL;
+ }
+
+ if ( ( error = IVAS_DEC_is_split_rendering_coded_out( hIvasDec, &isSplitCoded ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nError in IVAS_DEC_is_split_rendering_coded_out, code: %d\n", error );
+ return error;
+ }
+#endif
+
vec_pos_update = 0;
if ( ( error = IVAS_DEC_GetRenderFramesizeMs( hIvasDec, &systemTimeInc_ms ) ) != IVAS_ERR_OK )
{
@@ -3400,15 +3455,34 @@ static ivas_error decodeVoIP(
/* decode and get samples */
while ( nSamplesRendered < nOutSamples )
{
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ if ( isSplitRend )
+ {
#ifdef SUPPORT_JBM_TRACEFILE
- if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, writeJbmTraceFileFrameWrapper, jbmTraceWriter, &bitstreamReadDone, &nSamplesRendered, ¶metersAvailableForEditing, systemTime_ms ) ) != IVAS_ERR_OK )
+ if ( ( error = IVAS_DEC_VoIP_GetSplitBinauralBitstream( hIvasDec, (void *) pcmBuf, splitRendBits, writeJbmTraceFileFrameWrapper, jbmTraceWriter, &bitstreamReadDone, &nSamplesRendered, ¶metersAvailableForEditing, systemTime_ms ) ) != IVAS_ERR_OK )
#else
- if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, &bitstreamReadDone, ¶metersAvailableForEditing, systemTime_ms ) ) != IVAS_ERR_OK )
+ if ( ( error = IVAS_DEC_VoIP_GetSplitBinauralBitstream( hIvasDec, (void *) pcmBuf, splitRendBits, &bitstreamReadDone, &nSamplesRendered, ¶metersAvailableForEditing, systemTime_ms ) ) != IVAS_ERR_OK )
#endif
+ {
+ fprintf( stderr, "\nError in IVAS_DEC_VoIP_GetSplitBinauralBitstream: %s\n", IVAS_DEC_GetErrorMessage( error ) );
+ goto cleanup;
+ }
+ }
+ else
{
- fprintf( stderr, "\nError in IVAS_DEC_VoIP_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) );
- goto cleanup;
+#endif
+#ifdef SUPPORT_JBM_TRACEFILE
+ if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, writeJbmTraceFileFrameWrapper, jbmTraceWriter, &bitstreamReadDone, &nSamplesRendered, ¶metersAvailableForEditing, systemTime_ms ) ) != IVAS_ERR_OK )
+#else
+ if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, &bitstreamReadDone, ¶metersAvailableForEditing, systemTime_ms ) ) != IVAS_ERR_OK )
+#endif
+ {
+ fprintf( stderr, "\nError in IVAS_DEC_VoIP_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) );
+ goto cleanup;
+ }
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
}
+#endif
if ( bitstreamReadDone == true )
{
@@ -3488,9 +3562,15 @@ static ivas_error decodeVoIP(
/* Once good frame decoded, catch up */
if ( decodedGoodFrame )
{
+#ifndef FIX_1119_SPLIT_RENDERING_VOIP
SplitFileReadWrite *splitRendWriter = NULL;
+#endif
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, &nOutSamples, &vec_pos_len, delayNumSamples_orig, &delayNumSamples, &delayTimeScale,
+#else
if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, &nOutSamples, NULL, delayNumSamples_orig, &delayNumSamples, &delayTimeScale,
+#endif
&bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj, &splitRendWriter ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "Error in initOnFirstGoodFrame(): %s\n", IVAS_DEC_GetErrorMessage( error ) );
@@ -3506,19 +3586,35 @@ static ivas_error decodeVoIP(
/* Write current frame */
if ( decodedGoodFrame )
{
- if ( delayNumSamples < nOutSamples )
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ if ( isSplitRend )
{
- if ( ( error = AudioFileWriter_write( afWriter, &pcmBuf[delayNumSamples * nOutChannels], nOutSamples * nOutChannels - ( delayNumSamples * nOutChannels ) ) ) != IVAS_ERR_OK )
+ if ( split_rend_write_bitstream_to_file( splitRendWriter, splitRendBits->bits_buf, &splitRendBits->bits_read, &splitRendBits->bits_written ) != IVAS_ERR_OK )
{
- fprintf( stderr, "\nOutput audio file writer error\n" );
+ fprintf( stderr, "\nUnable to write to bitstream file!\n" );
goto cleanup;
}
- delayNumSamples = 0;
}
- else
+
+ if ( !isSplitCoded )
{
- delayNumSamples -= nOutSamples;
+#endif
+ if ( delayNumSamples < nOutSamples )
+ {
+ if ( ( error = AudioFileWriter_write( afWriter, &pcmBuf[delayNumSamples * nOutChannels], nOutSamples * nOutChannels - ( delayNumSamples * nOutChannels ) ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nOutput audio file writer error\n" );
+ goto cleanup;
+ }
+ delayNumSamples = 0;
+ }
+ else
+ {
+ delayNumSamples -= nOutSamples;
+ }
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
}
+#endif
/* Write ISM metadata to external file(s) */
if ( decodedGoodFrame && arg.outputConfig == IVAS_AUDIO_CONFIG_EXTERNAL )
@@ -3606,7 +3702,11 @@ static ivas_error decodeVoIP(
goto cleanup;
}
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ if ( nSamplesFlushed && !isSplitCoded )
+#else
if ( nSamplesFlushed )
+#endif
{
/* Write current frame */
if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, nSamplesFlushed * nOutChannels ) ) != IVAS_ERR_OK )
@@ -3677,11 +3777,19 @@ static ivas_error decodeVoIP(
*------------------------------------------------------------------------------------------*/
memset( pcmBuf, 0, delayNumSamples_orig[0] * nOutChannels * sizeof( int16_t ) );
- if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig[0] * nOutChannels ) ) != IVAS_ERR_OK )
+
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ if ( afWriter != NULL )
{
- fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) );
- goto cleanup;
+#endif
+ if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig[0] * nOutChannels ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) );
+ goto cleanup;
+ }
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
}
+#endif
/*------------------------------------------------------------------------------------------*
* Printouts after decoding has finished
@@ -3726,6 +3834,9 @@ cleanup:
EVS_RTPDUMP_DEPACKER_close( &rtpdumpDepacker );
AudioFileWriter_close( &afWriter );
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ split_rend_reader_writer_close( &splitRendWriter );
+#endif
JbmOffsetFileWriter_close( &jbmOffsetWriter );
#ifdef SUPPORT_JBM_TRACEFILE
JbmTraceFileWriter_close( &jbmTraceWriter );
diff --git a/apps/isar_post_rend.c b/apps/isar_post_rend.c
index e6c78bfed5ff938d9609a6494ee4c5cb002f6ced..3159548da417798d404345cf218d866fab139fa0 100644
--- a/apps/isar_post_rend.c
+++ b/apps/isar_post_rend.c
@@ -1068,6 +1068,19 @@ int main(
fprintf( stderr, "\nISAR_POST_REND_FeedSplitBinauralBitstream failed: %s\n", ivas_error_to_string( error ) );
goto cleanup;
}
+
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ /* Set BFI if frame is empty */
+ int16_t frameEmpty = (int16_t) ( bitsBuffer.config.bitsWritten == 0 );
+ if ( frameEmpty )
+ {
+ if ( ( error = ISAR_POST_REND_SetSplitRendBFI( hIsarPostRend, 1 ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "Error in ISAR_POST_REND_SetSplitRendBFI(): %s\n", ivas_error_to_string( error ) );
+ goto cleanup;
+ }
+ }
+#endif
}
}
diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h
index 469f6f0ee67094f8880d3ca592013939156f4354..7820d28a04cdc65c459252ba30d1a613e582da12 100644
--- a/lib_com/ivas_prot.h
+++ b/lib_com/ivas_prot.h
@@ -5217,6 +5217,43 @@ void ivas_binaural_add_LFE(
float *output_f[] /* o : synthesized core-coder transport channels/DirAC output */
);
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+
+/*---------------------------------------------------------------------------------*
+ * Multi-pose ring buffer Prototypes
+*-----------------------------------------------------------------------------------*/
+
+ivas_error ivas_CLDFB_RINGBUF_Open(
+ ISAR_CLDFB_RINGBUF_HANDLE *ph,
+ const int16_t capacity_columns
+);
+
+void ivas_CLDFB_RINGBUF_Close(
+ ISAR_CLDFB_RINGBUF_HANDLE *ph
+);
+
+void ivas_CLDFB_RINGBUF_Push(
+ ISAR_CLDFB_RINGBUF_HANDLE h,
+ const float *real,
+ const float *imag,
+ const int16_t num_bands
+);
+
+void ivas_CLDFB_RINGBUF_Pop(
+ ISAR_CLDFB_RINGBUF_HANDLE h,
+ float *real,
+ float *imag,
+ const int16_t num_bands
+);
+
+void ivas_CLDFB_RINGBUF_GetByIdx(
+ ISAR_CLDFB_RINGBUF_HANDLE h,
+ float **p_real,
+ float **p_imag,
+ const int16_t idx
+);
+
+#endif
/*----------------------------------------------------------------------------------*
* renderer prototypes
diff --git a/lib_com/options.h b/lib_com/options.h
index 0c8e51e7ec81c84fa3fcdba9e882430b974300ff..8826aa3420f1c5d07dc6cca2e78a927140656619 100644
--- a/lib_com/options.h
+++ b/lib_com/options.h
@@ -171,7 +171,8 @@
#define NONBE_1377_REND_DIRATT_CONF /* Eri: Issue 1377: Error in directivity attenuation configuration for both IVAS_dec and IVAS_rend */
#define FIX_1377_HANDLE_ERROR_CODE /* Eri: Add missing error code handling from IVAS_REND_SetObjectIDs */
#define FIX_1053_REVERB_RECONFIGURATION
-#define TMP_FIX_1119_SPLIT_RENDERING_VOIP /* FhG: Add error check for unsupported config: split rendering with VoIP mode */
+#define FIX_1119_SPLIT_RENDERING_VOIP /* FhG: Add split rendering support to decoder in VoIP mode */
+#define TMP_1342_WORKAROUND_DEC_FLUSH_BROKEN_IN_SR /* FhG: Temporary workaround for incorrect implementation of decoder flush with split rendering */
#define NONBE_1122_KEEP_EVS_MODE_UNCHANGED /* FhG: Disables fix for issue 1122 in EVS mode to keep BE tests green. This switch should be removed once the 1122 fix is added to EVS via a CR. */
#define FIX_938_COMPILER_WARNING /* FhG: Fix compiler warning in ivas_mdct_core_reconstruct() */
#define FIX_1376_MISSING_ISM_METADATA /* FhG: IVAS_rend: throw error if there exists an ISM input without a corresponding metadata file path */
diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c
index 7d1336f45d563c2dfeaecb6d57253ffde298f288..142cac7e50c4a9bcd7045e83230561ddfcd2331f 100644
--- a/lib_dec/ivas_dirac_dec.c
+++ b/lib_dec/ivas_dirac_dec.c
@@ -1657,7 +1657,9 @@ static void binRenderer_split(
float Cldfb_ImagBuffer_Binaural[][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Rotated Binaural signals */
float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */
float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */
+#ifndef FIX_1119_SPLIT_RENDERING_VOIP
const int16_t slot_idx_start,
+#endif
const int16_t num_freq_bands,
const int16_t nchan_out )
{
@@ -1687,8 +1689,16 @@ static void binRenderer_split(
{
for ( ch = 0; ch < nchan_out; ch++ )
{
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ ivas_CLDFB_RINGBUF_Push(
+ hSplitBinRend->hMultiBinCldfbData[pos_idx * BINAURAL_CHANNELS + ch],
+ Cldfb_RealBuffer_Binaural_loc[pos_idx][ch][slot_idx],
+ Cldfb_ImagBuffer_Binaural_loc[pos_idx][ch][slot_idx],
+ num_freq_bands );
+#else
mvr2r( Cldfb_RealBuffer_Binaural_loc[pos_idx][ch][slot_idx], hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], num_freq_bands );
mvr2r( Cldfb_ImagBuffer_Binaural_loc[pos_idx][ch][slot_idx], hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], num_freq_bands );
+#endif
}
}
}
@@ -2443,7 +2453,11 @@ void ivas_dirac_dec_render_sf(
if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
{
binRenderer_split( st_ivas->hBinRenderer, st_ivas->hSplitBinRend, st_ivas->hCombinedOrientationData, hSpatParamRendCom->subframe_nbslots[subframe_idx],
- Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer, slot_idx_start, hSpatParamRendCom->num_freq_bands, st_ivas->hDecoderConfig->nchan_out );
+ Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer,
+#ifndef FIX_1119_SPLIT_RENDERING_VOIP
+ slot_idx_start,
+#endif
+ hSpatParamRendCom->num_freq_bands, st_ivas->hDecoderConfig->nchan_out );
}
else
{
diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c
index 4d1d4decd9c344577d3fd7f8d3f49646d99fe44d..3576f19440641aa1d6312b66ebe82a00e6ef764c 100644
--- a/lib_dec/ivas_init_dec.c
+++ b/lib_dec/ivas_init_dec.c
@@ -1240,6 +1240,10 @@ ivas_error ivas_init_decoder_front(
}
}
+#ifdef TMP_1342_WORKAROUND_DEC_FLUSH_BROKEN_IN_SR
+ st_ivas->flushing = 0;
+#endif
+
return error;
}
diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c
index ea4226932a7d679b317a09c5c20d0bd99d86cd2b..81994844110522b848771d9a23385b3bb033b50e 100644
--- a/lib_dec/ivas_jbm_dec.c
+++ b/lib_dec/ivas_jbm_dec.c
@@ -1399,6 +1399,12 @@ ivas_error ivas_jbm_dec_render(
if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
{
nchan_out_syn_output = BINAURAL_CHANNELS * st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses;
+#ifdef TMP_1342_WORKAROUND_DEC_FLUSH_BROKEN_IN_SR
+ if ( st_ivas->flushing )
+ {
+ nchan_out_syn_output = BINAURAL_CHANNELS;
+ }
+#endif
}
else
{
diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c
index 22827d8b658e683e69f91fdc829bd46ac55b7206..e912222b579eb78c267f389129837e3a28ea5bcd 100644
--- a/lib_dec/ivas_mc_param_dec.c
+++ b/lib_dec/ivas_mc_param_dec.c
@@ -1787,8 +1787,16 @@ void ivas_param_mc_dec_render(
{
for ( ch = 0; ch < nchan_out_cldfb; ch++ )
{
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ ivas_CLDFB_RINGBUF_Push(
+ st_ivas->hSplitBinRend->hMultiBinCldfbData[pos_idx * BINAURAL_CHANNELS + ch],
+ Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx],
+ Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx],
+ hParamMC->num_freq_bands );
+#else
mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands );
mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands );
+#endif
}
}
}
diff --git a/lib_dec/ivas_mc_paramupmix_dec.c b/lib_dec/ivas_mc_paramupmix_dec.c
index 8ef994fb4fff87aed97f06743677a6be8da8d3e1..a95490b5c47469f3d10a74f45b857dbaabc08cc7 100644
--- a/lib_dec/ivas_mc_paramupmix_dec.c
+++ b/lib_dec/ivas_mc_paramupmix_dec.c
@@ -790,8 +790,16 @@ static void ivas_mc_paramupmix_dec_sf(
{
for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ )
{
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ ivas_CLDFB_RINGBUF_Push(
+ st_ivas->hSplitBinRend->hMultiBinCldfbData[pos_idx * BINAURAL_CHANNELS + ch],
+ Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx],
+ Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx],
+ maxBand );
+#else
mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_index_start + slot_idx], maxBand );
mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_index_start + slot_idx], maxBand );
+#endif
}
}
}
diff --git a/lib_dec/ivas_omasa_dec.c b/lib_dec/ivas_omasa_dec.c
index 5d4cb7c0fa95721ec5bc30ab54e7ea395199dab5..43d881dd47c486fd52c1dc4362e4d4689fb568f2 100644
--- a/lib_dec/ivas_omasa_dec.c
+++ b/lib_dec/ivas_omasa_dec.c
@@ -782,9 +782,13 @@ ivas_error ivas_omasa_dirac_td_binaural_jbm(
float data_separated_objects[BINAURAL_CHANNELS][L_FRAME48k];
ivas_error error;
float *p_sepobj[BINAURAL_CHANNELS];
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ float *re, *im;
+#else
int16_t slot_idx_start;
slot_idx_start = st_ivas->hSpatParamRendCom->slots_rendered;
+#endif
for ( n = 0; n < BINAURAL_CHANNELS; n++ )
{
@@ -825,9 +829,14 @@ ivas_error ivas_omasa_dirac_td_binaural_jbm(
{
cldfbAnalysis_ts( &( p_rend_obj[n][num_cldfb_bands * slot_idx] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, num_cldfb_bands, st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n] );
- /* note: this intentionally differs from OSBA by: no scaling by 0.5 */
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ ivas_CLDFB_RINGBUF_GetByIdx( st_ivas->hSplitBinRend->hMultiBinCldfbData[n], &re, &im, slot_idx - cldfb_slots );
+ v_add( re, Cldfb_RealBuffer, re, num_cldfb_bands );
+ v_add( im, Cldfb_ImagBuffer, im, num_cldfb_bands );
+#else
v_add( st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx_start + slot_idx], Cldfb_RealBuffer, st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx_start + slot_idx], num_cldfb_bands );
v_add( st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx_start + slot_idx], Cldfb_ImagBuffer, st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx_start + slot_idx], num_cldfb_bands );
+#endif
}
}
}
diff --git a/lib_dec/ivas_osba_dec.c b/lib_dec/ivas_osba_dec.c
index 7eb3d07356f76d258b206e5fb61efb145bada7e1..00025b6847b2d8f932d833ec503b42a2d417da61 100644
--- a/lib_dec/ivas_osba_dec.c
+++ b/lib_dec/ivas_osba_dec.c
@@ -137,9 +137,13 @@ ivas_error ivas_osba_dirac_td_binaural_jbm(
float output_separated_objects[BINAURAL_CHANNELS][L_FRAME48k];
float *p_sepobj[BINAURAL_CHANNELS];
int16_t channel_offset;
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ float *re, *im;
+#else
int16_t slot_idx_start;
slot_idx_start = st_ivas->hSpatParamRendCom->slots_rendered;
+#endif
for ( n = 0; n < BINAURAL_CHANNELS; n++ )
{
@@ -158,7 +162,10 @@ ivas_error ivas_osba_dirac_td_binaural_jbm(
if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
{
- int16_t slot_idx, num_cldfb_bands, b, nchan_transport_orig;
+ int16_t slot_idx, num_cldfb_bands, nchan_transport_orig;
+#ifndef FIX_1119_SPLIT_RENDERING_VOIP
+ int16_t b;
+#endif
int16_t cldfb_slots;
float Cldfb_RealBuffer[CLDFB_NO_CHANNELS_MAX];
float Cldfb_ImagBuffer[CLDFB_NO_CHANNELS_MAX];
@@ -179,6 +186,11 @@ ivas_error ivas_osba_dirac_td_binaural_jbm(
{
cldfbAnalysis_ts( &( output_f[n][num_cldfb_bands * slot_idx] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, num_cldfb_bands, st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n] );
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ ivas_CLDFB_RINGBUF_GetByIdx( st_ivas->hSplitBinRend->hMultiBinCldfbData[n], &re, &im, slot_idx - cldfb_slots );
+ v_add( re, Cldfb_RealBuffer, re, num_cldfb_bands );
+ v_add( im, Cldfb_ImagBuffer, im, num_cldfb_bands );
+#else
for ( b = 0; b < num_cldfb_bands; b++ )
{
st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx_start + slot_idx][b] =
@@ -187,6 +199,7 @@ ivas_error ivas_osba_dirac_td_binaural_jbm(
st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx_start + slot_idx][b] =
st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx_start + slot_idx][b] + Cldfb_ImagBuffer[b];
}
+#endif
}
}
}
diff --git a/lib_dec/ivas_output_config.c b/lib_dec/ivas_output_config.c
index 2175ecf089fcd01e0b077a340ba84de4ee96a381..fa4ff1c7d3459cd4586a99dea30ec4c68304619c 100644
--- a/lib_dec/ivas_output_config.c
+++ b/lib_dec/ivas_output_config.c
@@ -500,11 +500,21 @@ RENDERER_TYPE ivas_renderer_secondary_select(
renderer_type = RENDERER_DISABLE;
output_config = st_ivas->hDecoderConfig->output_config;
- if ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC && output_config == IVAS_AUDIO_CONFIG_BINAURAL )
+ if ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC &&
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+#else
+ output_config == IVAS_AUDIO_CONFIG_BINAURAL
+#endif
+ )
{
renderer_type = RENDERER_BINAURAL_OBJECTS_TD;
}
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ else if ( st_ivas->ivas_format == SBA_ISM_FORMAT && st_ivas->ism_mode == ISM_SBA_MODE_DISC && ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
+#else
else if ( st_ivas->ivas_format == SBA_ISM_FORMAT && st_ivas->ism_mode == ISM_SBA_MODE_DISC && ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
+#endif
{
renderer_type = RENDERER_BINAURAL_OBJECTS_TD;
}
diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h
index a6cd975989778a89cebc7abcfdedc2a538e31210..ac6c6e42ba078e46db565eb0eba71c0faea38026 100644
--- a/lib_dec/ivas_stat_dec.h
+++ b/lib_dec/ivas_stat_dec.h
@@ -821,6 +821,7 @@ typedef struct renderer_struct
* IVAS decoder specific ISAR wrapper structures
*----------------------------------------------------------------------------------*/
+#ifndef FIX_1119_SPLIT_RENDERING_VOIP
typedef struct
{
float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
@@ -828,18 +829,29 @@ typedef struct
} ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA, *ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE;
+#endif
typedef struct
{
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ float Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS][2 * CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; /* Double space to account for TSM */
+ float Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS][2 * CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
+#else
float Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
float Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
+#endif
IVAS_AUDIO_CONFIG config;
} ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA, *ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE;
typedef struct
{
- ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE hMultiBinCldfbData; /*scratch buffer for frame by frame processing*/
- ISAR_SPLIT_REND_BITS_HANDLE hSplitRendBits; /*scratch buffer for frame by frame processing*/
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ TD_RINGBUF_HANDLE hMultiBinTdData;
+ ISAR_CLDFB_RINGBUF_HANDLE hMultiBinCldfbData[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS];
+#else
+ ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE hMultiBinCldfbData; /*scratch buffer for frame by frame processing*/
+#endif
+ ISAR_SPLIT_REND_BITS_HANDLE hSplitRendBits; /*scratch buffer for frame by frame processing*/
SPLIT_REND_WRAPPER splitrend;
ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE hCldfbDataOut; /*buffer to store cldfb data before binauralization*/
int16_t numTdSamplesPerChannelCached;
@@ -1143,6 +1155,10 @@ typedef struct Decoder_Struct
int16_t ism_extmeta_active; /* Extended metadata active in decoder */
int16_t ism_extmeta_cnt; /* Change frame counter for extended metadata */
+#ifdef TMP_1342_WORKAROUND_DEC_FLUSH_BROKEN_IN_SR
+ int16_t flushing;
+#endif
+
} Decoder_Struct;
/* clang-format on */
diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c
index a53d8e1e852181aa3d73333168c61f1162d50226..d4032c36d75542c07232948397c8bb168b10fe59 100644
--- a/lib_dec/lib_dec.c
+++ b/lib_dec/lib_dec.c
@@ -117,7 +117,11 @@ static void store_JbmData( IVAS_DEC_VOIP *hVoIP, JB4_DATAUNIT_HANDLE dataUnit, c
static ivas_error evs_dec_main( Decoder_Struct *st_ivas );
static ivas_error input_format_API_to_internal( IVAS_DEC_INPUT_FORMAT input_format, int16_t *bitstream_format_internal, int16_t *sdp_hf_only, const bool is_voip_enabled );
static void init_decoder_config( DECODER_CONFIG_HANDLE hDecoderConfig );
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+static ivas_error ivas_dec_setup_all( IVAS_DEC_HANDLE hIvasDec, uint8_t *nTransportChannels, ISAR_SPLIT_REND_BITS_DATA *splitRendBits );
+#else
static ivas_error ivas_dec_setup_all( IVAS_DEC_HANDLE hIvasDec, uint8_t *nTransportChannels, const int16_t isSplitRend, ISAR_SPLIT_REND_BITS_DATA *splitRendBits );
+#endif
static ivas_error apa_setup( IVAS_DEC_HANDLE hIvasDec, const bool isInitialized_voip, const uint16_t nTransportChannels );
static PCM_RESOLUTION pcm_type_API_to_internal( const IVAS_DEC_PCM_TYPE pcmType );
static void *pcm_buffer_offset( void *buffer, const IVAS_DEC_PCM_TYPE pcmType, const int32_t offset );
@@ -128,6 +132,10 @@ static ivas_error ivas_dec_reconfig_split_rend( Decoder_Struct *st_ivas );
static ivas_error ivas_dec_init_split_rend( Decoder_Struct *st_ivas );
static void ivas_destroy_handle_isar( ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE *hSplitBinRend_out );
static int16_t get_render_frame_size_ms( IVAS_RENDER_FRAMESIZE render_framesize );
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+static int16_t get_render_frame_size_samples( const DECODER_CONFIG_HANDLE hDecoderConfig );
+static int16_t ivas_dec_split_rend_cldfb_in( const RENDERER_TYPE renderer_type );
+#endif
static void update_voip_rendered20ms( IVAS_DEC_HANDLE hIvasDec, const int16_t nSamplesRendered );
/*---------------------------------------------------------------------*
@@ -646,6 +654,23 @@ ivas_error IVAS_DEC_GetRenderFramesize(
return IVAS_ERR_OK;
}
+
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+/*---------------------------------------------------------------------*
+ * get_render_frame_size_samples( )
+ *
+ *
+ *---------------------------------------------------------------------*/
+
+static int16_t get_render_frame_size_samples(
+ const DECODER_CONFIG_HANDLE hDecoderConfig /* i : configuration structure */
+)
+{
+ return (int16_t) ( hDecoderConfig->output_Fs * hDecoderConfig->render_framesize / ( FRAMES_PER_SEC * IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ) );
+}
+#endif
+
+
/*---------------------------------------------------------------------*
* IVAS_DEC_GetGetRenderFramesizeSamples( )
*
@@ -662,7 +687,11 @@ ivas_error IVAS_DEC_GetRenderFramesizeSamples(
return IVAS_ERR_UNEXPECTED_NULL_POINTER;
}
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ *render_framesize = get_render_frame_size_samples( hIvasDec->st_ivas->hDecoderConfig );
+#else
*render_framesize = (int16_t) ( hIvasDec->st_ivas->hDecoderConfig->output_Fs * hIvasDec->st_ivas->hDecoderConfig->render_framesize / ( FRAMES_PER_SEC * IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ) );
+#endif
return IVAS_ERR_OK;
}
@@ -1127,8 +1156,10 @@ ivas_error IVAS_DEC_ReadFormat(
*---------------------------------------------------------------------*/
ivas_error IVAS_DEC_GetSamplesDecoder(
- IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */
- const int16_t isSplitRend, /* i : split rendering enabled flag */
+ IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */
+#ifndef FIX_1119_SPLIT_RENDERING_VOIP
+ const int16_t isSplitRend, /* i : split rendering enabled flag */
+#endif
ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */
)
{
@@ -1162,7 +1193,11 @@ ivas_error IVAS_DEC_GetSamplesDecoder(
* Setup all decoder parts (IVAS decoder, ISAR)
*-----------------------------------------------------------------*/
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ if ( ( error = ivas_dec_setup_all( hIvasDec, &nTransportChannels, splitRendBits ) ) != IVAS_ERR_OK )
+#else
if ( ( error = ivas_dec_setup_all( hIvasDec, &nTransportChannels, isSplitRend, splitRendBits ) ) != IVAS_ERR_OK )
+#endif
{
return error;
}
@@ -1733,6 +1768,199 @@ ivas_error IVAS_DEC_PrepareRenderer(
}
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+/*---------------------------------------------------------------------*
+ * isar_get_frame_size( )
+ *
+ *
+ *---------------------------------------------------------------------*/
+
+static int16_t isar_get_frame_size(
+ Decoder_Struct *st_ivas /* i : IVAS decoder handle */
+)
+{
+ int32_t output_Fs;
+ int16_t nSamplesPerChannel;
+
+ output_Fs = st_ivas->hDecoderConfig->output_Fs;
+
+ if ( st_ivas->hDecoderConfig->render_framesize != IVAS_RENDER_FRAMESIZE_20MS &&
+ ( st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ||
+ st_ivas->hRenderConfig->split_rend_config.dof == 0 ) )
+ {
+ nSamplesPerChannel = (int16_t) ( output_Fs / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES );
+ nSamplesPerChannel *= (int16_t) st_ivas->hDecoderConfig->render_framesize;
+ }
+ else
+ {
+ nSamplesPerChannel = (int16_t) ( output_Fs / FRAMES_PER_SEC );
+ }
+
+ return nSamplesPerChannel;
+}
+
+
+/*---------------------------------------------------------------------*
+ * isar_render_poses( )
+ *
+ *
+ *---------------------------------------------------------------------*/
+
+static ivas_error isar_render_poses(
+ IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */
+ const int16_t nSamplesAsked, /* i : number of samples wanted by the caller */
+ int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */
+ bool *needNewFrame /* o : indication that the decoder needs a new frame */
+)
+{
+ float pcmBuf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES * L_FRAME48k];
+ Decoder_Struct *st_ivas;
+ ivas_error error;
+ int16_t numPoses;
+
+ if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL )
+ {
+ return IVAS_ERR_UNEXPECTED_NULL_POINTER;
+ }
+
+ *needNewFrame = false;
+
+ st_ivas = hIvasDec->st_ivas;
+
+ numPoses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses;
+
+ /* init flush buffer for rate switch if not already initizalized */
+ if ( hIvasDec->flushbuffer == NULL )
+ {
+ hIvasDec->flushbuffer = (void *) malloc( numPoses * BINAURAL_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( float ) );
+ if ( hIvasDec->flushbuffer == NULL )
+ {
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate flush buffer" );
+ }
+ hIvasDec->pcmType = IVAS_DEC_PCM_FLOAT;
+ set_zero( (float *) hIvasDec->flushbuffer, numPoses * BINAURAL_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES );
+ }
+
+ /* render */
+ if ( ( error = IVAS_DEC_GetSamplesRenderer( hIvasDec, nSamplesAsked, IVAS_DEC_PCM_FLOAT, pcmBuf, nOutSamples, needNewFrame ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ if ( !hIvasDec->hasBeenFedFirstGoodFrame )
+ {
+ return IVAS_ERR_OK;
+ }
+
+ if ( !ivas_dec_split_rend_cldfb_in( st_ivas->renderer_type ) )
+ {
+ ivas_TD_RINGBUF_PushInterleaved( st_ivas->hSplitBinRend->hMultiBinTdData, pcmBuf, *nOutSamples );
+ }
+
+ return error;
+}
+
+
+/*---------------------------------------------------------------------*
+ * isar_generate_metadata_and_bitstream( )
+ *
+ *
+ *---------------------------------------------------------------------*/
+
+static ivas_error isar_generate_metadata_and_bitstream(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
+ float **p_head_pose_buf, /* i/o: PCM buffer with head-pose data */
+ int16_t nSamples, /* i : duration of audio (in samples per channel) for which metadata should be generated */
+ ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */
+)
+{
+ ivas_error error;
+ ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend;
+ int16_t max_band;
+ int16_t pcm_out_flag;
+ int16_t cldfb_in_flag;
+ int16_t ro_md_flag;
+ IVAS_QUATERNION Quaternion;
+ int16_t i, j, num_poses, num_cldfb_slots, n_samples_in_cldfb_slot;
+ float *p_Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX];
+ float *p_Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX];
+
+ hSplitBinRend = st_ivas->hSplitBinRend;
+
+ max_band = (int16_t) ( ( BINAURAL_MAXBANDS * st_ivas->hDecoderConfig->output_Fs ) / 48000 );
+ pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0;
+ cldfb_in_flag = ivas_dec_split_rend_cldfb_in( st_ivas->renderer_type );
+
+ if ( cldfb_in_flag )
+ {
+ n_samples_in_cldfb_slot = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS );
+ assert( nSamples % n_samples_in_cldfb_slot == 0 );
+ num_cldfb_slots = nSamples / n_samples_in_cldfb_slot;
+
+ num_poses = hSplitBinRend->splitrend.multiBinPoseData.num_poses;
+
+ for ( i = 0; i < BINAURAL_CHANNELS * num_poses; ++i )
+ {
+ for ( j = 0; j < num_cldfb_slots; ++j )
+ {
+ /* Save pointers to first CLDFB column in the ring buffer. Allows us to save
+ * significant amounts of memory by not copying CLDFB values into a separate buffer. */
+ ivas_CLDFB_RINGBUF_GetByIdx( hSplitBinRend->hMultiBinCldfbData[i], &p_Cldfb_RealBuffer_Binaural[i][j], &p_Cldfb_ImagBuffer_Binaural[i][j], 0 );
+
+ /* Pop the CLDFB column we just saved pointers to. This is fine as long as we use
+ * the saved columns only before any new columns are pushed to the buffer - the new
+ * columns could potentially overwrite the old columns we wanted to use.
+ * This requirement is fulfilled in this case. */
+ ivas_CLDFB_RINGBUF_Pop( hSplitBinRend->hMultiBinCldfbData[i], NULL, NULL, CLDFB_NO_CHANNELS_MAX );
+ }
+ }
+ }
+ else
+ {
+ ivas_TD_RINGBUF_PopChannels( st_ivas->hSplitBinRend->hMultiBinTdData, p_head_pose_buf, nSamples );
+ }
+
+
+ if ( st_ivas->hBinRendererTd != NULL )
+ {
+ ro_md_flag = 1;
+ }
+ else
+ {
+ ro_md_flag = 0;
+ }
+
+ if ( st_ivas->hHeadTrackData != NULL )
+ {
+ Quaternion = st_ivas->hHeadTrackData->Quaternions[0];
+ }
+ else
+ {
+ Quaternion.w = -3.0f;
+ Quaternion.x = 0.0f;
+ Quaternion.y = 0.0f;
+ Quaternion.z = 0.0f;
+ }
+
+ if ( ( error = ISAR_PRE_REND_MultiBinToSplitBinaural( &hSplitBinRend->splitrend,
+ Quaternion,
+ st_ivas->hRenderConfig->split_rend_config.splitRendBitRate,
+ st_ivas->hRenderConfig->split_rend_config.codec,
+ st_ivas->hRenderConfig->split_rend_config.isar_frame_size_ms,
+ st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms,
+ splitRendBits,
+ p_Cldfb_RealBuffer_Binaural,
+ p_Cldfb_ImagBuffer_Binaural,
+ max_band, p_head_pose_buf, 1, cldfb_in_flag, pcm_out_flag, ro_md_flag ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ return IVAS_ERR_OK;
+}
+#endif /* FIX_1119_SPLIT_RENDERING_VOIP */
+
+
/*---------------------------------------------------------------------*
* IVAS_DEC_GetSamplesRenderer( )
*
@@ -1879,6 +2107,70 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream(
bool *needNewFrame /* o : indication that the decoder needs a new frame */
)
{
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ Decoder_Struct *st_ivas;
+ ivas_error error;
+ float head_pose_buf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES][L_FRAME48k];
+ float *p_head_pose_buf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES];
+ int16_t i;
+ int16_t pcm_out_flag;
+ int16_t numSamplesPerChannelToOutput;
+
+ if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL )
+ {
+ return IVAS_ERR_UNEXPECTED_NULL_POINTER;
+ }
+
+ st_ivas = hIvasDec->st_ivas;
+
+ if ( is_split_rendering_enabled( st_ivas->hDecoderConfig, st_ivas->hRenderConfig ) == 0 )
+ {
+ return IVAS_ERR_WRONG_PARAMS;
+ }
+
+ pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0;
+ numSamplesPerChannelToOutput = isar_get_frame_size( st_ivas );
+
+ if ( ( error = isar_render_poses( hIvasDec, numSamplesPerChannelToOutput, nOutSamples, needNewFrame ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ if ( !hIvasDec->hasBeenFedFirstGoodFrame )
+ {
+ return IVAS_ERR_OK;
+ }
+
+ for ( i = 0; i < BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES; ++i )
+ {
+ p_head_pose_buf[i] = head_pose_buf[i];
+ }
+
+ if ( ( error = isar_generate_metadata_and_bitstream( st_ivas, p_head_pose_buf, *nOutSamples, splitRendBits ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ /* convert to int16 with limiting for BINAURAL_SPLIT_PCM */
+ if ( pcm_out_flag )
+ {
+ if ( st_ivas->hDecoderConfig->render_framesize == IVAS_RENDER_FRAMESIZE_5MS )
+ {
+#ifndef DISABLE_LIMITER
+ ivas_limiter_dec( st_ivas->hLimiter, p_head_pose_buf, st_ivas->hDecoderConfig->nchan_out, numSamplesPerChannelToOutput, st_ivas->BER_detect );
+#endif
+ }
+ else
+ {
+ ivas_limiter_dec( st_ivas->hLimiter, p_head_pose_buf, st_ivas->hDecoderConfig->nchan_out, numSamplesPerChannelToOutput, st_ivas->BER_detect );
+ }
+
+#ifdef DEBUGGING
+ st_ivas->noClipping +=
+#endif
+ ivas_syn_output( p_head_pose_buf, numSamplesPerChannelToOutput, st_ivas->hDecoderConfig->nchan_out, (int16_t *) pcmBuf_out );
+ }
+#else
Decoder_Struct *st_ivas;
AUDIO_CONFIG output_config;
int32_t output_Fs;
@@ -2065,7 +2357,9 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream(
#ifndef TMP_FIX_SPLIT_REND
free( st_ivas->hSplitBinRend->hMultiBinCldfbData );
#endif
- return error;
+#endif
+
+ return IVAS_ERR_OK;
}
@@ -2076,9 +2370,11 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream(
*---------------------------------------------------------------------*/
static ivas_error ivas_dec_setup_all(
- IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */
- uint8_t *nTransportChannels, /* o : number of decoded transport PCM channels */
- const int16_t isSplitRend, /* i : split rendering enabled flag */
+ IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */
+ uint8_t *nTransportChannels, /* o : number of decoded transport PCM channels */
+#ifndef FIX_1119_SPLIT_RENDERING_VOIP
+ const int16_t isSplitRend, /* i : split rendering enabled flag */
+#endif
ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */
)
{
@@ -2102,7 +2398,11 @@ static ivas_error ivas_dec_setup_all(
st_ivas = hIvasDec->st_ivas;
/* Setup IVAS split rendering */
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ if ( splitRendBits != NULL )
+#else
if ( isSplitRend )
+#endif
{
if ( ( error = isar_set_split_rend_setup( st_ivas->hSplitBinRend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hCombinedOrientationData, splitRendBits ) ) != IVAS_ERR_OK )
{
@@ -2134,7 +2434,11 @@ static ivas_error ivas_dec_setup_all(
* - reconfigure the ISAR handle in case of bitrate switching (renderer might change)
*-----------------------------------------------------------------*/
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ if ( st_ivas->ini_frame == 0 && splitRendBits != NULL )
+#else
if ( st_ivas->ini_frame == 0 && isSplitRend )
+#endif
{
if ( ( error = ivas_dec_init_split_rend( st_ivas ) ) != IVAS_ERR_OK )
{
@@ -3446,26 +3750,44 @@ ivas_error IVAS_DEC_TSM_SetQuality(
#endif
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+
+/*---------------------------------------------------------------------*
+ * ivas_dec_voip_get_samples_common( )
+ *
+ * Main function to output one frame in VoIP. Holds common code for
+ * regular output configs and split rendering configs.
+ *---------------------------------------------------------------------*/
+
+static ivas_error ivas_dec_voip_get_samples_common
+
+#else
/*---------------------------------------------------------------------*
* IVAS_DEC_VoIP_GetSamples( )
*
* Main function to decode one frame in VoIP
*---------------------------------------------------------------------*/
-ivas_error IVAS_DEC_VoIP_GetSamples(
- IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */
- uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */
- const IVAS_DEC_PCM_TYPE pcmType,
- void *pcmBuf,
+ivas_error IVAS_DEC_VoIP_GetSamples
+#endif
+ (
+ IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */
+ uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */
+ const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */
+ void *pcmBuf, /* o : output synthesis signal */
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ ISAR_SPLIT_REND_BITS_DATA *splitRendBits, /* o : output split rendering bits */
+ float **p_head_pose_buf, /* i : PCM buffer with head-pose data */
+#endif
#ifdef SUPPORT_JBM_TRACEFILE
- JbmTraceFileWriterFn jbmWriterFn,
- void *jbmWriter,
+ JbmTraceFileWriterFn jbmWriterFn,
+ void *jbmWriter,
#endif
- bool *bitstreamReadDone, /* o : flag indicating that bitstream was read */
- uint16_t *nSamplesRendered, /* o : number of samples rendered */
- bool *parametersAvailableForEditing,
- const uint32_t systemTimestamp_ms /* i : current system timestamp */
-)
+ bool *bitstreamReadDone, /* o : flag indicating that bitstream was read */
+ uint16_t *nSamplesRendered, /* o : number of samples rendered */
+ bool *parametersAvailableForEditing,
+ const uint32_t systemTimestamp_ms /* i : current system timestamp */
+ )
{
Decoder_Struct *st_ivas;
DECODER_CONFIG_HANDLE hDecoderConfig;
@@ -3493,12 +3815,20 @@ ivas_error IVAS_DEC_VoIP_GetSamples(
return IVAS_ERR_WRONG_PARAMS;
}
-#ifdef TMP_FIX_1119_SPLIT_RENDERING_VOIP
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ if ( ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ||
+ hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) &&
+ splitRendBits == NULL )
+ {
+ return IVAS_ERR_UNEXPECTED_NULL_POINTER;
+ }
+#else
if ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ||
hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED )
{
return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Split rendering is not integrated with VoIP mode" );
}
+
#endif
/* make sure that the FIFO after decoder/scaler contains at least one sound card frame (i.e. 20ms) */
@@ -3646,7 +3976,11 @@ ivas_error IVAS_DEC_VoIP_GetSamples(
{
if ( hIvasDec->nSamplesAvailableNext == 0 || hIvasDec->nSamplesAvailableNext == hIvasDec->nSamplesFrame )
{
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ if ( ( error = IVAS_DEC_GetSamplesDecoder( hIvasDec, splitRendBits ) ) != IVAS_ERR_OK )
+#else
if ( ( error = IVAS_DEC_GetSamplesDecoder( hIvasDec, 0, 0 ) ) != IVAS_ERR_OK )
+#endif
{
return error;
}
@@ -3668,20 +4002,165 @@ ivas_error IVAS_DEC_VoIP_GetSamples(
}
}
- /* render IVAS frames directly to the output buffer */
- if ( ( error = IVAS_DEC_GetSamplesRenderer( hIvasDec, nSamplesToRender, pcmType, pcm_buffer_offset( pcmBuf, pcmType, *nSamplesRendered * nOutChannels ), &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK )
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ if ( splitRendBits != NULL )
{
- return error;
+ /* Render head poses from time-scaled transport channels */
+ if ( ( error = isar_render_poses( hIvasDec, nSamplesToRender, &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ else
+ {
+#endif
+ /* render IVAS frames directly to the output buffer */
+ if ( ( error = IVAS_DEC_GetSamplesRenderer( hIvasDec, nSamplesToRender, pcmType, pcm_buffer_offset( pcmBuf, pcmType, *nSamplesRendered * nOutChannels ), &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
}
+#endif
*nSamplesRendered += nSamplesRendered_loop;
update_voip_rendered20ms( hIvasDec, nSamplesRendered_loop );
}
}
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ if ( hIvasDec->hasDecodedFirstGoodFrame && splitRendBits != NULL )
+ {
+ /* Analyse head poses over entire frame, generate ISAR metadata and maybe encode if split coded */
+ if ( ( error = isar_generate_metadata_and_bitstream( st_ivas, p_head_pose_buf, *nSamplesRendered, splitRendBits ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ /* Synthesise PCM output if split PCM */
+ if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+ {
+ if ( st_ivas->hDecoderConfig->render_framesize == IVAS_RENDER_FRAMESIZE_5MS )
+ {
+#ifndef DISABLE_LIMITER
+ ivas_limiter_dec( st_ivas->hLimiter, p_head_pose_buf, st_ivas->hDecoderConfig->nchan_out, *nSamplesRendered, st_ivas->BER_detect );
+#endif
+ }
+ else
+ {
+ ivas_limiter_dec( st_ivas->hLimiter, p_head_pose_buf, st_ivas->hDecoderConfig->nchan_out, *nSamplesRendered, st_ivas->BER_detect );
+ }
+
+#ifdef DEBUGGING
+ st_ivas->noClipping +=
+#endif
+ ivas_syn_output( p_head_pose_buf, *nSamplesRendered, st_ivas->hDecoderConfig->nchan_out, (int16_t *) pcmBuf );
+ }
+ }
+#endif
+
return IVAS_ERR_OK;
}
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+
+/*---------------------------------------------------------------------*
+ * IVAS_DEC_VoIP_GetSamples( )
+ *
+ * Main function to decode one frame in VoIP
+ *---------------------------------------------------------------------*/
+
+ivas_error IVAS_DEC_VoIP_GetSamples(
+ IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */
+ uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */
+ const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */
+ void *pcmBuf, /* o : output synthesis signal */
+#ifdef SUPPORT_JBM_TRACEFILE
+ JbmTraceFileWriterFn jbmWriterFn,
+ void *jbmWriter,
+#endif
+ bool *bitstreamReadDone, /* o : flag indicating that bitstream was read */
+ uint16_t *nSamplesRendered, /* o : number of samples rendered */
+ bool *parametersAvailableForEditing, /* o : indicates whether objects editing is available */
+ const uint32_t systemTimestamp_ms /* i : current system timestamp */
+)
+{
+ return ivas_dec_voip_get_samples_common(
+ hIvasDec,
+ nSamplesPerChannel,
+ pcmType,
+ pcmBuf,
+ NULL,
+ NULL,
+#ifdef SUPPORT_JBM_TRACEFILE
+ jbmWriterFn,
+ jbmWriter,
+#endif
+ bitstreamReadDone,
+ nSamplesRendered,
+ parametersAvailableForEditing,
+ systemTimestamp_ms );
+}
+
+
+/*---------------------------------------------------------------------*
+ * IVAS_DEC_VoIP_GetSplitBinauralBitstream( )
+ *
+ * Main function to decode one split-rendering frame in VoIP
+ *---------------------------------------------------------------------*/
+
+/*! r: error code */
+ivas_error IVAS_DEC_VoIP_GetSplitBinauralBitstream(
+ IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */
+ /* const IVAS_DEC_PCM_TYPE pcmType, */ /* i : type for the decoded PCM resolution */
+ void *pcmBuf, /* o : output synthesis signal */
+ ISAR_SPLIT_REND_BITS_DATA *splitRendBits, /* o : output split rendering bits */
+#ifdef SUPPORT_JBM_TRACEFILE
+ JbmTraceFileWriterFn jbmWriterFn,
+ void *jbmWriter,
+#endif
+ bool *bitstreamReadDone, /* o : flag indicating that bitstream was read */
+ uint16_t *nSamplesRendered, /* o : number of samples rendered */
+ bool *parametersAvailableForEditing, /* o : indicates whether objects editing is available */
+ const uint32_t systemTimestamp_ms /* i : current system timestamp */
+)
+{
+ int16_t i;
+ float head_pose_buf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES][L_FRAME48k];
+ float *pp_head_pose_buf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES];
+ ivas_error error = IVAS_ERR_UNKNOWN;
+ int16_t nSamplesPerChannel = 0;
+
+ if ( ( error = IVAS_DEC_GetRenderFramesizeSamples( hIvasDec, &nSamplesPerChannel ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ /* Set pointers to beginning of head pose buffers */
+ for ( i = 0; i < BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES; ++i )
+ {
+ pp_head_pose_buf[i] = head_pose_buf[i];
+ }
+
+ return ivas_dec_voip_get_samples_common(
+ hIvasDec,
+ nSamplesPerChannel,
+ IVAS_DEC_PCM_INT16,
+ pcmBuf,
+ splitRendBits,
+ pp_head_pose_buf,
+#ifdef SUPPORT_JBM_TRACEFILE
+ jbmWriterFn,
+ jbmWriter,
+#endif
+ bitstreamReadDone,
+ nSamplesRendered,
+ parametersAvailableForEditing,
+ systemTimestamp_ms );
+}
+#endif
+
+
/*---------------------------------------------------------------------*
* update_voip_rendered20ms( )
*
@@ -3732,6 +4211,10 @@ ivas_error IVAS_DEC_Flush(
return IVAS_ERR_UNEXPECTED_NULL_POINTER;
}
+#ifdef TMP_1342_WORKAROUND_DEC_FLUSH_BROKEN_IN_SR
+ hIvasDec->st_ivas->flushing = 1;
+#endif
+
*nSamplesFlushed = min( nSamplesPerChannel, hIvasDec->nSamplesAvailableNext );
nSamplesToRender = (uint16_t) *nSamplesFlushed;
@@ -3747,6 +4230,10 @@ ivas_error IVAS_DEC_Flush(
*nSamplesFlushed = 0;
}
+#ifdef TMP_1342_WORKAROUND_DEC_FLUSH_BROKEN_IN_SR
+ hIvasDec->st_ivas->flushing = 0;
+#endif
+
return error;
}
@@ -4775,6 +5262,9 @@ static ivas_error ivas_create_handle_isar(
)
{
ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend;
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ int16_t i;
+#endif
if ( ( hSplitBinRend = (ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_WRAPPER ) ) ) == NULL )
{
@@ -4783,7 +5273,15 @@ static ivas_error ivas_create_handle_isar(
isar_init_split_rend_handles( &hSplitBinRend->splitrend );
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ hSplitBinRend->hMultiBinTdData = NULL;
+ for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i )
+ {
+ hSplitBinRend->hMultiBinCldfbData[i] = NULL;
+ }
+#else
hSplitBinRend->hMultiBinCldfbData = NULL;
+#endif
hSplitBinRend->hCldfbDataOut = NULL;
hSplitBinRend->numTdSamplesPerChannelCached = 0;
@@ -4803,13 +5301,31 @@ static void ivas_destroy_handle_isar(
ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE *hSplitBinRend /* i/o: ISAR split binaural rendering handle */
)
{
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ int16_t i;
+#endif
+
if ( *hSplitBinRend != NULL )
{
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ if ( ( *hSplitBinRend )->hMultiBinTdData != NULL )
+ {
+ ivas_TD_RINGBUF_Close( &( *hSplitBinRend )->hMultiBinTdData );
+ }
+ for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i )
+ {
+ if ( ( *hSplitBinRend )->hMultiBinCldfbData[i] != NULL )
+ {
+ ivas_CLDFB_RINGBUF_Close( &( *hSplitBinRend )->hMultiBinCldfbData[i] );
+ }
+ }
+#else
#ifdef TMP_FIX_SPLIT_REND
free( ( *hSplitBinRend )->hMultiBinCldfbData );
( *hSplitBinRend )->hMultiBinCldfbData = NULL;
-
#endif
+#endif
+
ISAR_PRE_REND_close( &( *hSplitBinRend )->splitrend, NULL );
if ( ( *hSplitBinRend )->hCldfbDataOut != NULL )
@@ -4982,6 +5498,32 @@ static ivas_error ivas_dec_reconfig_split_rend(
}
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+/*-------------------------------------------------------------------*
+ * ivas_dec_split_rend_cldfb_in()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+static int16_t ivas_dec_split_rend_cldfb_in(
+ const RENDERER_TYPE renderer_type /* i : renderer type */
+)
+{
+ if ( renderer_type == RENDERER_BINAURAL_FASTCONV ||
+ renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ||
+ renderer_type == RENDERER_BINAURAL_PARAMETRIC ||
+ renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM )
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+#endif
+
+
/*-------------------------------------------------------------------*
* ivas_dec_init_split_rend()
*
@@ -4995,10 +5537,16 @@ static ivas_error ivas_dec_init_split_rend(
ivas_error error;
int16_t cldfb_in_flag, pcm_out_flag;
int16_t mixed_td_cldfb_flag;
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ int16_t i, num_poses;
+#endif
pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0;
cldfb_in_flag = 0;
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ cldfb_in_flag = ivas_dec_split_rend_cldfb_in( st_ivas->renderer_type );
+#else
if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ||
st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ||
st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC ||
@@ -5006,7 +5554,33 @@ static ivas_error ivas_dec_init_split_rend(
{
cldfb_in_flag = 1;
}
+#endif
+
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ ISAR_PRE_REND_GetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->sr_pose_pred_axis : DEFAULT_AXIS );
+ num_poses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses;
+ assert( num_poses <= MAX_HEAD_ROT_POSES );
+
+ if ( cldfb_in_flag )
+ {
+ for ( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i )
+ {
+ /* note: this is intra-frame heap memory */
+ if ( ( error = ivas_CLDFB_RINGBUF_Open( &st_ivas->hSplitBinRend->hMultiBinCldfbData[i], CLDFB_NO_COL_MAX ) ) != IVAS_ERR_OK )
+ {
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for split rendering structure" );
+ }
+ }
+ }
+ else
+ {
+ if ( ( error = ivas_TD_RINGBUF_Open( &st_ivas->hSplitBinRend->hMultiBinTdData, get_render_frame_size_samples( st_ivas->hDecoderConfig ), num_poses * BINAURAL_CHANNELS ) ) != IVAS_ERR_OK )
+ {
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for split rendering structure" );
+ }
+ }
+#else
#ifdef TMP_FIX_SPLIT_REND
/* note: this is intra-frame heap memory */
if ( ( st_ivas->hSplitBinRend->hMultiBinCldfbData = (ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA ) ) ) == NULL )
@@ -5016,6 +5590,7 @@ static ivas_error ivas_dec_init_split_rend(
#endif
ISAR_PRE_REND_GetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->sr_pose_pred_axis : DEFAULT_AXIS );
+#endif
if ( cldfb_in_flag == 1 && ( st_ivas->hSplitBinRend->splitrend.multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) )
{
diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h
index 677405b52d19ca9588400d76cf0a59ad4ef7c606..8bc3a1fe1b28686fb1c4564c995ad6659fdf9cc1 100644
--- a/lib_dec/lib_dec.h
+++ b/lib_dec/lib_dec.h
@@ -160,7 +160,9 @@ ivas_error IVAS_DEC_ReadFormat(
ivas_error IVAS_DEC_GetSamplesDecoder(
IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */
+#ifndef FIX_1119_SPLIT_RENDERING_VOIP
const int16_t isSplitRend, /* i : split rendering enabled flag */
+#endif
ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */
);
@@ -317,6 +319,24 @@ ivas_error IVAS_DEC_VoIP_GetSamples(
const uint32_t systemTimestamp_ms /* i : current system timestamp */
);
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+/*! r: error code */
+ivas_error IVAS_DEC_VoIP_GetSplitBinauralBitstream(
+ IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */
+ /* const IVAS_DEC_PCM_TYPE pcmType, */ /* i : type for the decoded PCM resolution */
+ void *pcmBuf, /* o : output synthesis signal */
+ ISAR_SPLIT_REND_BITS_DATA *splitRendBits, /* o : output split rendering bits */
+#ifdef SUPPORT_JBM_TRACEFILE
+ JbmTraceFileWriterFn jbmWriterFn,
+ void* jbmWriter,
+#endif
+ bool *bitstreamReadDone, /* o : flag indicating that bitstream was read */
+ uint16_t *nSamplesRendered, /* o : number of samples rendered */
+ bool *parametersAvailableForEditing, /* o : indicates whether objects editing is available */
+ const uint32_t systemTimestamp_ms /* i : current system timestamp */
+);
+#endif
+
ivas_error IVAS_DEC_Flush(
IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */
const int16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */
diff --git a/lib_isar/isar_prot.h b/lib_isar/isar_prot.h
index 85a99aa9036fece27de1acd48b5c387b3f6406f3..a81c5d34826e51e0e9f880d6ef0fa657c4be6cec 100644
--- a/lib_isar/isar_prot.h
+++ b/lib_isar/isar_prot.h
@@ -33,18 +33,21 @@
#ifndef ISAR_PROT_H
#define ISAR_PROT_H
-
#include "isar_stat.h"
-
-
#include
#include "options.h"
#include "ivas_error.h"
#include "lib_isar_post_rend.h"
+
+/* clang-format off */
+/*----------------------------------------------------------------------------------*
+ * General ISAR prototypes
+ *----------------------------------------------------------------------------------*/
+
ivas_error isar_splitBinPreRendOpen(
- ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend,
- MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData
+ ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend, /* i/o: binaural pre-renderer handle */
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData /* i/o: pose correction data handle */
#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
,
const int32_t output_Fs
@@ -52,58 +55,75 @@ ivas_error isar_splitBinPreRendOpen(
);
ivas_error split_renderer_open_lc3plus(
- SPLIT_REND_WRAPPER *hSplitRendWrapper,
- const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig,
- const int32_t OutSampleRate,
- const IVAS_RENDER_FRAMESIZE ivas_frame_size );
+ SPLIT_REND_WRAPPER *hSplitRendWrapper, /* i/o: Split renderer pre-renderer handle */
+ const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, /* i : Split renderer pre-renderer config */
+ const int32_t output_Fs, /* i : output sampling rate */
+ const IVAS_RENDER_FRAMESIZE ivas_frame_size /* i : IVAS frame size */
+);
void isar_splitBinPreRendClose(
- ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend );
+ ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend /* i/o: binaural pre-renderer handle */
+);
void lc3plusTimeAlignCldfbPoseCorr(
- SPLIT_REND_WRAPPER *hSplitBin,
- float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
- float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] );
+ SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renderer handle */
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ float *Cldfb_In_BinReal[][CLDFB_NO_COL_MAX], /* i/o: Binaural signals, real part */
+ float *Cldfb_In_BinImag[][CLDFB_NO_COL_MAX] /* i/o: Binaural signals, imag. part */
+#else
+ float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: Binaural signals, real part */
+ float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] /* i/o: Binaural signals, imag. part */
+#endif
+);
ivas_error splitRendLc3plusEncodeAndWrite(
- SPLIT_REND_WRAPPER *hSplitBin,
- ISAR_SPLIT_REND_BITS_HANDLE pBits,
- const int32_t available_bits,
- float *in[] );
+ SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renderer handle */
+ ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */
+ const int32_t available_bits, /* i : available bit-budget */
+ float *in[] /* i/o: PCM in/out buffer */
+);
+/*! r: parameter value */
int32_t ISAR_SPLIT_REND_BITStream_read_int32(
- ISAR_SPLIT_REND_BITS_HANDLE pBits,
- const int32_t bits );
+ ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */
+ const int32_t bits /* i : number of bits to be read */
+);
void ISAR_SPLIT_REND_BITStream_write_int32(
- ISAR_SPLIT_REND_BITS_HANDLE pBits,
- const int32_t val,
- const int32_t bits );
+ ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */
+ const int32_t val, /* i : parameter value */
+ const int32_t bits /* i : number of bits to be written */
+);
ivas_error isar_splitBinLCLDEncOpen(
- ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc,
+ ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc, /* o : ISAR LCLD encoder handle */
const int32_t iSampleRate,
const int16_t iChannels,
const int32_t iDataRate,
const int16_t iNumBlocks,
- const int16_t iNumIterations );
+ const int16_t iNumIterations
+);
ivas_error isar_splitBinRendPLCOpen(
- ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC,
- const int16_t iNumSubSets );
+ ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC, /* i/o: ISAR PLC handle */
+ const int16_t iNumSubSets
+);
void isar_splitBinRendPLCClose(
- ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC );
+ ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC /* i/o: ISAR PLC handle */
+);
ivas_error isar_splitBinLCLDDecOpen(
- ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec,
+ ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec, /* i/o: ISAR LCLD decoder handle */
const int32_t iSampleRate,
const int16_t iChannels,
const int16_t iNumBlocks,
- const int16_t iNumIterations );
+ const int16_t iNumIterations
+);
void isar_splitBinLCLDDecClose(
- ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec );
+ ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec /* o : ISAR LCLD decoder handle */
+);
void isar_splitBinRendPLCsaveState(
ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC,
@@ -111,7 +131,8 @@ void isar_splitBinRendPLCsaveState(
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 );
+ const int16_t iNumIterations
+);
void isar_splitBinRendPLC_xf(
ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC,
@@ -121,7 +142,8 @@ void isar_splitBinRendPLC_xf(
const int16_t iNumBlocks,
const int16_t iNumIterations,
int32_t **ppiDecodingFailed,
- int32_t **ppiDecodingFailedPrev );
+ int32_t **ppiDecodingFailedPrev
+);
void isar_splitBinRendPLC(
ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC,
@@ -130,7 +152,8 @@ void isar_splitBinRendPLC(
const int16_t num_chs,
const int16_t iNumBlocks,
const int16_t iNumIterations,
- int32_t **ppiDecodingFailed );
+ int32_t **ppiDecodingFailed
+);
#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
void isar_log_cldfb2wav_data(
@@ -142,51 +165,66 @@ void isar_log_cldfb2wav_data(
const int32_t output_Fs,
const int16_t start_slot_idx,
const int16_t md_band_idx,
- const char *filename );
-#endif
+ const char *filename
+);
+#endif
void isar_splitBinLCLDDecProcess(
- ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec,
- ISAR_SPLIT_REND_BITS_HANDLE pBits,
- float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
- float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
- const int16_t bfi );
+ ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec, /* i/o: ISAR LCLD decoder handle */
+ ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */
+ float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Binaural signals, real part */
+ float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Binaural signals, imag. part */
+ const int16_t bfi /* i : BFI flag */
+);
void set_fix_rotation_mat(
float fix_pos_rot_mat[][BINAURAL_CHANNELS][BINAURAL_CHANNELS],
- MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData );
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData /* i/o: pose correction data handle */
+);
void isar_splitBinLCLDEncClose(
- ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc );
+ ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc /* i/o: ISAR LCLD encoder handle */
+);
void isar_splitBinLCLDEncProcess(
- ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc,
+ ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc, /* i/o: ISAR LCLD encoder handle */
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ float *Cldfb_In_Real[][CLDFB_NO_COL_MAX], /* i/o: Binaural signals, real part */
+ float *Cldfb_In_Imag[][CLDFB_NO_COL_MAX], /* i/o: Binaural signals, imag. part */
+#else
float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
- const int32_t available_bits,
- ISAR_SPLIT_REND_BITS_HANDLE pBits );
+#endif
+ const int32_t available_bits, /* i : available bit-budget */
+ ISAR_SPLIT_REND_BITS_HANDLE pBits /* i/o: ISAR bits handle */
+);
void set_pose_types(
- ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1],
- MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData );
+ ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1],/* o : ISAR pose type */
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData /* i/o: pose correction data handle */
+);
void isar_split_rend_init_huff_cfg(
- ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg );
+ ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg
+);
ivas_error isar_splitBinPostRendOpen(
- ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend,
- MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
- const int32_t output_Fs );
+ ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend, /* i/o: binaural post-renderer handle */
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */
+ const int32_t output_Fs /* i : output sampling rate */
+);
void isar_splitBinPostRendClose(
- ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend );
+ ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend /* i/o: binaural post-renderer handle */
+);
void isar_SplitRenderer_getdiagdiff(
int16_t in_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
int16_t out_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
const int16_t sign,
const int16_t min_val,
- const int16_t max_val );
+ const int16_t max_val
+);
void isar_split_rend_get_quant_params(
const int16_t num_md_bands,
@@ -200,24 +238,24 @@ void isar_split_rend_get_quant_params(
int16_t pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
int16_t pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
const int16_t ro_flag,
- int16_t *num_quant_strats );
+ int16_t *num_quant_strats
+);
void isar_splitBinPostRendMdDec(
- ISAR_SPLIT_REND_BITS_HANDLE pBits,
- ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend,
+ ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */
+ ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, /* i/o: binaural post-renderer handle */
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData /* i/o: pose correction data handle */
#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
- MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
- BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend
-#else
- MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData
+ ,
+ BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend /* i/o: binaural pre-renderer handle */
#endif
);
void Quat2EulerDegree(
- const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */
- float *yaw, /* o : yaw */
- float *pitch, /* o : pitch */
- float *roll /* o : roll */
+ const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */
+ float *yaw, /* o : yaw */
+ float *pitch, /* o : pitch */
+ float *roll /* o : roll */
);
void isar_mat_mult_2by2_complex(
@@ -226,122 +264,141 @@ void isar_mat_mult_2by2_complex(
float in_re2[2][2],
float in_im2[2][2],
float out_re2[2][2],
- float out_im2[2][2] );
+ float out_im2[2][2]
+);
void isar_rend_CldfbSplitPostRendProcess(
- ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend,
- MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
+ ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, /* i/o: binaural post-renderer handle */
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */
const IVAS_QUATERNION QuaternionPost,
float Cldfb_RealBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
float Cldfb_ImagBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
float output[][L_FRAME48k],
- const int16_t cldfb_in_flag );
+ const int16_t cldfb_in_flag
+);
void isar_rend_CldfbSplitPreRendProcess(
- const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend,
- const IVAS_QUATERNION headPosition,
- MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
- float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
- float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
- ISAR_SPLIT_REND_BITS_HANDLE pBits,
- const int32_t target_md_bits,
- const int16_t low_res_pre_rend_rot,
- const int16_t ro_md_flag );
+ const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i : binaural pre-renderer handle */
+ const IVAS_QUATERNION headPosition, /* i : head rotation QUATERNION */
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ float* Cldfb_In_BinReal[][CLDFB_NO_COL_MAX], /* i : Binaural signals, real part */
+ float* Cldfb_In_BinImag[][CLDFB_NO_COL_MAX], /* i : Binaural signals, imag. part */
+#else
+ float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Binaural signals, real part */
+ float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Binaural signals, imag. part */
+#endif
+ ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */
+ const int32_t target_md_bits, /* i : ISAR MD bitrate */
+ const int16_t low_res_pre_rend_rot, /* i : low time resolution pre-renderer flag */
+ const int16_t ro_md_flag /* i : real only metadata for yaw flag */
+);
ivas_error isar_renderMultiTDBinToSplitBinaural(
- SPLIT_REND_WRAPPER *hSplitBin,
- const IVAS_QUATERNION headPosition,
- const int32_t SplitRendBitRate,
- const int16_t isar_frame_size_ms,
- const int16_t codec_frame_size_ms,
- ISAR_SPLIT_REND_BITS_HANDLE pBits,
- const int16_t max_bands,
- float *in[],
- const int16_t low_res_pre_rend_rot,
- const int16_t pcm_out_flag,
- const int16_t ro_md_flag );
+ SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renderer handle */
+ const IVAS_QUATERNION headPosition, /* i : head rotation QUATERNION */
+ const int32_t SplitRendBitRate, /* i : ISAR bitrate */
+ const int16_t isar_frame_size_ms, /* i : ISAR bit stream frame size in ms */
+ const int16_t codec_frame_size_ms, /* i : ISAR frame length in ms */
+ ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */
+ const int16_t max_bands, /* i : CLDFB bands */
+ float *in[], /* i/o: PCM in/out buffer */
+ const int16_t low_res_pre_rend_rot, /* i : low time resolution pre-renderer flag */
+ const int16_t pcm_out_flag, /* i : flag to indicate PCM output */
+ const int16_t ro_md_flag /* i : real only metadata for yaw flag */
+);
void isar_init_multi_bin_pose_data(
- MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData );
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData /* i/o: pose correction data handle */
+);
void isar_renderSplitGetMultiBinPoseData(
- const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config,
- MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
- const ISAR_SPLIT_REND_ROT_AXIS rot_axis );
+ const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, /* i : Split renderer pre-renderer config */
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */
+ const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i : external control for rotation axis for split rendering */
+);
int16_t isar_renderSplitGetRot_axisNumBits(
- const int16_t dof );
+ const int16_t dof
+);
ISAR_SPLIT_REND_ROT_AXIS isar_renderSplitGetRot_axisFromCode(
const int16_t dof,
- const int16_t code );
+ const int16_t code
+);
int16_t isar_renderSplitGetCodeFromRot_axis(
const int16_t dof,
const ISAR_SPLIT_REND_ROT_AXIS rot_axis,
- int16_t *num_bits );
+ int16_t *num_bits
+);
void isar_init_split_post_rend_handles(
- ISAR_SPLIT_POST_REND_WRAPPER *hSplitRendWrapper );
+ ISAR_SPLIT_POST_REND_WRAPPER *hSplitRendWrapper /* i/o: Split renderer post-renderer handle */
+);
void isar_set_split_rend_ht_setup(
- SPLIT_REND_WRAPPER *hSplitrend,
- IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES],
- float Rmat[MAX_PARAM_SPATIAL_SUBFRAMES][3][3] );
-
+ SPLIT_REND_WRAPPER *hSplitrend, /* i/o: Split renderer pre-renderer handle */
+ IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES], /* i/o: External orientation in quaternions */
+ float Rmat[MAX_PARAM_SPATIAL_SUBFRAMES][3][3] /* o : real-space rotation matrix */
+);
int32_t isar_get_lc3plus_bitrate(
- const int32_t SplitRendBitRate,
- const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode,
- const int32_t nChannels,
- const int32_t codecFrameDurationUs );
+ const int32_t SplitRendBitRate, /* i : ISAR bitrate */
+ const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, /* i : ISAR pose correction mode */
+ const int32_t nChannels, /* i : number of channels */
+ const int32_t lc3plus_frame_duration_us /* i : ISAR frame length in us */
+);
ivas_error isar_split_rend_validate_config(
- const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig,
- const int16_t pcm_out_flag );
+ const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, /* i : Split renderer pre-renderer config */
+ const int16_t pcm_out_flag /* i : flag to indicate PCM output */
+);
+/*! r: LCLD codec bitrate */
int32_t isar_get_lcld_bitrate(
- const int32_t SplitRendBitRate,
- const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode );
-
+ const int32_t SplitRendBitRate, /* i : ISAR bitrate */
+ const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode /* i : ISAR pose correction mode */
+);
+/*! r: ISAR MD bitrate */
int32_t isar_get_split_rend_md_target_brate(
- const int32_t SplitRendBitRate,
- const int16_t pcm_out_flag );
+ const int32_t SplitRendBitRate, /* i : ISAR bitrate */
+ const int16_t pcm_out_flag /* i : flag to indicate PCM output */
+);
ivas_error isar_framesize_to_ms(
- const IVAS_RENDER_FRAMESIZE frame_size, /* i : frame size enum */
- int16_t *ms /* o : frame size in ms */
+ const IVAS_RENDER_FRAMESIZE frame_size, /* i : frame size enum */
+ int16_t *ms /* o : frame size in ms */
);
ivas_error isar_split_rend_choose_default_codec(
- ISAR_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */
- int16_t *pIsar_frame_size_ms, /* i/o: pointer to isar frame size 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 num_subframes /* i : number of subframes */
+ ISAR_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */
+ int16_t *pIsar_frame_size_ms, /* i/o: pointer to ISAR frame size 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 num_subframes /* i : number of subframes */
);
-void ISAR_SPLIT_REND_BITStream_init(
- ISAR_SPLIT_REND_BITS_HANDLE pBits,
- const int32_t buf_len_bytes,
- uint8_t *pbuf );
-
void isar_renderSplitUpdateNoCorrectionPoseData(
- const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config,
- MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData );
+ const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, /* i : Split renderer pre-renderer config */
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData /* i/o: pose correction data handle */
+);
int32_t get_bit(
const int32_t state,
- const int32_t bit_id );
+ const int32_t bit_id
+);
+/*! r: ISAR audio type */
ISAR_POST_REND_AudioConfigType isar_getAudioConfigType(
- const IVAS_AUDIO_CONFIG config );
+ const IVAS_AUDIO_CONFIG config /* i : audio configuration */
+);
void isar_init_split_rend_handles(
- SPLIT_REND_WRAPPER *hSplitRendWrapper );
-
+ SPLIT_REND_WRAPPER *hSplitRendWrapper /* i/o: Split renderer pre-renderer handle */
+);
/* clang-format on */
diff --git a/lib_isar/isar_splitRend_lcld_enc.c b/lib_isar/isar_splitRend_lcld_enc.c
index 518c4226e658762e0f052a39c8486f33e3bf84f0..412e220adc701bfbbfca67b12459dd15595bdc43 100644
--- a/lib_isar/isar_splitRend_lcld_enc.c
+++ b/lib_isar/isar_splitRend_lcld_enc.c
@@ -157,10 +157,16 @@ void isar_splitBinLCLDEncClose(
void isar_splitBinLCLDEncProcess(
ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc,
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ float *Cldfb_In_Real[][CLDFB_NO_COL_MAX], /* i/o: Binaural signals, real part */
+ float *Cldfb_In_Imag[][CLDFB_NO_COL_MAX], /* i/o: Binaural signals, imag. part */
+#else
float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
- const int32_t available_bits,
- ISAR_SPLIT_REND_BITS_HANDLE pBits )
+#endif
+ const int32_t available_bits, /* i : available bit-budget */
+ ISAR_SPLIT_REND_BITS_HANDLE pBits /* i/o: ISAR bits handle */
+)
{
int32_t iBitsWritten, itr, available_bits_itr, rem_itr, available_bits_local;
push_wmops( "isar_splitBinLCLDEncProcess" );
diff --git a/lib_isar/isar_splitRendererPre.c b/lib_isar/isar_splitRendererPre.c
index 372c924ad091da283059d5618e3834f14ab739c9..734daae97719236aa4b692e5948eb65d5393e438 100644
--- a/lib_isar/isar_splitRendererPre.c
+++ b/lib_isar/isar_splitRendererPre.c
@@ -53,13 +53,16 @@
* Local function declarations
*---------------------------------------------------------------------*/
-static void isar_SplitRenderer_GetRotMd(
- ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i/o: binaural renderer handle */
- MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
- float Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */
- float Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */
- const int16_t low_res,
- const int16_t ro_md_flag );
+static void isar_SplitRenderer_GetRotMd( ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ float *Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX],
+ float *Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX],
+#else
+ float Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+ float Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+#endif
+ const int16_t low_res,
+ const int16_t ro_md_flag );
/*-------------------------------------------------------------------------
* Local functions
@@ -276,11 +279,21 @@ static void ComputePostPredCov(
static void ComputeBandedCrossCov(
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ float *Cldfb_RealBuffer1[][CLDFB_NO_COL_MAX],
+ float *Cldfb_ImagBuffer1[][CLDFB_NO_COL_MAX],
+#else
float Cldfb_RealBuffer1[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
float Cldfb_ImagBuffer1[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+#endif
const int16_t ch_start_idx1,
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ float *Cldfb_RealBuffer2[][CLDFB_NO_COL_MAX],
+ float *Cldfb_ImagBuffer2[][CLDFB_NO_COL_MAX],
+#else
float Cldfb_RealBuffer2[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
float Cldfb_ImagBuffer2[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+#endif
const int16_t ch_start_idx2,
float out_cov_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
float out_cov_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
@@ -345,8 +358,13 @@ static void ComputeBandedCrossCov(
static void ComputeBandedCov(
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ float *Cldfb_RealBuffer[][CLDFB_NO_COL_MAX],
+ float *Cldfb_ImagBuffer[][CLDFB_NO_COL_MAX],
+#else
float Cldfb_RealBuffer[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
float Cldfb_ImagBuffer[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
+#endif
const int16_t ch_start_idx,
float out_cov_re[][BINAURAL_CHANNELS],
float out_cov_im[][BINAURAL_CHANNELS],
@@ -1335,9 +1353,14 @@ static void isar_SplitRenderer_quant_code(
static void isar_SplitRenderer_GetRotMd(
ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i/o: binaural renderer handle */
- MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ float *Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX], /* o : Reference Binaural signals */
+ float *Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX], /* o : Reference Binaural signals */
+#else
float Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */
float Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */
+#endif
const int16_t low_res,
const int16_t ro_md_flag )
{
@@ -1418,15 +1441,21 @@ static void isar_SplitRenderer_GetRotMd(
*------------------------------------------------------------------------*/
void isar_rend_CldfbSplitPreRendProcess(
- const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend,
- const IVAS_QUATERNION headPosition,
- MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
- float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
- float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
- ISAR_SPLIT_REND_BITS_HANDLE pBits,
- const int32_t target_md_bits,
- const int16_t low_res_pre_rend_rot,
- const int16_t ro_md_flag )
+ const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i : binaural pre-renderer handle */
+ const IVAS_QUATERNION headPosition, /* i : head rotation QUATERNION */
+ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ float *Cldfb_In_BinReal[][CLDFB_NO_COL_MAX], /* i : Binaural signals, real part */
+ float *Cldfb_In_BinImag[][CLDFB_NO_COL_MAX], /* i : Binaural signals, imag. part */
+#else
+ float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Binaural signals, real part */
+ float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Binaural signals, imag. part */
+#endif
+ ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */
+ const int32_t target_md_bits, /* i : ISAR MD bitrate */
+ const int16_t low_res_pre_rend_rot, /* i : low time resolution pre-renderer flag */
+ const int16_t ro_md_flag /* i : real only metadata for yaw flag */
+)
{
push_wmops( "isar_rend_CldfbSplitPreRendProcess" );
@@ -1873,6 +1902,11 @@ ivas_error isar_renderMultiTDBinToSplitBinaural(
uint8_t useLc3plus;
float *in_delayed[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS];
int16_t i;
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ int16_t j;
+ float *p_Cldfb_In_BinReal[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX];
+ float *p_Cldfb_In_BinImag[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX];
+#endif
int32_t num_slots;
push_wmops( "isar_renderMultiTDBinToSplitBinaural" );
@@ -1882,6 +1916,17 @@ ivas_error isar_renderMultiTDBinToSplitBinaural(
useLc3plus = hSplitBin->hLc3plusEnc != NULL;
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i )
+ {
+ for ( j = 0; j < CLDFB_NO_COL_MAX; ++j )
+ {
+ p_Cldfb_In_BinReal[i][j] = Cldfb_In_BinReal[i][j];
+ p_Cldfb_In_BinImag[i][j] = Cldfb_In_BinImag[i][j];
+ }
+ }
+#endif
+
if ( useLc3plus )
{
/*this should always have the time resolution of pose correction MD. Note that this does not change frame size of LC3plus*/
@@ -1944,7 +1989,21 @@ ivas_error isar_renderMultiTDBinToSplitBinaural(
target_md_bits = isar_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000;
- isar_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, pBits, target_md_bits, low_res_pre_rend_rot, ro_md_flag );
+ isar_rend_CldfbSplitPreRendProcess(
+ hSplitBin->hBinHrSplitPreRend,
+ headPosition,
+ &hSplitBin->multiBinPoseData,
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ p_Cldfb_In_BinReal,
+ p_Cldfb_In_BinImag,
+#else
+ Cldfb_In_BinReal,
+ Cldfb_In_BinImag,
+#endif
+ pBits,
+ target_md_bits,
+ low_res_pre_rend_rot,
+ ro_md_flag );
}
if ( pcm_out_flag == 0 )
@@ -1959,7 +2018,17 @@ ivas_error isar_renderMultiTDBinToSplitBinaural(
pBits->codec_frame_size_ms = codec_frame_size_ms;
pBits->isar_frame_size_ms = isar_frame_size_ms;
- isar_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal, Cldfb_In_BinImag, available_bits, pBits );
+ isar_splitBinLCLDEncProcess(
+ hSplitBin->hSplitBinLCLDEnc,
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ p_Cldfb_In_BinReal,
+ p_Cldfb_In_BinImag,
+#else
+ Cldfb_In_BinReal,
+ Cldfb_In_BinImag,
+#endif
+ available_bits,
+ pBits );
}
else
{
@@ -2019,9 +2088,15 @@ ivas_error isar_renderMultiTDBinToSplitBinaural(
*------------------------------------------------------------------------*/
void lc3plusTimeAlignCldfbPoseCorr(
- SPLIT_REND_WRAPPER *hSplitBin,
- float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
- float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] )
+ SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renderer handle */
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ float *Cldfb_In_BinReal[][CLDFB_NO_COL_MAX], /* i/o: Binaural signals, real part */
+ float *Cldfb_In_BinImag[][CLDFB_NO_COL_MAX] /* i/o: Binaural signals, imag. part */
+#else
+ float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: Binaural signals, real part */
+ float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] /* ii/: Binaural signals, imag. part */
+#endif
+)
{
float Cldfb_In_BinReal_tmp[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][2][CLDFB_NO_CHANNELS_MAX];
float Cldfb_In_BinImag_tmp[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][2][CLDFB_NO_CHANNELS_MAX];
diff --git a/lib_isar/isar_splitRenderer_utils.c b/lib_isar/isar_splitRenderer_utils.c
index 02dd552ef918b6b4e1d604d843c61d94192db62d..962e52ff19264cc19a08cb9f33ca6a30a9648f41 100644
--- a/lib_isar/isar_splitRenderer_utils.c
+++ b/lib_isar/isar_splitRenderer_utils.c
@@ -78,26 +78,6 @@ void isar_mat_mult_2by2_complex(
}
-/*-------------------------------------------------------------------------
- * Function ISAR_SPLIT_REND_BITStream_init()
- *
- *
- *------------------------------------------------------------------------*/
-
-void ISAR_SPLIT_REND_BITStream_init(
- ISAR_SPLIT_REND_BITS_HANDLE pBits,
- const int32_t buf_len_bytes,
- uint8_t *pbuf )
-{
- pBits->bits_buf = pbuf;
- pBits->buf_len = buf_len_bytes;
- pBits->bits_read = 0;
- pBits->bits_written = 0;
-
- return;
-}
-
-
/*-------------------------------------------------------------------------
* Function isar_split_rend_huffman_dec_init_min_max_len()
*
diff --git a/lib_isar/isar_stat.h b/lib_isar/isar_stat.h
index 587c3c8ea7309fc6a4fe0fe3cbc66dbebfdcd0f8..4ed75ee97e81e4ff1ebacd476bfc4f36f5732eb3 100644
--- a/lib_isar/isar_stat.h
+++ b/lib_isar/isar_stat.h
@@ -345,4 +345,17 @@ typedef struct
} SPLIT_REND_WRAPPER;
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+typedef struct
+{
+ float *real;
+ float *imag;
+ int32_t capacity;
+ int32_t write_pos;
+ int32_t read_pos;
+ int16_t is_full;
+
+} ISAR_CLDFB_RINGBUF, *ISAR_CLDFB_RINGBUF_HANDLE;
+#endif
+
#endif /* ISAR_STAT_H */
diff --git a/lib_isar/lib_isar_pre_rend.c b/lib_isar/lib_isar_pre_rend.c
index 2e6c70b47ec88ce9c6fb09794a448107edf20a66..7203c97b28688060ac96acccfe4b9673fee1142c 100644
--- a/lib_isar/lib_isar_pre_rend.c
+++ b/lib_isar/lib_isar_pre_rend.c
@@ -294,21 +294,26 @@ void ISAR_PRE_REND_GetMultiBinPoseData(
*------------------------------------------------------------------------*/
ivas_error ISAR_PRE_REND_MultiBinToSplitBinaural(
- SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renerer handle */
- const IVAS_QUATERNION headPosition, /* i: head rotation QUATERNION */
- const int32_t SplitRendBitRate, /* i: Split renderer bitrate */
- ISAR_SPLIT_REND_CODEC splitCodec, /* i/o: Split renderer codec */
- const int16_t isar_frame_size_ms, /* i: ISAR framesize */
- int16_t codec_frame_size_ms, /* i/o: ISAR transport codec framesize */
- ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits struct handle */
+ SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renerer handle */
+ const IVAS_QUATERNION headPosition, /* i : head rotation QUATERNION */
+ const int32_t SplitRendBitRate, /* i : Split renderer bitrate */
+ ISAR_SPLIT_REND_CODEC splitCodec, /* i/o: Split renderer codec */
+ const int16_t isar_frame_size_ms, /* i : ISAR framesize */
+ int16_t codec_frame_size_ms, /* i/o: ISAR transport codec framesize */
+ ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits struct handle */
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ float *Cldfb_In_BinReal[][CLDFB_NO_COL_MAX], /* i/o: CLDFB real buffer */
+ float *Cldfb_In_BinImag[][CLDFB_NO_COL_MAX], /* i/o: CLDFB imag buffer */
+#else
float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB real buffer */
float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB imag buffer */
- const int16_t max_bands, /* i: CLDFB bands */
- float *output[], /* i/o: PCM in/out buffer */
- const int16_t low_res_pre_rend_rot, /* i: low time resolution pre-renderer flag */
- const int16_t cldfb_in_flag, /* i: Flag to indicate CLDFB or time doamin input */
- const int16_t pcm_out_flag, /* i: Flag to indicate PCM output */
- const int16_t ro_md_flag /* i: Flag to indicate real only metadata for yaw */
+#endif
+ const int16_t max_bands, /* i : CLDFB bands */
+ float *output[], /* i/o: PCM in/out buffer */
+ const int16_t low_res_pre_rend_rot, /* i : low time resolution pre-renderer flag */
+ const int16_t cldfb_in_flag, /* i : Flag to indicate CLDFB or time domain input */
+ const int16_t pcm_out_flag, /* i : Flag to indicate PCM output */
+ const int16_t ro_md_flag /* i : Flag to indicate real only metadata for yaw */
)
{
ivas_error error;
@@ -406,20 +411,22 @@ ivas_error ISAR_PRE_REND_MultiBinToSplitBinaural(
}
else
{
- int16_t ch, slot_idx;
+ int16_t ch, slot_idx, num_slots;
+ num_slots = (int16_t) ( isar_frame_size_ms * 1000000 / CLDFB_SLOT_NS );
+
/* 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];
- for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ )
+ for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ )
{
Cldfb_In_BinReal_p[slot_idx] = Cldfb_In_BinReal[ch][slot_idx];
Cldfb_In_BinImag_p[slot_idx] = Cldfb_In_BinImag[ch][slot_idx];
}
- 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] );
+ cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * num_slots, hSplitBin->hCldfbHandles->cldfbSyn[ch] );
}
pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode;
diff --git a/lib_isar/lib_isar_pre_rend.h b/lib_isar/lib_isar_pre_rend.h
index 201b46cd0ffc60607d29017f862a775342b32096..f11530e09668fdf8283435026408f0bdf110a792 100644
--- a/lib_isar/lib_isar_pre_rend.h
+++ b/lib_isar/lib_isar_pre_rend.h
@@ -59,21 +59,26 @@ void ISAR_PRE_REND_GetMultiBinPoseData(
);
ivas_error ISAR_PRE_REND_MultiBinToSplitBinaural(
- SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renerer handle */
- const IVAS_QUATERNION headPosition, /* i: head rotation QUATERNION */
- const int32_t SplitRendBitRate, /* i: Split renderer bitrate */
- ISAR_SPLIT_REND_CODEC splitCodec, /* i/o: Split renderer codec */
- const int16_t isar_frame_size_ms, /* i: ISAR framesize */
- int16_t codec_frame_size_ms, /* i/o: ISAR transport codec framesize */
- ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits struct handle */
+ SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renerer handle */
+ const IVAS_QUATERNION headPosition, /* i: head rotation QUATERNION */
+ const int32_t SplitRendBitRate, /* i: Split renderer bitrate */
+ ISAR_SPLIT_REND_CODEC splitCodec, /* i/o: Split renderer codec */
+ const int16_t isar_frame_size_ms, /* i: ISAR framesize */
+ int16_t codec_frame_size_ms, /* i/o: ISAR transport codec framesize */
+ ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits struct handle */
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ float *Cldfb_In_BinReal[][CLDFB_NO_COL_MAX], /* i/o: CLDFB real buffer */
+ float *Cldfb_In_BinImag[][CLDFB_NO_COL_MAX], /* i/o: CLDFB imag buffer */
+#else
float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB real buffer */
float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB imag buffer */
- const int16_t max_bands, /* i: CLDFB bands */
- float *output[], /* i/o: PCM in/out buffer */
- const int16_t low_res_pre_rend_rot, /* i: low time resolution pre-renderer flag */
- const int16_t cldfb_in_flag, /* i: Flag to indicate CLDFB or time doamin input */
- const int16_t pcm_out_flag, /* i: Flag to indicate PCM output */
- const int16_t ro_md_flag /* i: Flag to indicate real only metadata for yaw */
+#endif
+ const int16_t max_bands, /* i: CLDFB bands */
+ float *output[], /* i/o: PCM in/out buffer */
+ const int16_t low_res_pre_rend_rot, /* i: low time resolution pre-renderer flag */
+ const int16_t cldfb_in_flag, /* i: Flag to indicate CLDFB or time doamin input */
+ const int16_t pcm_out_flag, /* i: Flag to indicate PCM output */
+ const int16_t ro_md_flag /* i: Flag to indicate real only metadata for yaw */
);
#endif /* LIB_ISAR_PRE_REND_H */
diff --git a/lib_rend/ivas_cldfb_ring_buffer.c b/lib_rend/ivas_cldfb_ring_buffer.c
new file mode 100644
index 0000000000000000000000000000000000000000..669227540e063f5d156efa86fd99ad5676c27867
--- /dev/null
+++ b/lib_rend/ivas_cldfb_ring_buffer.c
@@ -0,0 +1,298 @@
+/******************************************************************************************************
+
+ (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#include
+#include "options.h"
+#include "cnst.h"
+#include "prot.h"
+#include "ivas_prot.h"
+#include
+#ifdef DEBUGGING
+#include "debug.h"
+#endif
+#include "wmc_auto.h"
+
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+/*---------------------------------------------------------------------*
+ * CLDFB ring-buffer functions needed in split-rendering outputs
+ *---------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------*
+ * ivas_cldfb_ringbuf_IsEmpty()
+ *
+ * Returns 1 if the ring buffer is empty, or 0 otherwise.
+ *---------------------------------------------------------------------*/
+
+static int16_t ivas_cldfb_ringbuf_IsEmpty(
+ ISAR_CLDFB_RINGBUF_HANDLE h )
+{
+ return (int16_t) ( h->read_pos == h->write_pos && !h->is_full );
+}
+
+
+/*---------------------------------------------------------------------*
+ * ivas_cldfb_ringbuf_IsFull()
+ *
+ * Returns 1 if the ring buffer is full, or 0 otherwise.
+ *---------------------------------------------------------------------*/
+
+static int16_t ivas_cldfb_ringbuf_IsFull(
+ ISAR_CLDFB_RINGBUF_HANDLE h )
+{
+ return h->is_full;
+}
+
+
+/*---------------------------------------------------------------------*
+ * ivas_CLDFB_RINGBUF_Open()
+ *
+ * Allocates a ring buffer for CLDFB data with the given capacity of CLDFB columns.
+ * Each column is expected to contain at most CLDFB_NO_CHANNELS_MAX frequency bands.
+ *
+ * May return IVAS_ERR_FAILED_ALLOC on failed allocation, or IVAS_ERR_OK otherwise.
+ *---------------------------------------------------------------------*/
+
+ivas_error ivas_CLDFB_RINGBUF_Open(
+ ISAR_CLDFB_RINGBUF_HANDLE *ph,
+ const int16_t capacity_columns )
+{
+ ISAR_CLDFB_RINGBUF_HANDLE h;
+ int32_t capacity;
+
+ capacity = (int32_t) capacity_columns * CLDFB_NO_CHANNELS_MAX;
+
+ if ( ( h = malloc( sizeof( ISAR_CLDFB_RINGBUF ) ) ) == NULL )
+ {
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Failed to allocate memory for CLDFB ring buffer\n" );
+ }
+ h->real = NULL;
+ h->imag = NULL;
+ h->capacity = 0;
+ h->write_pos = 0;
+ h->read_pos = 0;
+ h->is_full = 0;
+ *ph = h;
+
+ if ( ( h->real = malloc( capacity * sizeof( float ) ) ) == NULL )
+ {
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Failed to allocate memory for CLDFB ring buffer\n" );
+ }
+ if ( ( h->imag = malloc( capacity * sizeof( float ) ) ) == NULL )
+ {
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Failed to allocate memory for CLDFB ring buffer\n" );
+ }
+ h->capacity = capacity;
+
+ return IVAS_ERR_OK;
+}
+
+
+/*---------------------------------------------------------------------*
+ * ivas_CLDFB_RINGBUF_Close()
+ *
+ * Dellocates CLDFB ring buffer. The given handle will be set to NULL.
+ *---------------------------------------------------------------------*/
+
+void ivas_CLDFB_RINGBUF_Close(
+ ISAR_CLDFB_RINGBUF_HANDLE *ph )
+{
+ ISAR_CLDFB_RINGBUF_HANDLE h;
+
+ if ( ph == NULL )
+ {
+ return;
+ }
+ h = *ph;
+
+ if ( h == NULL )
+ {
+ return;
+ }
+
+ if ( h->real != NULL )
+ {
+ free( h->real );
+ }
+ if ( h->imag != NULL )
+ {
+ free( h->imag );
+ }
+
+ free( h );
+ *ph = NULL;
+
+ return;
+}
+
+
+/*---------------------------------------------------------------------*
+ * ivas_CLDFB_RINGBUF_Push()
+ *
+ * Push a single column onto the back of the CLDFB ring buffer from real and imag arrays.
+ *---------------------------------------------------------------------*/
+
+void ivas_CLDFB_RINGBUF_Push(
+ ISAR_CLDFB_RINGBUF_HANDLE h,
+ const float *real,
+ const float *imag,
+ const int16_t num_bands )
+{
+ assert( num_bands <= CLDFB_NO_CHANNELS_MAX );
+ assert( !ivas_cldfb_ringbuf_IsFull( h ) );
+
+ mvr2r( real, &h->real[h->write_pos], num_bands );
+ mvr2r( imag, &h->imag[h->write_pos], num_bands );
+
+ h->write_pos += CLDFB_NO_CHANNELS_MAX;
+ if ( h->write_pos == h->capacity )
+ {
+ h->write_pos = 0;
+ }
+
+ if ( h->read_pos == h->write_pos )
+ {
+ h->is_full = 1;
+ }
+
+ return;
+}
+
+
+/*---------------------------------------------------------------------*
+ * ivas_CLDFB_RINGBUF_Pop()
+ *
+ * Pops a single column from the front of the CLDFB ring buffer into real and imag arrays.
+ *---------------------------------------------------------------------*/
+
+void ivas_CLDFB_RINGBUF_Pop(
+ ISAR_CLDFB_RINGBUF_HANDLE h,
+ float *real,
+ float *imag,
+ const int16_t num_bands )
+{
+ assert( num_bands <= CLDFB_NO_CHANNELS_MAX );
+ assert( !ivas_cldfb_ringbuf_IsEmpty( h ) );
+
+ if ( real != NULL )
+ {
+ mvr2r( &h->real[h->read_pos], real, num_bands );
+ }
+ if ( imag != NULL )
+ {
+ mvr2r( &h->imag[h->read_pos], imag, num_bands );
+ }
+
+ h->read_pos += CLDFB_NO_CHANNELS_MAX;
+ if ( h->read_pos == h->capacity )
+ {
+ h->read_pos = 0;
+ }
+
+ h->is_full = 0;
+
+ return;
+}
+
+
+/*---------------------------------------------------------------------*
+ * ivas_cldfb_ringbuf_total_size()
+ *
+ * Returns total number of buffered samples (including number of channels)
+ *---------------------------------------------------------------------*/
+
+static int32_t ivas_cldfb_ringbuf_total_size(
+ ISAR_CLDFB_RINGBUF_HANDLE h )
+{
+ if ( ivas_cldfb_ringbuf_IsFull( h ) )
+ {
+ return h->capacity;
+ }
+
+ if ( h->read_pos <= h->write_pos )
+ {
+ return h->write_pos - h->read_pos;
+ }
+
+ /* else wrap around */
+ return h->write_pos + h->capacity - h->read_pos;
+}
+
+
+/*---------------------------------------------------------------------*
+ * ivas_CLDFB_RINGBUF_GetByIdx()
+ *
+ * Get pointers into a specific column in the CLDFB ring buffer based on given index.
+ * Non-negative indices access from the front of the ring buffer, negative indexes access
+ * from the back, similar to Python arrays. For example:
+ *
+ * - index 0 accesses the front of the buffer, i.e. the oldest CLDFB column in the queue.
+ * - index -1 accesses the back of the buffer, i.e. the newest (last pushed) CLDFB column in the queue.
+ *---------------------------------------------------------------------*/
+
+void ivas_CLDFB_RINGBUF_GetByIdx(
+ ISAR_CLDFB_RINGBUF_HANDLE h,
+ float **p_real,
+ float **p_imag,
+ const int16_t col_idx )
+{
+ int32_t idx = col_idx * CLDFB_NO_CHANNELS_MAX;
+ int32_t num_floats = ivas_cldfb_ringbuf_total_size( h );
+ int32_t offset;
+
+ assert( -num_floats <= idx && idx <= num_floats );
+
+ if ( idx >= 0 )
+ {
+ offset = h->read_pos + idx;
+ if ( h->capacity <= offset )
+ {
+ offset -= h->capacity;
+ }
+ }
+ else
+ {
+ if ( -idx <= h->write_pos )
+ {
+ offset = h->write_pos + idx;
+ }
+ else
+ {
+ offset = h->write_pos + h->capacity + idx;
+ }
+ }
+
+ *p_real = &h->real[offset];
+ *p_imag = &h->imag[offset];
+
+ return;
+}
+#endif
diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c
index 11a3a16aae1a74300bbcd9126a9b3d761dc2df18..5571d91b50dea82b769287ae9a7e7b5db02cc1dd 100644
--- a/lib_rend/ivas_dirac_dec_binaural_functions.c
+++ b/lib_rend/ivas_dirac_dec_binaural_functions.c
@@ -822,8 +822,12 @@ static void ivas_dirac_dec_binaural_internal(
{
for ( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe]; i++ )
{
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ ivas_CLDFB_RINGBUF_Push( st_ivas->hSplitBinRend->hMultiBinCldfbData[ch], tmp_Cldfb_out_re[ch][i], tmp_Cldfb_out_im[ch][i], CLDFB_NO_CHANNELS_MAX );
+#else
mvr2r( tmp_Cldfb_out_re[ch][i], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[ch][hSpatParamRendCom->slots_rendered + i], CLDFB_NO_CHANNELS_MAX );
mvr2r( tmp_Cldfb_out_im[ch][i], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[ch][hSpatParamRendCom->slots_rendered + i], CLDFB_NO_CHANNELS_MAX );
+#endif
}
}
}
@@ -873,14 +877,21 @@ static void ivas_dirac_dec_binaural_internal(
mvr2r( st_ivas->hDiracDecBin[0]->ChCrossIm, hDiracDecBin->ChCrossIm, hSpatParamRendCom->num_freq_bands );
ivas_dirac_dec_binaural_formulate_target_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Rmat_local, subframe,
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0,
+#else
hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0,
+#endif
subFrameTotalEne, IIReneLimiter, st_ivas->hMasaIsmData );
ivas_dirac_dec_binaural_determine_processing_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat_local, subframe,
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0,
+#else
hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0,
+#endif
nchanSeparateChannels, st_ivas->hMasaIsmData );
-
/* re-use reverb and decorr from main direction for the sides */
ivas_dirac_dec_binaural_process_output( hDiracDecBin, hSpatParamRendCom, st_ivas->cldfbSynDec, output_f, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in,
max_band_decorr, numInChannels, config_data.processReverb, subframe, tmp_Cldfb_out_re, tmp_Cldfb_out_im,
@@ -891,8 +902,12 @@ static void ivas_dirac_dec_binaural_internal(
{
for ( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe]; i++ )
{
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ ivas_CLDFB_RINGBUF_Push( st_ivas->hSplitBinRend->hMultiBinCldfbData[pos_idx * BINAURAL_CHANNELS + ch], tmp_Cldfb_out_re[ch][i], tmp_Cldfb_out_im[ch][i], CLDFB_NO_CHANNELS_MAX );
+#else
mvr2r( tmp_Cldfb_out_re[ch][i], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[pos_idx * BINAURAL_CHANNELS + ch][hSpatParamRendCom->slots_rendered + i], CLDFB_NO_CHANNELS_MAX );
mvr2r( tmp_Cldfb_out_im[ch][i], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[pos_idx * BINAURAL_CHANNELS + ch][hSpatParamRendCom->slots_rendered + i], CLDFB_NO_CHANNELS_MAX );
+#endif
}
}
diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h
index 1e9c4df5a06fa4c3572f7a4f228c74632999c196..d20958172afb319f75552cdad93bdc105fad93a4 100644
--- a/lib_rend/ivas_prot_rend.h
+++ b/lib_rend/ivas_prot_rend.h
@@ -1593,6 +1593,66 @@ void ivas_rend_closeCldfbRend(
CLDFB_REND_WRAPPER *pCldfbRend
);
+/*----------------------------------------------------------------------------------*
+ * Time domain ring buffer prototypes
+ *----------------------------------------------------------------------------------*/
+
+ivas_error ivas_TD_RINGBUF_Open(
+ TD_RINGBUF_HANDLE *ph, /* i/o: Ring buffer handle */
+ const int16_t capacity_per_channel, /* i : Number of samples stored per channel */
+ const int16_t num_channels /* i : Number of channels */
+);
+
+void ivas_TD_RINGBUF_Close(
+ TD_RINGBUF_HANDLE *ph /* i/o: Ring buffer handle */
+);
+
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+void ivas_TD_RINGBUF_PushInterleaved(
+ TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */
+ const float *data, /* i : Input audio in interleaved channels layout */
+ const int16_t num_samples_per_channel /* i : Number of samples per channel to push */
+);
+
+void ivas_TD_RINGBUF_PushChannels(
+ TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */
+ const float *p_channels[], /* i : Array of pointers to each input channel */
+ const int16_t num_samples_per_channel /* i : Number of samples per channel to store */
+);
+
+void ivas_TD_RINGBUF_PushConstant(
+ TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */
+ const float value, /* i : Value to push */
+ const int16_t num_samples_per_channel /* i : Number of samples per channel to push */
+);
+
+void ivas_TD_RINGBUF_PopChannels(
+ TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */
+ float *p_channels[], /* i : Array of pointers to each output channel */
+ const int16_t num_samples_per_channel /* i : Number of samples per channel to pop */
+);
+#else
+void ivas_TD_RINGBUF_Push(
+ TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */
+ const float *data, /* i : Input data */
+ const uint16_t num_samples_per_channel /* i : Number of samples per channel to store */
+);
+
+void ivas_TD_RINGBUF_PushZeros(
+ TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */
+ const uint16_t num_samples_per_channel /* i : Number of zeros per channel to store */
+);
+
+void ivas_TD_RINGBUF_Pop(
+ TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */
+ float *data, /* i : Output data */
+ const uint16_t num_samples_per_channel /* i : Number of samples per channel to retrieve*/
+);
+#endif
+
+int16_t ivas_TD_RINGBUF_Size(
+ const TD_RINGBUF_HANDLE h /* i : Ring buffer handle */
+);
/* clang-format on */
diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h
index bba88de8efe8f7b4c322391d13484180fb2b15fa..fe039cacb0dee30993cfc599a09795844e043711 100644
--- a/lib_rend/ivas_stat_rend.h
+++ b/lib_rend/ivas_stat_rend.h
@@ -1375,6 +1375,22 @@ typedef struct
} CLDFB_REND_WRAPPER;
+/*----------------------------------------------------------------------------------*
+ * Time domain ring buffer structure
+ *----------------------------------------------------------------------------------*/
+
+typedef struct
+{
+ float *data; /* samples in interleaved layout, e.g. for channels A, B, C, samples are stored: A1, B1, C1, A2, B2, C2, ... */
+ int32_t capacity; /* max number of float values that can be stored */
+ int16_t num_channels;
+ int32_t write_pos;
+ int32_t read_pos;
+ int16_t is_full;
+
+} TD_RINGBUF_DATA, *TD_RINGBUF_HANDLE;
+
+
/*----------------------------------------------------------------------------------*
* MASA external renderer structure
*----------------------------------------------------------------------------------*/
diff --git a/lib_rend/ivas_td_ring_buffer.c b/lib_rend/ivas_td_ring_buffer.c
new file mode 100644
index 0000000000000000000000000000000000000000..98b3e4d15b8de980fcf8fa1b3d289ed1147ea48a
--- /dev/null
+++ b/lib_rend/ivas_td_ring_buffer.c
@@ -0,0 +1,425 @@
+/******************************************************************************************************
+
+ (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository. All Rights Reserved.
+
+ This software is protected by copyright law and by international treaties.
+ The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
+ Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
+ Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
+ Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
+ contributors to this repository retain full ownership rights in their respective contributions in
+ the software. This notice grants no license of any kind, including but not limited to patent
+ license, nor is any license granted by implication, estoppel or otherwise.
+
+ Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
+ contributions.
+
+ This software is provided "AS IS", without any express or implied warranties. The software is in the
+ development stage. It is intended exclusively for experts who have experience with such software and
+ solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
+ and fitness for a particular purpose are hereby disclaimed and excluded.
+
+ Any dispute, controversy or claim arising under or in relation to providing this software shall be
+ submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
+ accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
+ the United Nations Convention on Contracts on the International Sales of Goods.
+
+*******************************************************************************************************/
+
+#include
+#include
+#include
+#include "ivas_error_utils.h"
+#include "ivas_prot_rend.h"
+#include "options.h"
+#include "wmc_auto.h"
+
+
+/*-----------------------------------------------------------------------*
+ * Local function prototypes
+ *-----------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------*
+ * ivas_td_ringbuf_total_size()
+ *
+ * Returns total number of buffered samples (including number of channels)
+ *---------------------------------------------------------------------*/
+
+static int32_t ivas_td_ringbuf_total_size(
+ TD_RINGBUF_HANDLE h )
+{
+ if ( h->is_full )
+ {
+ return h->capacity;
+ }
+
+ if ( h->read_pos <= h->write_pos )
+ {
+ return h->write_pos - h->read_pos;
+ }
+ /* else wrap around */
+ return h->write_pos + h->capacity - h->read_pos;
+}
+
+
+static int16_t ivas_td_ringbuf_has_space_for_num_samples(
+ TD_RINGBUF_HANDLE h,
+ const int32_t num_samples )
+{
+ return (int16_t) ( ivas_td_ringbuf_total_size( h ) + num_samples <= h->capacity );
+}
+
+
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+static void ivas_td_ringbuf_push_interleaved(
+ TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */
+ const float *data, /* i : Input audio in interleaved channels layout */
+ const int16_t num_samples_per_channel, /* i : Number of samples per channel to push */
+ const int16_t read_stride /* i: : 1 for normal operation, 0 for reading from a single input value */
+)
+{
+ int32_t s, read_s;
+
+ assert( h != NULL );
+ assert( data != NULL );
+ assert( read_stride == 0 || read_stride == 1 );
+ assert( ivas_td_ringbuf_has_space_for_num_samples( h, (int32_t) num_samples_per_channel * h->num_channels ) );
+
+ for ( s = 0, read_s = 0; s < (int32_t) num_samples_per_channel * h->num_channels; ++s, read_s += read_stride )
+ {
+ h->data[h->write_pos] = data[read_s];
+ ++h->write_pos;
+
+ if ( h->write_pos == h->capacity )
+ {
+ h->write_pos = 0;
+ }
+ }
+
+ if ( h->read_pos == h->write_pos )
+ {
+ h->is_full = 1;
+ }
+
+ return;
+}
+#endif
+
+
+/*-----------------------------------------------------------------------*
+ * Global function definitions
+ *-----------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------*
+ * ivas_TD_RINGBUF_Open()
+ *
+ * Allocates a ring buffer for TD data with the given capacity of TD samples per channel.
+ *
+ * May return IVAS_ERR_FAILED_ALLOC on failed allocation, or IVAS_ERR_OK otherwise.
+ *---------------------------------------------------------------------*/
+
+ivas_error ivas_TD_RINGBUF_Open(
+ TD_RINGBUF_HANDLE *ph, /* i/o: Ring buffer handle */
+ const int16_t capacity_per_channel, /* i : Number of samples stored per channel */
+ const int16_t num_channels /* i : Number of channels */
+)
+{
+ TD_RINGBUF_HANDLE h;
+ int32_t capacity;
+
+ capacity = (int32_t) capacity_per_channel * num_channels;
+
+ h = malloc( sizeof( TD_RINGBUF_DATA ) );
+ if ( h == NULL )
+ {
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Failed to allocate memory for TD ring buffer\n" );
+ }
+ h->data = NULL;
+ h->capacity = 0;
+ h->num_channels = num_channels;
+ h->write_pos = 0;
+ h->read_pos = 0;
+ h->is_full = 0;
+ *ph = h;
+
+ h->data = malloc( capacity * sizeof( float ) );
+ if ( h->data == NULL )
+ {
+ return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Failed to allocate memory for TD ring buffer\n" );
+ }
+ h->capacity = capacity;
+
+ return IVAS_ERR_OK;
+}
+
+
+/*---------------------------------------------------------------------*
+ * ivas_TD_RINGBUF_Close()
+ *
+ * Dellocates TD ring buffer. The given handle will be set to NULL.
+ *---------------------------------------------------------------------*/
+
+void ivas_TD_RINGBUF_Close(
+ TD_RINGBUF_HANDLE *ph /* i/o: Ring buffer handle */
+)
+{
+ TD_RINGBUF_HANDLE h;
+
+ if ( ph == NULL )
+ {
+ return;
+ }
+ h = *ph;
+
+ if ( h == NULL )
+ {
+ return;
+ }
+
+ if ( h->data != NULL )
+ {
+ free( h->data );
+ }
+
+ free( h );
+ *ph = NULL;
+
+ return;
+}
+
+
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+/*---------------------------------------------------------------------*
+ * ivas_TD_RINGBUF_PushInterleaved()
+ *
+ * Pushes samples from a buffer with interleaved channel layout onto the back of the TD ring buffer.
+ *---------------------------------------------------------------------*/
+
+void ivas_TD_RINGBUF_PushInterleaved(
+ TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */
+ const float *data, /* i : Input audio in interleaved channels layout */
+ const int16_t num_samples_per_channel /* i : Number of samples per channel to push */
+)
+{
+ ivas_td_ringbuf_push_interleaved( h, data, num_samples_per_channel, 1 );
+
+ return;
+}
+
+
+/*---------------------------------------------------------------------*
+ * ivas_TD_RINGBUF_PushChannels()
+ *
+ * Pushes samples from channel pointers onto the back of the TD ring buffer.
+ *---------------------------------------------------------------------*/
+
+void ivas_TD_RINGBUF_PushChannels(
+ TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */
+ const float *p_channels[], /* i : Array of pointers to each input channel */
+ const int16_t num_samples_per_channel /* i : Number of samples per channel to push */
+)
+#else
+/*---------------------------------------------------------------------*
+ * ivas_TD_RINGBUF_Push()
+ *
+ * Push samples onto the back of the TD ring buffer.
+ * Returns total number of buffered samples (includes number of channels)
+ *---------------------------------------------------------------------*/
+
+void ivas_TD_RINGBUF_Push(
+ TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */
+ const float *data, /* i : Input data */
+ const uint16_t num_samples_per_channel /* i : Number of samples per channel to store */
+)
+#endif
+{
+ int32_t s;
+ int16_t c;
+
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ assert( h != NULL );
+ assert( p_channels != NULL );
+ for ( c = 0; c < h->num_channels; ++c )
+ {
+ assert( p_channels[c] != NULL );
+ }
+#endif
+ assert( ivas_td_ringbuf_has_space_for_num_samples( h, (int32_t) num_samples_per_channel * h->num_channels ) );
+
+ for ( s = 0; s < num_samples_per_channel; ++s )
+ {
+ for ( c = 0; c < h->num_channels; ++c )
+ {
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ h->data[h->write_pos] = p_channels[c][s];
+#else
+ h->data[h->write_pos] = *( data + c * num_samples_per_channel + s );
+#endif
+ ++h->write_pos;
+
+ if ( h->write_pos == h->capacity )
+ {
+ h->write_pos = 0;
+ }
+ }
+ }
+
+ if ( h->read_pos == h->write_pos )
+ {
+ h->is_full = 1;
+ }
+
+ return;
+}
+
+
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+/*---------------------------------------------------------------------*
+ * ivas_TD_RINGBUF_PushConstant()
+ *
+ * Pushes samples with a constant value onto the back of the TD ring buffer.
+ *---------------------------------------------------------------------*/
+
+void ivas_TD_RINGBUF_PushConstant(
+ TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */
+ const float value, /* i : Value to push */
+ const int16_t num_samples_per_channel /* i : Number of samples per channel to push */
+)
+{
+ ivas_td_ringbuf_push_interleaved( h, &value, num_samples_per_channel, 0 );
+
+ return;
+}
+#else
+/*---------------------------------------------------------------------*
+ * ivas_TD_RINGBUF_PushZeros()
+ *
+ * Push zero samples onto the back of the TD ring buffer.
+ *---------------------------------------------------------------------*/
+
+void ivas_TD_RINGBUF_PushZeros(
+ TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */
+ const uint16_t num_samples_per_channel /* i : Number of zeros per channel to store */
+)
+{
+ uint16_t c, s;
+
+ assert( ivas_td_ringbuf_has_space_for_num_samples( h, num_samples_per_channel * h->num_channels ) );
+ if ( !num_samples_per_channel )
+ {
+ return;
+ }
+
+ for ( s = 0; s < num_samples_per_channel; ++s )
+ {
+ for ( c = 0; c < h->num_channels; ++c )
+ {
+ h->data[h->write_pos] = 0.f;
+ ++h->write_pos;
+
+ if ( h->write_pos == h->capacity )
+ {
+ h->write_pos = 0;
+ }
+ }
+ }
+
+ if ( h->read_pos == h->write_pos )
+ {
+ h->is_full = 1;
+ }
+
+ return;
+}
+#endif
+
+
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+/*---------------------------------------------------------------------*
+ * ivas_TD_RINGBUF_PopChannels()
+ *
+ * Pops samples from the front of the TD ring buffer to an array of channel pointers.
+ *---------------------------------------------------------------------*/
+
+void ivas_TD_RINGBUF_PopChannels(
+ TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */
+ float *p_channels[], /* i : Array of pointers to each output channel */
+ const int16_t num_samples_per_channel /* i : Number of samples per channel to pop */
+)
+#else
+/*---------------------------------------------------------------------*
+ * ivas_TD_RINGBUF_Pop()
+ *
+ * Pop samples from the front of the TD ring buffer.
+ *---------------------------------------------------------------------*/
+
+void ivas_TD_RINGBUF_Pop(
+ TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */
+ float *data, /* i : Output data */
+ const uint16_t num_samples_per_channel /* i : Number of samples per channel to retrieve */
+)
+#endif
+{
+ int32_t s;
+ int16_t c;
+
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ assert( h != NULL );
+ assert( p_channels != NULL );
+ for ( c = 0; c < h->num_channels; ++c )
+ {
+ assert( p_channels[c] != NULL );
+ }
+#endif
+ assert( ivas_td_ringbuf_total_size( h ) >= (int32_t) num_samples_per_channel * h->num_channels );
+
+ for ( s = 0; s < num_samples_per_channel; ++s )
+ {
+ for ( c = 0; c < h->num_channels; ++c )
+ {
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ p_channels[c][s] = h->data[h->read_pos];
+#else
+ *( data + c * num_samples_per_channel + s ) = h->data[h->read_pos];
+#endif
+ ++h->read_pos;
+
+ if ( h->read_pos == h->capacity )
+ {
+ h->read_pos = 0;
+ }
+ }
+ }
+
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ if ( num_samples_per_channel != 0 )
+ {
+ h->is_full = 0;
+ }
+#else
+ if ( h->is_full )
+ {
+ h->is_full = 0;
+ }
+#endif
+
+ return;
+}
+
+
+/*---------------------------------------------------------------------*
+ * ivas_TD_RINGBUF_Size()
+ *
+ * Returns number of buffered samples per channel.
+ *---------------------------------------------------------------------*/
+
+int16_t ivas_TD_RINGBUF_Size(
+ const TD_RINGBUF_HANDLE h /* i : Ring buffer handle */
+)
+{
+ return (int16_t) ( ivas_td_ringbuf_total_size( h ) / h->num_channels );
+}
diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c
index e7e7003b0f116b5743514b73b4cd1e45cf40d176..e1dd767ad9271315968baed4cb71cced718038f0 100644
--- a/lib_rend/lib_rend.c
+++ b/lib_rend/lib_rend.c
@@ -7597,6 +7597,19 @@ static ivas_error getSamplesInternal(
int16_t ch;
int16_t i, ro_md_flag;
float *tmpBinaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS], tmpBinaural_buff[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][L_FRAME48k];
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP /* Temporary fix. Proper implementation of port 391 can only be added once port 369 is complete. */
+ float *p_Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX];
+ float *p_Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX];
+
+ for ( ch = 0; ch < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++ch )
+ {
+ for ( i = 0; i < CLDFB_NO_COL_MAX; ++i )
+ {
+ p_Cldfb_RealBuffer_Binaural[ch][i] = Cldfb_RealBuffer_Binaural[ch][i];
+ p_Cldfb_ImagBuffer_Binaural[ch][i] = Cldfb_ImagBuffer_Binaural[ch][i];
+ }
+ }
+#endif
for ( ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++ )
{
@@ -7634,8 +7647,13 @@ static ivas_error getSamplesInternal(
hIvasRend->hRendererConfig->split_rend_config.isar_frame_size_ms,
hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms,
&bits,
+#ifdef FIX_1119_SPLIT_RENDERING_VOIP
+ p_Cldfb_RealBuffer_Binaural,
+ p_Cldfb_ImagBuffer_Binaural,
+#else
Cldfb_RealBuffer_Binaural,
Cldfb_ImagBuffer_Binaural,
+#endif
( const int16_t )( ( BINAURAL_MAXBANDS * hIvasRend->sampleRateOut ) / 48000 ),
tmpBinaural,
1,