Skip to content
......@@ -39,6 +39,9 @@
#include "wmc_auto.h"
#include "ivas_rom_rend.h"
#include "ivas_rom_binaural_crend_head.h"
#ifdef FIX_989_TD_REND_ROM
#include <math.h>
#endif
#ifdef DEBUGGING
#include "debug.h"
#endif
......@@ -386,6 +389,9 @@ static ivas_error DefaultBSplineModel(
ModelParamsITD_t *modelITD;
int16_t i, j;
ivas_error error;
#ifdef FIX_989_TD_REND_ROM
float azimSegSamples;
#endif
HrFiltSet_p->FilterMethod = TDREND_HRFILT_Method_BSplineModel;
model = &( HrFiltSet_p->ModelParams );
......@@ -396,6 +402,15 @@ static ivas_error DefaultBSplineModel(
model->modelROM = TRUE;
/* int16_t parameters */
#ifdef FIX_989_TD_REND_ROM
model->UseItdModel = defaultHRIR_rom_model_configuration[0];
model->elevDim3 = defaultHRIR_rom_model_configuration[1];
model->AlphaN = defaultHRIR_rom_model_configuration[2];
model->num_unique_azim_splines = defaultHRIR_rom_model_configuration[3];
model->elevSegSamples = defaultHRIR_rom_model_configuration[4];
model->elevBsLen = defaultHRIR_rom_elevBsLen;
model->elevBsStart = defaultHRIR_rom_elevBsStart;
#else
model->UseItdModel = 1;
model->SplineDegree = 4;
model->elevDim2 = 17;
......@@ -413,6 +428,7 @@ static ivas_error DefaultBSplineModel(
model->elevBsStart[3] = 27;
model->azimDim2 = defaultHRIR_rom_azimDim2;
#endif
model->azimDim3 = defaultHRIR_rom_azimDim3;
model->azim_start_idx = defaultHRIR_rom_azim_start_idx;
model->azimSegSamples = defaultHRIR_rom_azimSegSamples;
......@@ -429,10 +445,36 @@ static ivas_error DefaultBSplineModel(
}
model->azimBsShape[0] = (const float *) defaultHRIR_rom_azimBsShape;
#ifdef FIX_989_TD_REND_ROM
if ( ( model->azimKSeq = (float **) malloc( model->elevDim3 * sizeof( float * ) ) ) == NULL )
#else
if ( ( model->azimKSeq = (float **) malloc( 18 * sizeof( float * ) ) ) == NULL )
#endif
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) );
}
#ifdef FIX_989_TD_REND_ROM
for ( i = 0; i < model->elevDim3; i++ )
{
if ( ( model->azimKSeq[i] = (float *) malloc( ( model->azimDim3[i] + 1 ) * sizeof( float * ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) );
}
if ( model->azimShapeIdx[i] < 0 )
{
azimSegSamples = 360.0f;
}
else
{
azimSegSamples = defaultHRIR_rom_azimSegSamples[model->azimShapeIdx[i]];
}
assert( azimSegSamples == 360.0f / model->azimDim3[i] );
for ( j = 0; j < model->azimDim3[i] + 1; j++ )
{
model->azimKSeq[i][j] = azimSegSamples * j;
}
}
#else
if ( ( model->azimKSeq[0] = (float *) malloc( 2 * sizeof( float * ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) );
......@@ -457,6 +499,7 @@ static ivas_error DefaultBSplineModel(
model->azimKSeq[i][j] = (float) defaultHRIR_rom_azimSegSamples[0] * j;
}
}
#endif
switch ( output_Fs )
{
......@@ -465,7 +508,11 @@ static ivas_error DefaultBSplineModel(
model->AlphaR = (const float *) defaultHRIR_rom_AlphaR48;
model->EL = (const float *) defaultHRIR_rom_EL48;
model->ER = (const float *) defaultHRIR_rom_ER48;
#ifdef FIX_989_TD_REND_ROM
model->K = defaultHRIR_rom_model_configuration[5];
#else
model->K = 128;
#endif
if ( HrFiltSet_p->ModelParams.UseItdModel )
{
modelITD->resamp_factor = 1.0f;
......@@ -476,7 +523,11 @@ static ivas_error DefaultBSplineModel(
model->AlphaR = (const float *) defaultHRIR_rom_AlphaR32;
model->EL = (const float *) defaultHRIR_rom_EL32;
model->ER = (const float *) defaultHRIR_rom_ER32;
#ifdef FIX_989_TD_REND_ROM
model->K = (int16_t) ceil( RESAMPLE_FACTOR_32_48 * defaultHRIR_rom_model_configuration[5] );
#else
model->K = 86;
#endif
if ( HrFiltSet_p->ModelParams.UseItdModel )
{
modelITD->resamp_factor = RESAMPLE_FACTOR_32_48;
......@@ -487,7 +538,11 @@ static ivas_error DefaultBSplineModel(
model->AlphaR = (const float *) defaultHRIR_rom_AlphaR16;
model->EL = (const float *) defaultHRIR_rom_EL16;
model->ER = (const float *) defaultHRIR_rom_ER16;
#ifdef FIX_989_TD_REND_ROM
model->K = (int16_t) ceil( RESAMPLE_FACTOR_16_48 * defaultHRIR_rom_model_configuration[5] );
#else
model->K = 43;
#endif
if ( HrFiltSet_p->ModelParams.UseItdModel )
{
modelITD->resamp_factor = RESAMPLE_FACTOR_16_48;
......@@ -497,6 +552,14 @@ static ivas_error DefaultBSplineModel(
break;
}
#ifdef FIX_989_TD_REND_ROM
modelITD->elevDim3 = defaultHRIR_rom_ITD_model_configuration[0];
modelITD->azimDim3 = defaultHRIR_rom_ITD_model_configuration[1];
modelITD->elevSegSamples = defaultHRIR_rom_ITD_model_configuration[2];
modelITD->azimSegSamples = defaultHRIR_rom_ITD_model_configuration[3];
modelITD->elevBsLen = defaultHRIR_rom_ITD_elevBsLen;
modelITD->elevBsStart = defaultHRIR_rom_ITD_elevBsStart;
#else
modelITD->N = 4;
modelITD->elevDim2 = 20;
modelITD->elevDim3 = 18;
......@@ -511,9 +574,14 @@ static ivas_error DefaultBSplineModel(
modelITD->elevBsStart[1] = 4;
modelITD->elevBsStart[2] = 11;
modelITD->elevBsStart[3] = 21;
#endif
modelITD->elevKSeq = defaultHRIR_rom_ITD_elevKSeq;
#ifdef FIX_989_TD_REND_ROM
modelITD->azimBsLen = defaultHRIR_rom_ITD_azimBsLen;
modelITD->azimBsStart = defaultHRIR_rom_ITD_azimBsStart;
#else
modelITD->azimBsLen[0] = 11;
modelITD->azimBsLen[1] = 21;
modelITD->azimBsLen[2] = 31;
......@@ -524,6 +592,7 @@ static ivas_error DefaultBSplineModel(
modelITD->azimBsStart[3] = 63;
modelITD->azimSegSamples = 10;
#endif
modelITD->azimKSeq = defaultHRIR_rom_ITD_azimKSeq;
modelITD->W = (const float *) defaultHRIR_rom_ITD_W;
......
......@@ -51,6 +51,10 @@ static void TDREND_SRC_SPATIAL_Init( TDREND_SRC_SPATIAL_t *SrcSpatial_p, const T
static void TDREND_SRC_SPATIAL_SetDirAtten( TDREND_SRC_SPATIAL_t *SrcSpatial_p, const TDREND_DirAtten_t *DirAtten_p );
#ifdef CONF_DISTATT
static void TDREND_SRC_SPATIAL_SetDistAtten( TDREND_SRC_SPATIAL_t *SrcSpatial_p, const TDREND_DistAtten_t *DistAtten_p );
#endif
static float TDREND_SRC_SPATIAL_GetDirGain( const TDREND_DirAtten_t *DirAtten_p, const float *Front_p, const float *RelPos_p );
static float TDREND_SRC_SPATIAL_GetDistGain( const TDREND_DistAtten_t *DistAtten_p, const float Dist );
......@@ -153,6 +157,33 @@ ivas_error TDREND_MIX_SRC_SetDirAtten(
return IVAS_ERR_OK;
}
#ifdef CONF_DISTATT
/*-------------------------------------------------------------------*
* TDREND_MIX_SRC_SetDistAtten()
*
* Set distance attenuation for the mixer.
--------------------------------------------------------------------*/
ivas_error TDREND_MIX_SRC_SetDistAtten(
BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */
const int16_t SrcInd, /* i : Source index */
const TDREND_DistAtten_t *DistAtten_p /* i : Distance attenuation specifier */
)
{
TDREND_SRC_SPATIAL_t *SrcSpatial_p;
if ( SrcInd > hBinRendererTd->MaxSrcInd )
{
return ( IVAS_ERROR( IVAS_ERR_INVALID_INDEX, "Index exceeds max index\n" ) );
}
else
{
SrcSpatial_p = hBinRendererTd->Sources[SrcInd]->SrcSpatial_p;
TDREND_SRC_SPATIAL_SetDistAtten( SrcSpatial_p, DistAtten_p );
}
return IVAS_ERR_OK;
}
#endif
/*-------------------------------------------------------------------*
* TDREND_MIX_SRC_SetPlayState()
......@@ -483,7 +514,27 @@ static void TDREND_SRC_SPATIAL_SetDirAtten(
return;
}
#ifdef CONF_DISTATT
/*-------------------------------------------------------------------*
* TDREND_SRC_SPATIAL_SetDistAtten()
*
* Sets the distance attenuation.
--------------------------------------------------------------------*/
static void TDREND_SRC_SPATIAL_SetDistAtten(
TDREND_SRC_SPATIAL_t *SrcSpatial_p,
const TDREND_DistAtten_t *DistAtten_p )
{
/* Set distance attenuation */
SrcSpatial_p->DistAttenEnabled = TRUE;
SrcSpatial_p->DistAtten.DistAttenModel = DistAtten_p->DistAttenModel;
SrcSpatial_p->DistAtten.MaxDist = DistAtten_p->MaxDist;
SrcSpatial_p->DistAtten.RefDist = DistAtten_p->RefDist;
SrcSpatial_p->DistAtten.RollOffFactor = DistAtten_p->RollOffFactor;
return;
}
#endif
/*-------------------------------------------------------------------*
* TDREND_SRC_SPATIAL_GetDirGain()
*
......@@ -557,7 +608,11 @@ static float TDREND_SRC_SPATIAL_GetDistGain(
switch ( DistAtten_p->DistAttenModel )
{
case TDREND_DIST_ATTEN_MODEL_INV_DIST:
#ifdef CONF_DISTATT
DistGain = powf( DistAtten_p->RefDist / Dist2, DistAtten_p->RollOffFactor );
#else
DistGain = DistAtten_p->RefDist / ( DistAtten_p->RefDist + DistAtten_p->RollOffFactor * ( Dist2 - DistAtten_p->RefDist ) );
#endif
break;
case TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED:
......@@ -570,8 +625,11 @@ static float TDREND_SRC_SPATIAL_GetDistGain(
{
Dist2 = DistAtten_p->MaxDist;
}
#ifdef CONF_DISTATT
DistGain = powf( DistAtten_p->RefDist / Dist2, DistAtten_p->RollOffFactor );
#else
DistGain = DistAtten_p->RefDist / ( DistAtten_p->RefDist + DistAtten_p->RollOffFactor * ( Dist2 - DistAtten_p->RefDist ) );
#endif
break;
}
......
......@@ -49,9 +49,7 @@
*------------------------------------------------------------------------------------------*/
#define OTR_UPDATE_RATE (float) FRAMES_PER_SEC /* rate of the Process() calls [Hz]; 1x per IVAS frame */
#ifdef NONBE_FIX_1067_QUATERNIONSLERP_INACCURACIES
#define COS_ONE_TENTH_DEGREE ( 0.999998476913288f )
#endif
/*------------------------------------------------------------------------------------------*
* Local functions
......@@ -159,7 +157,6 @@ void QuaternionSlerp(
const float t,
IVAS_QUATERNION *const r )
{
#ifdef NONBE_FIX_1067_QUATERNIONSLERP_INACCURACIES
IVAS_QUATERNION r1, r2;
float phi, sinPhi, cosPhi, s1, s2;
......@@ -198,29 +195,6 @@ void QuaternionSlerp(
r->y = ( s1 * r1.y + s2 * r2.y ) / sinPhi;
r->z = ( s1 * r1.z + s2 * r2.z ) / sinPhi;
}
#else
float angle, denom, s, s2;
s = QuaternionDotProduct( q1, q2 );
if ( fabsf( s ) >= 1.0f )
{
*r = q2;
return;
}
angle = acosf( s );
denom = sinf( angle );
s = sinf( ( 1 - t ) * angle );
s2 = sinf( t * angle );
r->x = ( q1.x * s + q2.x * s2 ) / denom;
r->y = ( q1.y * s + q2.y * s2 ) / denom;
r->z = ( q1.z * s + q2.z * s2 ) / denom;
r->w = ( q1.w * s + q2.w * s2 ) / denom;
#endif
QuaternionNormalize( *r, r );
return;
......
......@@ -408,7 +408,11 @@ int16_t ivas_get_nchan_buffers_dec(
{
nchan_out_buff = max( nchan_out_buff, st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe );
}
#ifdef FIX_1052_EXT_OUTPUT
else if ( output_config != IVAS_AUDIO_CONFIG_EXTERNAL )
#else
else
#endif
{
nchan_out_buff = max( audioCfg2channels( st_ivas->transport_config ), audioCfg2channels( st_ivas->intern_config ) );
nchan_out_buff = max( nchan_out_buff, audioCfg2channels( output_config ) );
......@@ -418,7 +422,7 @@ int16_t ivas_get_nchan_buffers_dec(
#ifdef SPLIT_REND_WITH_HEAD_ROT
if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
{
nchan_out_buff = max( nchan_out_buff, st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS );
nchan_out_buff = max( nchan_out_buff, st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS );
}
#endif
......
......@@ -77,37 +77,6 @@ int16_t ivas_get_nchan_buffers_dec(
const int32_t ivas_total_brate /* i : total IVAS bitrate */
);
/*----------------------------------------------------------------------------------*
* Limiter prototypes
*----------------------------------------------------------------------------------*/
ivas_error ivas_limiter_open(
IVAS_LIMITER_HANDLE *hLimiter_out, /* o : limiter struct handle */
const int16_t num_channels, /* i : number of I/O channels */
const int32_t sampling_rate /* i : sampling rate for processing */
);
void ivas_limiter_close(
IVAS_LIMITER_HANDLE* phLimiter /* i/o: pointer to limiter handle, can be NULL */
);
void ivas_limiter_dec
(
IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */
float *output[MAX_OUTPUT_CHANNELS], /* i/o: input/output buffer */
const int16_t num_channels, /* i : number of channels to be processed */
const int16_t output_frame, /* i : number of samples per channel in the buffer */
const int16_t BER_detect /* i : BER detect flag */
);
void limiter_process(
IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */
const int16_t output_frame, /* i : number of samples to be processed per channel in the I/O buffer */
const float threshold, /* i : signal amplitude above which limiting starts to be applied */
const int16_t BER_detect, /* i : BER detect flag */
int16_t *strong_saturation_cnt /* i/o: counter of strong saturations (can be NULL) */
);
/*----------------------------------------------------------------------------------*
* TD decorr. function prototypes
......@@ -665,6 +634,9 @@ ivas_error ivas_td_binaural_open_unwrap(
const IVAS_FORMAT ivas_format, /* i : IVAS format (ISM/MC) */
const AUDIO_CONFIG transport_config, /* i : Transport configuration */
const float *directivity, /* i : Directivity pattern (used for ISM) */
#ifdef CONF_DISTATT
const float *distAtt, /* i : Distance attenuation (used for ISM) */
#endif
const IVAS_OUTPUT_SETUP hTransSetup, /* i : Loudspeaker layout */
BINAURAL_TD_OBJECT_RENDERER_HANDLE *hBinRendererTd, /* o : TD renderer handle */
int32_t *binaural_latency_ns /* i : Binauralization delay */
......@@ -753,7 +725,13 @@ ivas_error TDREND_MIX_SRC_SetDirAtten(
const int16_t SrcInd, /* i : Source index */
const TDREND_DirAtten_t *DirAtten_p /* i : Directional attenuation specifier */
);
#ifdef CONF_DISTATT
ivas_error TDREND_MIX_SRC_SetDistAtten(
BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */
const int16_t SrcInd, /* i : Source index */
const TDREND_DistAtten_t *DistAtten_p /* i : Distance attenuation specifier */
);
#endif
ivas_error TDREND_MIX_SRC_SetPlayState(
BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */
const int16_t SrcInd, /* i : Source index */
......@@ -1229,10 +1207,6 @@ void Euler2Quat(
IVAS_QUATERNION *quat /* o : quaternion describing the rotation */
);
float deg2rad(
float degrees
);
float rad2deg(
float radians
);
......@@ -1428,245 +1402,6 @@ ivas_error ivas_orient_trk_Process(
IVAS_QUATERNION *pTrkRot /* o : tracked rotation */
);
#ifdef SPLIT_REND_WITH_HEAD_ROT
void ivas_set_split_rend_ht_setup(
IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend,
COMBINED_ORIENTATION_HANDLE hCombinedOrientationData
);
/*----------------------------------------------------------------------------------*
* Split binaural renderer prototypes
*----------------------------------------------------------------------------------*/
void ivas_set_split_rend_ht_setup(
IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend,
COMBINED_ORIENTATION_HANDLE hCombinedOrientationData
);
ivas_error ivas_set_split_rend_setup(
IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend,
IVAS_SPLIT_REND_CONFIG_DATA *hSplitBinConfig,
COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientation handle */
uint8_t *splitRendBitsBuf
);
void ivas_init_split_rend_handles(
SPLIT_REND_WRAPPER *hSplitRendWrapper
);
void ivas_init_split_post_rend_handles(
SPLIT_POST_REND_WRAPPER *hSplitRendWrapper
);
ivas_error ivas_split_renderer_open(
SPLIT_REND_WRAPPER *hSplitBinRend,
const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig,
const int32_t output_Fs,
const int16_t cldfb_in_flag,
const int16_t pcm_out_flag,
const int16_t num_subframes
);
void ivas_split_renderer_close(
SPLIT_REND_WRAPPER *hSplitBinRend
);
ivas_error ivas_splitBinLCLDEncOpen(
BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc,
const int32_t iSampleRate,
const int16_t iChannels,
const int32_t iDataRate,
const int16_t iNumBlocks,
const int16_t iNumIterations
);
void ivas_splitBinLCLDEncClose(
BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc
);
void ivas_splitBinLCLDEncProcess(
BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc,
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,
IVAS_SPLIT_REND_BITS_HANDLE pBits
);
ivas_error ivas_splitBinLCLDDecOpen(
BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec,
const int32_t iSampleRate,
const int16_t iChannels,
const int16_t iNumBlocks,
const int16_t iNumIterations
);
void ivas_splitBinLCLDDecClose(
BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec
);
void ivas_splitBinLCLDDecProcess(
BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec,
IVAS_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
);
ivas_error ivas_splitBinPreRendOpen(
BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend,
#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
const int32_t output_Fs
#else
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData
#endif
);
ivas_error ivas_splitBinPostRendOpen(
BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend,
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
const int32_t output_Fs
);
void ivas_init_multi_bin_pose_data(
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData
);
void ivas_renderSplitGetMultiBinPoseData(
const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config,
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
const IVAS_SPLIT_REND_ROT_AXIS rot_axis
);
void ivas_renderSplitUpdateNoCorrectionPoseData(
const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config,
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData
);
ivas_error ivas_renderMultiBinToSplitBinaural(
SPLIT_REND_WRAPPER *hSplitBin,
const IVAS_QUATERNION headPosition,
const int32_t SplitRendBitRate,
IVAS_SPLIT_REND_CODEC splitCodec,
int16_t codec_frame_size_ms,
IVAS_SPLIT_REND_BITS_HANDLE pBits,
float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
const int16_t max_bands,
float *output[],
const int16_t low_res_pre_rend_rot,
const int16_t cldfb_in_flag,
const int16_t pcm_out_flag,
const int16_t ro_md_flag
);
void ivas_rend_CldfbSplitPreRendProcess(
const 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],
IVAS_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
);
void ivas_rend_CldfbSplitPostRendProcess(
BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend,
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
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
);
void ivas_splitBinPreRendClose(
BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend
);
void ivas_splitBinPostRendClose(
BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend );
void ivas_splitBinPostRendMdDec(
IVAS_SPLIT_REND_BITS_HANDLE pBits,
BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend,
#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
#endif
);
ivas_error ivas_splitBinRendPLCOpen(
SPLIT_REND_PLC_HANDLE* phSplitRendPLC
);
void ivas_splitBinRendPLCClose(
SPLIT_REND_PLC_HANDLE* phSplitRendPLC
);
void ivas_splitBinRendPLCsaveState(
SPLIT_REND_PLC_HANDLE hSplitRendPLC,
float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
const int16_t num_chs,
const int16_t iNumBlocks,
const int16_t iNumIterations
);
void ivas_splitBinRendPLC_xf(
SPLIT_REND_PLC_HANDLE hSplitRendPLC,
float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
const int16_t num_chs,
const int16_t iNumBlocks,
const int16_t iNumIterations
);
void ivas_splitBinRendPLC(
SPLIT_REND_PLC_HANDLE hSplitRendPLC,
float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
const int16_t num_chs,
const int16_t iNumBlocks,
const int16_t iNumIterations
);
#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
void ivas_log_cldfb2wav_data(
float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
HANDLE_CLDFB_FILTER_BANK *cldfbSyn,
const int16_t num_chs,
const int16_t num_freq_bands,
const int32_t output_Fs,
const int16_t start_slot_idx,
const int16_t md_band_idx,
const char *filename
);
#endif
void ivas_SplitRenderer_GetRotMd(
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
);
void ivas_SplitRenderer_PostRenderer(
BIN_HR_SPLIT_POST_REND_HANDLE hBinPostRenderer, /* i/o: binaural renderer handle */
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
float Cldfb_RealBuffer_Ref_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */
float Cldfb_ImagBuffer_Ref_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */
const IVAS_QUATERNION Quaternion_act
);
#endif
/*----------------------------------------------------------------------------------*
* Rendering & merging to MASA format
......@@ -1782,17 +1517,10 @@ void masaPrerendClose(
* Split rendering
*----------------------------------------------------------------------------------*/
/* TODO(sgi): Rework interface */
ivas_error ObjRenderIvasFrame_splitBinaural(
Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
float *output[], /* i/o: SCE channels / Binaural synthesis */
const int16_t output_frame /* i : output frame length */
);
ivas_error ivas_td_binaural_renderer_sf_splitBinaural(
Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
float *output[], /* i/o: SCE channels / Binaural synthesis */
int16_t nSamplesRendered /* i : number of samples to render */
const int16_t nSamplesRendered /* i : number of samples to render */
);
ivas_error ivas_rend_crendProcessSubframesSplitBin(
......@@ -1816,8 +1544,8 @@ ivas_error ivas_rend_crendProcessSplitBin(
const AUDIO_CONFIG inConfig,
const AUDIO_CONFIG outConfig,
const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
DECODER_CONFIG_HANDLE hDecoderConfig,
COMBINED_ORIENTATION_HANDLE hCombinedOrientationData,
const DECODER_CONFIG_HANDLE hDecoderConfig,
const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData,
const IVAS_OUTPUT_SETUP_HANDLE hIntSetup,
EFAP_HANDLE hEFAPdata,
float *output[],
......@@ -1858,125 +1586,10 @@ ivas_error ivas_rend_openCldfbRend(
const int32_t output_Fs
);
void ivas_mat_mult_2by2_complex(
float in_re1[2][2],
float in_im1[2][2],
float in_re2[2][2],
float in_im2[2][2],
float out_re2[2][2],
float out_im2[2][2]
);
void ivas_split_rend_bitstream_init(
IVAS_SPLIT_REND_BITS_HANDLE pBits,
const int32_t buf_len_bytes, uint8_t *pbuf
);
void ivas_split_rend_huffman_dec_init_min_max_len(
ivas_split_rend_huffman_cfg_t *p_huff_cfg
);
void ivas_split_rend_init_huff_cfg(
BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg );
void set_fix_rotation_mat(
float fix_pos_rot_mat[][BINAURAL_CHANNELS][BINAURAL_CHANNELS],
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData
);
void set_pose_types(
IVAS_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1],
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData
);
int16_t wrap_a(
int16_t val,
const int16_t min_val,
const int16_t max_val
);
void ivas_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
);
void ivas_split_rend_bitstream_write_int32(
IVAS_SPLIT_REND_BITS_HANDLE pBits,
const int32_t val,
const int32_t bits
);
int32_t ivas_split_rend_bitstream_read_int32(
IVAS_SPLIT_REND_BITS_HANDLE pBits,
const int32_t bits
);
int32_t get_bit(
const int32_t state,
const int32_t bit_id
);
void ivas_rend_closeCldfbRend(
CLDFB_REND_WRAPPER *pCldfbRend
);
int32_t ivas_get_lcld_bitrate(
const int32_t SplitRendBitRate,
const IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode
);
int32_t ivas_get_split_rend_md_target_brate(
const int32_t SplitRendBitRate,
const int16_t pcm_out_flag
);
int32_t ivas_get_lc3plus_bitrate(
const int32_t SplitRendBitRate,
const IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode,
const int16_t split_prerender_frame_size_ms
);
int8_t ivas_get_lc3plus_bitrate_id(
const int32_t SplitRendBitRate
);
int32_t ivas_get_lc3plus_size_from_id(
const int8_t SplitRendBitRateId,
const IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode,
const int16_t split_prerender_frame_size_ms
);
ivas_error ivas_split_rend_validate_config(
const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig,
const int16_t pcm_out_flag
);
void ivas_split_rend_get_quant_params(
const int16_t num_md_bands,
int16_t pred_real_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS],
int16_t pred_imag_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS],
int16_t pred_quant_pnts_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS],
float pred_quantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS],
float pred_1byquantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS],
int16_t d_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS],
int16_t bands_pitch[IVAS_SPLIT_REND_NUM_QUANT_STRATS],
int16_t pred_real_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS],
int16_t pred_imag_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS],
int16_t *num_quant_strats,
int16_t *num_complex_bands
);
ivas_error ivas_split_rend_choose_default_codec(
IVAS_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */
int16_t *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */
const int16_t cldfb_in_flag, /* i : flag indicating rendering in TD */
const int16_t pcm_out_flag, /* i : flag to indicate PCM output */
const int16_t num_subframes /* i : number of subframes */
);
#endif
/* clang-format on */
......
......@@ -131,15 +131,26 @@ ivas_error ivas_render_config_init_from_rom(
( *hRenderConfig )->directivity[i * 3 + 1] = 360.0f; /* Back cone */
( *hRenderConfig )->directivity[i * 3 + 2] = 1.0f; /* Back attenuation */
}
#ifdef CONF_DISTATT
( *hRenderConfig )->distAtt[0] = 15.75f; /* Default max dist */
( *hRenderConfig )->distAtt[1] = 1.0f; /* Default ref dist */
( *hRenderConfig )->distAtt[2] = 1.0f; /* Default rolloff factor */
#endif
#ifdef SPLIT_REND_WITH_HEAD_ROT
( *hRenderConfig )->split_rend_config.splitRendBitRate = SPLIT_REND_768k;
( *hRenderConfig )->split_rend_config.dof = 3;
( *hRenderConfig )->split_rend_config.hq_mode = 0;
( *hRenderConfig )->split_rend_config.codec_delay_ms = 0;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
( *hRenderConfig )->split_rend_config.isar_frame_size_ms = 20;
#endif
( *hRenderConfig )->split_rend_config.codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */
( *hRenderConfig )->split_rend_config.codec = IVAS_SPLIT_REND_CODEC_DEFAULT;
( *hRenderConfig )->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB;
( *hRenderConfig )->split_rend_config.rendererSelection = IVAS_SPLIT_REND_RENDERER_SELECTION_DEFAULT;
( *hRenderConfig )->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT;
( *hRenderConfig )->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB;
( *hRenderConfig )->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_DEFAULT;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
( *hRenderConfig )->split_rend_config.lc3plus_highres = 0;
#endif
#endif
return IVAS_ERR_OK;
......
......@@ -105,9 +105,11 @@ typedef struct ivas_reverb_params_t
float *pFc; /* Center frequencies for FFT filter design */
float *pRt60; /* RT60 values at these frequencies */
float *pDsr; /* DSR values at these frequencies */
#ifndef FIX_1053_REVERB_RECONFIGURATION
float *pHrtf_avg_pwr_response_l; /* The HRTF set's average left ear power response */
float *pHrtf_avg_pwr_response_r; /* The HRTF set's average right ear power response */
float *pHrtf_inter_aural_coherence; /* The HRTF set's inter-aural coherence for diffuse sound */
#endif
const float *pHrtf_avg_pwr_response_l_const; /* The HRTF set's average left ear power response */
const float *pHrtf_avg_pwr_response_r_const; /* The HRTF set's average right ear power response */
const float *pHrtf_inter_aural_coherence_const; /* The HRTF set's inter-aural coherence for diffuse sound */
......@@ -977,7 +979,9 @@ static ivas_error setup_FDN_branches(
{
int16_t nr_coefs, branch_idx, channel_idx;
ivas_error error;
#ifndef FIX_1053_REVERB_RECONFIGURATION
float *pCoef_a, *pCoef_b;
#endif
error = IVAS_ERR_OK;
/* initialize feedback branches */
......@@ -999,6 +1003,7 @@ static ivas_error setup_FDN_branches(
{
for ( branch_idx = 0; branch_idx < pParams->nr_loops; branch_idx++ )
{
#ifndef FIX_1053_REVERB_RECONFIGURATION
pCoef_a = &pParams->pT60_filter_coeff[2 * nr_coefs * branch_idx + nr_coefs];
pCoef_b = &pParams->pT60_filter_coeff[2 * nr_coefs * branch_idx];
......@@ -1006,7 +1011,7 @@ static ivas_error setup_FDN_branches(
{
return error;
}
#endif
if ( ( error = set_feedback_delay( hReverb, branch_idx, pParams->pLoop_delays[branch_idx] ) ) != IVAS_ERR_OK )
{
return error;
......@@ -1031,11 +1036,19 @@ static ivas_error setup_FDN_branches(
}
#ifdef FIX_1053_REVERB_RECONFIGURATION
/*-------------------------------------------------------------------------
* ivas_reverb_open()
*
* Allocate and initialize FDN reverberation handle
*------------------------------------------------------------------------*/
#else
/*-------------------------------------------------------------------------
* ivas_reverb_open()
*
* Allocate and initialize Crend reverberation handle
*------------------------------------------------------------------------*/
#endif
ivas_error ivas_reverb_open(
REVERB_HANDLE *hReverb, /* i/o: Reverberator handle */
......@@ -1045,7 +1058,13 @@ ivas_error ivas_reverb_open(
)
{
ivas_error error;
#ifdef FIX_1053_REVERB_RECONFIGURATION
REVERB_HANDLE pState = *hReverb;
int16_t nr_coefs, branch_idx;
float *pCoef_a, *pCoef_b;
#else
REVERB_HANDLE pState = NULL;
#endif
int16_t bin_idx, subframe_len, output_frame, predelay_bf_len, loop_idx;
ivas_reverb_params_t params;
rv_fftwf_type_complex pFft_wf_filter_ch0[RV_LENGTH_NR_FC];
......@@ -1063,17 +1082,47 @@ ivas_error ivas_reverb_open(
predelay_bf_len = output_frame;
nr_fc_input = hRenderConfig->roomAcoustics.nBands;
#ifdef FIX_1053_REVERB_RECONFIGURATION
if ( *hReverb == NULL )
{
/* Allocate main reverb. handle */
if ( ( pState = (REVERB_HANDLE) malloc( sizeof( REVERB_DATA ) ) ) == NULL )
{
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for FDN Reverberator " );
}
}
#else
/* Allocate main reverb. handle */
if ( ( pState = (REVERB_HANDLE) malloc( sizeof( REVERB_DATA ) ) ) == NULL )
{
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend Reverberator " );
}
#endif
if ( ( error = set_base_config( &params, output_Fs ) ) != IVAS_ERR_OK )
{
return error;
}
#ifdef FIX_1053_REVERB_RECONFIGURATION
if ( *hReverb == NULL )
{
/* Allocate memory for feedback delay lines */
for ( loop_idx = 0; loop_idx < IVAS_REV_MAX_NR_BRANCHES; loop_idx++ )
{
if ( ( pState->loop_delay_buffer[loop_idx] = (float *) malloc( params.pLoop_delays[loop_idx] * sizeof( float ) ) ) == NULL )
{
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for FDN Reverberator" );
}
}
/* Allocate memory for the pre-delay delay line */
if ( ( pState->pPredelay_buffer = (float *) malloc( output_frame * sizeof( float ) ) ) == NULL )
{
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for FDN Reverberator" );
}
}
#else
/* Allocate memory for feedback delay lines */
for ( loop_idx = 0; loop_idx < IVAS_REV_MAX_NR_BRANCHES; loop_idx++ )
{
......@@ -1088,20 +1137,26 @@ ivas_error ivas_reverb_open(
{
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CREND Reverberator" );
}
#endif
pState->nr_of_branches = IVAS_REV_MAX_NR_BRANCHES;
set_fft_and_datablock_sizes( pState, subframe_len );
nr_fc_fft_filter = ( pState->fft_size >> 1 ) + 1;
/* === 'Control logic': compute the reverb processing parameters from the === */
/* === room, source and listener acoustic information provided in the reverb config === */
/* Setting up shared temporary buffers for fc, RT60, DSR, etc. */
#ifndef FIX_1053_REVERB_RECONFIGURATION
params.pHrtf_avg_pwr_response_l = &pFft_wf_filter_ch0[0][0];
params.pHrtf_avg_pwr_response_r = params.pHrtf_avg_pwr_response_l + nr_fc_fft_filter;
#endif
params.pRt60 = &pFft_wf_filter_ch1[0][0];
params.pDsr = params.pRt60 + nr_fc_fft_filter;
params.pFc = &pState->fft_filter_color_0.fft_spectrum[0];
#ifndef FIX_1053_REVERB_RECONFIGURATION
params.pHrtf_inter_aural_coherence = &pState->fft_filter_color_1.fft_spectrum[0];
#endif
/* Note: these temp buffers can only be used before the final step of the FFT filter design : */
/* before calls to ivas_reverb_calc_correl_filters(...) or to ivas_reverb_calc_color_filters(...) */
......@@ -1132,7 +1187,15 @@ ivas_error ivas_reverb_open(
}
/* set up input downmix */
#ifdef FIX_1053_REVERB_RECONFIGURATION
if ( *hReverb == NULL )
{
pState->dmx_gain = calc_dmx_gain();
}
#else
/* set up input downmix */
pState->dmx_gain = calc_dmx_gain();
#endif
/* set up predelay - must be after set_base_config() and before compute_t60_coeffs() */
calc_predelay( &params, hRenderConfig->roomAcoustics.acousticPreDelay, output_Fs );
......@@ -1156,7 +1219,20 @@ ivas_error ivas_reverb_open(
/* Compute the window used for FFT filters */
ivas_reverb_define_window_fft( pTime_window, transition_start, transition_length, nr_fc_fft_filter );
#ifdef FIX_1053_REVERB_RECONFIGURATION
/* === Copy parameters from ivas_reverb_params_t into DSP blocks === */
/* === to be used for subsequent audio signal processing === */
if ( *hReverb == NULL )
{
pState->do_corr_filter = params.do_corr_filter;
/* clear & init jot reverb fft filters */
if ( ( error = initialize_reverb_filters( pState ) ) != IVAS_ERR_OK )
{
return error;
}
}
#else
/* === Now, copy parameters from ivas_reverb_params_t into DSP blocks === */
/* === to be used for subsequent audio signal processing === */
......@@ -1167,6 +1243,7 @@ ivas_error ivas_reverb_open(
{
return error;
}
#endif
if ( pState->do_corr_filter )
{
......@@ -1199,6 +1276,36 @@ ivas_error ivas_reverb_open(
return error;
}
#ifdef FIX_1053_REVERB_RECONFIGURATION
if ( *hReverb == NULL )
{
/* init predelay */
ivas_rev_delay_line_init( &( pState->predelay_line ), pState->pPredelay_buffer, params.pre_delay, predelay_bf_len );
/* set up feedback delay network */
if ( ( error = setup_FDN_branches( pState, &params ) ) != IVAS_ERR_OK )
{
return error;
}
}
else
{
pState->predelay_line.Delay = params.pre_delay;
}
nr_coefs = params.t60_filter_order + 1;
for ( branch_idx = 0; branch_idx < params.nr_loops; branch_idx++ )
{
pCoef_a = &params.pT60_filter_coeff[2 * nr_coefs * branch_idx + nr_coefs];
pCoef_b = &params.pT60_filter_coeff[2 * nr_coefs * branch_idx];
if ( ( error = set_t60_filter( pState, branch_idx, nr_coefs, pCoef_a, pCoef_b ) ) != IVAS_ERR_OK )
{
return error;
}
}
#else
/* init predelay */
ivas_rev_delay_line_init( &( pState->predelay_line ), pState->pPredelay_buffer, params.pre_delay, predelay_bf_len );
......@@ -1207,6 +1314,7 @@ ivas_error ivas_reverb_open(
{
return error;
}
#endif
*hReverb = pState;
......
......@@ -50,9 +50,26 @@
*------------------------------------------------------------------------*/
/* TD renderer default HRIR model */
const float defaultHRIR_rom_latency_s = 0.000020834f;
#ifdef FIX_989_TD_REND_ROM
const int16_t defaultHRIR_rom_model_configuration[6] = {
1, /* UseItdModel */
15, /* elevDim3 */
470, /* AlphaN */
1, /* num_unique_azim_splines */
4, /* elevSegSamples */
128, /* K_48k */
};
const int16_t defaultHRIR_rom_elevBsLen[4] = {
5, 9, 13, 9,
};
const int16_t defaultHRIR_rom_elevBsStart[4] = {
0, 5, 14, 27,
};
#else
const int16_t defaultHRIR_rom_azimDim2[15] = {
1, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 1,
};
#endif
const int16_t defaultHRIR_rom_azimDim3[15] = {
1, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 1,
};
......@@ -10139,6 +10156,26 @@ const uint32_t defaultHRIR_rom_ITD_W[658] = {
0x3c678a1c,0xbdeb0ba5,0xbe2218a5,0x3e58dcde,0x3d71aaa0,0xbef80fb9,0xbf3d07e1,0x3f3485be,0x3db783c0,0x3c142933,0xbed36b04,0xbb9f1f49,0x3ebfdc23,0xbcc7652e,0xbdb4e6cd,0xbf3be092,0x3f399c4e,0x3ef2eb6a,0xbd93a618,0xbe480d88,0x3e1bd187,0x3df79a5d,0xbc53f8d6,0xbf002186,0xbd41bc42,
0x3e5c0f28,0x3f2ad402,0xbf3cc2c3,0xbedc59d1,0xbe021816,0x3ea43429,0x3d349309,0xbab986b3,
};
#ifdef FIX_989_TD_REND_ROM
const int16_t defaultHRIR_rom_ITD_model_configuration[4] = {
18, /* elevDim3 */
41, /* azimDim3 */
3, /* elevSegSamples */
10, /* azimSegSamples */
};
const int16_t defaultHRIR_rom_ITD_elevBsLen[4] = {
4, 7, 10, 7,
};
const int16_t defaultHRIR_rom_ITD_elevBsStart[4] = {
0, 4, 11, 21,
};
const int16_t defaultHRIR_rom_ITD_azimBsLen[4] = {
11, 21, 31, 21,
};
const int16_t defaultHRIR_rom_ITD_azimBsStart[4] = {
0, 11, 32, 63,
};
#endif
const uint32_t defaultHRIR_rom_ITD_azimBsShape[84] = {
0x3f800000,0x3f3a9fbe,0x3f03126f,0x3eaf9db2,0x3e5d2f1b,0x3e000000,0x3d83126f,0x3cdd2f1b,0x3c03126f,0x3a83126f,0xa5800000,0x00000000,0x3e8374bc,0x3ede353f,0x3f0ad0e5,0x3f178d50,0x3f180000,0x3f0ed917,0x3efd9168,0x3ed4fdf4,0x3ea95810,0x3e800000,0x3e3a9fbe,0x3e03126f,0x3daf9db2,
0x3d5d2f1b,0x3d000000,0x3c83126f,0x3bdd2f1b,0x3b03126f,0x3983126f,0xa6000000,0x00000000,0x3c66bdc8,0x3d57b901,0x3de1cac1,0x3e39af72,0x3e855555,0x3eaf1aa0,0x3ed756b3,0x3efb38a9,0x3f0bf7cf,0x3f155555,0x3f18aec3,0x3f16872b,0x3f0fc3ed,0x3f054a69,0x3ef00000,0x3ed19423,0x3eb11bfd,
......@@ -47,7 +47,11 @@
*------------------------------------------------------------------------*/
/* TD renderer default HRIR model */
extern const float defaultHRIR_rom_latency_s;
#ifdef FIX_989_TD_REND_ROM
extern const int16_t defaultHRIR_rom_model_configuration[6];
#else
extern const int16_t defaultHRIR_rom_azimDim2[15];
#endif
extern const int16_t defaultHRIR_rom_azimDim3[15];
extern const int16_t defaultHRIR_rom_azim_start_idx[15];
extern const int16_t defaultHRIR_rom_azimSegSamples[1];
......@@ -66,6 +70,10 @@ extern const uint32_t defaultHRIR_rom_EL32[HRTF_MODEL_N_SECTIONS * 470];
extern const uint32_t defaultHRIR_rom_ER32[HRTF_MODEL_N_SECTIONS * 470];
extern const uint32_t defaultHRIR_rom_EL16[HRTF_MODEL_N_SECTIONS * 470];
extern const uint32_t defaultHRIR_rom_ER16[HRTF_MODEL_N_SECTIONS * 470];
#ifdef FIX_989_TD_REND_ROM
extern const int16_t defaultHRIR_rom_elevBsLen[4];
extern const int16_t defaultHRIR_rom_elevBsStart[4];
#endif
extern const uint32_t defaultHRIR_rom_elevBsShape[36];
extern const uint32_t defaultHRIR_rom_azimBsShape[21];
extern const uint32_t defaultHRIR_rom_ITD_W[658];
......@@ -73,4 +81,11 @@ extern const uint32_t defaultHRIR_rom_ITD_azimBsShape[84];
extern const float defaultHRIR_rom_ITD_azimKSeq[19];
extern const uint32_t defaultHRIR_rom_ITD_elevBsShape[28];
extern const float defaultHRIR_rom_ITD_elevKSeq[16];
#ifdef FIX_989_TD_REND_ROM
extern const int16_t defaultHRIR_rom_ITD_model_configuration[4];
extern const int16_t defaultHRIR_rom_ITD_elevBsLen[4];
extern const int16_t defaultHRIR_rom_ITD_elevBsStart[4];
extern const int16_t defaultHRIR_rom_ITD_azimBsLen[4];
extern const int16_t defaultHRIR_rom_ITD_azimBsStart[4];
#endif
#endif
......@@ -137,12 +137,4 @@ extern const float ls_conversion_cicpX_stereo[12][2];
extern const LS_CONVERSION_MAPPING ls_conversion_mapping[];
#ifdef SPLIT_REND_WITH_HEAD_ROT
/*----------------------------------------------------------------------------------*
* Split binaural rendering ROM tables
*----------------------------------------------------------------------------------*/
extern const int32_t split_rend_brate_tbl[];
#endif
#endif /* IVAS_ROM_REND_H */
......@@ -37,6 +37,7 @@
#include <math.h>
#include "cnst.h"
#include "prot.h"
#include "ivas_prot.h"
#include "ivas_prot_rend.h"
#ifdef DEBUGGING
#include "debug.h"
......@@ -52,7 +53,7 @@ static ivas_error combine_external_and_head_orientations(
IVAS_QUATERNION *headRotQuaternions,
IVAS_VECTOR3 *listenerPos,
#ifdef SPLIT_REND_WITH_HEAD_ROT
IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis, /* i : split rend pose prediction axis*/
ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis, /* i : split rend pose prediction axis*/
#endif
EXTERNAL_ORIENTATION_HANDLE hExtOrientationData,
COMBINED_ORIENTATION_HANDLE hCombinedOrientationData );
......@@ -186,100 +187,6 @@ void QuatToRotMat(
}
/*-------------------------------------------------------------------------
* Euler2Quat()
*
* Calculate corresponding Quaternion from Euler angles in radians
*------------------------------------------------------------------------*/
void Euler2Quat(
const float yaw, /* i : yaw (x) */
const float pitch, /* i : pitch (y) */
const float roll, /* i : roll (z) */
IVAS_QUATERNION *quat /* o : quaternion describing the rotation */
)
{
float cr = cosf( roll * 0.5f );
float sr = sinf( roll * 0.5f );
float cp = cosf( pitch * 0.5f );
float sp = sinf( pitch * 0.5f );
float cy = cosf( yaw * 0.5f );
float sy = sinf( yaw * 0.5f );
quat->w = cr * cp * cy + sr * sp * sy;
quat->x = sr * cp * cy - cr * sp * sy;
quat->y = sr * cp * sy + cr * sp * cy;
quat->z = cr * cp * sy - sr * sp * cy;
return;
}
#ifdef SPLIT_REND_WITH_HEAD_ROT
/*-------------------------------------------------------------------------
* Quat2EulerDegree()
*
* Quaternion handling: calculate corresponding Euler angles in degrees
*------------------------------------------------------------------------*/
void Quat2EulerDegree(
const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */
float *yaw, /* o : yaw */
float *pitch, /* o : pitch */
float *roll /* o : roll */
)
{
if ( quat.w != -3.0 )
{
float p;
*yaw = atan2f( 2 * ( quat.w * quat.x + quat.y * quat.z ), 1 - 2 * ( quat.x * quat.x + quat.y * quat.y ) );
p = 2 * ( quat.w * quat.y - quat.z * quat.x );
p = max( -1.0f, min( 1.0f, p ) );
*pitch = asinf( p );
*roll = atan2f( 2 * ( quat.w * quat.z + quat.x * quat.y ), 1 - 2 * ( quat.y * quat.y + quat.z * quat.z ) );
*yaw *= _180_OVER_PI;
*pitch *= _180_OVER_PI;
*roll *= _180_OVER_PI;
}
else
{
/* Euler angles in R_X(roll)*R_Y(pitch)*R_Z(yaw) convention
*
* yaw: rotate scene counter-clockwise in the horizontal plane
* pitch: rotate scene in the median plane, increase elevation with positive values
* roll: rotate scene from the right ear to the top
*/
*yaw = quat.z;
*pitch = quat.y;
*roll = quat.x;
}
return;
}
#endif
/*-------------------------------------------------------------------------
* deg2rad()
*
* Converts degrees to normalized radians
*------------------------------------------------------------------------*/
float deg2rad(
float degrees )
{
while ( degrees >= 180.0f )
{
degrees = degrees - 360.0f;
}
while ( degrees <= -180.0f )
{
degrees = degrees + 360.0f;
}
return PI_OVER_180 * degrees;
}
/*-------------------------------------------------------------------------
* rad2deg()
*
......@@ -995,7 +902,7 @@ ivas_error combine_external_and_head_orientations_dec(
)
{
#ifdef SPLIT_REND_WITH_HEAD_ROT
IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis;
ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis;
#endif
IVAS_QUATERNION *pHeadRotQuaternion = NULL;
IVAS_VECTOR3 *listenerPos = NULL;
......@@ -1036,7 +943,7 @@ ivas_error combine_external_and_head_orientations_rend(
)
{
#ifdef SPLIT_REND_WITH_HEAD_ROT
IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis;
ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis;
#endif
IVAS_QUATERNION *headRotQuaternions = NULL;
IVAS_VECTOR3 *listenerPos = NULL;
......@@ -1087,7 +994,7 @@ ivas_error combine_external_and_head_orientations(
IVAS_QUATERNION *headRotQuaternions, /* i : quaternions for head rotation */
IVAS_VECTOR3 *listenerPos, /* i : listener position */
#ifdef SPLIT_REND_WITH_HEAD_ROT
IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis, /* i : split rend pose prediction axis */
ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis, /* i : split rend pose prediction axis */
#endif
EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, /* i : external orientation handle */
COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */
......
......@@ -33,6 +33,7 @@
#include "options.h"
#include <stdint.h>
#include <math.h>
#include "ivas_prot.h"
#include "ivas_prot_rend.h"
#include "ivas_stat_rend.h"
#include "ivas_cnst.h"
......
......@@ -39,12 +39,7 @@
#include "ivas_stat_com.h" // note: needed for DIRAC_DEC_BIN_HANDLE until #156 is solved
#include "stat_com.h" /* Note: Currently needed for CLDFB. */
#include "common_api_types.h"
#ifdef SPLIT_REND_WITH_HEAD_ROT
#include "stat_com.h"
#include "ivas_lcld_prot.h"
#include "ivas_lc3plus_enc.h"
#include "ivas_lc3plus_dec.h"
#endif
#include "isar_stat.h"
/*----------------------------------------------------------------------------------*
......@@ -485,7 +480,9 @@ typedef struct ivas_binaural_reverb_struct
uint32_t binRend_RandNext;
int16_t highestBinauralCoherenceBin;
#ifndef FIX_1053_REVERB_RECONFIGURATION
float dmxmtx[BINAURAL_CHANNELS][MAX_OUTPUT_CHANNELS];
#endif
float foa_enc[MAX_OUTPUT_CHANNELS][FOA_CHANNELS];
} REVERB_STRUCT, *REVERB_STRUCT_HANDLE;
......@@ -640,7 +637,7 @@ typedef struct EFAP
} EFAP, *EFAP_HANDLE;
/*----------------------------------------------------------------------------------*
* Orientation tracking structure
* Head rotation data structure
*----------------------------------------------------------------------------------*/
typedef struct ivas_orient_trk_state_t
......@@ -657,18 +654,14 @@ typedef struct ivas_orient_trk_state_t
} ivas_orient_trk_state_t;
/*----------------------------------------------------------------------------------*
* Head rotation data structure
*----------------------------------------------------------------------------------*/
typedef struct
{
int8_t headRotEnabled;
IVAS_QUATERNION headPositions[MAX_PARAM_SPATIAL_SUBFRAMES];
IVAS_VECTOR3 Pos[MAX_PARAM_SPATIAL_SUBFRAMES];
float crossfade[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES];
IVAS_QUATERNION headPositions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES];
IVAS_VECTOR3 Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES];
float crossfade[L_FRAME48k / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES];
#ifdef SPLIT_REND_WITH_HEAD_ROT
IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis;
ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis;
#endif
ivas_orient_trk_state_t *hOrientationTracker;
......@@ -692,30 +685,11 @@ typedef struct ivas_binaural_head_track_struct
ivas_orient_trk_state_t *OrientationTracker;
#ifdef SPLIT_REND_WITH_HEAD_ROT
IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis;
ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis;
#endif
} HEAD_TRACK_DATA, *HEAD_TRACK_DATA_HANDLE;
/*----------------------------------------------------------------------------------*
* External orientation data structure
*----------------------------------------------------------------------------------*/
typedef struct ivas_external_orientation_struct
{
int8_t enableHeadRotation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable, 2 - freeze to previous rotation */
int8_t enableExternalOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable, 2 - freeze to previous orientation */
int8_t enableRotationInterpolation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable */
int16_t numFramesToTargetOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* Number of frames until target orientation is reached */
IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES]; /* External orientation in quaternions */
int16_t num_subframes;
} EXTERNAL_ORIENTATION_DATA, *EXTERNAL_ORIENTATION_HANDLE;
/*----------------------------------------------------------------------------------*
* Combined orientation data structure for the external orienations and head orientation
*----------------------------------------------------------------------------------*/
typedef struct ivas_combined_orientation_struct
{
int16_t enableCombinedOrientation[MAX_PARAM_SPATIAL_SUBFRAMES];
......@@ -741,7 +715,7 @@ typedef struct ivas_combined_orientation_struct
int16_t shd_rot_max_order;
IVAS_VECTOR3 listenerPos[MAX_PARAM_SPATIAL_SUBFRAMES];
#ifdef SPLIT_REND_WITH_HEAD_ROT
IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis;
ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis;
int16_t sr_low_res_flag;
#endif
IVAS_QUATERNION Quaternion_frozen_ext;
......@@ -756,6 +730,21 @@ typedef struct ivas_combined_orientation_struct
int16_t cur_subframe_samples_rendered_start;
} COMBINED_ORIENTATION_DATA, *COMBINED_ORIENTATION_HANDLE;
/*----------------------------------------------------------------------------------*
* External orientation data structure
*----------------------------------------------------------------------------------*/
typedef struct ivas_external_orientation_struct
{
int8_t enableHeadRotation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable, 2 - freeze to previous rotation */
int8_t enableExternalOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable, 2 - freeze to previous orientation */
int8_t enableRotationInterpolation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable */
int16_t numFramesToTargetOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* Number of frames until target orientation is reached */
IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES]; /* External orientation in quaternions */
int16_t num_subframes;
} EXTERNAL_ORIENTATION_DATA, *EXTERNAL_ORIENTATION_HANDLE;
/*----------------------------------------------------------------------------------*
* Reverberator structure
......@@ -839,7 +828,6 @@ typedef struct ivas_reverb_state_t
uint16_t fft_subblock_size; /* fft block processing size */
uint16_t num_fft_subblocks; /* number of fft subblocks */
uint16_t full_block_size; /* full block processing size */
} REVERB_DATA, *REVERB_HANDLE;
......@@ -938,17 +926,26 @@ typedef struct
{
int16_t modelROM; /* Flag that indicates that the model resides in ROM (controls init/dealloc). */
int16_t UseItdModel; /* Controls whether ITD model is used. */
#ifdef FIX_989_TD_REND_ROM
int16_t K; /* Length of filter */
#else
int16_t SplineDegree; /* Degree of the spline functions */
int16_t K; /* Length of filter */
int16_t elevDim2;
#endif
int16_t elevDim3;
int16_t AlphaN; /* Number of rows in Alpha matrices */
int16_t num_unique_azim_splines;
int16_t elevSegSamples;
#ifdef FIX_989_TD_REND_ROM
const int16_t *elevBsLen;
const int16_t *elevBsStart;
#else
int16_t elevBsLen[HRTF_MODEL_BSPLINE_NUM_COEFFS];
int16_t elevBsStart[HRTF_MODEL_BSPLINE_NUM_COEFFS];
const int16_t *azimDim2;
#endif
const int16_t *azimDim3;
const int16_t *azim_start_idx;
const int16_t *azimSegSamples;
......@@ -975,7 +972,12 @@ typedef struct
float *ER_dyn;
float *elevBsShape_dyn;
float *elevKSeq_dyn;
#ifdef FIX_989_TD_REND_ROM
int16_t *elevBsLen_dyn;
int16_t *elevBsStart_dyn;
#else
int16_t *azimDim2_dyn;
#endif
int16_t *azimDim3_dyn;
int16_t *azim_start_idx_dyn;
int16_t *azimSegSamples_dyn;
......@@ -987,6 +989,13 @@ typedef struct
typedef struct
{
#ifdef FIX_989_TD_REND_ROM
int16_t elevDim3;
const float *elevKSeq; /* Array, length elevDim3-2 */
int16_t azimDim3;
const float *azimKSeq; /* Array, length azimDim3-2 */
const float *W; /* Array, size (elevDim3*azimDim3) x K */
#else
int16_t N; /* Polynomial degree */
int16_t elevDim2;
......@@ -996,14 +1005,25 @@ typedef struct
int16_t azimDim3;
const float *azimKSeq; /* Array, length azimDim3-2 */
const float *W; /* Array, size (elevDim3*azimDim3) x K */
#endif
#ifdef FIX_989_TD_REND_ROM
const int16_t *azimBsLen;
const int16_t *azimBsStart;
#else
int16_t azimBsLen[HRTF_MODEL_BSPLINE_NUM_COEFFS];
int16_t azimBsStart[HRTF_MODEL_BSPLINE_NUM_COEFFS];
#endif
const float *azimBsShape;
int16_t azimSegSamples;
#ifdef FIX_989_TD_REND_ROM
const int16_t *elevBsLen;
const int16_t *elevBsStart;
#else
int16_t elevBsLen[HRTF_MODEL_BSPLINE_NUM_COEFFS];
int16_t elevBsStart[HRTF_MODEL_BSPLINE_NUM_COEFFS];
#endif
const float *elevBsShape;
int16_t elevSegSamples;
float resamp_factor;
......@@ -1014,6 +1034,12 @@ typedef struct
float *W_dyn;
float *azimBsShape_dyn;
float *elevBsShape_dyn;
#ifdef FIX_989_TD_REND_ROM
int16_t *azimBsLen_dyn;
int16_t *azimBsStart_dyn;
int16_t *elevBsLen_dyn;
int16_t *elevBsStart_dyn;
#endif
} ModelParamsITD_t;
......@@ -1367,20 +1393,20 @@ typedef struct ivas_split_rend_huffman_cfg_t
typedef struct ivas_binaural_head_rot_split_rendering_huff_struct
{
ivas_split_rend_huffman_cfg_t pred[2];
int16_t pred_idx_trav[2][IVAS_SPLIT_REND_PRED_63QUANT_PNTS];
int16_t pred_idx_trav[2][ISAR_SPLIT_REND_PRED_63QUANT_PNTS];
int16_t pred_base2_code_len[2];
ivas_split_rend_huffman_cfg_t pred_roll;
int16_t pred_roll_idx_trav[IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS];
int16_t pred_roll_idx_trav[ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS];
int16_t pred_roll_base2_code_len;
ivas_split_rend_huffman_cfg_t gd;
int16_t gd_base2_code_len;
int16_t gd_idx_trav[IVAS_SPLIT_REND_D_QUANT_PNTS];
int16_t gd_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS];
ivas_split_rend_huffman_cfg_t p_gd;
int16_t p_gd_base2_code_len;
int16_t p_gd_idx_trav[IVAS_SPLIT_REND_D_QUANT_PNTS];
int16_t p_gd_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS];
ivas_split_rend_huffman_cfg_t p_gd_diff;
int16_t p_gd_diff_base2_code_len;
int16_t p_gd_diff_idx_trav[IVAS_SPLIT_REND_D_QUANT_PNTS];
int16_t p_gd_diff_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS];
} BIN_HR_SPLIT_REND_HUFF, *BIN_HR_SPLIT_REND_HUFF_HANDLE;
......@@ -1392,7 +1418,7 @@ typedef struct ivas_binaural_head_rot_split_post_rendering_struct
int16_t low_Res;
float fix_pos_rot_mat[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS];
IVAS_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1];
ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1];
BIN_HR_SPLIT_REND_HUFF huff_cfg;
#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
float mixer_mat_re[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS];
......@@ -1416,7 +1442,7 @@ typedef struct ivas_binaural_head_rot_split_pre_rendering_struct
{
BIN_HR_SPLIT_REND_MD rot_md[MAX_HEAD_ROT_POSES - 1][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS];
float fix_pos_rot_mat[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS];
IVAS_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1];
ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1];
BIN_HR_SPLIT_REND_HUFF huff_cfg;
#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
HANDLE_CLDFB_FILTER_BANK cldfbSynRotBinDec[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS];
......@@ -1448,10 +1474,7 @@ typedef struct
{
float Cldfb_Prev_BinReal[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX];
float Cldfb_Prev_BinImag[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX];
#if CLDFB_PLC_XF > 0
float xf_bet[2][CLDFB_NO_CHANNELS_MAX][CLDFB_PLC_XF];
#endif
} CLDFB_PLC, *CLDFB_PLC_HANDLE;
typedef struct
......@@ -1459,6 +1482,7 @@ typedef struct
CLDFB_PLC CldfbPLC_state;
int16_t prev_bfi;
int16_t bf_count;
int16_t iNumSubSets;
} SPLIT_REND_PLC_STRUCT, *SPLIT_REND_PLC_HANDLE;
......@@ -1479,50 +1503,6 @@ typedef struct ivas_binaural_head_rot_split_rendering_lcld_dec_struct
} BIN_HR_SPLIT_LCLD_DEC, *BIN_HR_SPLIT_LCLD_DEC_HANDLE;
typedef struct
{
#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
HANDLE_CLDFB_FILTER_BANK cldfbAna[( 1 + MAX_HEAD_ROT_POSES ) * BINAURAL_CHANNELS];
#else
HANDLE_CLDFB_FILTER_BANK cldfbAna[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS];
#endif
HANDLE_CLDFB_FILTER_BANK cldfbSyn[BINAURAL_CHANNELS];
} CLDFB_HANDLES_WRAPPER, *CLDFB_HANDLES_WRAPPER_HANDLE;
typedef struct
{
int16_t num_poses;
float relative_head_poses[MAX_HEAD_ROT_POSES][3];
int16_t dof;
int16_t hq_mode;
IVAS_SPLIT_REND_ROT_AXIS rot_axis;
IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode;
} MULTI_BIN_REND_POSE_DATA;
typedef struct
{
MULTI_BIN_REND_POSE_DATA multiBinPoseData;
BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend;
BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc;
CLDFB_HANDLES_WRAPPER_HANDLE hCldfbHandles;
IVAS_LC3PLUS_ENC_HANDLE hLc3plusEnc;
BINAURAL_TD_OBJECT_RENDERER_HANDLE hTdRendHandles[MAX_HEAD_ROT_POSES - 1];
float *lc3plusDelayBuffers[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; /* Used to time-align head pose correction metadata with LC3plus-coded reference audio */
int32_t lc3plusDelaySamples;
} SPLIT_REND_WRAPPER;
typedef struct
{
MULTI_BIN_REND_POSE_DATA multiBinPoseData;
BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend;
BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec;
int16_t first_good_frame_received;
IVAS_LC3PLUS_DEC_HANDLE hLc3plusDec;
} SPLIT_POST_REND_WRAPPER;
#endif
......
......@@ -35,6 +35,9 @@
#include "prot.h"
#include "ivas_prot.h"
#include "ivas_prot_rend.h"
#include "isar_prot.h"
#include "isar_stat.h"
#include "lib_isar_pre_rend.h"
#include "ivas_cnst.h"
#include "ivas_rom_com.h"
#include "ivas_rom_rend.h"
......@@ -48,30 +51,10 @@
* Local constants
*-------------------------------------------------------------------*/
/* Maximum buffer length (per channel) in samples.
* Keep this separate from L_FRAME48k in case we want to support different size later */
#define MAX_BUFFER_LENGTH_PER_CHANNEL ( L_FRAME48k )
#ifdef SPLIT_REND_WITH_HEAD_ROT
#define MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL ( MAX_BUFFER_LENGTH_PER_CHANNEL * 2 )
#endif
/* Maximum buffer length (total) in samples. */
/* Maximum buffer length (total) in samples. */
#ifdef SPLIT_REND_WITH_HEAD_ROT
#define MAX_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS )
#define MAX_CLDFB_BUFFER_LENGTH ( MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS )
#define MAX_BIN_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * BINAURAL_CHANNELS )
#define MAX_CLDFB_BIN_BUFFER_LENGTH ( MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL * BINAURAL_CHANNELS )
#else
#define MAX_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS )
#endif
#define MAX_BIN_DELAY_SAMPLES 150 /* Maximum supported rendering latency for binaural IRs */
/* Frame size required when rendering to binaural */
#define BINAURAL_RENDERING_FRAME_SIZE_MS 5
/*-------------------------------------------------------------------*
* Local types
*-------------------------------------------------------------------*/
......@@ -201,18 +184,6 @@ typedef struct
DIRAC_ANA_HANDLE hDirAC;
} input_sba;
#ifdef SPLIT_REND_WITH_HEAD_ROT
typedef struct
{
input_base base;
SPLIT_POST_REND_WRAPPER splitPostRendWrapper;
float *bufferData;
int16_t numCachedSamples; /* Number of decoded samples in bufferData that have not yet been played out */
IVAS_REND_BitstreamBuffer *hBits;
} input_split_post_rend;
#endif
typedef struct
{
input_base base;
......@@ -245,9 +216,6 @@ struct IVAS_REND
input_mc inputsMc[RENDERER_MAX_MC_INPUTS];
input_sba inputsSba[RENDERER_MAX_SBA_INPUTS];
input_masa inputsMasa[RENDERER_MAX_MASA_INPUTS];
#ifdef SPLIT_REND_WITH_HEAD_ROT
input_split_post_rend inputsSplitPost[RENDERER_MAX_BIN_INPUTS];
#endif
AUDIO_CONFIG inputConfig;
AUDIO_CONFIG outputConfig;
......@@ -282,6 +250,20 @@ static ivas_error initMasaExtRenderer( input_masa *inputMasa, const AUDIO_CONFIG
static void freeMasaExtRenderer( MASA_EXT_REND_HANDLE *hMasaExtRendOut );
#ifdef SPLIT_REND_WITH_HEAD_ROT
static ivas_error renderSbaToMultiBinauralCldfb(
input_sba *sbaInput,
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 low_res_pre_rend_rot,
const int16_t num_subframes );
static ivas_error renderSbaToMultiBinaural(
input_sba *sbaInput,
const AUDIO_CONFIG outConfig,
float out[][L_FRAME48k] );
#endif
/*-------------------------------------------------------------------*
* Local functions
*-------------------------------------------------------------------*/
......@@ -356,7 +338,7 @@ static float *getSmplPtr(
#ifdef SPLIT_REND_WITH_HEAD_ROT
static void convertBitsBufferToInternalBitsBuff(
const IVAS_REND_BitstreamBuffer outBits,
IVAS_SPLIT_REND_BITS_HANDLE hBits )
ISAR_SPLIT_REND_BITS_HANDLE hBits )
{
hBits->bits_buf = outBits.bits;
hBits->bits_read = outBits.config.bitsRead;
......@@ -371,7 +353,7 @@ static void convertBitsBufferToInternalBitsBuff(
static void convertInternalBitsBuffToBitsBuffer(
IVAS_REND_BitstreamBuffer *hOutBits,
const IVAS_SPLIT_REND_BITS_DATA bits )
const ISAR_SPLIT_REND_BITS_DATA bits )
{
hOutBits->bits = bits.bits_buf;
hOutBits->config.bitsRead = bits.bits_read;
......@@ -2630,35 +2612,6 @@ static ivas_error initSbaPanGainsForSbaOut(
}
#ifdef SPLIT_REND_WITH_HEAD_ROT
static ivas_error updateSplitPostRendPanGains(
input_split_post_rend *inputSplitPostRend,
const AUDIO_CONFIG outConfig,
RENDER_CONFIG_DATA *hRendCfg )
{
ivas_error error;
rendering_context rendCtx;
int16_t numOutChannels;
if ( ( error = getAudioConfigNumChannels( outConfig, &numOutChannels ) ) != IVAS_ERR_OK )
{
return error;
}
rendCtx = inputSplitPostRend->base.ctx;
ivas_renderSplitGetMultiBinPoseData( &hRendCfg->split_rend_config, &inputSplitPostRend->splitPostRendWrapper.multiBinPoseData, rendCtx.pHeadRotData->sr_pose_pred_axis );
if ( ( error = ivas_splitBinPostRendOpen( &inputSplitPostRend->splitPostRendWrapper.hBinHrSplitPostRend, &inputSplitPostRend->splitPostRendWrapper.multiBinPoseData, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK )
{
return error;
}
return IVAS_ERR_OK;
}
#endif
static ivas_error updateSbaPanGains(
input_sba *inputSba,
const AUDIO_CONFIG outConfig,
......@@ -2691,7 +2644,7 @@ static ivas_error updateSbaPanGains(
case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED:
case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM:
{
if ( hRendCfg->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV )
if ( hRendCfg->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV )
{
assert( inConfig == IVAS_AUDIO_CONFIG_HOA3 && ( *rendCtx.pOutSampleRate == 48000 ) && "split binaural fast conv mode is currently supported with HOA3 input and 48k sampling rate only" );
......@@ -2713,7 +2666,7 @@ static ivas_error updateSbaPanGains(
#endif
case IVAS_AUDIO_CONFIG_BINAURAL:
#ifdef SPLIT_REND_WITH_HEAD_ROT
if ( hRendCfg->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV )
if ( hRendCfg->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV )
{
if ( ( error = ivas_rend_openCldfbRend( &inputSba->cldfbRendWrapper, inConfig, outConfig, &rendCtx.pSplitRendWrapper->multiBinPoseData, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK )
{
......@@ -2770,52 +2723,6 @@ static ivas_error updateSbaPanGains(
}
#ifdef SPLIT_REND_WITH_HEAD_ROT
static ivas_error setRendInputActiveSplitPostRend(
void *input,
const AUDIO_CONFIG inConfig,
const IVAS_REND_InputId id,
RENDER_CONFIG_DATA *hRendCfg,
#if defined _MSC_VER && !defined __clang__
#ifdef _MSC_VER
#pragma warning( disable : 4100 )
#endif
hrtf_handles *hrtfs
#ifdef _MSC_VER
#pragma warning( default : 4100 )
#endif
#else
hrtf_handles *hrtfs __attribute__( ( unused ) ) /* avoid unused parameter warning when compiling with clang */
#endif
)
{
ivas_error error;
rendering_context rendCtx;
AUDIO_CONFIG outConfig;
input_split_post_rend *inputSplitPostRend;
inputSplitPostRend = (input_split_post_rend *) input;
rendCtx = inputSplitPostRend->base.ctx;
outConfig = *rendCtx.pOutConfig;
if ( ( error = allocateInputBaseBufferData( &inputSplitPostRend->bufferData, MAX_CLDFB_BIN_BUFFER_LENGTH ) ) != IVAS_ERR_OK )
{
return error;
}
initRendInputBase( &inputSplitPostRend->base, inConfig, id, rendCtx, inputSplitPostRend->bufferData, MAX_CLDFB_BIN_BUFFER_LENGTH );
inputSplitPostRend->numCachedSamples = 0;
if ( ( error = updateSplitPostRendPanGains( inputSplitPostRend, outConfig, hRendCfg ) ) != IVAS_ERR_OK )
{
return error;
}
return IVAS_ERR_OK;
}
#endif
static ivas_error initSbaMasaRendering(
input_sba *inputSba,
int32_t inSampleRate )
......@@ -2908,38 +2815,6 @@ static ivas_error setRendInputActiveSba(
}
#ifdef SPLIT_REND_WITH_HEAD_ROT
static void clearInputSplitRend(
input_split_post_rend *inputSplitRend )
{
rendering_context rendCtx;
rendCtx = inputSplitRend->base.ctx;
freeInputBaseBufferData( &inputSplitRend->bufferData );
initRendInputBase( &inputSplitRend->base, IVAS_AUDIO_CONFIG_INVALID, 0, rendCtx, NULL, 0 );
if ( inputSplitRend->splitPostRendWrapper.hBinHrSplitPostRend != NULL )
{
ivas_splitBinPostRendClose( &inputSplitRend->splitPostRendWrapper.hBinHrSplitPostRend );
}
if ( inputSplitRend->splitPostRendWrapper.hSplitBinLCLDDec != NULL )
{
ivas_splitBinLCLDDecClose( &inputSplitRend->splitPostRendWrapper.hSplitBinLCLDDec );
}
if ( inputSplitRend->splitPostRendWrapper.hLc3plusDec != NULL )
{
IVAS_LC3PLUS_DEC_Close( &inputSplitRend->splitPostRendWrapper.hLc3plusDec );
}
return;
}
#endif /* SPLIT_REND_WITH_HEAD_ROT */
static void clearInputSba(
input_sba *inputSba )
{
......@@ -3040,62 +2915,6 @@ static void clearInputMasa(
return;
}
#ifdef SPLIT_REND_WITH_HEAD_ROT
static ivas_error initSplitRend(
SPLIT_REND_WRAPPER *pSplitRendWrapper,
IVAS_REND_AudioBuffer *pSplitRendEncBuffer,
const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config,
IVAS_REND_HeadRotData headRotData,
const int32_t outputSampleRate,
const AUDIO_CONFIG outConfig,
const int16_t cldfb_in_flag,
const int16_t num_subframes )
{
ivas_error error;
IVAS_REND_AudioBufferConfig bufConfig;
if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
{
if ( pSplit_rend_config->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
{
ivas_renderSplitGetMultiBinPoseData( pSplit_rend_config, &pSplitRendWrapper->multiBinPoseData, headRotData.sr_pose_pred_axis );
}
else if ( pSplit_rend_config->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE )
{
ivas_renderSplitUpdateNoCorrectionPoseData( pSplit_rend_config, &pSplitRendWrapper->multiBinPoseData );
}
if ( ( error = ivas_split_renderer_open( pSplitRendWrapper, pSplit_rend_config, outputSampleRate, cldfb_in_flag, outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, num_subframes ) ) != IVAS_ERR_OK )
{
return error;
}
/*allocate for CLDFB in and change to TD during process if needed*/
bufConfig.numSamplesPerChannel = MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL;
bufConfig.numChannels = BINAURAL_CHANNELS * pSplitRendWrapper->multiBinPoseData.num_poses;
bufConfig.is_cldfb = 1;
pSplitRendEncBuffer->config = bufConfig;
if ( ( pSplitRendEncBuffer->data = malloc( bufConfig.numChannels * bufConfig.numSamplesPerChannel * sizeof( float ) ) ) == NULL )
{
return IVAS_ERR_FAILED_ALLOC;
}
}
else
{
IVAS_REND_AudioBufferConfig bufConfig2;
bufConfig2.numSamplesPerChannel = 0;
bufConfig2.numChannels = 0;
bufConfig2.is_cldfb = 0;
pSplitRendEncBuffer->config = bufConfig2;
pSplitRendEncBuffer->data = NULL;
}
return IVAS_ERR_OK;
}
#endif
/*-------------------------------------------------------------------------
* IVAS_REND_Open()
......@@ -3191,7 +3010,7 @@ ivas_error IVAS_REND_Open(
/* Initialize inputs */
#ifdef SPLIT_REND_WITH_HEAD_ROT
ivas_init_split_rend_handles( &hIvasRend->splitRendWrapper );
isar_init_split_rend_handles( &hIvasRend->splitRendWrapper );
hIvasRend->splitRendEncBuffer.data = NULL;
#endif
......@@ -3260,19 +3079,6 @@ ivas_error IVAS_REND_Open(
hIvasRend->inputsMasa[i].hMasaExtRend = NULL;
}
#ifdef SPLIT_REND_WITH_HEAD_ROT
for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i )
{
initRendInputBase( &hIvasRend->inputsSplitPost[i].base, IVAS_AUDIO_CONFIG_INVALID, 0, getRendCtx( hIvasRend ), NULL, 0 );
ivas_init_split_post_rend_handles( &hIvasRend->inputsSplitPost[i].splitPostRendWrapper );
#ifdef SPLIT_REND_WITH_HEAD_ROT
hIvasRend->splitRendBFI = 0;
#endif
hIvasRend->inputsSplitPost[i].bufferData = NULL;
}
#endif
hIvasRend->hHrtfs.hHrtfFastConv = NULL;
hIvasRend->hHrtfs.hHrtfParambin = NULL;
......@@ -3556,15 +3362,6 @@ static ivas_error getInputById(
}
pInputBase = &hIvasRend->inputsMasa[inputIndex].base;
break;
#ifdef SPLIT_REND_WITH_HEAD_ROT
case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL:
if ( inputIndex > RENDERER_MAX_BIN_INPUTS )
{
return IVAS_ERR_INVALID_INPUT_ID;
}
pInputBase = &hIvasRend->inputsSplitPost[inputIndex].base;
break;
#endif
default:
return IVAS_ERR_INVALID_INPUT_ID;
}
......@@ -3630,15 +3427,6 @@ static ivas_error getConstInputById(
}
pInputBase = &hIvasRend->inputsMasa[inputIndex].base;
break;
#ifdef SPLIT_REND_WITH_HEAD_ROT
case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL:
if ( inputIndex > RENDERER_MAX_BIN_INPUTS )
{
return IVAS_ERR_INVALID_INPUT_ID;
}
pInputBase = &hIvasRend->inputsSplitPost[inputIndex].base;
break;
#endif
default:
return IVAS_ERR_INVALID_INPUT_ID;
}
......@@ -3731,7 +3519,7 @@ static int16_t getCldfbRendFlag(
{
isCldfbRend = 0;
}
else if ( ( numMasaInputs > 0 ) || ( numSbaInputs > 0 && hIvasRend->hRendererConfig->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) )
else if ( ( numMasaInputs > 0 ) || ( numSbaInputs > 0 && hIvasRend->hRendererConfig->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) )
{
isCldfbRend = 1;
}
......@@ -3740,24 +3528,66 @@ static int16_t getCldfbRendFlag(
return isCldfbRend;
}
/*-------------------------------------------------------------------------
* Function ivas_pre_rend_init()
*
*
*------------------------------------------------------------------------*/
static void closeSplitRend(
static ivas_error ivas_pre_rend_init(
SPLIT_REND_WRAPPER *pSplitRendWrapper,
IVAS_REND_AudioBuffer *pSplitRendEncBuffer )
IVAS_REND_AudioBuffer *pSplitRendEncBuffer,
ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config,
IVAS_REND_HeadRotData headRotData,
const int32_t outputSampleRate,
const AUDIO_CONFIG outConfig,
const int16_t cldfb_in_flag,
const int16_t num_subframes )
{
ivas_error error;
IVAS_REND_AudioBufferConfig bufConfig;
if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
{
if ( pSplit_rend_config->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
{
ISAR_PRE_REND_GetMultiBinPoseData( pSplit_rend_config, &pSplitRendWrapper->multiBinPoseData, headRotData.sr_pose_pred_axis );
}
else if ( pSplit_rend_config->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE )
{
ivas_split_renderer_close( pSplitRendWrapper );
isar_renderSplitUpdateNoCorrectionPoseData( pSplit_rend_config, &pSplitRendWrapper->multiBinPoseData );
}
if ( pSplitRendEncBuffer->data != NULL )
if ( ( error = ISAR_PRE_REND_open( pSplitRendWrapper, pSplit_rend_config, outputSampleRate, cldfb_in_flag, outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, num_subframes, 0 ) ) != IVAS_ERR_OK )
{
free( pSplitRendEncBuffer->data );
pSplitRendEncBuffer->data = NULL;
return error;
}
pSplitRendEncBuffer->config.numChannels = 0;
pSplitRendEncBuffer->config.numSamplesPerChannel = 0;
/*allocate for CLDFB in and change to TD during process if needed*/
bufConfig.numSamplesPerChannel = MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL;
bufConfig.numChannels = BINAURAL_CHANNELS * pSplitRendWrapper->multiBinPoseData.num_poses;
bufConfig.is_cldfb = 1;
pSplitRendEncBuffer->config = bufConfig;
return;
if ( ( pSplitRendEncBuffer->data = malloc( bufConfig.numChannels * bufConfig.numSamplesPerChannel * sizeof( float ) ) ) == NULL )
{
return IVAS_ERR_FAILED_ALLOC;
}
}
else
{
IVAS_REND_AudioBufferConfig bufConfig2;
bufConfig2.numSamplesPerChannel = 0;
bufConfig2.numChannels = 0;
bufConfig2.is_cldfb = 0;
pSplitRendEncBuffer->config = bufConfig2;
pSplitRendEncBuffer->data = NULL;
}
return IVAS_ERR_OK;
}
#endif
......@@ -3792,12 +3622,7 @@ ivas_error IVAS_REND_AddInput(
int16_t cldfb_in_flag;
cldfb_in_flag = getCldfbRendFlag( hIvasRend, getAudioConfigType( inConfig ) );
if ( ( error = ivas_split_rend_choose_default_codec( &hIvasRend->hRendererConfig->split_rend_config.codec, &hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, hIvasRend->num_subframes ) ) != IVAS_ERR_OK )
{
return error;
}
if ( ( error = initSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, hIvasRend->num_subframes ) ) != IVAS_ERR_OK )
if ( ( error = ivas_pre_rend_init( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, hIvasRend->num_subframes ) ) != IVAS_ERR_OK )
{
return error;
}
......@@ -3830,14 +3655,6 @@ ivas_error IVAS_REND_AddInput(
inputStructSize = sizeof( *hIvasRend->inputsMasa );
activateInput = setRendInputActiveMasa;
break;
#ifdef SPLIT_REND_WITH_HEAD_ROT
case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL:
maxNumInputsOfType = RENDERER_MAX_BIN_INPUTS;
inputsArray = hIvasRend->inputsSplitPost;
inputStructSize = sizeof( *hIvasRend->inputsSplitPost );
activateInput = setRendInputActiveSplitPostRend;
break;
#endif
default:
return IVAS_ERR_INVALID_INPUT_FORMAT;
}
......@@ -4106,11 +3923,6 @@ ivas_error IVAS_REND_RemoveInput(
case IVAS_REND_AUDIO_CONFIG_TYPE_MASA:
clearInputMasa( (input_masa *) inputBase );
break;
#ifdef SPLIT_REND_WITH_HEAD_ROT
case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL:
clearInputSplitRend( (input_split_post_rend *) inputBase );
break;
#endif
default:
return IVAS_ERR_INVALID_INPUT_FORMAT;
}
......@@ -4236,7 +4048,7 @@ ivas_error IVAS_REND_GetDelay(
#ifdef SPLIT_REND_WITH_HEAD_ROT
if ( hIvasRend->splitRendWrapper.hBinHrSplitPreRend != NULL )
{
if ( hIvasRend->hRendererConfig->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV )
if ( hIvasRend->hRendererConfig->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV )
{
latency_ns = hIvasRend->inputsSba[i].cldfbRendWrapper.binaural_latency_ns;
}
......@@ -4261,31 +4073,6 @@ ivas_error IVAS_REND_GetDelay(
}
}
#ifdef SPLIT_REND_WITH_HEAD_ROT
for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; i++ )
{
if ( hIvasRend->inputsSplitPost[i].base.inConfig != IVAS_AUDIO_CONFIG_INVALID )
{
latency_ns = 0;
if ( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hLc3plusDec != NULL )
{
int32_t lc3plusDelaySamples;
IVAS_LC3PLUS_DEC_GetDelay( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hLc3plusDec, &lc3plusDelaySamples );
latency_ns = (int32_t) roundf( lc3plusDelaySamples * 1000000000.f / *timeScale );
}
if ( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
{
latency_ns += IVAS_FB_DEC_DELAY_NS;
}
else if ( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hSplitBinLCLDDec != NULL )
{
latency_ns += IVAS_FB_DEC_DELAY_NS;
}
max_latency_ns = max( max_latency_ns, latency_ns );
}
}
#endif
for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; i++ )
{
if ( hIvasRend->inputsMasa[i].base.inConfig != IVAS_AUDIO_CONFIG_INVALID )
......@@ -4591,10 +4378,16 @@ int16_t IVAS_REND_GetRenderConfig(
hRCout->split_rend_config.dof = 3;
hRCout->split_rend_config.hq_mode = 0;
hRCout->split_rend_config.codec_delay_ms = 0;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
hRCout->split_rend_config.isar_frame_size_ms = 20;
#endif
hRCout->split_rend_config.codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */
hRCout->split_rend_config.codec = IVAS_SPLIT_REND_CODEC_DEFAULT;
hRCout->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB;
hRCout->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT;
hRCout->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB;
hRCout->split_rend_config.rendererSelection = hRCin->split_rend_config.rendererSelection;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
hRCout->split_rend_config.lc3plus_highres = 0;
#endif
#endif
hRCout->roomAcoustics.use_er = hRCin->roomAcoustics.use_er;
......@@ -4616,8 +4409,17 @@ int16_t IVAS_REND_FeedRenderConfig(
)
{
RENDER_CONFIG_HANDLE hRenderConfig;
#ifdef SPLIT_REND_WITH_HEAD_ROT
#ifdef FIX_1053_REVERB_RECONFIGURATION
uint16_t i;
input_ism *pIsmInput;
input_masa *pMasaInput;
input_mc *pMcInput;
input_sba *pSbaInput;
ivas_error error;
#else
#ifdef SPLIT_REND_WITH_HEAD_ROT
ivas_error error;
#endif
#endif
if ( hIvasRend == NULL || hIvasRend->hRendererConfig == NULL )
......@@ -4649,80 +4451,179 @@ int16_t IVAS_REND_FeedRenderConfig(
mvr2r( renderConfig.roomAcoustics.AbsCoeff, hRenderConfig->roomAcoustics.AbsCoeff, IVAS_ROOM_ABS_COEFF );
}
#ifdef FIX_1053_REVERB_RECONFIGURATION
/* Re-initialize reverb instance if already available */
/* ISM inputs */
for ( i = 0, pIsmInput = hIvasRend->inputsIsm; i < RENDERER_MAX_ISM_INPUTS; ++i, ++pIsmInput )
{
if ( pIsmInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID )
{
/* Skip inactive inputs */
continue;
}
if ( pIsmInput->hReverb != NULL )
{
if ( ( error = ivas_reverb_open( &pIsmInput->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pIsmInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK )
{
return error;
}
}
#ifdef SPLIT_REND_WITH_HEAD_ROT
hRenderConfig->split_rend_config = renderConfig.split_rend_config;
/* Overwrite any pose correction settings if 0 DOF (no pose correction) was selected */
if ( hRenderConfig->split_rend_config.dof == 0 )
if ( pIsmInput->crendWrapper != NULL && pIsmInput->crendWrapper->hCrend[0] != NULL )
#else
if ( pIsmInput->crendWrapper != NULL && pIsmInput->crendWrapper->hCrend != NULL )
#endif
{
#ifdef SPLIT_REND_WITH_HEAD_ROT
if ( ( error = ivas_reverb_open( &pIsmInput->crendWrapper->hCrend[0]->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pIsmInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK )
#else
if ( ( error = ivas_reverb_open( &pIsmInput->crendWrapper->hCrend->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pIsmInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK )
#endif
{
hRenderConfig->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE;
return error;
}
}
}
hRenderConfig->split_rend_config.codec = renderConfig.split_rend_config.codec;
/* MASA inputs */
for ( i = 0, pMasaInput = hIvasRend->inputsMasa; i < RENDERER_MAX_MASA_INPUTS; ++i, ++pMasaInput )
{
if ( pMasaInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID )
{
/* Skip inactive inputs */
continue;
}
if ( ( error = ivas_split_rend_validate_config( &hRenderConfig->split_rend_config, ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ) ) != IVAS_ERR_OK )
if ( pMasaInput->hMasaExtRend != NULL )
{
#ifdef SPLIT_REND_WITH_HEAD_ROT
if ( pMasaInput->hMasaExtRend->hDiracDecBin[0] != NULL && pMasaInput->hMasaExtRend->hDiracDecBin[0]->hReverb != NULL )
{
ivas_binaural_reverb_close( &pMasaInput->hMasaExtRend->hDiracDecBin[0]->hReverb );
if ( ( error = ivas_binaural_reverb_init( &pMasaInput->hMasaExtRend->hDiracDecBin[0]->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, pMasaInput->hMasaExtRend->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &( hRenderConfig->roomAcoustics ), *pMasaInput->base.ctx.pOutSampleRate, NULL, NULL ) ) != IVAS_ERR_OK )
{
return error;
}
}
#else
if ( pMasaInput->hMasaExtRend->hDiracDecBin != NULL && pMasaInput->hMasaExtRend->hDiracDecBin->hReverb != NULL )
{
ivas_binaural_reverb_close( &pMasaInput->hMasaExtRend->hDiracDecBin->hReverb );
if ( ( error = ivas_binaural_reverb_init( &pMasaInput->hMasaExtRend->hDiracDecBin->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, pMasaInput->hMasaExtRend->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &( hRenderConfig->roomAcoustics ), *pMasaInput->base.ctx.pOutSampleRate, NULL, NULL ) ) != IVAS_ERR_OK )
{
return error;
}
}
#endif
if ( pMasaInput->hMasaExtRend->hReverb != NULL )
{
ivas_binaural_reverb_close( &pMasaInput->hMasaExtRend->hReverb );
if ( ( error = ivas_binaural_reverb_init( &pMasaInput->hMasaExtRend->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, pMasaInput->hMasaExtRend->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &( hRenderConfig->roomAcoustics ), *pMasaInput->base.ctx.pOutSampleRate, NULL, NULL ) ) != IVAS_ERR_OK )
{
return error;
}
}
}
}
/* Must re-initialize split rendering config in case renderer config is updated after adding renderer inputs */
/* if its not initialized yet then no need to re-initialize, initialization will happen while adding inputs*/
if ( hIvasRend->splitRendEncBuffer.data != NULL && hIvasRend->hRendererConfig != NULL )
/* Multi-channel inputs */
for ( i = 0, pMcInput = hIvasRend->inputsMc; i < RENDERER_MAX_MC_INPUTS; ++i, ++pMcInput )
{
int16_t cldfb_in_flag;
cldfb_in_flag = getCldfbRendFlag( hIvasRend, IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN );
closeSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer );
if ( pMcInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID )
{
/* Skip inactive inputs */
continue;
}
if ( ( error = ivas_split_rend_choose_default_codec( &hIvasRend->hRendererConfig->split_rend_config.codec, &hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, hIvasRend->num_subframes ) ) != IVAS_ERR_OK )
if ( pMcInput->hReverb != NULL )
{
if ( ( error = ivas_reverb_open( &pMcInput->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pMcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK )
{
return error;
}
if ( ( error = initSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, hIvasRend->num_subframes ) ) != IVAS_ERR_OK )
}
#ifdef SPLIT_REND_WITH_HEAD_ROT
if ( pMcInput->crendWrapper != NULL && pMcInput->crendWrapper->hCrend[0] && pMcInput->crendWrapper->hCrend[0]->hReverb != NULL )
{
if ( ( error = ivas_reverb_open( &pMcInput->crendWrapper->hCrend[0]->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pMcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK )
{
return error;
}
}
#else
if ( pMcInput->crendWrapper != NULL && pMcInput->crendWrapper->hCrend && pMcInput->crendWrapper->hCrend->hReverb != NULL )
{
if ( ( error = ivas_reverb_open( &pMcInput->crendWrapper->hCrend->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pMcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK )
{
return error;
}
}
#endif
return IVAS_ERR_OK;
}
/* SBA inputs */
for ( i = 0, pSbaInput = hIvasRend->inputsSba; i < RENDERER_MAX_SBA_INPUTS; ++i, ++pSbaInput )
{
if ( pSbaInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID )
{
/* Skip inactive inputs */
continue;
}
#ifdef SPLIT_REND_WITH_HEAD_ROT
/*-------------------------------------------------------------------*
* IVAS_REND_FeedSplitBinauralBitstream()
*
*
*-------------------------------------------------------------------*/
ivas_error IVAS_REND_FeedSplitBinauralBitstream(
IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
const IVAS_REND_InputId inputId, /* i : ID of the input */
IVAS_REND_BitstreamBuffer *hBits /* i : buffer for input bitstream */
)
if ( pSbaInput->crendWrapper != NULL && pSbaInput->crendWrapper->hCrend[0] != NULL && pSbaInput->crendWrapper->hCrend[0]->hReverb != NULL )
{
ivas_error error;
input_base *inputBase;
input_split_post_rend *inputSplitPostRend;
if ( ( error = ivas_reverb_open( &pSbaInput->crendWrapper->hCrend[0]->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pSbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK )
{
return error;
}
}
#else
if ( pSbaInput->crendWrapper != NULL && pSbaInput->crendWrapper->hCrend != NULL && pSbaInput->crendWrapper->hCrend->hReverb != NULL )
{
if ( ( error = ivas_reverb_open( &pSbaInput->crendWrapper->hCrend->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pSbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK )
{
return error;
}
}
#endif
}
#endif
/* Validate function arguments */
if ( hIvasRend == NULL || hBits == NULL )
#ifdef SPLIT_REND_WITH_HEAD_ROT
hRenderConfig->split_rend_config = renderConfig.split_rend_config;
/* Overwrite any pose correction settings if 0 DOF (no pose correction) was selected */
if ( hRenderConfig->split_rend_config.dof == 0 )
{
return IVAS_ERR_UNEXPECTED_NULL_POINTER;
hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE;
}
if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK )
hRenderConfig->split_rend_config.codec = renderConfig.split_rend_config.codec;
if ( ( error = isar_split_rend_validate_config( &hRenderConfig->split_rend_config, ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ) ) != IVAS_ERR_OK )
{
return error;
}
inputSplitPostRend = (input_split_post_rend *) inputBase;
inputSplitPostRend->hBits = hBits;
/* Must re-initialize split rendering config in case renderer config is updated after adding renderer inputs */
/* if its not initialized yet then no need to re-initialize, initialization will happen while adding inputs*/
if ( hIvasRend->splitRendEncBuffer.data != NULL && hIvasRend->hRendererConfig != NULL )
{
int16_t cldfb_in_flag;
cldfb_in_flag = getCldfbRendFlag( hIvasRend, IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN );
ISAR_PRE_REND_close( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer );
return IVAS_ERR_OK;
if ( ( error = ivas_pre_rend_init( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, hIvasRend->num_subframes ) ) != IVAS_ERR_OK )
{
return error;
}
}
#endif
return IVAS_ERR_OK;
}
/*-------------------------------------------------------------------*
* IVAS_REND_SetHeadRotation()
......@@ -4735,7 +4636,7 @@ ivas_error IVAS_REND_SetHeadRotation(
const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */
const IVAS_VECTOR3 Pos, /* i : listener positions for next rendering call */
#ifdef SPLIT_REND_WITH_HEAD_ROT
const IVAS_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering */
const ISAR_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering */
#endif
const int16_t sf_idx /* i : subframe index */
)
......@@ -5837,7 +5738,7 @@ static ivas_error renderIsmToSplitBinaural(
pCombinedOrientationData = *ismInput->base.ctx.pCombinedOrientationData;
if ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
if ( pMultiBinPoseData->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
{
for ( i = 1; i < pCombinedOrientationData->num_subframes; ++i )
{
......@@ -6536,7 +6437,7 @@ static ivas_error renderMcToSplitBinaural(
/* save current head positions */
pCombinedOrientationDataLocal = *mcInput->base.ctx.pCombinedOrientationData;
combinedOrientationDataLocal = *pCombinedOrientationDataLocal;
if ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
if ( pMultiBinPoseData->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
{
for ( sf = 1; sf < combinedOrientationDataLocal.num_subframes; ++sf )
{
......@@ -6798,331 +6699,6 @@ static void renderSbaToSba(
}
#ifdef SPLIT_REND_WITH_HEAD_ROT
static ivas_error splitBinLc3plusDecode(
SPLIT_POST_REND_WRAPPER *hSplitBin,
IVAS_SPLIT_REND_BITS_HANDLE bits,
float outputBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k],
IVAS_SPLIT_REND_POSE_CORRECTION_MODE pose_correction )
{
ivas_error error;
float *channel_ptrs[MAX_HEAD_ROT_POSES * 2];
int32_t lc3plusBitrateId, lc3plusBitstreamSize;
push_wmops( "splitBinLc3plusDecode" );
assert( hSplitBin->hLc3plusDec != NULL );
/* Find next byte boundary */
while ( bits->bits_read % 8 != 0 )
{
++bits->bits_read;
}
/* Read LC3plus bitstream size info */
lc3plusBitrateId = ivas_split_rend_bitstream_read_int32( bits, 8 );
lc3plusBitstreamSize = ivas_get_lc3plus_size_from_id( (int8_t) lc3plusBitrateId, pose_correction, (int16_t) ( hSplitBin->hLc3plusDec->config.ivas_frame_duration_us / 1000 ) );
for ( int16_t i = 0; i < BINAURAL_CHANNELS * hSplitBin->multiBinPoseData.num_poses; ++i )
{
channel_ptrs[i] = outputBuffer[i];
}
if ( ( error = IVAS_LC3PLUS_DEC_Decode( hSplitBin->hLc3plusDec, &bits->bits_buf[bits->bits_read / 8], lc3plusBitstreamSize, channel_ptrs ) ) != IVAS_ERR_OK )
{
return error;
}
pop_wmops();
return IVAS_ERR_OK;
}
static ivas_error renderSplitBinauralWithPostRot(
input_split_post_rend *splitBinInput,
IVAS_REND_AudioBuffer outAudio,
const int16_t SplitRendBFI )
{
float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
ivas_error error;
float Cldfb_RealBuffer_Binaural_5ms[MAX_PARAM_SPATIAL_SUBFRAMES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
float Cldfb_ImagBuffer_Binaural_5ms[MAX_PARAM_SPATIAL_SUBFRAMES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
IVAS_QUATERNION QuaternionsPost[MAX_PARAM_SPATIAL_SUBFRAMES];
int16_t sf_idx, ch_idx;
IVAS_SPLIT_REND_BITS_DATA bits;
float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k];
float tmpCrendBuffer_sf[BINAURAL_CHANNELS][L_FRAME48k];
COMBINED_ORIENTATION_HANDLE pCombinedOrientationData;
SPLIT_POST_REND_WRAPPER *hSplitBin;
int8_t isPostRendInputCldfb;
int16_t chnlIdx, slotIdx, smplIdx;
int16_t preRendFrameSize_ms;
int16_t outBufNumSamplesPerChannel, outBufNumColPerChannel;
int16_t numSamplesPerChannelCacheSize, numColPerChannelCacheSize;
float *readPtr, *writePtr;
LC3PLUS_CONFIG config;
int16_t iNumBlocksPerFrame, iNumLCLDIterationsPerFrame;
isPostRendInputCldfb = 0;
push_wmops( "renderSplitBinauralWithPostRot" );
error = IVAS_ERR_OK;
pCombinedOrientationData = *splitBinInput->base.ctx.pCombinedOrientationData;
hSplitBin = &splitBinInput->splitPostRendWrapper;
convertBitsBufferToInternalBitsBuff( *splitBinInput->hBits, &bits );
config.lc3plus_frame_duration_us = bits.codec_frame_size_ms * 1000;
if ( pCombinedOrientationData->num_subframes != MAX_PARAM_SPATIAL_SUBFRAMES )
{
if ( bits.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS )
{
config.ivas_frame_duration_us = ( bits.pose_correction == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ? config.lc3plus_frame_duration_us * pCombinedOrientationData->num_subframes : 20000;
}
else
{
config.ivas_frame_duration_us = ( bits.pose_correction == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ? config.lc3plus_frame_duration_us : 20000;
}
iNumLCLDIterationsPerFrame = 1;
}
else
{
config.ivas_frame_duration_us = 20000;
}
if ( bits.codec_frame_size_ms > 0 )
{
iNumLCLDIterationsPerFrame = (int16_t) config.ivas_frame_duration_us / ( 1000 * bits.codec_frame_size_ms );
iNumLCLDIterationsPerFrame = max( 1, iNumLCLDIterationsPerFrame );
iNumBlocksPerFrame = CLDFB_NO_COL_MAX * bits.codec_frame_size_ms / 20;
}
else
{
iNumLCLDIterationsPerFrame = 1;
iNumBlocksPerFrame = CLDFB_NO_COL_MAX;
}
config.channels = BINAURAL_CHANNELS;
config.samplerate = *splitBinInput->base.ctx.pOutSampleRate;
if ( bits.codec == IVAS_SPLIT_REND_CODEC_LCLD && splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec == NULL )
{
if ( ( error = ivas_splitBinLCLDDecOpen( &splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec, *splitBinInput->base.ctx.pOutSampleRate, BINAURAL_CHANNELS, iNumBlocksPerFrame, iNumLCLDIterationsPerFrame ) ) != IVAS_ERR_OK )
{
return error;
}
}
else if ( bits.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && splitBinInput->splitPostRendWrapper.hLc3plusDec == NULL )
{
if ( ( error = IVAS_LC3PLUS_DEC_Open( config,
&splitBinInput->splitPostRendWrapper.hLc3plusDec ) ) != IVAS_ERR_OK )
{
return error;
}
}
outBufNumSamplesPerChannel = outAudio.config.numSamplesPerChannel / pCombinedOrientationData->num_subframes;
for ( sf_idx = 0; sf_idx < pCombinedOrientationData->num_subframes; sf_idx++ )
{
QuaternionsPost[sf_idx] = pCombinedOrientationData->Quaternions[sf_idx];
}
if ( !SplitRendBFI )
{
hSplitBin->first_good_frame_received = 1;
}
if ( hSplitBin->first_good_frame_received == 1 )
{
if ( bits.pose_correction == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
{
if ( !SplitRendBFI )
{
#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
ivas_splitBinPostRendMdDec( &bits, hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData, hSplitBin->hBinHrSplitPreRend );
#else
ivas_splitBinPostRendMdDec( &bits, hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData );
#endif
}
}
/*copy pose correction after MD is parsed*/
hSplitBin->multiBinPoseData.poseCorrectionMode = bits.pose_correction;
/* decode audio */
if ( splitBinInput->base.inConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED )
{
if ( bits.codec == IVAS_SPLIT_REND_CODEC_LCLD )
{
isPostRendInputCldfb = 1;
}
preRendFrameSize_ms = (int16_t) ( config.ivas_frame_duration_us ) / 1000;
numSamplesPerChannelCacheSize = (int16_t) ( *splitBinInput->base.ctx.pOutSampleRate * ( preRendFrameSize_ms - bits.codec_frame_size_ms ) / 1000 );
outBufNumColPerChannel = MAX_PARAM_SPATIAL_SUBFRAMES;
numColPerChannelCacheSize = ( iNumBlocksPerFrame * iNumLCLDIterationsPerFrame ) - outBufNumColPerChannel;
for ( sf_idx = 0; sf_idx < pCombinedOrientationData->num_subframes; sf_idx++ )
{
if ( splitBinInput->numCachedSamples == 0 )
{
if ( bits.codec == IVAS_SPLIT_REND_CODEC_LCLD )
{
ivas_splitBinLCLDDecProcess( hSplitBin->hSplitBinLCLDDec, &bits, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, SplitRendBFI );
/* copy data over to 5ms buffer */
for ( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx )
{
for ( slotIdx = 0; slotIdx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; ++slotIdx )
{
mvr2r( Cldfb_RealBuffer_Binaural[chnlIdx][slotIdx], Cldfb_RealBuffer_Binaural_5ms[sf_idx][chnlIdx][slotIdx], CLDFB_NO_CHANNELS_MAX );
mvr2r( Cldfb_ImagBuffer_Binaural[chnlIdx][slotIdx], Cldfb_ImagBuffer_Binaural_5ms[sf_idx][chnlIdx][slotIdx], CLDFB_NO_CHANNELS_MAX );
}
}
/* cache the remaining 15ms */
splitBinInput->numCachedSamples = numColPerChannelCacheSize;
writePtr = splitBinInput->bufferData;
for ( slotIdx = CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slotIdx < ( iNumBlocksPerFrame * iNumLCLDIterationsPerFrame ); ++slotIdx )
{
for ( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx )
{
for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx )
{
*writePtr++ = Cldfb_RealBuffer_Binaural[chnlIdx][slotIdx][smplIdx];
}
for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx )
{
*writePtr++ = Cldfb_ImagBuffer_Binaural[chnlIdx][slotIdx][smplIdx];
}
}
}
}
else
{
if ( ( error = splitBinLc3plusDecode( hSplitBin, &bits, tmpCrendBuffer, bits.pose_correction ) ) != IVAS_ERR_OK )
{
return error;
}
/* cache the remaining 15ms */
splitBinInput->numCachedSamples = numSamplesPerChannelCacheSize;
mvr2r( &tmpCrendBuffer[0][outBufNumSamplesPerChannel], splitBinInput->bufferData, numSamplesPerChannelCacheSize );
mvr2r( &tmpCrendBuffer[1][outBufNumSamplesPerChannel], splitBinInput->bufferData + numSamplesPerChannelCacheSize, numSamplesPerChannelCacheSize );
}
}
else
{
/* copy from cache */
if ( bits.codec == IVAS_SPLIT_REND_CODEC_LCLD )
{
int16_t readOffset = ( numColPerChannelCacheSize - splitBinInput->numCachedSamples );
readPtr = splitBinInput->bufferData;
isPostRendInputCldfb = 1;
readPtr += 2 * readOffset * CLDFB_NO_CHANNELS_MAX * BINAURAL_CHANNELS;
for ( slotIdx = 0; slotIdx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; ++slotIdx )
{
for ( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx )
{
for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx )
{
Cldfb_RealBuffer_Binaural_5ms[sf_idx][chnlIdx][slotIdx][smplIdx] = *readPtr++;
}
for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx )
{
Cldfb_ImagBuffer_Binaural_5ms[sf_idx][chnlIdx][slotIdx][smplIdx] = *readPtr++;
}
}
}
splitBinInput->numCachedSamples -= outBufNumColPerChannel;
}
else
{
int16_t readOffset = numSamplesPerChannelCacheSize - splitBinInput->numCachedSamples;
mvr2r( splitBinInput->bufferData + readOffset, &tmpCrendBuffer[0][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel );
mvr2r( splitBinInput->bufferData + readOffset + numSamplesPerChannelCacheSize, &tmpCrendBuffer[1][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel );
splitBinInput->numCachedSamples -= outBufNumSamplesPerChannel;
}
}
}
}
else
{
copyBufferTo2dArray( splitBinInput->base.inputBuffer, tmpCrendBuffer );
if ( splitBinInput->numCachedSamples == 0 )
{
preRendFrameSize_ms = (int16_t) ( config.ivas_frame_duration_us ) / 1000;
numSamplesPerChannelCacheSize = (int16_t) ( *splitBinInput->base.ctx.pOutSampleRate * preRendFrameSize_ms / 1000 );
numSamplesPerChannelCacheSize -= outAudio.config.numSamplesPerChannel;
splitBinInput->numCachedSamples = numSamplesPerChannelCacheSize;
}
else
{
splitBinInput->numCachedSamples -= outAudio.config.numSamplesPerChannel;
}
}
/* apply pose correction if enabled */
for ( sf_idx = 0; sf_idx < pCombinedOrientationData->num_subframes; sf_idx++ )
{
if ( bits.pose_correction == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE && isPostRendInputCldfb )
{
/* 0DOF with LCLD codec requires CLDFB synthesis */
int16_t slot_idx;
for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ )
{
float *RealBuffer[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES];
float *ImagBuffer[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES];
for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ )
{
RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural_5ms[sf_idx][ch_idx][slot_idx];
ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural_5ms[sf_idx][ch_idx][slot_idx];
}
cldfbSynthesis( RealBuffer,
ImagBuffer,
&( tmpCrendBuffer[ch_idx][sf_idx * outBufNumSamplesPerChannel] ),
hSplitBin->hBinHrSplitPostRend->cldfbSyn[0]->no_channels * CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES,
hSplitBin->hBinHrSplitPostRend->cldfbSyn[ch_idx] );
}
}
else if ( bits.pose_correction == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
{
mvr2r( &tmpCrendBuffer[0][sf_idx * outBufNumSamplesPerChannel], tmpCrendBuffer_sf[0], outBufNumSamplesPerChannel );
mvr2r( &tmpCrendBuffer[1][sf_idx * outBufNumSamplesPerChannel], tmpCrendBuffer_sf[1], outBufNumSamplesPerChannel );
ivas_rend_CldfbSplitPostRendProcess( hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData, QuaternionsPost[sf_idx], Cldfb_RealBuffer_Binaural_5ms[sf_idx], Cldfb_ImagBuffer_Binaural_5ms[sf_idx], tmpCrendBuffer_sf, isPostRendInputCldfb );
mvr2r( tmpCrendBuffer_sf[0], &tmpCrendBuffer[0][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel );
mvr2r( tmpCrendBuffer_sf[1], &tmpCrendBuffer[1][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel );
}
}
}
else
{
if ( splitBinInput->base.inConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED )
{
for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ )
{
set_zero( tmpCrendBuffer[ch_idx], outAudio.config.numSamplesPerChannel );
}
}
else
{
copyBufferTo2dArray( splitBinInput->base.inputBuffer, tmpCrendBuffer );
}
}
convertInternalBitsBuffToBitsBuffer( splitBinInput->hBits, bits );
accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio );
pop_wmops();
return error;
}
static ivas_error renderSbaToMultiBinaural(
input_sba *sbaInput,
......@@ -7148,7 +6724,7 @@ static ivas_error renderSbaToMultiBinaural(
pCombinedOrientationDataLocal = *sbaInput->base.ctx.pCombinedOrientationData;
combinedOrientationDataLocal = *pCombinedOrientationDataLocal;
if ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
if ( pMultiBinPoseData->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
{
for ( sf = 1; sf < combinedOrientationDataLocal.num_subframes; sf++ )
{
......@@ -7223,7 +6799,6 @@ static ivas_error renderSbaToMultiBinaural(
return IVAS_ERR_OK;
}
static ivas_error renderSbaToMultiBinauralCldfb(
input_sba *sbaInput,
float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
......@@ -7259,7 +6834,7 @@ static ivas_error renderSbaToSplitBinaural(
push_wmops( "renderSbaToSplitBinaural" );
error = IVAS_ERR_OK;
if ( sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV )
if ( sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV )
{
if ( ( renderSbaToMultiBinauralCldfb( sbaInput, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, low_res_pre_rend_rot,
getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK )
......@@ -7301,7 +6876,7 @@ static ivas_error renderSbaToBinaural(
push_wmops( "renderSbaToBinaural" );
#ifdef SPLIT_REND_WITH_HEAD_ROT
if ( sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV )
if ( sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV )
{
float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
......@@ -7490,39 +7065,6 @@ static ivas_error renderSbaToBinauralRoom(
}
#ifdef SPLIT_REND_WITH_HEAD_ROT
static ivas_error renderInputSplitBin(
input_split_post_rend *splitBinInput,
const AUDIO_CONFIG outConfig,
IVAS_REND_AudioBuffer outAudio,
const int16_t SplitRendBFI )
{
ivas_error error;
IVAS_REND_AudioBuffer inAudio;
inAudio = splitBinInput->base.inputBuffer;
splitBinInput->base.numNewSamplesPerChannel = 0;
/* Apply input gain to new audio */
v_multc( inAudio.data,
splitBinInput->base.gain,
inAudio.data,
inAudio.config.numSamplesPerChannel * inAudio.config.numChannels ); /* TODO: the output buffer is empty at this point, should be moved to a point after decoding the split bitstream */
switch ( outConfig )
{
case IVAS_AUDIO_CONFIG_BINAURAL:
error = renderSplitBinauralWithPostRot( splitBinInput, outAudio, SplitRendBFI );
break;
default:
return IVAS_ERR_INVALID_OUTPUT_FORMAT;
}
return error;
}
#endif
static void renderSbaToMasa(
input_sba *sbaInput,
IVAS_REND_AudioBuffer outAudio )
......@@ -7610,34 +7152,6 @@ static ivas_error renderInputSba(
}
#ifdef SPLIT_REND_WITH_HEAD_ROT
static ivas_error renderActiveInputsSplitBin(
IVAS_REND_HANDLE hIvasRend,
IVAS_REND_AudioBuffer outAudio )
{
int16_t i;
input_split_post_rend *pCurrentInput;
ivas_error error;
for ( i = 0, pCurrentInput = hIvasRend->inputsSplitPost; i < RENDERER_MAX_BIN_INPUTS; ++i, ++pCurrentInput )
{
if ( pCurrentInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID )
{
/* Skip inactive inputs */
continue;
}
if ( ( error = renderInputSplitBin( pCurrentInput, hIvasRend->outputConfig, outAudio, hIvasRend->splitRendBFI ) ) != IVAS_ERR_OK )
{
return error;
}
}
return IVAS_ERR_OK;
}
#endif
static ivas_error renderActiveInputsSba(
IVAS_REND_HANDLE hIvasRend,
IVAS_REND_AudioBuffer outAudio )
......@@ -8161,7 +7675,7 @@ ivas_error IVAS_REND_SetIsmMetadataDelay(
static ivas_error getSamplesInternal(
IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
#ifdef SPLIT_REND_WITH_HEAD_ROT
IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */,
IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */
IVAS_REND_BitstreamBuffer *hBits /*i/o: buffer for input/output bitstream. Needed in split rendering mode*/
#else
IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */
......@@ -8268,7 +7782,7 @@ static ivas_error getSamplesInternal(
int16_t num_poses_orig;
num_poses_orig = hIvasRend->splitRendWrapper.multiBinPoseData.num_poses;
outAudio = hIvasRend->splitRendEncBuffer;
ivas_renderSplitGetMultiBinPoseData( &hIvasRend->hRendererConfig->split_rend_config, &hIvasRend->splitRendWrapper.multiBinPoseData, hIvasRend->headRotData.sr_pose_pred_axis );
ISAR_PRE_REND_GetMultiBinPoseData( &hIvasRend->hRendererConfig->split_rend_config, &hIvasRend->splitRendWrapper.multiBinPoseData, hIvasRend->headRotData.sr_pose_pred_axis );
assert( num_poses_orig == hIvasRend->splitRendWrapper.multiBinPoseData.num_poses && "number of poses should not change dynamically" );
/* Clear output buffer for split rendering bitstream */
......@@ -8296,13 +7810,7 @@ static ivas_error getSamplesInternal(
return error;
}
#ifdef SPLIT_REND_WITH_HEAD_ROT
if ( ( error = renderActiveInputsSplitBin( hIvasRend, outAudio ) ) != IVAS_ERR_OK )
{
return error;
}
#else
#ifndef SPLIT_REND_WITH_HEAD_ROT
#ifndef DISABLE_LIMITER
#ifdef DEBUGGING
hIvasRend->numClipping +=
......@@ -8310,11 +7818,10 @@ static ivas_error getSamplesInternal(
limitRendererOutput( hIvasRend->hLimiter, outAudio.data, outAudio.config.numSamplesPerChannel, IVAS_LIMITER_THRESHOLD );
#endif
#endif
#ifdef SPLIT_REND_WITH_HEAD_ROT
if ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
{
IVAS_SPLIT_REND_BITS_DATA bits;
ISAR_SPLIT_REND_BITS_DATA bits;
int16_t cldfb_in_flag;
float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
......@@ -8351,8 +7858,23 @@ static ivas_error getSamplesInternal(
}
}
if ( ( error = ivas_renderMultiBinToSplitBinaural( &hIvasRend->splitRendWrapper, hIvasRend->headRotData.headPositions[0], hIvasRend->hRendererConfig->split_rend_config.splitRendBitRate, hIvasRend->hRendererConfig->split_rend_config.codec, hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms,
&bits, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, ( const int16_t )( ( BINAURAL_MAXBANDS * hIvasRend->sampleRateOut ) / 48000 ), tmpBinaural, 1, cldfb_in_flag, ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0, ro_md_flag ) ) != IVAS_ERR_OK )
if ( ( error = ISAR_PRE_REND_MultiBinToSplitBinaural( &hIvasRend->splitRendWrapper,
hIvasRend->headRotData.headPositions[0],
hIvasRend->hRendererConfig->split_rend_config.splitRendBitRate,
hIvasRend->hRendererConfig->split_rend_config.codec,
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
hIvasRend->hRendererConfig->split_rend_config.isar_frame_size_ms,
#endif
hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms,
&bits,
Cldfb_RealBuffer_Binaural,
Cldfb_ImagBuffer_Binaural,
( const int16_t )( ( BINAURAL_MAXBANDS * hIvasRend->sampleRateOut ) / 48000 ),
tmpBinaural,
1,
cldfb_in_flag,
( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0,
ro_md_flag ) ) != IVAS_ERR_OK )
{
return error;
}
......@@ -8425,7 +7947,7 @@ ivas_error IVAS_REND_GetSplitBinauralBitstream(
cldfb_in_flag = getCldfbRendFlag( hIvasRend, IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN );
hIvasRend->splitRendEncBuffer.config.is_cldfb = cldfb_in_flag;
if ( hIvasRend->hRendererConfig->split_rend_config.dof == 0 || hIvasRend->hRendererConfig->split_rend_config.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE )
if ( hIvasRend->hRendererConfig->split_rend_config.dof == 0 || hIvasRend->hRendererConfig->split_rend_config.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE )
{
hIvasRend->splitRendEncBuffer.config.numSamplesPerChannel = outAudio.config.numSamplesPerChannel;
}
......@@ -8440,28 +7962,30 @@ ivas_error IVAS_REND_GetSplitBinauralBitstream(
return getSamplesInternal( hIvasRend, outAudio, hBits );
}
/*-------------------------------------------------------------------*
* IVAS_REND_GetSplitBinauralSamples()
*
*
*-------------------------------------------------------------------*/
ivas_error IVAS_REND_GetSplitBinauralSamples(
IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */
bool *needNewFrame )
ivas_error IVAS_REND_GetSplitRendBitstreamHeader(
IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */
ISAR_SPLIT_REND_CODEC *pCodec, /* o: pointer to codec setting */
ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o: pointer to pose correction mode */
int16_t *pCodec_frame_size_ms /* o: pointer to codec frame size setting */
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
,
int16_t *pIsar_frame_size_ms /* o: pointer to isar frame size setting */
#endif
)
{
ivas_error error;
if ( ( error = getSamplesInternal( hIvasRend, outAudio, NULL ) ) != IVAS_ERR_OK )
if ( hIvasRend == NULL || hIvasRend->hRendererConfig == NULL )
{
return error;
return IVAS_ERR_UNEXPECTED_NULL_POINTER;
}
*needNewFrame = hIvasRend->inputsSplitPost[0].numCachedSamples == 0;
*pCodec = hIvasRend->hRendererConfig->split_rend_config.codec;
*pCodec_frame_size_ms = hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
*pIsar_frame_size_ms = hIvasRend->hRendererConfig->split_rend_config.isar_frame_size_ms;
#endif
*poseCorrection = hIvasRend->hRendererConfig->split_rend_config.poseCorrectionMode;
return IVAS_ERR_OK;
}
#endif
......@@ -8507,12 +8031,6 @@ void IVAS_REND_Close(
{
clearInputMasa( &hIvasRend->inputsMasa[i] );
}
#ifdef SPLIT_REND_WITH_HEAD_ROT
for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i )
{
clearInputSplitRend( &hIvasRend->inputsSplitPost[i] );
}
#endif
/* clear Config. Renderer */
ivas_render_config_close( &( hIvasRend->hRendererConfig ) );
......@@ -8521,7 +8039,7 @@ void IVAS_REND_Close(
#ifdef SPLIT_REND_WITH_HEAD_ROT
/* Split binaural rendering */
closeSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer );
ISAR_PRE_REND_close( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer );
#endif
closeHeadRotation( hIvasRend );
......
......@@ -35,6 +35,7 @@
#include "common_api_types.h"
#include <stdbool.h>
#include "ivas_stat_rend.h"
/*---------------------------------------------------------------------*
* Renderer constants
......@@ -45,10 +46,6 @@
#define RENDERER_MAX_SBA_INPUTS 1
#define RENDERER_MAX_MASA_INPUTS 1
#define RENDERER_MAX_INPUT_LFE_CHANNELS 4
#ifdef SPLIT_REND_WITH_HEAD_ROT
#define RENDERER_MAX_BIN_INPUTS 1
#endif
/*---------------------------------------------------------------------*
* Renderer structures
......@@ -56,30 +53,19 @@
typedef float IVAS_REND_LfePanMtx[RENDERER_MAX_INPUT_LFE_CHANNELS][IVAS_MAX_OUTPUT_CHANNELS];
typedef struct
{
int16_t numSamplesPerChannel;
int16_t numChannels;
#ifdef SPLIT_REND_WITH_HEAD_ROT
int16_t is_cldfb;
#endif
} IVAS_REND_AudioBufferConfig;
typedef struct
{
IVAS_REND_AudioBufferConfig config;
float *data;
} IVAS_REND_AudioBuffer;
#ifdef SPLIT_REND_WITH_HEAD_ROT
typedef struct
{
int32_t bufLenInBytes;
int32_t bitsWritten;
int32_t bitsRead;
IVAS_SPLIT_REND_CODEC codec;
IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection;
ISAR_SPLIT_REND_CODEC codec;
ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection;
int16_t codec_frame_size_ms;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
int16_t isar_frame_size_ms;
int16_t lc3plus_highres;
#endif
} IVAS_REND_BitstreamBufferConfig;
typedef struct
{
......@@ -284,6 +270,17 @@ ivas_error IVAS_REND_GetSplitBinauralBitstream(
IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */
IVAS_REND_BitstreamBuffer *hBits /* o : buffer for output bitstream */
);
ivas_error IVAS_REND_GetSplitRendBitstreamHeader(
IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */
ISAR_SPLIT_REND_CODEC *pCodec, /* o: pointer to codec setting */
ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o: pointer to pose correction mode */
int16_t *pCodec_frame_size_ms /* o: pointer to codec frame size setting */
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
,
int16_t *pIsar_frame_size_ms /* o: pointer to isar frame size setting */
#endif
);
#endif
ivas_error IVAS_REND_SetHeadRotation(
......@@ -291,7 +288,7 @@ ivas_error IVAS_REND_SetHeadRotation(
const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */
const IVAS_VECTOR3 Pos, /* i : listener positions for next rendering call */
#ifdef SPLIT_REND_WITH_HEAD_ROT
const IVAS_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering*/
const ISAR_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering*/
#endif
const int16_t sf_idx /* i : subframe index */
);
......
......@@ -249,6 +249,15 @@ static void LoadBSplineBinaryITD(
)
{
int16_t tmp;
#ifdef FIX_989_TD_REND_ROM
fread( &modelITD->elevDim3, sizeof( int16_t ), 1, f_hrtf );
modelITD->elevKSeq_dyn = (float *) malloc( ( modelITD->elevDim3 - 2 ) * sizeof( float ) );
fread( modelITD->elevKSeq_dyn, sizeof( float ), modelITD->elevDim3 - 2, f_hrtf );
fread( &modelITD->azimDim3, sizeof( int16_t ), 1, f_hrtf );
modelITD->azimKSeq_dyn = (float *) malloc( ( ( modelITD->azimDim3 + 1 ) / 2 - 2 ) * sizeof( float ) ); /* basis functions are flipped around 180 deg, number of basis functions above/below is (N+1)/2 */
fread( modelITD->azimKSeq_dyn, sizeof( float ), ( modelITD->azimDim3 + 1 ) / 2 - 2, f_hrtf );
#else
fread( &modelITD->N, sizeof( int16_t ), 1, f_hrtf );
fread( &modelITD->elevDim2, sizeof( int16_t ), 1, f_hrtf );
fread( &modelITD->elevDim3, sizeof( int16_t ), 1, f_hrtf );
......@@ -259,14 +268,22 @@ static void LoadBSplineBinaryITD(
fread( &modelITD->azimDim3, sizeof( int16_t ), 1, f_hrtf );
modelITD->azimKSeq_dyn = (float *) malloc( ( ( modelITD->azimDim3 + 1 ) / 2 - 2 ) * sizeof( float ) ); /* basis functions are flipped around 180 deg, number of basis functions above/below is (N+1)/2 */
fread( modelITD->azimKSeq_dyn, sizeof( float ), ( modelITD->azimDim3 + 1 ) / 2 - 2, f_hrtf );
#endif
fread( &tmp, sizeof( int16_t ), 1, f_hrtf );
modelITD->W_dyn = (float *) malloc( tmp * sizeof( float ) );
fread( modelITD->W_dyn, sizeof( float ), tmp, f_hrtf );
/* azimuth */
#ifdef FIX_989_TD_REND_ROM
modelITD->azimBsLen_dyn = (int16_t *) malloc( HRTF_MODEL_BSPLINE_NUM_COEFFS * sizeof( int16_t ) );
fread( modelITD->azimBsLen_dyn, sizeof( int16_t ), HRTF_MODEL_BSPLINE_NUM_COEFFS, f_hrtf );
modelITD->azimBsStart_dyn = (int16_t *) malloc( HRTF_MODEL_BSPLINE_NUM_COEFFS * sizeof( int16_t ) );
fread( modelITD->azimBsStart_dyn, sizeof( int16_t ), HRTF_MODEL_BSPLINE_NUM_COEFFS, f_hrtf );
#else
fread( modelITD->azimBsLen, sizeof( int16_t ), HRTF_MODEL_BSPLINE_NUM_COEFFS, f_hrtf );
fread( modelITD->azimBsStart, sizeof( int16_t ), HRTF_MODEL_BSPLINE_NUM_COEFFS, f_hrtf );
#endif
fread( &tmp, sizeof( int16_t ), 1, f_hrtf );
......@@ -276,8 +293,15 @@ static void LoadBSplineBinaryITD(
fread( &modelITD->azimSegSamples, sizeof( int16_t ), 1, f_hrtf );
/* elevation */
#ifdef FIX_989_TD_REND_ROM
modelITD->elevBsLen_dyn = (int16_t *) malloc( HRTF_MODEL_BSPLINE_NUM_COEFFS * sizeof( int16_t ) );
fread( modelITD->elevBsLen_dyn, sizeof( int16_t ), HRTF_MODEL_BSPLINE_NUM_COEFFS, f_hrtf );
modelITD->elevBsStart_dyn = (int16_t *) malloc( HRTF_MODEL_BSPLINE_NUM_COEFFS * sizeof( int16_t ) );
fread( modelITD->elevBsStart_dyn, sizeof( int16_t ), HRTF_MODEL_BSPLINE_NUM_COEFFS, f_hrtf );
#else
fread( modelITD->elevBsLen, sizeof( int16_t ), HRTF_MODEL_BSPLINE_NUM_COEFFS, f_hrtf );
fread( modelITD->elevBsStart, sizeof( int16_t ), HRTF_MODEL_BSPLINE_NUM_COEFFS, f_hrtf );
#endif
fread( &tmp, sizeof( int16_t ), 1, f_hrtf );
......@@ -291,6 +315,12 @@ static void LoadBSplineBinaryITD(
modelITD->W = (const float *) modelITD->W_dyn;
modelITD->azimBsShape = (const float *) modelITD->azimBsShape_dyn;
modelITD->elevBsShape = (const float *) modelITD->elevBsShape_dyn;
#ifdef FIX_989_TD_REND_ROM
modelITD->azimBsLen = (const int16_t *) modelITD->azimBsLen_dyn;
modelITD->azimBsStart = (const int16_t *) modelITD->azimBsStart_dyn;
modelITD->elevBsLen = (const int16_t *) modelITD->elevBsLen_dyn;
modelITD->elevBsStart = (const int16_t *) modelITD->elevBsStart_dyn;
#endif
return;
}
......@@ -347,6 +377,12 @@ static ivas_error LoadBSplineBinary(
return IVAS_ERROR( IVAS_ERR_INVALID_HRTF, "Error: HR filter file had an unsupported sampling rate (%d kHz)", tmp );
}
#ifdef FIX_989_TD_REND_ROM
fread( &model->K, sizeof( int16_t ), 1, f_hrtf );
fread( &model->elevDim3, sizeof( int16_t ), 1, f_hrtf );
model->elevKSeq_dyn = (float *) malloc( ( model->elevDim3 - 2 ) * sizeof( float ) );
fread( model->elevKSeq_dyn, sizeof( float ), model->elevDim3 - 2, f_hrtf );
#else
fread( &model->SplineDegree, sizeof( int16_t ), 1, f_hrtf );
fread( &model->K, sizeof( int16_t ), 1, f_hrtf );
......@@ -355,12 +391,15 @@ static ivas_error LoadBSplineBinary(
model->elevKSeq_dyn = (float *) malloc( ( model->elevDim3 - 2 ) * sizeof( float ) );
fread( model->elevKSeq_dyn, sizeof( float ), model->elevDim3 - 2, f_hrtf );
model->azimDim2_dyn = (int16_t *) malloc( model->elevDim3 * sizeof( int16_t ) );
#endif
model->azimDim3_dyn = (int16_t *) malloc( model->elevDim3 * sizeof( int16_t ) );
model->azim_start_idx_dyn = (int16_t *) malloc( model->elevDim3 * sizeof( int16_t ) );
model->azimKSeq = (float **) malloc( model->elevDim3 * sizeof( float * ) );
for ( i = 0; i < model->elevDim3; i++ )
{
#ifndef FIX_989_TD_REND_ROM
fread( &model->azimDim2_dyn[i], sizeof( int16_t ), 1, f_hrtf );
#endif
fread( &model->azimDim3_dyn[i], sizeof( int16_t ), 1, f_hrtf );
fread( &model->azim_start_idx_dyn[i], sizeof( int16_t ), 1, f_hrtf );
model->azimKSeq[i] = (float *) malloc( ( model->azimDim3_dyn[i] + 1 ) * sizeof( float ) );
......@@ -393,8 +432,15 @@ static ivas_error LoadBSplineBinary(
fread( model->azimShapeSampFactor_dyn, sizeof( int16_t ), model->elevDim3, f_hrtf );
/* elevation */
#ifdef FIX_989_TD_REND_ROM
model->elevBsLen_dyn = (int16_t *) malloc( HRTF_MODEL_BSPLINE_NUM_COEFFS * sizeof( int16_t ) );
fread( model->elevBsLen_dyn, sizeof( int16_t ), HRTF_MODEL_BSPLINE_NUM_COEFFS, f_hrtf );
model->elevBsStart_dyn = (int16_t *) malloc( HRTF_MODEL_BSPLINE_NUM_COEFFS * sizeof( int16_t ) );
fread( model->elevBsStart_dyn, sizeof( int16_t ), HRTF_MODEL_BSPLINE_NUM_COEFFS, f_hrtf );
#else
fread( model->elevBsLen, sizeof( int16_t ), HRTF_MODEL_BSPLINE_NUM_COEFFS, f_hrtf );
fread( model->elevBsStart, sizeof( int16_t ), HRTF_MODEL_BSPLINE_NUM_COEFFS, f_hrtf );
#endif
fread( &tmp, sizeof( int16_t ), 1, f_hrtf );
model->elevBsShape_dyn = (float *) malloc( tmp * sizeof( float ) );
fread( model->elevBsShape_dyn, sizeof( float ), tmp, f_hrtf );
......@@ -406,9 +452,15 @@ static ivas_error LoadBSplineBinary(
model->AlphaR = (const float *) model->AlphaR_dyn;
model->EL = (const float *) model->EL_dyn;
model->ER = (const float *) model->ER_dyn;
#ifdef FIX_989_TD_REND_ROM
model->elevBsLen = (const int16_t *) model->elevBsLen_dyn;
model->elevBsStart = (const int16_t *) model->elevBsStart_dyn;
#endif
model->elevBsShape = (const float *) model->elevBsShape_dyn;
model->elevKSeq = (const float *) model->elevKSeq_dyn;
#ifndef FIX_989_TD_REND_ROM
model->azimDim2 = (const int16_t *) model->azimDim2_dyn;
#endif
model->azimDim3 = (const int16_t *) model->azimDim3_dyn;
model->azim_start_idx = (const int16_t *) model->azim_start_idx_dyn;
model->azimSegSamples = (const int16_t *) model->azimSegSamples_dyn;
......@@ -777,10 +829,18 @@ void destroy_td_hrtf(
free( ( *hHrtf )->ModelParamsITD.W_dyn );
free( ( *hHrtf )->ModelParamsITD.azimBsShape_dyn );
free( ( *hHrtf )->ModelParamsITD.elevBsShape_dyn );
#ifdef FIX_989_TD_REND_ROM
free( ( *hHrtf )->ModelParamsITD.azimBsLen_dyn );
free( ( *hHrtf )->ModelParamsITD.azimBsStart_dyn );
free( ( *hHrtf )->ModelParamsITD.elevBsLen_dyn );
free( ( *hHrtf )->ModelParamsITD.elevBsStart_dyn );
#endif
}
free( ( *hHrtf )->ModelParams.elevKSeq_dyn );
free( ( *hHrtf )->ModelParams.azim_start_idx_dyn );
#ifndef FIX_989_TD_REND_ROM
free( ( *hHrtf )->ModelParams.azimDim2_dyn );
#endif
free( ( *hHrtf )->ModelParams.azimDim3_dyn );
free( ( *hHrtf )->ModelParams.AlphaL_dyn );
free( ( *hHrtf )->ModelParams.AlphaR_dyn );
......@@ -788,6 +848,10 @@ void destroy_td_hrtf(
free( ( *hHrtf )->ModelParams.azimShapeIdx_dyn );
free( ( *hHrtf )->ModelParams.azimShapeSampFactor_dyn );
#ifdef FIX_989_TD_REND_ROM
free( ( *hHrtf )->ModelParams.elevBsLen_dyn );
free( ( *hHrtf )->ModelParams.elevBsStart_dyn );
#endif
free( ( *hHrtf )->ModelParams.elevBsShape_dyn );
for ( i = 0; i < ( *hHrtf )->ModelParams.num_unique_azim_splines; i++ )
......@@ -1860,7 +1924,7 @@ ivas_error destroy_hrtf_statistics(
IVAS_DEC_HRTF_STATISTICS_HANDLE *hHrtfStatistics /* i/o: HRTF statistics handle */
)
{
if ( hHrtfStatistics != NULL && ( *hHrtfStatistics )->fromROM == FALSE )
if ( ( hHrtfStatistics != NULL ) && ( *hHrtfStatistics != NULL ) && ( ( *hHrtfStatistics )->fromROM == FALSE ) )
{
free( ( *hHrtfStatistics )->average_energy_l );
free( ( *hHrtfStatistics )->average_energy_r );
......
......@@ -124,6 +124,9 @@ struct RenderConfigReader
AcousticEnv *pAE; /* Acoustic environments */
uint32_t nDP; /* Number of directivity patterns */
DirectrivityPat *pDP; /* Directivity Pattern */
#ifdef CONF_DISTATT
float distAtt[3]; /* [MaxDist, RefDist, Rolloff] */
#endif
};
......@@ -996,6 +999,77 @@ static ivas_error get_bin_outer_attenuation(
return IVAS_ERR_OK;
}
#ifdef CONF_DISTATT
/*-----------------------------------------------------------------------------------------*
* Function get_bin_max_dist ()
* Gets a Maximum Distance value [1.0, 64.0]
*-----------------------------------------------------------------------------------------*/
static ivas_error get_bin_max_dist(
RenderConfigReader *this, /* i/o : Render config reader handle */
float *pResult /* o : Attenuation value */
)
{
ivas_error error;
uint32_t value;
if ( ( error = read_bin_bits( this, &value, 6 ) ) != IVAS_ERR_OK )
{
return error;
}
*pResult = usdequant( (int16_t) value, 1.0f, 1.0f );
return IVAS_ERR_OK;
}
/*-----------------------------------------------------------------------------------------*
* Function get_bin_ref_dist ()
* Gets a Reference Distance value [0.1, 6.4]
*-----------------------------------------------------------------------------------------*/
static ivas_error get_bin_ref_dist(
RenderConfigReader *this, /* i/o : Render config reader handle */
float *pResult /* o : Attenuation value */
)
{
ivas_error error;
uint32_t value;
if ( ( error = read_bin_bits( this, &value, 6 ) ) != IVAS_ERR_OK )
{
return error;
}
*pResult = usdequant( (int16_t) value, 0.1f, 0.1f );
return IVAS_ERR_OK;
}
/*-----------------------------------------------------------------------------------------*
* Function get_bin_rolloff ()
* Gets a Rollof Factor [0.0, 4.0]
*-----------------------------------------------------------------------------------------*/
static ivas_error get_bin_rolloff(
RenderConfigReader *this, /* i/o : Render config reader handle */
float *pResult /* o : Attenuation value */
)
{
ivas_error error;
uint32_t value;
if ( ( error = read_bin_bits( this, &value, 6 ) ) != IVAS_ERR_OK )
{
return error;
}
*pResult = usdequant( (int16_t) value, 0.0f, 0.1f );
return IVAS_ERR_OK;
}
#endif
/*-----------------------------------------------------------------------------------------*
* Function read_txt_vector()
......@@ -1128,6 +1202,9 @@ ivas_error RenderConfigReader_checkValues(
pRoom_acoustics = &hRenderConfig->roomAcoustics;
tab_value_err_count = 0;
int16_t wall_idx;
#ifdef CONF_DISTATT
int16_t i;
#endif
/* Verify the number of frequency bands in the config input data */
......@@ -1245,6 +1322,22 @@ ivas_error RenderConfigReader_checkValues(
pRoom_acoustics->AbsCoeff[wall_idx] = ER_MAX_ABS_COEFF;
}
}
#ifdef CONF_DISTATT
/* Verify range of distance attenuation parameters: 0.1 <= distAtt[0] <= distAtt[1] */
/* 0.0 <= distAtt[2] <= 10.0 */
hRenderConfig->distAtt[0] = max( 0.1f, hRenderConfig->distAtt[0] );
hRenderConfig->distAtt[1] = max( hRenderConfig->distAtt[0], hRenderConfig->distAtt[1] );
hRenderConfig->distAtt[2] = max( 0.0f, min( 10.0f, hRenderConfig->distAtt[2] ) );
/* Verify range of directivity patterns */
for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; i++ )
{
hRenderConfig->directivity[i * 3] = max( 0.0f, min( 360.0f, hRenderConfig->directivity[i * 3] ) );
hRenderConfig->directivity[i * 3 + 1] = max( 0.0f, min( 360.0f, hRenderConfig->directivity[i * 3 + 1] ) );
hRenderConfig->directivity[i * 3 + 2] = max( 0.0f, min( 1.0f, hRenderConfig->directivity[i * 3 + 2] ) );
}
#endif
}
......@@ -1287,6 +1380,9 @@ ivas_error RenderConfigReader_open(
pSelf->pAE = NULL;
pSelf->nDP = 0;
pSelf->pDP = NULL;
#ifdef CONF_DISTATT
pSelf->distAtt[0] = -1;
#endif
*ppRenderConfigReader = pSelf;
return IVAS_ERR_OK;
......@@ -1806,6 +1902,36 @@ static ivas_error RenderConfigReader_readBinary(
}
}
}
#ifdef CONF_DISTATT
/**********************************/
/* Read the distance attenuation */
/**********************************/
/* Has distance attenuation */
if ( ( error = read_bin_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK )
{
return error;
}
if ( value == true )
{
/* Read the Max Distance */
if ( ( error = get_bin_max_dist( pRenderConfigReader, &pRenderConfigReader->distAtt[0] ) ) != IVAS_ERR_OK )
{
return error;
}
/* Read the Ref Distance */
if ( ( error = get_bin_ref_dist( pRenderConfigReader, &pRenderConfigReader->distAtt[1] ) ) != IVAS_ERR_OK )
{
return error;
}
/* Read the Rolloff Facto r*/
if ( ( error = get_bin_rolloff( pRenderConfigReader, &pRenderConfigReader->distAtt[2] ) ) != IVAS_ERR_OK )
{
return error;
}
}
#endif
/* Cleanup */
free( pRenderConfigReader->pBitstream );
......@@ -2486,18 +2612,18 @@ ivas_error RenderConfigReader_read(
/* 0 DOF implies no pose correction */
if ( hRenderConfig->split_rend_config.dof == 0 && !poseCorrProvided )
{
hRenderConfig->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE;
hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE;
}
}
else if ( strcmp( item, "CODEC" ) == 0 )
{
if ( strcmp( pValue, "LCLD" ) == 0 )
{
hRenderConfig->split_rend_config.codec = IVAS_SPLIT_REND_CODEC_LCLD;
hRenderConfig->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_LCLD;
}
else if ( strcmp( pValue, "LC3PLUS" ) == 0 )
{
hRenderConfig->split_rend_config.codec = IVAS_SPLIT_REND_CODEC_LC3PLUS;
hRenderConfig->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_LC3PLUS;
}
else
{
......@@ -2522,11 +2648,11 @@ ivas_error RenderConfigReader_read(
poseCorrProvided = true;
if ( strcmp( pValue, "CLDFB" ) == 0 )
{
hRenderConfig->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB;
hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB;
}
else if ( strcmp( pValue, "NONE" ) == 0 )
{
hRenderConfig->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE;
hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE;
/* no pose correction implies 0 DOF */
if ( !dofProvided )
{
......@@ -2542,25 +2668,34 @@ ivas_error RenderConfigReader_read(
{
if ( strcmp( pValue, "CREND" ) == 0 )
{
hRenderConfig->split_rend_config.rendererSelection = IVAS_SPLIT_REND_RENDERER_SELECTION_CREND;
hRenderConfig->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_CREND;
}
else if ( strcmp( pValue, "FASTCONV" ) == 0 )
{
hRenderConfig->split_rend_config.rendererSelection = IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV;
hRenderConfig->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV;
}
else if ( strcmp( pValue, "PARAMBIN" ) == 0 )
{
hRenderConfig->split_rend_config.rendererSelection = IVAS_SPLIT_REND_RENDERER_SELECTION_PARAMBIN;
hRenderConfig->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_PARAMBIN;
}
else if ( strcmp( pValue, "TDREND" ) == 0 )
{
hRenderConfig->split_rend_config.rendererSelection = IVAS_SPLIT_REND_RENDERER_SELECTION_TDREND;
hRenderConfig->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_TDREND;
}
else
{
errorHandler( pValue, ERROR_VALUE_INVALID );
}
}
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
else if ( strcmp( item, "LC3PLUS_HIGHRES" ) == 0 )
{
if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.lc3plus_highres ) )
{
errorHandler( item, ERROR_VALUE_INVALID );
}
}
#endif
#ifdef DEBUGGING
else
{
......@@ -2653,6 +2788,54 @@ ivas_error RenderConfigReader_read(
free( pValue );
accDPIdx++;
}
#ifdef CONF_DISTATT
else if ( strcmp( chapter, "DISTANCEATTENUATION" ) == 0 )
{
params_idx = 0;
pValue = (char *) calloc( strlen( pParams ), sizeof( char ) );
/* Set default values if parameters are only partially specified */
pRenderConfigReader->distAtt[0] = 15.75f;
pRenderConfigReader->distAtt[1] = 1.0f;
pRenderConfigReader->distAtt[2] = 1.0f;
while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 )
{
params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 );
if ( strcmp( item, "MAXDIST" ) == 0 )
{
/* Read the Maximum distance */
if ( !sscanf( pValue, "%f", &pRenderConfigReader->distAtt[0] ) )
{
errorHandler( item, ERROR_VALUE_INVALID );
return IVAS_ERR_INVALID_RENDER_CONFIG;
}
}
if ( strcmp( item, "REFDIST" ) == 0 )
{
/* Read the Reference distance */
if ( !sscanf( pValue, "%f", &pRenderConfigReader->distAtt[1] ) )
{
errorHandler( item, ERROR_VALUE_INVALID );
return IVAS_ERR_INVALID_RENDER_CONFIG;
}
}
if ( strcmp( item, "ROLLOFFFACTOR" ) == 0 )
{
/* Read the Rolloff Factor */
if ( !sscanf( pValue, "%f", &pRenderConfigReader->distAtt[2] ) )
{
errorHandler( item, ERROR_VALUE_INVALID );
return IVAS_ERR_INVALID_RENDER_CONFIG;
}
}
}
free( pValue );
}
#endif
else if ( strcmp( chapter, "GENERAL" ) == 0 && strlen( pParams ) != 0 )
{
params_idx = 0;
......@@ -2821,6 +3004,12 @@ ivas_error RenderConfigReader_getAcousticEnvironment(
pAcEnv->AbsCoeff[j] = pRenderConfigReader->pAE[n].pEarlyReflections->pAbsCoeff[j];
}
}
#ifdef FIX_1053_REVERB_RECONFIGURATION
else
{
pAcEnv->use_er = false;
}
#endif
return IVAS_ERR_OK;
}
}
......@@ -2903,6 +3092,34 @@ ivas_error RenderConfigReader_getDirectivity(
return IVAS_ERR_OK;
}
#ifdef CONF_DISTATT
/*------------------------------------------------------------------------------------------*
* RenderConfigReader_getDistanceAttenuation()
*
* Gets Distance Attenuation
*------------------------------------------------------------------------------------------*/
ivas_error RenderConfigReader_getDistanceAttenuation(
RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */
float *distAtt /* o : Distance attenuation */
)
{
if ( pRenderConfigReader->distAtt[0] == -1 )
{
distAtt[0] = 15.75f;
distAtt[1] = 1.0f;
distAtt[2] = 1.0f;
}
else
{
distAtt[0] = pRenderConfigReader->distAtt[0];
distAtt[1] = pRenderConfigReader->distAtt[1];
distAtt[2] = pRenderConfigReader->distAtt[2];
}
return IVAS_ERR_OK;
}
#endif
/*------------------------------------------------------------------------------------------*
* RenderConfigReader_close()
......
......@@ -62,6 +62,12 @@ ivas_error RenderConfigReader_getDirectivity(
uint16_t *pId, /* i : Directivity pattern ID */
float *directivity /* o : Target directivity */
);
#ifdef CONF_DISTATT
ivas_error RenderConfigReader_getDistanceAttenuation(
RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */
float *distAtt /* o : Distance attenuation */
);
#endif
/* Verifies configuration parameters */
ivas_error RenderConfigReader_checkValues(
IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */
......
......@@ -32,10 +32,8 @@
#include <stdint.h>
#include "options.h"
#ifdef SPLIT_REND_WITH_HEAD_ROT
#include "split_rend_bfi_file_reader.h"
#include <stdio.h>
#include <stdlib.h>
#ifdef SPLIT_REND_WITH_HEAD_ROT
#include <string.h>
#include "prot.h"
......
......@@ -32,15 +32,10 @@
#include <stdint.h>
#include "options.h"
#ifdef SPLIT_REND_WITH_HEAD_ROT
#include "split_render_file_read_write.h"
#include <ctype.h>
#ifdef SPLIT_REND_WITH_HEAD_ROT
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "cmdl_tools.h"
#include "prot.h"
#include "ivas_cnst.h"
/*------------------------------------------------------------------------------------------*
......@@ -68,7 +63,17 @@ struct SplitFileReadWrite
ivas_error split_rend_reader_open(
SplitFileReadWrite **hhSplitRendFileReadWrite,
char *filename )
char *filename,
ISAR_SPLIT_REND_CODEC *codec,
ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection,
int16_t *codec_frame_size_ms
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
,
int16_t *isar_frame_size_ms,
int32_t *sampling_rate,
int16_t *lc3plus_highres
#endif
)
{
SplitFileReadWrite *hSplitRendFileReadWrite;
size_t header_len, h;
......@@ -104,6 +109,40 @@ ivas_error split_rend_reader_open(
fread( &hSplitRendFileReadWrite->delay_ns, sizeof( uint32_t ), 1, hSplitRendFileReadWrite->file );
/* read codec signalling */
if ( fread( codec, sizeof( *codec ), 1, hSplitRendFileReadWrite->file ) != 1 )
{
return IVAS_ERR_FAILED_FILE_READ;
}
/* read pose correction signalling */
if ( fread( poseCorrection, sizeof( *poseCorrection ), 1, hSplitRendFileReadWrite->file ) != 1 )
{
return IVAS_ERR_FAILED_FILE_READ;
}
/* read transport codec frame size signalling */
if ( fread( codec_frame_size_ms, sizeof( *codec_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 )
{
return IVAS_ERR_FAILED_FILE_READ;
}
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
/* read isar bitstream frame size signalling */
if ( fread( isar_frame_size_ms, sizeof( *isar_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 )
{
return IVAS_ERR_FAILED_FILE_READ;
}
/* read sampling rate signalling */
if ( fread( sampling_rate, sizeof( *sampling_rate ), 1, hSplitRendFileReadWrite->file ) != 1 )
{
return IVAS_ERR_FAILED_FILE_READ;
}
/* read LC3plus highres signalling */
if ( fread( lc3plus_highres, sizeof( *lc3plus_highres ), 1, hSplitRendFileReadWrite->file ) != 1 )
{
return IVAS_ERR_FAILED_FILE_READ;
}
#endif
*hhSplitRendFileReadWrite = hSplitRendFileReadWrite;
return IVAS_ERR_OK;
......@@ -120,7 +159,17 @@ ivas_error split_rend_writer_open(
SplitFileReadWrite **hhSplitRendFileReadWrite,
char *filename,
const int16_t delayNumSamples,
const int32_t delayTimeScale )
const int32_t delayTimeScale,
ISAR_SPLIT_REND_CODEC codec,
ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection,
int16_t codec_frame_size_ms
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
,
const int16_t isar_frame_size_ms,
const int32_t sampling_rate,
const int16_t lc3plus_highres
#endif
)
{
SplitFileReadWrite *hSplitRendFileReadWrite;
size_t header_len, h;
......@@ -155,6 +204,40 @@ ivas_error split_rend_writer_open(
hSplitRendFileReadWrite->delay_ns = (int32_t) ( (float) delayNumSamples * 1000000000.0f / (float) delayTimeScale );
fwrite( &hSplitRendFileReadWrite->delay_ns, sizeof( int32_t ), 1, hSplitRendFileReadWrite->file );
/* Write codec signalling */
if ( fwrite( &codec, sizeof( codec ), 1, hSplitRendFileReadWrite->file ) != 1 )
{
return IVAS_ERR_FAILED_FILE_WRITE;
}
/* Write pose correction signalling */
if ( fwrite( &poseCorrection, sizeof( poseCorrection ), 1, hSplitRendFileReadWrite->file ) != 1 )
{
return IVAS_ERR_FAILED_FILE_WRITE;
}
/* Write transport codec frame size signalling */
if ( fwrite( &codec_frame_size_ms, sizeof( codec_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 )
{
return IVAS_ERR_FAILED_FILE_WRITE;
}
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
/* Write isar bit stream frame size signalling */
if ( fwrite( &isar_frame_size_ms, sizeof( isar_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 )
{
return IVAS_ERR_FAILED_FILE_WRITE;
}
/* Write sampling rate signalling */
if ( fwrite( &sampling_rate, sizeof( sampling_rate ), 1, hSplitRendFileReadWrite->file ) != 1 )
{
return IVAS_ERR_FAILED_FILE_WRITE;
}
/* Write LC3plus highres signalling */
if ( fwrite( &lc3plus_highres, sizeof( lc3plus_highres ), 1, hSplitRendFileReadWrite->file ) != 1 )
{
return IVAS_ERR_FAILED_FILE_WRITE;
}
#endif
*hhSplitRendFileReadWrite = hSplitRendFileReadWrite;
return IVAS_ERR_OK;
......@@ -167,7 +250,7 @@ ivas_error split_rend_writer_open(
*
*-----------------------------------------------------------------------------------------*/
ivas_error split_rend_reader_writer_close(
void split_rend_reader_writer_close(
SplitFileReadWrite **hhSplitRendFileReadWrite )
{
if ( ( *hhSplitRendFileReadWrite ) != NULL )
......@@ -182,7 +265,7 @@ ivas_error split_rend_reader_writer_close(
*hhSplitRendFileReadWrite = NULL;
}
return IVAS_ERR_OK;
return;
}
......@@ -196,10 +279,7 @@ ivas_error split_rend_write_bitstream_to_file(
SplitFileReadWrite *hSplitRendFileReadWrite,
uint8_t *bits,
int32_t *bits_read,
int32_t *bits_written,
IVAS_SPLIT_REND_CODEC codec,
IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection,
int16_t codec_frame_size_ms )
int32_t *bits_written )
{
char header[SPLIT_RENDERER_FRAME_HEADER_LEN] = "SPLIT_FRAME";
size_t header_len, i, num_bytes;
......@@ -232,23 +312,6 @@ ivas_error split_rend_write_bitstream_to_file(
return IVAS_ERR_FAILED_FILE_WRITE;
}
/* Write codec signalling */
if ( fwrite( &codec, sizeof( codec ), 1, hSplitRendFileReadWrite->file ) != 1 )
{
return IVAS_ERR_FAILED_FILE_WRITE;
}
/* Write pose correction signalling */
if ( fwrite( &poseCorrection, sizeof( poseCorrection ), 1, hSplitRendFileReadWrite->file ) != 1 )
{
return IVAS_ERR_FAILED_FILE_WRITE;
}
/* Write frame size signalling */
if ( fwrite( &codec_frame_size_ms, sizeof( codec_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 )
{
return IVAS_ERR_FAILED_FILE_WRITE;
}
/* write num bytes */
if ( fwrite( bits_written, sizeof( int32_t ), 1, hSplitRendFileReadWrite->file ) != 1 )
{
......@@ -278,10 +341,7 @@ ivas_error split_rend_read_bits_from_file(
SplitFileReadWrite *hSplitRendFileReadWrite,
uint8_t *bits,
int32_t *bits_read,
int32_t *bits_written,
IVAS_SPLIT_REND_CODEC *codec,
IVAS_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection,
int16_t *codec_frame_size_ms )
int32_t *bits_written )
{
char header[SPLIT_RENDERER_FRAME_HEADER_LEN] = "SPLIT_FRAME";
char header_read[SPLIT_RENDERER_FRAME_HEADER_LEN];
......@@ -326,23 +386,6 @@ ivas_error split_rend_read_bits_from_file(
return IVAS_ERR_FAILED_FILE_READ;
}
/* read codec signalling */
if ( fread( codec, sizeof( *codec ), 1, hSplitRendFileReadWrite->file ) != 1 )
{
return IVAS_ERR_FAILED_FILE_READ;
}
/* read pose correction signalling */
if ( fread( poseCorrection, sizeof( *poseCorrection ), 1, hSplitRendFileReadWrite->file ) != 1 )
{
return IVAS_ERR_FAILED_FILE_READ;
}
/* read frame size signalling */
if ( fread( codec_frame_size_ms, sizeof( *codec_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 )
{
return IVAS_ERR_FAILED_FILE_READ;
}
/* write num bytes */
if ( fread( &bit_len, sizeof( int32_t ), 1, hSplitRendFileReadWrite->file ) != 1 )
{
......@@ -354,7 +397,7 @@ ivas_error split_rend_read_bits_from_file(
{
return IVAS_ERR_FAILED_FILE_READ;
}
for ( i = 0; i < IVAS_SPLIT_REND_ADDITIONAL_BYTES_TO_READ; i++ )
for ( i = 0; i < ISAR_SPLIT_REND_ADDITIONAL_BYTES_TO_READ; i++ )
{
bits[num_bytes + i] = 0;
}
......