Skip to content
......@@ -33,7 +33,7 @@
#include <stdint.h>
#include "options.h"
#ifdef SPLIT_REND_WITH_HEAD_ROT
#include "ivas_prot_rend.h"
#include "isar_prot.h"
#include "ivas_prot.h"
#ifdef DEBUGGING
#include "debug.h"
......@@ -42,23 +42,23 @@
/*-------------------------------------------------------------------------
* Function ivas_splitBinLCLDEncOpen()
* Function isar_splitBinLCLDEncOpen()
*
*
*------------------------------------------------------------------------*/
ivas_error ivas_splitBinLCLDEncOpen(
BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc,
ivas_error isar_splitBinLCLDEncOpen(
ISAR_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 )
{
BIN_HR_SPLIT_LCLD_ENC_HANDLE splitBinLCLDEnc;
ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE splitBinLCLDEnc;
ivas_error error;
if ( ( splitBinLCLDEnc = (BIN_HR_SPLIT_LCLD_ENC_HANDLE) malloc( sizeof( BIN_HR_SPLIT_LCLD_ENC ) ) ) == NULL )
if ( ( splitBinLCLDEnc = (ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE) malloc( sizeof( ISAR_BIN_HR_SPLIT_LCLD_ENC ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) );
}
......@@ -66,7 +66,7 @@ ivas_error ivas_splitBinLCLDEncOpen(
splitBinLCLDEnc->pLcld_enc = NULL; /* place holder for CLDFB encoder handle*/
splitBinLCLDEnc->iChannels = iChannels;
if ( ( error = CreateLCLDEncoder( &( splitBinLCLDEnc->psLCLDEncoder ), iSampleRate, iChannels, iDataRate, 1, iNumBlocks, (int16_t) CLDFB_NO_COL_MAX / iNumBlocks ) ) != IVAS_ERR_OK )
if ( ( error = CreateLCLDEncoder( &( splitBinLCLDEnc->psLCLDEncoder ), iSampleRate, iChannels, iDataRate, 1, iNumBlocks, (int16_t) CLDFB_NO_COL_MAX / iNumBlocks, 0 ) ) != IVAS_ERR_OK )
{
return error;
}
......@@ -115,13 +115,13 @@ ivas_error ivas_splitBinLCLDEncOpen(
/*-------------------------------------------------------------------------
* Function ivas_splitBinLCLDEncClose()
* Function isar_splitBinLCLDEncClose()
*
*
*------------------------------------------------------------------------*/
void ivas_splitBinLCLDEncClose(
BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc )
void isar_splitBinLCLDEncClose(
ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc )
{
if ( ( *hSplitBinLCLDEnc ) != NULL )
{
......@@ -151,20 +151,20 @@ void ivas_splitBinLCLDEncClose(
/*-------------------------------------------------------------------------
* Function ivas_splitBinLCLDEncProcess()
* Function isar_splitBinLCLDEncProcess()
*
*
*------------------------------------------------------------------------*/
void ivas_splitBinLCLDEncProcess(
BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc,
void isar_splitBinLCLDEncProcess(
ISAR_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 )
ISAR_SPLIT_REND_BITS_HANDLE pBits )
{
int32_t iBitsWritten, itr, available_bits_itr, rem_itr, available_bits_local;
push_wmops( "ivas_splitBinLCLDEncProcess" );
push_wmops( "isar_splitBinLCLDEncProcess" );
assert( hSplitBinLCLDEnc != NULL );
assert( Cldfb_In_Real != NULL );
......
......@@ -37,7 +37,7 @@
#include "ivas_prot.h"
#include "prot.h"
#include "ivas_cnst.h"
#include "ivas_prot_rend.h"
#include "isar_prot.h"
#ifdef DEBUGGING
#include "debug.h"
#endif
......@@ -48,8 +48,6 @@
* Local constants
*------------------------------------------------------------------------*/
#define DO_PERTURB 1
#define PH_PERT_ONLY 1
#define START_VAL_AVG_LEN 2
#define SR_PLC_FADE_START 10 /* start fading at this number of bad frames in row */
#define SR_PLC_MUTE 30 /* Total mute at this number of bad frames in row */
......@@ -68,13 +66,9 @@ static void adaptive_polar_ext_plc(
const float *prev_real,
const float *prev_imag,
float *rec_real,
float *rec_imag
#if CLDFB_PLC_XF > 0
,
float *rec_imag,
float xf_alp[CLDFB_PLC_XF],
float xf_bet[CLDFB_PLC_XF]
#endif
,
float xf_bet[CLDFB_PLC_XF],
const int16_t iNumCols )
{
float uth[CLDFB_NO_COL_MAX], uthu[CLDFB_NO_COL_MAX], urh[CLDFB_NO_COL_MAX];
......@@ -170,7 +164,6 @@ static void adaptive_polar_ext_plc(
fac_real = min( 1, drho ) * fac_ph_real;
fac_imag = min( 1, drho ) * fac_ph_imag;
#if START_VAL_AVG_LEN > 1
/* Calculate start value for evolution from last samples of previous frame */
fac_powj_real = fac_real;
fac_powj_imag = fac_imag;
......@@ -186,28 +179,16 @@ static void adaptive_polar_ext_plc(
}
start_real *= 1.0f / START_VAL_AVG_LEN;
start_imag *= 1.0f / START_VAL_AVG_LEN;
#else
/* take last sample of previous frame as start value */
start_real = prev_real[iNumCols - 1];
start_imag = prev_imag[iNumCols - 1];
#endif
#if DO_PERTURB != 0
/* make evolution less static: apply per samples differences as in preceding frame */
rat_real = ( prev_real[1] * prev_real[0] + prev_imag[1] * prev_imag[0] );
rat_imag = ( -prev_real[1] * prev_imag[0] + prev_imag[1] * prev_real[0] );
#if PH_PERT_ONLY != 0
/* only phase perturbation */
abs_temp = sqrtf( SQR( rat_real ) + SQR( rat_imag ) );
abs2inv = min( 1, drho ) / max( EPSILON, abs_temp );
rat_real *= abs2inv;
rat_imag *= abs2inv;
#else
/* phase and magnitude perturbation */
abs2inv = 1 / ( max( 1, drho ) * ( SQR( prev_real[0] ) + SQR( prev_imag[0] ) ) );
rat_real *= abs2inv;
rat_imag *= abs2inv;
#endif
/* apply complex evolution for first substitution sample */
rec_real[0] = rat_real * start_real - rat_imag * start_imag;
......@@ -217,14 +198,11 @@ static void adaptive_polar_ext_plc(
/* make evolution less static: apply per samples differences as in preceding frame */
rat_real = ( prev_real[j] * prev_real[j - 1] + prev_imag[j] * prev_imag[j - 1] );
rat_imag = ( -prev_real[j] * prev_imag[j - 1] + prev_imag[j] * prev_real[j - 1] );
#if PH_PERT_ONLY != 0
/* only phase perturbation */
abs_temp = sqrtf( SQR( rat_real ) + SQR( rat_imag ) );
abs2inv = min( 1, drho ) / max( EPSILON, abs_temp );
#else
/* phase and magnitude perturbation */
abs2inv = 1 / ( max( 1, drho ) * ( SQR( prev_real[j - 1] ) + SQR( prev_imag[j - 1] ) ) );
#endif
rat_real *= abs2inv;
rat_imag *= abs2inv;
/* apply complex evolution for further substitution samples */
......@@ -237,28 +215,17 @@ static void adaptive_polar_ext_plc(
{
rat_real = ( prev_real[j] * prev_real[j - 1] + prev_imag[j] * prev_imag[j - 1] );
rat_imag = ( -prev_real[j] * prev_imag[j - 1] + prev_imag[j] * prev_real[j - 1] );
#if PH_PERT_ONLY != 0
abs_temp = sqrtf( SQR( rat_real ) + SQR( rat_imag ) );
abs2inv = min( 1, drho ) / max( EPSILON, abs_temp );
#else
abs2inv = 1 / ( max( 1, drho ) * ( SQR( prev_real[j - 1] ) + SQR( prev_imag[j - 1] ) ) );
#endif
rat_real *= abs2inv;
rat_imag *= abs2inv;
rec_real[j + iNumCols - 2] = rat_real * rec_real[j + iNumCols - 3] - rat_imag * rec_imag[j + iNumCols - 3];
rec_imag[j + iNumCols - 2] = rat_imag * rec_real[j + iNumCols - 3] + rat_real * rec_imag[j + iNumCols - 3];
}
#else
rec_real[0] = fac_real * start_real - fac_imag * start_imag;
rec_imag[0] = fac_imag * start_real + fac_real * start_imag;
for ( j = 1; j < iNumCols + CLDFB_PLC_XF; j++ )
{
rec_real[j] = fac_real * rec_real[j - 1] - fac_imag * rec_imag[j - 1];
rec_imag[j] = fac_imag * rec_real[j - 1] + fac_real * rec_imag[j - 1];
}
#endif
#if CLDFB_PLC_XF > 0
/* apply crossfade */
for ( j = 0; j < CLDFB_PLC_XF; j++ )
{
......@@ -266,7 +233,6 @@ static void adaptive_polar_ext_plc(
rec_imag[iNumCols + j] *= xf_alp[j];
xf_bet[j] = 1 - xf_alp[j];
}
#endif
}
else
{
......@@ -314,7 +280,6 @@ static void adaptive_polar_ext_plc(
fac_powj_real = fac_real;
fac_powj_imag = fac_imag;
abs_fac_powj = abs_fac;
#if CLDFB_PLC_XF > 0
for ( j = 0; j < CLDFB_PLC_XF; j++ )
{
xf_bet[j] = 1 - abs_fac_powj;
......@@ -325,7 +290,6 @@ static void adaptive_polar_ext_plc(
fac_powj_imag = fac_powj_real * fac_imag + fac_powj_imag * fac_real;
fac_powj_real = temp;
}
#endif
}
}
else
......@@ -335,14 +299,12 @@ static void adaptive_polar_ext_plc(
rec_real[j] = prev_real[j];
rec_imag[j] = prev_imag[j];
}
#if CLDFB_PLC_XF > 0
for ( j = 0; j < CLDFB_PLC_XF; j++ )
{
xf_bet[j] = 1;
rec_real[j + iNumCols] = 0;
rec_imag[j + iNumCols] = 0;
}
#endif
}
return;
......@@ -350,25 +312,27 @@ static void adaptive_polar_ext_plc(
/*-------------------------------------------------------------------------
* Function ivas_splitBinRendPLCOpen()
* Function isar_splitBinRendPLCOpen()
*
*
*------------------------------------------------------------------------*/
ivas_error ivas_splitBinRendPLCOpen(
SPLIT_REND_PLC_HANDLE *phSplitRendPLC )
ivas_error isar_splitBinRendPLCOpen(
ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC,
const int16_t iNumSubSets )
{
ivas_error error;
SPLIT_REND_PLC_HANDLE hSplitRendPLC;
ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC;
error = IVAS_ERR_OK;
if ( ( hSplitRendPLC = (SPLIT_REND_PLC_HANDLE) malloc( sizeof( SPLIT_REND_PLC_STRUCT ) ) ) == NULL )
if ( ( hSplitRendPLC = (ISAR_SPLIT_REND_PLC_HANDLE) malloc( sizeof( SPLIT_REND_PLC_STRUCT ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for bin split renderer PLC Module \n" ) );
}
hSplitRendPLC->prev_bfi = 0;
hSplitRendPLC->bf_count = 0;
hSplitRendPLC->iNumSubSets = iNumSubSets;
set_zero( &hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[0][0][0], 2 * ( CLDFB_NO_COL_MAX + CLDFB_PLC_XF ) * CLDFB_NO_CHANNELS_MAX );
set_zero( &hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[0][0][0], 2 * ( CLDFB_NO_COL_MAX + CLDFB_PLC_XF ) * CLDFB_NO_CHANNELS_MAX );
*phSplitRendPLC = hSplitRendPLC;
......@@ -378,13 +342,13 @@ ivas_error ivas_splitBinRendPLCOpen(
/*-------------------------------------------------------------------------
* Function ivas_splitBinRendPLCClose()
* Function isar_splitBinRendPLCClose()
*
*
*------------------------------------------------------------------------*/
void ivas_splitBinRendPLCClose(
SPLIT_REND_PLC_HANDLE *phSplitRendPLC )
void isar_splitBinRendPLCClose(
ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC )
{
if ( ( *phSplitRendPLC ) != NULL )
{
......@@ -397,13 +361,13 @@ void ivas_splitBinRendPLCClose(
/*-------------------------------------------------------------------------
* Function ivas_splitBinRendPLCsaveState()
* Function isar_splitBinRendPLCsaveState()
*
*
*------------------------------------------------------------------------*/
void ivas_splitBinRendPLCsaveState(
SPLIT_REND_PLC_HANDLE hSplitRendPLC,
void isar_splitBinRendPLCsaveState(
ISAR_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,
......@@ -427,18 +391,20 @@ void ivas_splitBinRendPLCsaveState(
/*-------------------------------------------------------------------------
* Function ivas_splitBinRendPLC_xf()
* Function isar_splitBinRendPLC_xf()
*
* Cross-fade of preceding bad frame into good frame
*------------------------------------------------------------------------*/
void ivas_splitBinRendPLC_xf(
SPLIT_REND_PLC_HANDLE hSplitRendPLC,
void isar_splitBinRendPLC_xf(
ISAR_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 )
const int16_t iNumIterations,
int32_t **ppiDecodingFailed,
int32_t **ppiDecodingFailedPrev )
{
int16_t n, i, k;
......@@ -454,13 +420,15 @@ void ivas_splitBinRendPLC_xf(
{
for ( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ )
{
#if CLDFB_PLC_XF > 0
int16_t iSubSet = i % hSplitRendPLC->iNumSubSets;
if ( ppiDecodingFailedPrev[n][iSubSet] == 1 && ppiDecodingFailed[n][iSubSet] == 0 )
{
for ( k = 0; k < CLDFB_PLC_XF; k++ )
{
Cldfb_RealBuffer_Binaural[n][k][i] = hSplitRendPLC->CldfbPLC_state.xf_bet[n][i][k] * Cldfb_RealBuffer_Binaural[n][k][i] + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k + ( iNumBlocks * iNumIterations )][i];
Cldfb_ImagBuffer_Binaural[n][k][i] = hSplitRendPLC->CldfbPLC_state.xf_bet[n][i][k] * Cldfb_ImagBuffer_Binaural[n][k][i] + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k + ( iNumBlocks * iNumIterations )][i];
}
#endif
}
}
}
......@@ -469,25 +437,24 @@ void ivas_splitBinRendPLC_xf(
/*-------------------------------------------------------------------------
* Function ivas_splitBinRendPLC()
* Function isar_splitBinRendPLC()
*
* Conceal bad frame
*------------------------------------------------------------------------*/
void ivas_splitBinRendPLC(
SPLIT_REND_PLC_HANDLE hSplitRendPLC,
void isar_splitBinRendPLC(
ISAR_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 )
const int16_t iNumIterations,
int32_t **ppiDecodingFailed )
{
int32_t i, n, k;
float fade_fac;
float prev_real[CLDFB_NO_COL_MAX], prev_imag[CLDFB_NO_COL_MAX], rec_real[CLDFB_NO_COL_MAX + CLDFB_PLC_XF], rec_imag[CLDFB_NO_COL_MAX + CLDFB_PLC_XF];
#if CLDFB_PLC_XF > 0
float xf_alp[CLDFB_PLC_XF];
#endif
int16_t iNumCols, fade_start_cntr, mute_cntr, fade_val;
iNumCols = iNumBlocks * iNumIterations;
......@@ -495,47 +462,43 @@ void ivas_splitBinRendPLC(
/* Indicate that next transition will be from a bad frame */
hSplitRendPLC->prev_bfi = 1;
#if CLDFB_PLC_XF > 0
for ( i = 0; i < CLDFB_PLC_XF; i++ )
{
xf_alp[i] = 1.0f - ( i + 1.0f ) / ( CLDFB_PLC_XF + 1.0f );
}
#endif
for ( n = 0; n < num_chs; n++ )
{
for ( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ )
{
int32_t iSubSet = i % hSplitRendPLC->iNumSubSets;
for ( k = 0; k < iNumCols; k++ )
{
prev_real[k] = hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k][i];
prev_imag[k] = hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k][i];
}
adaptive_polar_ext_plc( prev_real, prev_imag, rec_real, rec_imag
#if CLDFB_PLC_XF > 0
,
xf_alp, hSplitRendPLC->CldfbPLC_state.xf_bet[n][i]
#endif
,
adaptive_polar_ext_plc( prev_real, prev_imag, rec_real, rec_imag,
xf_alp, hSplitRendPLC->CldfbPLC_state.xf_bet[n][i],
iNumCols );
for ( k = 0; k < iNumCols; k++ )
{
Cldfb_RealBuffer_Binaural[n][k][i] = rec_real[k];
hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k][i] = rec_real[k];
Cldfb_ImagBuffer_Binaural[n][k][i] = rec_imag[k];
hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k][i] = rec_imag[k];
if ( ppiDecodingFailed[n][iSubSet] == 1 )
{ /* only then copy to output */
Cldfb_RealBuffer_Binaural[n][k][i] = rec_real[k];
Cldfb_ImagBuffer_Binaural[n][k][i] = rec_imag[k];
}
}
#if CLDFB_PLC_XF > 0
for ( k = iNumCols; k < iNumCols + CLDFB_PLC_XF; k++ )
{
hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k][i] = rec_real[k];
hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k][i] = rec_imag[k];
}
#endif
}
}
......
......@@ -39,30 +39,41 @@
#endif
#include "ivas_prot.h"
#include "prot.h"
#include "ivas_rom_dec.h"
#include "ivas_prot_rend.h"
#include "isar_rom_post_rend.h"
#include "isar_prot.h"
#ifdef DEBUGGING
#include "debug.h"
#endif
#include "wmc_auto.h"
/*---------------------------------------------------------------------*
* Local function declarations
*---------------------------------------------------------------------*/
static void isar_SplitRenderer_PostRenderer(
ISAR_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 );
/*-------------------------------------------------------------------------
* ivas_splitBinPostRendOpen()
* isar_splitBinPostRendOpen()
*
*
*------------------------------------------------------------------------*/
ivas_error ivas_splitBinPostRendOpen(
BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend,
ivas_error isar_splitBinPostRendOpen(
ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend,
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
const int32_t output_Fs )
{
BIN_HR_SPLIT_POST_REND_HANDLE hBinRend;
ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinRend;
ivas_error error;
int16_t ch;
if ( ( hBinRend = (BIN_HR_SPLIT_POST_REND_HANDLE) malloc( sizeof( BIN_HR_SPLIT_POST_REND ) ) ) == NULL )
if ( ( hBinRend = (ISAR_BIN_HR_SPLIT_POST_REND_HANDLE) malloc( sizeof( ISAR_BIN_HR_SPLIT_POST_REND ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for bin split post renderer Module \n" ) );
}
......@@ -109,7 +120,7 @@ ivas_error ivas_splitBinPostRendOpen(
hBinRend->cf_flag = 0;
set_fix_rotation_mat( hBinRend->fix_pos_rot_mat, pMultiBinPoseData );
set_pose_types( hBinRend->pose_type, pMultiBinPoseData );
ivas_split_rend_init_huff_cfg( &hBinRend->huff_cfg );
isar_split_rend_init_huff_cfg( &hBinRend->huff_cfg );
*hBinHrSplitPostRend = hBinRend;
return IVAS_ERR_OK;
......@@ -117,13 +128,13 @@ ivas_error ivas_splitBinPostRendOpen(
/*-------------------------------------------------------------------------
* ivas_splitBinPostRendClose()
* isar_splitBinPostRendClose()
*
*
*------------------------------------------------------------------------*/
void ivas_splitBinPostRendClose(
BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend )
void isar_splitBinPostRendClose(
ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend )
{
int16_t ch;
......@@ -165,14 +176,14 @@ void ivas_splitBinPostRendClose(
/*-----------------------------------------------------------------------------------------*
* Function ivas_split_rend_huffman_decode_opt()
* Function isar_split_rend_huffman_decode_opt()
*
*
*-----------------------------------------------------------------------------------------*/
static int16_t ivas_split_rend_huffman_decode_opt(
ivas_split_rend_huffman_cfg_t *huff_cfg,
IVAS_SPLIT_REND_BITS_HANDLE pBits,
static int16_t isar_split_rend_huffman_decode_opt(
isar_split_rend_huffman_cfg_t *huff_cfg,
ISAR_SPLIT_REND_BITS_HANDLE pBits,
const int16_t *idx_trav_list )
{
int32_t i, ind, code, num_bits, code_b, num_bits_read;
......@@ -191,7 +202,7 @@ static int16_t ivas_split_rend_huffman_decode_opt(
code = code << num_bits_read;
if ( num_bits_read > 0 )
{
code |= ivas_split_rend_bitstream_read_int32( pBits, num_bits_read );
code |= ISAR_SPLIT_REND_BITStream_read_int32( pBits, num_bits_read );
}
if ( code == code_b )
......@@ -211,15 +222,15 @@ static int16_t ivas_split_rend_huffman_decode_opt(
}
/*-----------------------------------------------------------------------------------------*
* Function ivas_split_rend_unquant_md()
* Function isar_split_rend_unquant_md()
*
*
*-----------------------------------------------------------------------------------------*/
static void ivas_split_rend_unquant_md(
BIN_HR_SPLIT_REND_MD_HANDLE hMd,
IVAS_SPLIT_REND_POSE_TYPE pose_type,
int16_t real_only,
static void isar_split_rend_unquant_md(
ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd,
ISAR_SPLIT_REND_POSE_TYPE pose_type,
const int16_t real_only,
float fix_pos_rot_mat[][BINAURAL_CHANNELS],
const float pred_quant_step )
{
......@@ -231,7 +242,7 @@ static void ivas_split_rend_unquant_md(
float quantstep;
quantstep = pred_quant_step;
#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
......@@ -240,8 +251,20 @@ static void ivas_split_rend_unquant_md(
hMd->pred_mat_re[ch1][ch2] = hMd->pred_mat_re[ch1][ch2] + fix_pos_rot_mat[ch1][ch2];
}
}
#endif
if ( real_only )
{
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
hMd->pred_mat_re[ch1][ch2] = hMd->pred_mat_re_idx[ch1][ch2] * quantstep;
hMd->pred_mat_re[ch1][ch2] = hMd->pred_mat_re[ch1][ch2] + ( ( ch1 == ch2 ) ? 1.0f : 0.0f );
}
}
#endif
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
......@@ -252,6 +275,17 @@ static void ivas_split_rend_unquant_md(
}
else
{
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
hMd->pred_mat_re[ch1][ch2] = hMd->pred_mat_re_idx[ch1][ch2] * quantstep;
hMd->pred_mat_re[ch1][ch2] = hMd->pred_mat_re[ch1][ch2] + fix_pos_rot_mat[ch1][ch2];
}
}
#endif
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
......@@ -263,18 +297,18 @@ static void ivas_split_rend_unquant_md(
}
else if ( pose_type == COM_GAIN_ONLY )
{
gd_idx_min = (int16_t) roundf( IVAS_SPLIT_REND_D_1BYQ_STEP * IVAS_SPLIT_REND_D_MIN_VAL );
gd_idx_min = (int16_t) roundf( ISAR_SPLIT_REND_D_1BYQ_STEP * ISAR_SPLIT_REND_D_MIN_VAL );
hMd->gd_idx += gd_idx_min;
hMd->gd = hMd->gd_idx * IVAS_SPLIT_REND_D_Q_STEP;
hMd->gd = hMd->gd_idx * ISAR_SPLIT_REND_D_Q_STEP;
}
else if ( pose_type == LR_GAIN_ONLY )
{
gd_idx_min = (int16_t) roundf( IVAS_SPLIT_REND_PITCH_G_1BYQ_STEP * IVAS_SPLIT_REND_PITCH_G_MIN_VAL );
gd_idx_min = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * ISAR_SPLIT_REND_PITCH_G_MIN_VAL );
hMd->gd_idx += gd_idx_min;
hMd->gd = hMd->gd_idx * IVAS_SPLIT_REND_PITCH_G_Q_STEP;
hMd->gd = hMd->gd_idx * ISAR_SPLIT_REND_PITCH_G_Q_STEP;
hMd->gd2_idx += gd_idx_min;
hMd->gd2 = hMd->gd2_idx * IVAS_SPLIT_REND_PITCH_G_Q_STEP;
hMd->gd2 = hMd->gd2_idx * ISAR_SPLIT_REND_PITCH_G_Q_STEP;
}
else
{
......@@ -286,14 +320,14 @@ static void ivas_split_rend_unquant_md(
/*-----------------------------------------------------------------------------------------*
* Function ivas_splitBinPostRendMdBase2Dec()
* Function isar_splitBinPostRendMdBase2Dec()
*
*
*-----------------------------------------------------------------------------------------*/
static void ivas_splitBinPostRendMdBase2Dec(
IVAS_SPLIT_REND_BITS_HANDLE pBits,
BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend,
static void isar_splitBinPostRendMdBase2Dec(
ISAR_SPLIT_REND_BITS_HANDLE pBits,
ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend,
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
const int16_t num_subframes,
const int16_t pred_real_bands_yaw,
......@@ -309,12 +343,12 @@ static void ivas_splitBinPostRendMdBase2Dec(
int16_t min_pred_roll_idx, pred_roll_code_len;
int16_t pred_cb_idx;
int16_t code;
BIN_HR_SPLIT_REND_MD_HANDLE hMd;
BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg;
ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd;
ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg;
pHuff_cfg = &hBinHrSplitPostRend->huff_cfg;
if ( pred_quant_pnts_yaw == IVAS_SPLIT_REND_PRED_63QUANT_PNTS )
if ( pred_quant_pnts_yaw == ISAR_SPLIT_REND_PRED_63QUANT_PNTS )
{
pred_cb_idx = 1;
}
......@@ -337,6 +371,7 @@ static void ivas_splitBinPostRendMdBase2Dec(
{
if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW )
{
#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
for ( b = 0; b < pred_real_bands_yaw; b++ )
{
hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
......@@ -344,7 +379,7 @@ static void ivas_splitBinPostRendMdBase2Dec(
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, pred_code_len );
code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len );
hMd->pred_mat_re_idx[ch1][ch2] = code + min_pred_idx;
}
}
......@@ -356,15 +391,49 @@ static void ivas_splitBinPostRendMdBase2Dec(
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, pred_code_len );
code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len );
hMd->pred_mat_im_idx[ch1][ch2] = code + min_pred_idx;
}
}
}
#else
for ( b = 0; b < pred_imag_bands_yaw; b++ )
{
hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len );
hMd->pred_mat_re_idx[ch1][ch2] = code + min_pred_idx;
}
}
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len );
hMd->pred_mat_im_idx[ch1][ch2] = code + min_pred_idx;
}
}
}
for ( ; b < pred_real_bands_yaw; b++ )
{
hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len );
hMd->pred_mat_re_idx[ch1][ch1] = code + min_pred_idx;
}
hMd->pred_mat_re_idx[0][1] = 0;
hMd->pred_mat_re_idx[1][0] = 0;
}
#endif
for ( b = 0; b < d_bands_yaw; b++ )
{
hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, gd_code_len );
code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, gd_code_len );
hMd->gd_idx = code + min_gd_idx;
}
}
......@@ -373,14 +442,15 @@ static void ivas_splitBinPostRendMdBase2Dec(
for ( b = 0; b < bands_pitch; b++ )
{
hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, p_gd_code_len );
code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, p_gd_code_len );
hMd->gd_idx = code + min_p_gd_idx;
code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, p_gd_code_len );
code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, p_gd_code_len );
hMd->gd2_idx = code + min_p_gd_idx;
}
}
else
{
#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
for ( b = 0; b < pred_real_bands_roll; b++ )
{
hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
......@@ -388,7 +458,7 @@ static void ivas_splitBinPostRendMdBase2Dec(
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, pred_roll_code_len );
code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len );
hMd->pred_mat_re_idx[ch1][ch2] = code + min_pred_roll_idx;
}
}
......@@ -400,11 +470,45 @@ static void ivas_splitBinPostRendMdBase2Dec(
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, pred_roll_code_len );
code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len );
hMd->pred_mat_im_idx[ch1][ch2] = code + min_pred_roll_idx;
}
}
}
#else
for ( b = 0; b < pred_imag_bands_roll; b++ )
{
hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len );
hMd->pred_mat_re_idx[ch1][ch2] = code + min_pred_roll_idx;
}
}
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len );
hMd->pred_mat_im_idx[ch1][ch2] = code + min_pred_roll_idx;
}
}
}
for ( ; b < pred_real_bands_roll; b++ )
{
hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len );
hMd->pred_mat_re_idx[ch1][ch1] = code + min_pred_roll_idx;
}
hMd->pred_mat_re_idx[0][1] = 0;
hMd->pred_mat_re_idx[1][0] = 0;
}
#endif
}
}
}
......@@ -414,14 +518,14 @@ static void ivas_splitBinPostRendMdBase2Dec(
/*-----------------------------------------------------------------------------------------*
* Function ivas_splitBinPostRendMdHuffDec()
* Function isar_splitBinPostRendMdHuffDec()
*
*
*-----------------------------------------------------------------------------------------*/
static void ivas_splitBinPostRendMdHuffDec(
IVAS_SPLIT_REND_BITS_HANDLE pBits,
BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend,
static void isar_splitBinPostRendMdHuffDec(
ISAR_SPLIT_REND_BITS_HANDLE pBits,
ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend,
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
const int16_t num_subframes,
const int16_t pred_real_bands_yaw,
......@@ -437,12 +541,12 @@ static void ivas_splitBinPostRendMdHuffDec(
int16_t sym_adj_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
int16_t min_pred_idx, max_pred_idx;
int16_t min_pred_roll_idx, max_pred_roll_idx, pred_cb_idx;
BIN_HR_SPLIT_REND_MD_HANDLE hMd;
BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg;
ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd;
ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg;
pHuff_cfg = &hBinHrSplitPostRend->huff_cfg;
if ( pred_quant_pnts_yaw == IVAS_SPLIT_REND_PRED_63QUANT_PNTS )
if ( pred_quant_pnts_yaw == ISAR_SPLIT_REND_PRED_63QUANT_PNTS )
{
pred_cb_idx = 1;
}
......@@ -454,7 +558,7 @@ static void ivas_splitBinPostRendMdHuffDec(
max_pred_idx = (int16_t) pHuff_cfg->pred[pred_cb_idx].codebook[( pred_quant_pnts_yaw - 1 ) * 3];
min_pred_roll_idx = (int16_t) pHuff_cfg->pred_roll.codebook[0];
max_pred_roll_idx = (int16_t) pHuff_cfg->pred_roll.codebook[( IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) * 3];
max_pred_roll_idx = (int16_t) pHuff_cfg->pred_roll.codebook[( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) * 3];
for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
{
......@@ -462,6 +566,7 @@ static void ivas_splitBinPostRendMdHuffDec(
{
if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW )
{
#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
for ( b = 0; b < pred_real_bands_yaw; b++ )
{
hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
......@@ -469,11 +574,10 @@ static void ivas_splitBinPostRendMdHuffDec(
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] );
// sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred, pBits );
sym_adj_idx[ch1][ch2] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] );
}
}
ivas_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_idx, max_pred_idx );
isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_idx, max_pred_idx );
}
for ( b = 0; b < pred_imag_bands_yaw; b++ )
{
......@@ -482,17 +586,48 @@ static void ivas_splitBinPostRendMdHuffDec(
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] );
// sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred, pBits );
sym_adj_idx[ch1][ch2] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] );
}
}
isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_idx, max_pred_idx );
}
#else
for ( b = 0; b < pred_imag_bands_yaw; b++ )
{
hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
sym_adj_idx[ch1][ch2] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] );
}
}
isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_idx, max_pred_idx );
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
sym_adj_idx[ch1][ch2] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] );
}
}
ivas_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_idx, max_pred_idx );
isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_idx, max_pred_idx );
}
for ( ; b < pred_real_bands_yaw; b++ )
{
hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
sym_adj_idx[ch1][ch1] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] );
}
sym_adj_idx[1][0] = 0;
sym_adj_idx[0][1] = 0;
isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, -1, min_pred_idx, max_pred_idx );
}
#endif
for ( b = 0; b < d_bands_yaw; b++ )
{
hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
hMd->gd_idx = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->gd, pBits, pHuff_cfg->gd_idx_trav );
// hMd->gd_idx = ivas_split_rend_huffman_decode( &pHuff_cfg->gd, pBits );
hMd->gd_idx = isar_split_rend_huffman_decode_opt( &pHuff_cfg->gd, pBits, pHuff_cfg->gd_idx_trav );
}
}
else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY )
......@@ -500,14 +635,14 @@ static void ivas_splitBinPostRendMdHuffDec(
for ( b = 0; b < bands_pitch; b++ )
{
hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
hMd->gd_idx = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->p_gd, pBits, pHuff_cfg->p_gd_idx_trav );
// hMd->gd_idx = ivas_split_rend_huffman_decode( &pHuff_cfg->gd, pBits );
hMd->gd_idx = isar_split_rend_huffman_decode_opt( &pHuff_cfg->p_gd, pBits, pHuff_cfg->p_gd_idx_trav );
hMd->gd2_idx = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->p_gd, pBits, pHuff_cfg->p_gd_idx_trav );
hMd->gd2_idx = isar_split_rend_huffman_decode_opt( &pHuff_cfg->p_gd, pBits, pHuff_cfg->p_gd_idx_trav );
}
}
else
{
#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
for ( b = 0; b < pred_real_bands_roll; b++ )
{
hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
......@@ -516,11 +651,10 @@ static void ivas_splitBinPostRendMdHuffDec(
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav );
// sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred_roll, pBits );
sym_adj_idx[ch1][ch2] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav );
}
}
ivas_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_roll_idx, max_pred_roll_idx );
isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_roll_idx, max_pred_roll_idx );
}
for ( b = 0; b < pred_imag_bands_roll; b++ )
{
......@@ -529,13 +663,48 @@ static void ivas_splitBinPostRendMdHuffDec(
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav );
// sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred_roll, pBits );
sym_adj_idx[ch1][ch2] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav );
}
}
isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_roll_idx, max_pred_roll_idx );
}
#else
for ( b = 0; b < pred_imag_bands_roll; b++ )
{
hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
sym_adj_idx[ch1][ch2] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav );
}
}
ivas_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_roll_idx, max_pred_roll_idx );
isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_roll_idx, max_pred_roll_idx );
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
sym_adj_idx[ch1][ch2] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav );
}
}
isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_roll_idx, max_pred_roll_idx );
}
for ( ; b < pred_real_bands_roll; b++ )
{
hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
sym_adj_idx[ch1][ch1] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav );
}
sym_adj_idx[1][0] = 0;
sym_adj_idx[0][1] = 0;
isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, -1, min_pred_roll_idx, max_pred_roll_idx );
}
#endif
}
}
}
......@@ -544,14 +713,14 @@ static void ivas_splitBinPostRendMdHuffDec(
/*-----------------------------------------------------------------------------------------*
* Function ivas_splitBinPostRendMdDec()
* Function isar_splitBinPostRendMdDec()
*
*
*-----------------------------------------------------------------------------------------*/
void ivas_splitBinPostRendMdDec(
IVAS_SPLIT_REND_BITS_HANDLE pBits,
BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend,
void isar_splitBinPostRendMdDec(
ISAR_SPLIT_REND_BITS_HANDLE pBits,
ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend,
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData
#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
,
......@@ -560,28 +729,50 @@ void ivas_splitBinPostRendMdDec(
)
{
int16_t pos_idx, b, sf_idx, num_subframes, ch1;
int16_t pred_real_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], pred_real_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS];
int16_t pred_imag_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], pred_imag_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS];
int16_t d_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], bands_pitch[IVAS_SPLIT_REND_NUM_QUANT_STRATS];
int16_t pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
int16_t pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
int16_t d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
int16_t num_quant_strats;
#else
int16_t num_complex_bands, num_quant_strats;
#endif
int32_t quant_strat_bits, is_huff_coding, quant_strat;
int16_t pred_quant_pnts_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS];
float pred_1byquantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS];
float pred_quantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS];
int16_t pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
float pred_1byquantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
float pred_quantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
int16_t ch1, ch2;
#endif
BIN_HR_SPLIT_REND_MD_HANDLE hMd;
IVAS_SPLIT_REND_CONFIG_DATA split_rend_config;
IVAS_SPLIT_REND_ROT_AXIS rot_axis;
ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd;
ISAR_SPLIT_REND_CONFIG_DATA split_rend_config;
ISAR_SPLIT_REND_ROT_AXIS rot_axis;
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
int16_t ro_md_flag, num_bits, axis_code;
#endif
hBinHrSplitPostRend->low_Res = 1;
split_rend_config.dof = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_DOF_BITS );
split_rend_config.hq_mode = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_HQ_MODE_BITS );
rot_axis = (IVAS_SPLIT_REND_ROT_AXIS) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_ROT_AXIS_BITS );
split_rend_config.dof = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_DOF_BITS );
split_rend_config.hq_mode = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_HQ_MODE_BITS );
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
num_bits = isar_renderSplitGetRot_axisNumBits( split_rend_config.dof );
if ( num_bits > 0 )
{
axis_code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, (int32_t) num_bits );
}
else
{
axis_code = 0;
}
rot_axis = isar_renderSplitGetRot_axisFromCode( split_rend_config.dof, axis_code );
ro_md_flag = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_RO_FLAG_BITS );
#else
rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_ROT_AXIS_BITS );
#endif
ivas_renderSplitGetMultiBinPoseData( &split_rend_config, pMultiBinPoseData, rot_axis );
isar_renderSplitGetMultiBinPoseData( &split_rend_config, pMultiBinPoseData, rot_axis );
set_fix_rotation_mat( hBinHrSplitPostRend->fix_pos_rot_mat, pMultiBinPoseData );
set_pose_types( hBinHrSplitPostRend->pose_type, pMultiBinPoseData );
......@@ -593,20 +784,35 @@ void ivas_splitBinPostRendMdDec(
hBinHrSplitPostRend->QuaternionsPre[sf_idx].w = -3.0f;
angle = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_HEAD_POSE_BITS );
angle = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_HEAD_POSE_BITS );
angle -= 180;
hBinHrSplitPostRend->QuaternionsPre[sf_idx].x = (float) angle;
angle = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_HEAD_POSE_BITS );
angle = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_HEAD_POSE_BITS );
angle -= 180;
hBinHrSplitPostRend->QuaternionsPre[sf_idx].y = (float) angle;
angle = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_HEAD_POSE_BITS );
angle = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_HEAD_POSE_BITS );
angle -= 180;
hBinHrSplitPostRend->QuaternionsPre[sf_idx].z = (float) angle;
}
ivas_split_rend_get_quant_params(
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
isar_split_rend_get_quant_params(
MAX_SPLIT_REND_MD_BANDS,
pred_real_bands_yaw,
pred_imag_bands_yaw,
pred_quant_pnts_yaw,
pred_quantstep_yaw,
pred_1byquantstep_yaw,
d_bands_yaw,
bands_pitch,
pred_real_bands_roll,
pred_imag_bands_roll,
ro_md_flag,
&num_quant_strats );
#else
isar_split_rend_get_quant_params(
MAX_SPLIT_REND_MD_BANDS,
pred_real_bands_yaw,
pred_imag_bands_yaw,
......@@ -619,14 +825,15 @@ void ivas_splitBinPostRendMdDec(
pred_imag_bands_roll,
&num_quant_strats,
&num_complex_bands );
#endif
quant_strat_bits = (int32_t) ceilf( log2f( num_quant_strats ) );
is_huff_coding = ivas_split_rend_bitstream_read_int32( pBits, 1 );
quant_strat = ivas_split_rend_bitstream_read_int32( pBits, quant_strat_bits );
is_huff_coding = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 );
quant_strat = ISAR_SPLIT_REND_BITStream_read_int32( pBits, quant_strat_bits );
if ( is_huff_coding == 0 )
{
ivas_splitBinPostRendMdBase2Dec(
isar_splitBinPostRendMdBase2Dec(
pBits, hBinHrSplitPostRend,
pMultiBinPoseData,
num_subframes,
......@@ -640,7 +847,7 @@ void ivas_splitBinPostRendMdDec(
}
else
{
ivas_splitBinPostRendMdHuffDec(
isar_splitBinPostRendMdHuffDec(
pBits, hBinHrSplitPostRend,
pMultiBinPoseData,
num_subframes,
......@@ -765,12 +972,12 @@ void ivas_splitBinPostRendMdDec(
for ( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ )
{
hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
ivas_split_rend_unquant_md( hMd, PRED_ONLY, 0, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], pred_quantstep_yaw[quant_strat] );
isar_split_rend_unquant_md( hMd, PRED_ONLY, 0, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], pred_quantstep_yaw[quant_strat] );
}
for ( ; b < pred_real_bands_yaw[quant_strat]; b++ )
{
hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
ivas_split_rend_unquant_md( hMd, PRED_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], pred_quantstep_yaw[quant_strat] );
isar_split_rend_unquant_md( hMd, PRED_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], pred_quantstep_yaw[quant_strat] );
}
for ( ; b < MAX_SPLIT_REND_MD_BANDS; b++ )
{
......@@ -785,7 +992,7 @@ void ivas_splitBinPostRendMdDec(
for ( b = 0; b < d_bands_yaw[quant_strat]; b++ )
{
hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
ivas_split_rend_unquant_md( hMd, COM_GAIN_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], 0 );
isar_split_rend_unquant_md( hMd, COM_GAIN_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], 0 );
}
for ( ; b < MAX_SPLIT_REND_MD_BANDS; b++ )
{
......@@ -798,7 +1005,7 @@ void ivas_splitBinPostRendMdDec(
for ( b = 0; b < bands_pitch[quant_strat]; b++ )
{
hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
ivas_split_rend_unquant_md( hMd, LR_GAIN_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], 0 );
isar_split_rend_unquant_md( hMd, LR_GAIN_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], 0 );
}
for ( ; b < MAX_SPLIT_REND_MD_BANDS; b++ )
{
......@@ -812,12 +1019,12 @@ void ivas_splitBinPostRendMdDec(
for ( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ )
{
hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
ivas_split_rend_unquant_md( hMd, PRED_ROLL_ONLY, 0, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], IVAS_SPLIT_REND_PRED_ROLL_Q_STEP );
isar_split_rend_unquant_md( hMd, PRED_ROLL_ONLY, 0, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_Q_STEP );
}
for ( ; b < pred_real_bands_roll[quant_strat]; b++ )
{
hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b];
ivas_split_rend_unquant_md( hMd, PRED_ROLL_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], IVAS_SPLIT_REND_PRED_ROLL_Q_STEP );
isar_split_rend_unquant_md( hMd, PRED_ROLL_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_Q_STEP );
}
for ( ; b < MAX_SPLIT_REND_MD_BANDS; b++ )
{
......@@ -1136,7 +1343,7 @@ static void get_interpolation_vars(
*-----------------------------------------------------------------------------------------*/
static void interpolate_pred_matrix(
BIN_HR_SPLIT_REND_MD rot_md[][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS],
ISAR_BIN_HR_SPLIT_REND_MD rot_md[][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS],
const int16_t sf_idx,
const int16_t band_idx,
const int16_t ind[2],
......@@ -1146,7 +1353,7 @@ static void interpolate_pred_matrix(
{
int16_t ch_idx1, ch_idx2;
float diff;
BIN_HR_SPLIT_REND_MD *pRot_md;
ISAR_BIN_HR_SPLIT_REND_MD *pRot_md;
float mix_mat_re1[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
float mix_mat_im1[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
float mix_mat_re2[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
......@@ -1214,7 +1421,7 @@ static void interpolate_pred_matrix(
*-----------------------------------------------------------------------------------------*/
static void interpolate_rend_md(
BIN_HR_SPLIT_REND_MD rot_md[][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS],
ISAR_BIN_HR_SPLIT_REND_MD rot_md[][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS],
float mix_mat_re[][BINAURAL_CHANNELS],
float mix_mat_im[][BINAURAL_CHANNELS],
float *gd_int,
......@@ -1317,7 +1524,7 @@ static void interpolate_rend_md(
{
interpolate_pred_matrix( rot_md, sf_idx, band_idx, interp_roll_pose_idx, interp_roll_fact, mix_mat_re3, mix_mat_im3 );
ivas_mat_mult_2by2_complex( mix_mat_re, mix_mat_im, mix_mat_re3, mix_mat_im3, mix_mat_re1, mix_mat_im1 );
isar_mat_mult_2by2_complex( mix_mat_re, mix_mat_im, mix_mat_re3, mix_mat_im3, mix_mat_re1, mix_mat_im1 );
for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ )
{
......@@ -1334,25 +1541,25 @@ static void interpolate_rend_md(
/*-----------------------------------------------------------------------------------------*
* Function ivas_SplitRenderer_PostRenderer()
* Function isar_SplitRenderer_PostRenderer()
*
*
*-----------------------------------------------------------------------------------------*/
void ivas_SplitRenderer_PostRenderer(
BIN_HR_SPLIT_POST_REND_HANDLE hBinPostRenderer, /* i/o: binaural renderer handle */
static void isar_SplitRenderer_PostRenderer(
ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinPostRenderer, /* i/o: binaural renderer handle */
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
float Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */
float Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */
const IVAS_QUATERNION Quaternion_act )
{
int16_t pos_idx, b, brange[2], ch_idx1;
int16_t num_md_bands, slot_idx, b2, index_slot, num_slots, sf_idx_md;
int16_t num_md_bands, slot_idx, b2, num_slots, sf_idx_md;
float pred_out_re[BINAURAL_CHANNELS], pred_out_im[BINAURAL_CHANNELS], tmp_re, tmp_im, gd_int;
#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
BIN_HR_SPLIT_REND_MD rot_md_act[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS];
ISAR_BIN_HR_SPLIT_REND_MD rot_md_act[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS];
#else
BIN_HR_SPLIT_REND_MD rot_md_act[1][MAX_SPLIT_REND_MD_BANDS];
ISAR_BIN_HR_SPLIT_REND_MD rot_md_act[1][MAX_SPLIT_REND_MD_BANDS];
#endif
int16_t interp_yaw_pose_idx[2], interp_pitch_pose_idx[2], interp_roll_pose_idx[2];
float interp_yaw_fact, interp_pitch_fact, interp_roll_fact;
......@@ -1365,11 +1572,11 @@ void ivas_SplitRenderer_PostRenderer(
float fade;
float *pMix_mat_re_prev[BINAURAL_CHANNELS];
float *pMix_mat_im_prev[BINAURAL_CHANNELS];
const int16_t *pBand_grouping = ivas_split_rend_band_grouping;
const int16_t *pBand_grouping = isar_split_rend_band_grouping;
num_md_bands = MAX_SPLIT_REND_MD_BANDS;
push_wmops( "ivas_SplitRenderer_PostRenderer" );
push_wmops( "isar_SplitRenderer_PostRenderer" );
num_slots = MAX_PARAM_SPATIAL_SUBFRAMES;
#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
......@@ -1450,7 +1657,6 @@ void ivas_SplitRenderer_PostRenderer(
{
for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ )
{
index_slot = slot_idx; /* TODO: can be cleaned up */
fade = ( (float) slot_idx + 1.0f ) / MAX_PARAM_SPATIAL_SUBFRAMES;
fade = min( fade, 1.0f );
for ( b = 0; b < num_md_bands; b++ )
......@@ -1487,8 +1693,8 @@ void ivas_SplitRenderer_PostRenderer(
for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ )
{
/* Apply prediction matrix */
IVAS_CMULT_FLOAT( Cldfb_RealBuffer_Ref_Binaural[0][index_slot][b2],
Cldfb_ImagBuffer_Ref_Binaural[0][index_slot][b2],
IVAS_CMULT_FLOAT( Cldfb_RealBuffer_Ref_Binaural[0][slot_idx][b2],
Cldfb_ImagBuffer_Ref_Binaural[0][slot_idx][b2],
mix_mat_re[0][ch_idx1],
mix_mat_im[0][ch_idx1],
tmp_re,
......@@ -1496,8 +1702,8 @@ void ivas_SplitRenderer_PostRenderer(
pred_out_re[ch_idx1] = tmp_re;
pred_out_im[ch_idx1] = tmp_im;
IVAS_CMULT_FLOAT( Cldfb_RealBuffer_Ref_Binaural[1][index_slot][b2],
Cldfb_ImagBuffer_Ref_Binaural[1][index_slot][b2],
IVAS_CMULT_FLOAT( Cldfb_RealBuffer_Ref_Binaural[1][slot_idx][b2],
Cldfb_ImagBuffer_Ref_Binaural[1][slot_idx][b2],
mix_mat_re[1][ch_idx1],
mix_mat_im[1][ch_idx1],
tmp_re,
......@@ -1510,11 +1716,11 @@ void ivas_SplitRenderer_PostRenderer(
for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ )
{
#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
Cldfb_RealBuffer_Recons_Binaural[pos_idx][ch_idx1][index_slot][b2] = pred_out_re[ch_idx1];
Cldfb_ImagBuffer_Recons_Binaural[pos_idx][ch_idx1][index_slot][b2] = pred_out_im[ch_idx1];
Cldfb_RealBuffer_Recons_Binaural[pos_idx][ch_idx1][slot_idx][b2] = pred_out_re[ch_idx1];
Cldfb_ImagBuffer_Recons_Binaural[pos_idx][ch_idx1][slot_idx][b2] = pred_out_im[ch_idx1];
#else
Cldfb_RealBuffer_Ref_Binaural[ch_idx1][index_slot][b2] = pred_out_re[ch_idx1];
Cldfb_ImagBuffer_Ref_Binaural[ch_idx1][index_slot][b2] = pred_out_im[ch_idx1];
Cldfb_RealBuffer_Ref_Binaural[ch_idx1][slot_idx][b2] = pred_out_re[ch_idx1];
Cldfb_ImagBuffer_Ref_Binaural[ch_idx1][slot_idx][b2] = pred_out_im[ch_idx1];
#endif
}
}
......@@ -1564,7 +1770,7 @@ void ivas_SplitRenderer_PostRenderer(
tag[1] = '\0';
strcat( fname, tag );
strcat( fname, ".wav" );
ivas_log_cldfb2wav_data(
isar_log_cldfb2wav_data(
Cldfb_RealBuffer_Recons_Binaural[pos_idx],
Cldfb_ImagBuffer_Recons_Binaural[pos_idx],
hBinPostRenderer->cldfbSynReconsBinDec[pos_idx],
......@@ -1584,13 +1790,13 @@ void ivas_SplitRenderer_PostRenderer(
/*-----------------------------------------------------------------------------------------*
* Function ivas_rend_CldfbSplitPostRendProcessTdIn()
* Function isar_rend_CldfbSplitPostRendProcessTdIn()
*
*
*-----------------------------------------------------------------------------------------*/
static void ivas_rend_CldfbSplitPostRendProcessTdIn(
BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend,
static void isar_rend_CldfbSplitPostRendProcessTdIn(
ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend,
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
const IVAS_QUATERNION QuaternionPost,
float output[][L_FRAME48k] )
......@@ -1613,7 +1819,7 @@ static void ivas_rend_CldfbSplitPostRendProcessTdIn(
}
}
ivas_SplitRenderer_PostRenderer( hBinHrSplitPostRend, pMultiBinPoseData, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, QuaternionPost );
isar_SplitRenderer_PostRenderer( hBinHrSplitPostRend, pMultiBinPoseData, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, QuaternionPost );
/* Implement CLDFB synthesis */
for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ )
......@@ -1635,13 +1841,13 @@ static void ivas_rend_CldfbSplitPostRendProcessTdIn(
/*-----------------------------------------------------------------------------------------*
* Function ivas_rend_CldfbSplitPostRendProcess()
* Function isar_rend_CldfbSplitPostRendProcess()
*
*
*-----------------------------------------------------------------------------------------*/
void ivas_rend_CldfbSplitPostRendProcess(
BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend,
void isar_rend_CldfbSplitPostRendProcess(
ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend,
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
const IVAS_QUATERNION QuaternionPost,
float Cldfb_RealBuffer_Binaural[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
......@@ -1651,18 +1857,18 @@ void ivas_rend_CldfbSplitPostRendProcess(
{
int16_t ch_idx, slot_idx, num_cldfb_bands;
push_wmops( "ivas_rend_CldfbSplitPostRendProcess" );
push_wmops( "isar_rend_CldfbSplitPostRendProcess" );
num_cldfb_bands = hBinHrSplitPostRend->cldfbSyn[0]->no_channels;
if ( cldfb_in_flag == 0 )
{
ivas_rend_CldfbSplitPostRendProcessTdIn( hBinHrSplitPostRend, pMultiBinPoseData, QuaternionPost, output );
isar_rend_CldfbSplitPostRendProcessTdIn( hBinHrSplitPostRend, pMultiBinPoseData, QuaternionPost, output );
pop_wmops();
return;
}
ivas_SplitRenderer_PostRenderer( hBinHrSplitPostRend, pMultiBinPoseData, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, QuaternionPost );
isar_SplitRenderer_PostRenderer( hBinHrSplitPostRend, pMultiBinPoseData, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, QuaternionPost );
/* Implement CLDFB synthesis */
for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ )
......@@ -1685,18 +1891,18 @@ void ivas_rend_CldfbSplitPostRendProcess(
/*-----------------------------------------------------------------------------------------*
* Function ivas_init_split_post_rend_handles()
* Function isar_init_split_post_rend_handles()
*
*
*-----------------------------------------------------------------------------------------*/
void ivas_init_split_post_rend_handles(
SPLIT_POST_REND_WRAPPER *hSplitRendWrapper )
void isar_init_split_post_rend_handles(
ISAR_SPLIT_POST_REND_WRAPPER *hSplitRendWrapper )
{
hSplitRendWrapper->hBinHrSplitPostRend = NULL;
hSplitRendWrapper->hSplitBinLCLDDec = NULL;
hSplitRendWrapper->hLc3plusDec = NULL;
ivas_init_multi_bin_pose_data( &hSplitRendWrapper->multiBinPoseData );
isar_init_multi_bin_pose_data( &hSplitRendWrapper->multiBinPoseData );
hSplitRendWrapper->first_good_frame_received = 0;
return;
......
......@@ -39,9 +39,9 @@
#endif
#include "ivas_prot.h"
#include "prot.h"
#include "ivas_cnst.h"
#include "ivas_rom_dec.h"
#include "ivas_prot_rend.h"
#include "isar_rom_post_rend.h"
#include "lib_isar_pre_rend.h"
#include "isar_prot.h"
#ifdef DEBUGGING
#include "debug.h"
#endif
......@@ -50,6 +50,17 @@
#include "string.h"
#endif
/*---------------------------------------------------------------------*
* Local function declarations
*---------------------------------------------------------------------*/
static void isar_SplitRenderer_GetRotMd(
ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i/o: binaural renderer handle */
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
float Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */
float Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */
const int16_t low_res,
const int16_t ro_md_flag );
/*-------------------------------------------------------------------------
* Local functions
......@@ -57,7 +68,7 @@
*
*------------------------------------------------------------------------*/
static void ivas_calc_mat_det_2by2_complex(
static void isar_calc_mat_det_2by2_complex(
float in_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
float in_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
float *det_re,
......@@ -74,14 +85,14 @@ static void ivas_calc_mat_det_2by2_complex(
}
static int16_t ivas_is_mat_inv_2by2_complex(
static int16_t isar_is_mat_inv_2by2_complex(
float in_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
float in_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS] )
{
int16_t is_det_zero = 1;
float det, det_re, det_im;
ivas_calc_mat_det_2by2_complex( in_re, in_im, &det_re, &det_im );
isar_calc_mat_det_2by2_complex( in_re, in_im, &det_re, &det_im );
det = ( ( det_re * det_re ) + ( det_im * det_im ) );
......@@ -94,7 +105,7 @@ static int16_t ivas_is_mat_inv_2by2_complex(
}
static void ivas_calc_mat_inv_2by2_complex(
static void isar_calc_mat_inv_2by2_complex(
float in_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
float in_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
float out_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
......@@ -103,7 +114,7 @@ static void ivas_calc_mat_inv_2by2_complex(
float det_re, det_im;
float re, im, det;
ivas_calc_mat_det_2by2_complex( in_re, in_im, &det_re, &det_im );
isar_calc_mat_det_2by2_complex( in_re, in_im, &det_re, &det_im );
det = ( det_re * det_re ) + ( det_im * det_im );
......@@ -140,8 +151,8 @@ static void ComputePredMat(
float cov_io_im[][BINAURAL_CHANNELS],
float pred_mat_re[][BINAURAL_CHANNELS],
float pred_mat_im[][BINAURAL_CHANNELS],
int16_t num_chs,
int16_t real_only )
const int16_t num_chs,
const int16_t real_only )
{
float cov_ii_local_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
float cov_ii_inv_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
......@@ -178,10 +189,10 @@ static void ComputePredMat(
cov_ii_local_re[i][i] = cov_ii_re[i][i] + ( trace_cov * 0.0001f );
}
if ( ivas_is_mat_inv_2by2_complex( cov_ii_local_re, cov_ii_im ) )
if ( isar_is_mat_inv_2by2_complex( cov_ii_local_re, cov_ii_im ) )
{
ivas_calc_mat_inv_2by2_complex( cov_ii_local_re, cov_ii_im, cov_ii_inv_re, cov_ii_inv_im );
ivas_mat_mult_2by2_complex( cov_ii_inv_re, cov_ii_inv_im, cov_io_re, cov_io_im, pred_mat_re, pred_mat_im );
isar_calc_mat_inv_2by2_complex( cov_ii_local_re, cov_ii_im, cov_ii_inv_re, cov_ii_inv_im );
isar_mat_mult_2by2_complex( cov_ii_inv_re, cov_ii_inv_im, cov_io_re, cov_io_im, pred_mat_re, pred_mat_im );
}
else
{
......@@ -226,14 +237,14 @@ static void ComputePostPredCov(
float pred_mat_re[][BINAURAL_CHANNELS],
float pred_mat_im[][BINAURAL_CHANNELS],
float postpred_cov_re[][BINAURAL_CHANNELS],
float postpred_cov_im[][BINAURAL_CHANNELS],
int16_t num_chs )
const int16_t num_chs )
{
int16_t i, j;
float dmx_mat_conj_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
float dmx_mat_conj_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
float temp_mat_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
float temp_mat_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
float postpred_cov_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
assert( num_chs == BINAURAL_CHANNELS );
for ( i = 0; i < num_chs; i++ )
......@@ -247,21 +258,18 @@ static void ComputePostPredCov(
temp_mat_im[i][j] = pred_mat_im[i][j];
}
set_zero( postpred_cov_re[i], BINAURAL_CHANNELS );
set_zero( postpred_cov_im[i], BINAURAL_CHANNELS );
}
/* 2x2 mult */
ivas_mat_mult_2by2_complex( dmx_mat_conj_re, dmx_mat_conj_im, cov_ii_re, cov_ii_im, temp_mat_re, temp_mat_im );
ivas_mat_mult_2by2_complex( temp_mat_re, temp_mat_im, pred_mat_re, pred_mat_im, postpred_cov_re, postpred_cov_im );
isar_mat_mult_2by2_complex( dmx_mat_conj_re, dmx_mat_conj_im, cov_ii_re, cov_ii_im, temp_mat_re, temp_mat_im );
isar_mat_mult_2by2_complex( temp_mat_re, temp_mat_im, pred_mat_re, pred_mat_im, postpred_cov_re, postpred_cov_im );
for ( i = 0; i < BINAURAL_CHANNELS; i++ )
{
for ( j = 0; j < i; j++ )
{
postpred_cov_re[i][j] = postpred_cov_re[j][i];
postpred_cov_im[i][j] = -postpred_cov_im[j][i];
}
postpred_cov_im[i][i] = 0;
}
return;
......@@ -446,9 +454,9 @@ static float GetNormFact(
}
static void ivas_split_rend_huffman_encode(
ivas_split_rend_huffman_cfg_t *huff_cfg,
int16_t in,
static void isar_split_rend_huffman_encode(
isar_split_rend_huffman_cfg_t *huff_cfg,
const int16_t in,
int32_t *hcode,
int32_t *hlen )
{
......@@ -465,16 +473,20 @@ static void ivas_split_rend_huffman_encode(
}
static void ivas_split_rend_quant_md(
BIN_HR_SPLIT_REND_MD_HANDLE hMd,
IVAS_SPLIT_REND_POSE_TYPE pose_type,
int16_t real_only,
static void isar_split_rend_quant_md(
ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd,
const ISAR_SPLIT_REND_POSE_TYPE pose_type,
const int16_t real_only,
float fix_pos_rot_mat[][BINAURAL_CHANNELS],
const float pred_1byquantstep )
{
int16_t ch1, ch2;
int16_t gd_idx_min;
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
float quant_val;
#else
float sign, quant_val;
#endif
if ( pose_type == PRED_ONLY || pose_type == PRED_ROLL_ONLY )
{
......@@ -483,6 +495,24 @@ static void ivas_split_rend_quant_md(
onebyquantstep = pred_1byquantstep;
if ( real_only == 1 )
{
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
hMd->pred_mat_re[ch1][ch1] = hMd->pred_mat_re2[ch1];
}
hMd->pred_mat_re[1][0] = 0.0f;
hMd->pred_mat_re[0][1] = 0.0f;
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
quant_val = hMd->pred_mat_re[ch1][ch2] - ( ( ch1 == ch2 ) ? 1.0f : 0.0f );
quant_val = min( ISAR_SPLIT_REND_PRED_MAX_VAL, max( quant_val, ISAR_SPLIT_REND_PRED_MIN_VAL ) );
hMd->pred_mat_re_idx[ch1][ch2] = (int16_t) roundf( onebyquantstep * quant_val );
}
}
#else
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
......@@ -493,17 +523,24 @@ static void ivas_split_rend_quant_md(
hMd->pred_mat_im[ch1][ch2] = 0.0f;
}
}
#endif
}
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
else
{
#endif
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
quant_val = hMd->pred_mat_re[ch1][ch2] - fix_pos_rot_mat[ch1][ch2];
quant_val = min( IVAS_SPLIT_REND_PRED_MAX_VAL, max( quant_val, IVAS_SPLIT_REND_PRED_MIN_VAL ) );
quant_val = min( ISAR_SPLIT_REND_PRED_MAX_VAL, max( quant_val, ISAR_SPLIT_REND_PRED_MIN_VAL ) );
hMd->pred_mat_re_idx[ch1][ch2] = (int16_t) roundf( onebyquantstep * quant_val );
}
}
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
}
#endif
if ( real_only == 0 )
{
......@@ -511,36 +548,57 @@ static void ivas_split_rend_quant_md(
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
quant_val = min( IVAS_SPLIT_REND_PRED_MAX_VAL, max( hMd->pred_mat_im[ch1][ch2], IVAS_SPLIT_REND_PRED_MIN_VAL ) );
quant_val = min( ISAR_SPLIT_REND_PRED_MAX_VAL, max( hMd->pred_mat_im[ch1][ch2], ISAR_SPLIT_REND_PRED_MIN_VAL ) );
hMd->pred_mat_im_idx[ch1][ch2] = (int16_t) roundf( onebyquantstep * quant_val );
// hMd->pred_mat_im[ch1][ch2] = hMd->pred_mat_im_idx[ch1][ch2] * IVAS_SPLIT_REND_PRED_Q_STEP;
}
}
}
}
else if ( pose_type == COM_GAIN_ONLY )
{
quant_val = min( IVAS_SPLIT_REND_D_MAX_VAL, max( hMd->gd, IVAS_SPLIT_REND_D_MIN_VAL ) );
gd_idx_min = (int16_t) roundf( IVAS_SPLIT_REND_D_1BYQ_STEP * IVAS_SPLIT_REND_D_MIN_VAL );
hMd->gd_idx = (int16_t) roundf( IVAS_SPLIT_REND_D_1BYQ_STEP * quant_val );
hMd->gd = hMd->gd_idx * IVAS_SPLIT_REND_D_Q_STEP;
quant_val = min( ISAR_SPLIT_REND_D_MAX_VAL, max( hMd->gd, ISAR_SPLIT_REND_D_MIN_VAL ) );
gd_idx_min = (int16_t) roundf( ISAR_SPLIT_REND_D_1BYQ_STEP * ISAR_SPLIT_REND_D_MIN_VAL );
hMd->gd_idx = (int16_t) roundf( ISAR_SPLIT_REND_D_1BYQ_STEP * quant_val );
hMd->gd = hMd->gd_idx * ISAR_SPLIT_REND_D_Q_STEP;
hMd->gd_idx = hMd->gd_idx - gd_idx_min;
}
else if ( pose_type == LR_GAIN_ONLY )
{
quant_val = min( IVAS_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd, IVAS_SPLIT_REND_PITCH_G_MIN_VAL ) );
gd_idx_min = (int16_t) roundf( IVAS_SPLIT_REND_PITCH_G_1BYQ_STEP * IVAS_SPLIT_REND_PITCH_G_MIN_VAL );
hMd->gd_idx = (int16_t) roundf( IVAS_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val );
quant_val = min( ISAR_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd, ISAR_SPLIT_REND_PITCH_G_MIN_VAL ) );
gd_idx_min = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * ISAR_SPLIT_REND_PITCH_G_MIN_VAL );
hMd->gd_idx = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val );
hMd->gd_idx = hMd->gd_idx - gd_idx_min;
quant_val = min( IVAS_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd2, IVAS_SPLIT_REND_PITCH_G_MIN_VAL ) );
hMd->gd2_idx = (int16_t) roundf( IVAS_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val );
quant_val = min( ISAR_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd2, ISAR_SPLIT_REND_PITCH_G_MIN_VAL ) );
hMd->gd2_idx = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val );
hMd->gd2_idx = hMd->gd2_idx - gd_idx_min;
}
return;
}
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
static void get_lr_gains( float cov_in[][BINAURAL_CHANNELS],
float cov_out[][BINAURAL_CHANNELS],
float gains[BINAURAL_CHANNELS] )
{
int16_t i;
for ( i = 0; i < BINAURAL_CHANNELS; i++ )
{
gains[i] = cov_in[i][i];
if ( gains[i] < EPSILON )
{
gains[i] = 1.0f;
}
else
{
gains[i] = ( cov_out[i][i] ) / gains[i];
gains[i] = sqrtf( gains[i] );
}
}
return;
}
#endif
static void ComputeCoeffs(
float cov_ii_re[][BINAURAL_CHANNELS],
......@@ -548,12 +606,11 @@ static void ComputeCoeffs(
float cov_io_re[][BINAURAL_CHANNELS],
float cov_io_im[][BINAURAL_CHANNELS],
float cov_oo_re[][BINAURAL_CHANNELS],
BIN_HR_SPLIT_REND_MD_HANDLE hMd,
const IVAS_SPLIT_REND_POSE_TYPE pose_type,
ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd,
const ISAR_SPLIT_REND_POSE_TYPE pose_type,
const int16_t real_only )
{
float postpred_cov_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
float postpred_cov_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
float cov_ii_norm_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
float cov_ii_norm_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
float cov_io_norm_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
......@@ -565,7 +622,9 @@ static void ComputeCoeffs(
if ( pose_type == PITCH_ONLY )
{
float gd_tmp[BINAURAL_CHANNELS];
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
get_lr_gains( cov_ii_re, cov_oo_re, gd_tmp );
#else
for ( i = 0; i < BINAURAL_CHANNELS; i++ )
{
gd_tmp[i] = cov_ii_re[i][i];
......@@ -579,6 +638,7 @@ static void ComputeCoeffs(
gd_tmp[i] = sqrtf( gd_tmp[i] );
}
}
#endif
hMd->gd = gd_tmp[0];
hMd->gd2 = gd_tmp[1];
}
......@@ -587,7 +647,15 @@ static void ComputeCoeffs(
if ( real_only )
{
float gd_tmp[BINAURAL_CHANNELS];
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
get_lr_gains( cov_ii_re, cov_oo_re, gd_tmp );
for ( i = 0; i < BINAURAL_CHANNELS; i++ )
{
hMd->pred_mat_re[i][i] = gd_tmp[i];
hMd->pred_mat_re2[i] = gd_tmp[i];
set_zero( hMd->pred_mat_im[i], BINAURAL_CHANNELS );
}
#else
for ( i = 0; i < BINAURAL_CHANNELS; i++ )
{
gd_tmp[i] = cov_ii_re[i][i];
......@@ -603,11 +671,15 @@ static void ComputeCoeffs(
hMd->pred_mat_re[i][i] = gd_tmp[i];
set_zero( hMd->pred_mat_im[i], BINAURAL_CHANNELS );
}
#endif
hMd->pred_mat_re[1][0] = 0.0f;
hMd->pred_mat_re[0][1] = 0.0f;
}
else
{
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
get_lr_gains( cov_ii_re, cov_oo_re, hMd->pred_mat_re2 );
#endif
cov_norm_fact = GetNormFact( cov_ii_re, cov_ii_im, cov_io_re, cov_io_im, cov_oo_re );
/* normalize the covariance */
......@@ -625,8 +697,7 @@ static void ComputeCoeffs(
ComputePredMat( cov_ii_norm_re, cov_ii_norm_im, cov_io_norm_re, cov_io_norm_im, hMd->pred_mat_re, hMd->pred_mat_im, BINAURAL_CHANNELS, real_only );
/*TODO : change this function to real only as thats what is needed*/
ComputePostPredCov( cov_ii_norm_re, cov_ii_norm_im, hMd->pred_mat_re, hMd->pred_mat_im, postpred_cov_re, postpred_cov_im, BINAURAL_CHANNELS );
ComputePostPredCov( cov_ii_norm_re, cov_ii_norm_im, hMd->pred_mat_re, hMd->pred_mat_im, postpred_cov_re, BINAURAL_CHANNELS );
/* normalize everything to +-1 range */
gd = 1.0f / ( PCM16_TO_FLT_FAC );
......@@ -688,32 +759,32 @@ static void ComputeCoeffs(
static void get_base2_bits(
const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend,
const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend,
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
const int16_t num_subframes,
const int16_t num_quant_strats,
const int16_t pred_real_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS],
const int16_t pred_imag_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS],
int16_t pred_quant_pnts_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS],
const int16_t d_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS],
const int16_t bands_pitch[IVAS_SPLIT_REND_NUM_QUANT_STRATS],
const int16_t pred_real_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS],
const int16_t pred_imag_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS],
int32_t base2bits[IVAS_SPLIT_REND_NUM_QUANT_STRATS] )
const int16_t pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
const int16_t pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
int16_t pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
const int16_t d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
const int16_t bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
const int16_t pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
const int16_t pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
int32_t base2bits[ISAR_SPLIT_REND_NUM_QUANT_STRATS] )
{
int16_t pred_roll_bits;
int16_t d_gain_bits, pitch_gain_bits, pose_idx, q;
int16_t pred_yaw_bits[IVAS_SPLIT_REND_NUM_QUANT_STRATS];
int16_t pred_yaw_bits[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
IVAS_SPLIT_REND_POSE_TYPE pose_type;
ISAR_SPLIT_REND_POSE_TYPE pose_type;
for ( q = 0; q < num_quant_strats; q++ )
{
pred_yaw_bits[q] = (int16_t) ceilf( log2f( pred_quant_pnts_yaw[q] ) );
}
pred_roll_bits = (int16_t) ceilf( log2f( IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS ) );
pred_roll_bits = (int16_t) ceilf( log2f( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS ) );
d_gain_bits = (int16_t) ceilf( log2f( IVAS_SPLIT_REND_D_QUANT_PNTS ) );
d_gain_bits = (int16_t) ceilf( log2f( ISAR_SPLIT_REND_D_QUANT_PNTS ) );
pitch_gain_bits = d_gain_bits;
for ( q = 0; q < num_quant_strats; q++ )
......@@ -728,8 +799,14 @@ static void get_base2_bits(
pose_type = hBinHrSplitPreRend->pose_type[pose_idx];
if ( pose_type == ANY_YAW )
{
#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
base2bits[q] += pred_yaw_bits[q] * pred_real_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS;
base2bits[q] += pred_yaw_bits[q] * pred_imag_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS;
#else
base2bits[q] += pred_yaw_bits[q] * pred_real_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS;
base2bits[q] += pred_yaw_bits[q] * pred_imag_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS;
base2bits[q] += pred_yaw_bits[q] * pred_imag_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS;
#endif
base2bits[q] += d_gain_bits * d_bands_yaw[q] * num_subframes;
}
else if ( pose_type == PITCH_ONLY )
......@@ -739,8 +816,14 @@ static void get_base2_bits(
}
else
{
#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
base2bits[q] += pred_roll_bits * pred_real_bands_roll[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS;
base2bits[q] += pred_roll_bits * pred_imag_bands_roll[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS;
#else
base2bits[q] += pred_roll_bits * pred_real_bands_roll[q] * num_subframes * BINAURAL_CHANNELS;
base2bits[q] += pred_roll_bits * pred_imag_bands_roll[q] * num_subframes * BINAURAL_CHANNELS;
base2bits[q] += pred_roll_bits * pred_imag_bands_roll[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS;
#endif
}
}
}
......@@ -749,8 +832,8 @@ static void get_base2_bits(
}
static void ivas_SplitRenderer_code_md_base2(
const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend,
static void isar_SplitRenderer_code_md_base2(
const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend,
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
const int16_t num_subframes,
const int16_t pred_real_bands_yaw,
......@@ -760,18 +843,18 @@ static void ivas_SplitRenderer_code_md_base2(
const int16_t bands_pitch,
const int16_t pred_real_bands_roll,
const int16_t pred_imag_bands_roll,
IVAS_SPLIT_REND_BITS_HANDLE pBits )
ISAR_SPLIT_REND_BITS_HANDLE pBits )
{
int16_t pos_idx, b, ch1, ch2, sf_idx;
int16_t min_pred_idx, min_gd_idx, min_p_gd_idx, pred_code_len, gd_code_len, p_gd_code_len, num_poses;
int16_t min_pred_roll_idx, pred_roll_code_len;
int16_t pred_cb_idx;
int32_t code;
BIN_HR_SPLIT_REND_MD_HANDLE hMd;
BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg;
ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd;
ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg;
pHuff_cfg = &hBinHrSplitPreRend->huff_cfg;
if ( pred_quant_pnts_yaw == IVAS_SPLIT_REND_PRED_63QUANT_PNTS )
if ( pred_quant_pnts_yaw == ISAR_SPLIT_REND_PRED_63QUANT_PNTS )
{
pred_cb_idx = 1;
}
......@@ -797,6 +880,7 @@ static void ivas_SplitRenderer_code_md_base2(
{
if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW )
{
#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
for ( b = 0; b < pred_real_bands_yaw; b++ )
{
hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
......@@ -805,7 +889,7 @@ static void ivas_SplitRenderer_code_md_base2(
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
code = hMd->pred_mat_re_idx[ch1][ch2] - min_pred_idx;
ivas_split_rend_bitstream_write_int32( pBits, code, pred_code_len );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len );
}
}
}
......@@ -818,15 +902,49 @@ static void ivas_SplitRenderer_code_md_base2(
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
code = hMd->pred_mat_im_idx[ch1][ch2] - min_pred_idx;
ivas_split_rend_bitstream_write_int32( pBits, code, pred_code_len );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len );
}
}
}
#else
for ( b = 0; b < pred_imag_bands_yaw; b++ )
{
hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
code = hMd->pred_mat_re_idx[ch1][ch2] - min_pred_idx;
ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len );
}
}
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
code = hMd->pred_mat_im_idx[ch1][ch2] - min_pred_idx;
ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len );
}
}
}
for ( ; b < pred_real_bands_yaw; b++ )
{
hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
code = hMd->pred_mat_re_idx[ch1][ch1] - min_pred_idx;
ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len );
}
}
#endif
for ( b = 0; b < d_bands_yaw; b++ )
{
hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
code = hMd->gd_idx - min_gd_idx;
ivas_split_rend_bitstream_write_int32( pBits, code, gd_code_len );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, gd_code_len );
}
}
else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY )
......@@ -835,14 +953,15 @@ static void ivas_SplitRenderer_code_md_base2(
{
hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
code = hMd->gd_idx - min_p_gd_idx;
ivas_split_rend_bitstream_write_int32( pBits, code, p_gd_code_len );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, p_gd_code_len );
code = hMd->gd2_idx - min_p_gd_idx;
ivas_split_rend_bitstream_write_int32( pBits, code, p_gd_code_len );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, p_gd_code_len );
}
}
else
{
#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
for ( b = 0; b < pred_real_bands_roll; b++ )
{
hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
......@@ -851,7 +970,7 @@ static void ivas_SplitRenderer_code_md_base2(
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
code = hMd->pred_mat_re_idx[ch1][ch2] - min_pred_roll_idx;
ivas_split_rend_bitstream_write_int32( pBits, code, pred_roll_code_len );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len );
}
}
}
......@@ -864,10 +983,42 @@ static void ivas_SplitRenderer_code_md_base2(
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
code = hMd->pred_mat_im_idx[ch1][ch2] - min_pred_roll_idx;
ivas_split_rend_bitstream_write_int32( pBits, code, pred_roll_code_len );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len );
}
}
}
#else
for ( b = 0; b < pred_imag_bands_roll; b++ )
{
hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
code = hMd->pred_mat_re_idx[ch1][ch2] - min_pred_roll_idx;
ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len );
}
}
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
code = hMd->pred_mat_im_idx[ch1][ch2] - min_pred_roll_idx;
ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len );
}
}
}
for ( ; b < pred_real_bands_roll; b++ )
{
hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
code = hMd->pred_mat_re_idx[ch1][ch1] - min_pred_roll_idx;
ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len );
}
}
#endif
}
}
}
......@@ -895,8 +1046,8 @@ static void ivas_SplitRenderer_code_md_base2(
}
static void ivas_SplitRenderer_code_md_huff(
const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend,
static void isar_SplitRenderer_code_md_huff(
const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend,
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
const int16_t num_subframes,
const int16_t pred_real_bands_yaw,
......@@ -906,19 +1057,19 @@ static void ivas_SplitRenderer_code_md_huff(
const int16_t bands_pitch,
const int16_t pred_real_bands_roll,
const int16_t pred_imag_bands_roll,
IVAS_SPLIT_REND_BITS_HANDLE pBits )
ISAR_SPLIT_REND_BITS_HANDLE pBits )
{
int16_t pos_idx, b, ch1, ch2, sf_idx, num_poses;
int16_t sym_adj_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
int16_t min_pred_idx, max_pred_idx;
int16_t min_pred_roll_idx, max_pred_roll_idx, pred_cb_idx;
int32_t code, len;
BIN_HR_SPLIT_REND_MD_HANDLE hMd;
BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg;
ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd;
ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg;
pHuff_cfg = &hBinHrSplitPreRend->huff_cfg;
if ( pred_quant_pnts_yaw == IVAS_SPLIT_REND_PRED_63QUANT_PNTS )
if ( pred_quant_pnts_yaw == ISAR_SPLIT_REND_PRED_63QUANT_PNTS )
{
pred_cb_idx = 1;
}
......@@ -930,7 +1081,7 @@ static void ivas_SplitRenderer_code_md_huff(
min_pred_idx = (int16_t) pHuff_cfg->pred[pred_cb_idx].codebook[0];
max_pred_idx = (int16_t) pHuff_cfg->pred[pred_cb_idx].codebook[( pred_quant_pnts_yaw - 1 ) * 3];
min_pred_roll_idx = (int16_t) pHuff_cfg->pred_roll.codebook[0];
max_pred_roll_idx = (int16_t) pHuff_cfg->pred_roll.codebook[( IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) * 3];
max_pred_roll_idx = (int16_t) pHuff_cfg->pred_roll.codebook[( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) * 3];
num_poses = pMultiBinPoseData->num_poses;
......@@ -940,39 +1091,76 @@ static void ivas_SplitRenderer_code_md_huff(
{
if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW )
{
#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
for ( b = 0; b < pred_real_bands_yaw; b++ )
{
hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
ivas_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_idx, max_pred_idx );
isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_idx, max_pred_idx );
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
ivas_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len );
ivas_split_rend_bitstream_write_int32( pBits, code, len );
isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
}
}
}
for ( b = 0; b < pred_imag_bands_yaw; b++ )
{
hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
ivas_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_idx, max_pred_idx );
isar_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_idx, max_pred_idx );
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
ivas_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len );
isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
}
}
}
#else
for ( b = 0; b < pred_imag_bands_yaw; b++ )
{
hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_idx, max_pred_idx );
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
}
}
ivas_split_rend_bitstream_write_int32( pBits, code, len );
isar_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_idx, max_pred_idx );
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
}
}
}
for ( ; b < pred_real_bands_yaw; b++ )
{
hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, 1, min_pred_idx, max_pred_idx );
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch1], &code, &len );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
}
}
#endif
for ( b = 0; b < d_bands_yaw; b++ )
{
hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
ivas_split_rend_huffman_encode( &pHuff_cfg->gd, hMd->gd_idx, &code, &len );
ivas_split_rend_bitstream_write_int32( pBits, code, len );
isar_split_rend_huffman_encode( &pHuff_cfg->gd, hMd->gd_idx, &code, &len );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
}
}
else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY )
......@@ -980,41 +1168,78 @@ static void ivas_SplitRenderer_code_md_huff(
for ( b = 0; b < bands_pitch; b++ )
{
hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
ivas_split_rend_huffman_encode( &pHuff_cfg->p_gd, hMd->gd_idx, &code, &len );
ivas_split_rend_bitstream_write_int32( pBits, code, len );
isar_split_rend_huffman_encode( &pHuff_cfg->p_gd, hMd->gd_idx, &code, &len );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
ivas_split_rend_huffman_encode( &pHuff_cfg->p_gd, hMd->gd2_idx, &code, &len );
ivas_split_rend_bitstream_write_int32( pBits, code, len );
isar_split_rend_huffman_encode( &pHuff_cfg->p_gd, hMd->gd2_idx, &code, &len );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
}
}
else
{
#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
for ( b = 0; b < pred_real_bands_roll; b++ )
{
hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
ivas_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_roll_idx, max_pred_roll_idx );
isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_roll_idx, max_pred_roll_idx );
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
}
}
}
for ( b = 0; b < pred_imag_bands_roll; b++ )
{
hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
isar_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_roll_idx, max_pred_roll_idx );
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
ivas_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len );
ivas_split_rend_bitstream_write_int32( pBits, code, len );
isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
}
}
}
#else
for ( b = 0; b < pred_imag_bands_roll; b++ )
{
hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
ivas_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_roll_idx, max_pred_roll_idx );
isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_roll_idx, max_pred_roll_idx );
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
}
}
isar_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_roll_idx, max_pred_roll_idx );
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ )
{
ivas_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len );
ivas_split_rend_bitstream_write_int32( pBits, code, len );
isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
}
}
}
for ( ; b < pred_real_bands_roll; b++ )
{
hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, 1, min_pred_roll_idx, max_pred_roll_idx );
for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ )
{
isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch1], &code, &len );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len );
}
}
#endif
}
}
}
......@@ -1041,24 +1266,34 @@ static void ivas_SplitRenderer_code_md_huff(
}
static void ivas_SplitRenderer_quant_code(
const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend,
static void isar_SplitRenderer_quant_code(
const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend,
const IVAS_QUATERNION headPosition,
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
IVAS_SPLIT_REND_BITS_HANDLE pBits,
ISAR_SPLIT_REND_BITS_HANDLE pBits,
const int16_t low_res_pre_rend_rot,
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
const int16_t ro_md_flag,
#endif
const int32_t target_md_bits )
{
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
int16_t q, num_subframes, sf_idx, pos_idx, b, num_quant_strats;
#else
int16_t num_complex_bands, q, num_subframes, sf_idx, pos_idx, b, num_quant_strats;
#endif
int32_t overhead_bits, quant_strat_bits, huff_bits, start_bit;
int16_t pred_real_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], pred_real_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS];
int16_t pred_imag_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], pred_imag_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS];
int16_t d_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], bands_pitch[IVAS_SPLIT_REND_NUM_QUANT_STRATS];
int32_t base2bits[IVAS_SPLIT_REND_NUM_QUANT_STRATS];
int16_t pred_quant_pnts_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS];
float pred_1byquantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS];
float pred_quantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS];
BIN_HR_SPLIT_REND_MD_HANDLE hMd;
int16_t pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
int16_t pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
int16_t d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
int32_t base2bits[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
int16_t pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
float pred_1byquantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
float pred_quantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS];
ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd;
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
int16_t rot_axis_code, num_bits;
#endif
if ( low_res_pre_rend_rot )
{
......@@ -1071,9 +1306,18 @@ static void ivas_SplitRenderer_quant_code(
overhead_bits = pBits->bits_written;
ivas_split_rend_bitstream_write_int32( pBits, pMultiBinPoseData->dof, IVAS_SPLIT_REND_DOF_BITS );
ivas_split_rend_bitstream_write_int32( pBits, pMultiBinPoseData->hq_mode, IVAS_SPLIT_REND_HQ_MODE_BITS );
ivas_split_rend_bitstream_write_int32( pBits, (int32_t) pMultiBinPoseData->rot_axis, IVAS_SPLIT_REND_ROT_AXIS_BITS );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, pMultiBinPoseData->dof, ISAR_SPLIT_REND_DOF_BITS );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, pMultiBinPoseData->hq_mode, ISAR_SPLIT_REND_HQ_MODE_BITS );
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
rot_axis_code = isar_renderSplitGetCodeFromRot_axis( pMultiBinPoseData->dof, pMultiBinPoseData->rot_axis, &num_bits );
if ( num_bits > 0 )
{
ISAR_SPLIT_REND_BITStream_write_int32( pBits, (int32_t) rot_axis_code, num_bits );
}
ISAR_SPLIT_REND_BITStream_write_int32( pBits, (int32_t) ro_md_flag, ISAR_SPLIT_REND_RO_FLAG_BITS );
#else
ISAR_SPLIT_REND_BITStream_write_int32( pBits, (int32_t) pMultiBinPoseData->rot_axis, ISAR_SPLIT_REND_ROT_AXIS_BITS );
#endif
/* code ref pose*/
for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
......@@ -1084,22 +1328,27 @@ static void ivas_SplitRenderer_quant_code(
Quat2EulerDegree( headPosition, &head_pos_euler.z, &head_pos_euler.y, &head_pos_euler.x );
angle = (int16_t) roundf( head_pos_euler.x );
angle += 180;
ivas_split_rend_bitstream_write_int32( pBits, angle, IVAS_SPLIT_REND_HEAD_POSE_BITS );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, angle, ISAR_SPLIT_REND_HEAD_POSE_BITS );
angle = (int16_t) roundf( head_pos_euler.y );
angle += 180;
ivas_split_rend_bitstream_write_int32( pBits, angle, IVAS_SPLIT_REND_HEAD_POSE_BITS );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, angle, ISAR_SPLIT_REND_HEAD_POSE_BITS );
angle = (int16_t) roundf( head_pos_euler.z );
angle += 180;
ivas_split_rend_bitstream_write_int32( pBits, angle, IVAS_SPLIT_REND_HEAD_POSE_BITS );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, angle, ISAR_SPLIT_REND_HEAD_POSE_BITS );
}
ivas_split_rend_get_quant_params( MAX_SPLIT_REND_MD_BANDS, pred_real_bands_yaw, pred_imag_bands_yaw,
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
isar_split_rend_get_quant_params( MAX_SPLIT_REND_MD_BANDS, pred_real_bands_yaw, pred_imag_bands_yaw,
pred_quant_pnts_yaw, pred_quantstep_yaw, pred_1byquantstep_yaw,
d_bands_yaw, bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, ro_md_flag, &num_quant_strats );
#else
isar_split_rend_get_quant_params( MAX_SPLIT_REND_MD_BANDS, pred_real_bands_yaw, pred_imag_bands_yaw,
pred_quant_pnts_yaw, pred_quantstep_yaw, pred_1byquantstep_yaw,
d_bands_yaw, bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, &num_quant_strats, &num_complex_bands );
#endif
quant_strat_bits = (int32_t) ceilf( log2f( num_quant_strats ) );
overhead_bits = pBits->bits_written - overhead_bits + quant_strat_bits + 1; /* 1 for base2 vs huff */
......@@ -1120,20 +1369,20 @@ static void ivas_SplitRenderer_quant_code(
{
hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
ivas_split_rend_quant_md( hMd, PRED_ONLY, 0, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], pred_1byquantstep_yaw[q] );
isar_split_rend_quant_md( hMd, PRED_ONLY, 0, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], pred_1byquantstep_yaw[q] );
}
for ( ; b < pred_real_bands_yaw[q]; b++ )
{
hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
ivas_split_rend_quant_md( hMd, PRED_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], pred_1byquantstep_yaw[q] );
isar_split_rend_quant_md( hMd, PRED_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], pred_1byquantstep_yaw[q] );
}
for ( b = 0; b < d_bands_yaw[q]; b++ )
{
hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
ivas_split_rend_quant_md( hMd, COM_GAIN_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], 0 );
isar_split_rend_quant_md( hMd, COM_GAIN_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], 0 );
}
}
else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY )
......@@ -1141,7 +1390,7 @@ static void ivas_SplitRenderer_quant_code(
for ( b = 0; b < bands_pitch[q]; b++ )
{
hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
ivas_split_rend_quant_md( hMd, LR_GAIN_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], 0 );
isar_split_rend_quant_md( hMd, LR_GAIN_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], 0 );
}
}
else
......@@ -1149,12 +1398,12 @@ static void ivas_SplitRenderer_quant_code(
for ( b = 0; b < pred_imag_bands_roll[q]; b++ )
{
hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
ivas_split_rend_quant_md( hMd, PRED_ROLL_ONLY, 0, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], IVAS_SPLIT_REND_PRED_ROLL_1BYQ_STEP );
isar_split_rend_quant_md( hMd, PRED_ROLL_ONLY, 0, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP );
}
for ( ; b < pred_real_bands_roll[q]; b++ )
{
hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b];
ivas_split_rend_quant_md( hMd, PRED_ROLL_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], IVAS_SPLIT_REND_PRED_ROLL_1BYQ_STEP );
isar_split_rend_quant_md( hMd, PRED_ROLL_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP );
}
}
}
......@@ -1163,11 +1412,11 @@ static void ivas_SplitRenderer_quant_code(
/*get base2 bits and check if its within target. if yes then code with base2 to save complexity on post renderer*/
start_bit = pBits->bits_written;
ivas_split_rend_bitstream_write_int32( pBits, 1, 1 );
ivas_split_rend_bitstream_write_int32( pBits, q, quant_strat_bits );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, q, quant_strat_bits );
huff_bits = pBits->bits_written;
ivas_SplitRenderer_code_md_huff(
isar_SplitRenderer_code_md_huff(
hBinHrSplitPreRend,
pMultiBinPoseData,
num_subframes,
......@@ -1188,10 +1437,10 @@ static void ivas_SplitRenderer_quant_code(
{
pBits->bits_written = start_bit;
ivas_split_rend_bitstream_write_int32( pBits, 0, 1 );
ivas_split_rend_bitstream_write_int32( pBits, q, quant_strat_bits );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, q, quant_strat_bits );
ivas_SplitRenderer_code_md_base2( hBinHrSplitPreRend, pMultiBinPoseData, num_subframes, pred_real_bands_yaw[q], pred_imag_bands_yaw[q],
isar_SplitRenderer_code_md_base2( hBinHrSplitPreRend, pMultiBinPoseData, num_subframes, pred_real_bands_yaw[q], pred_imag_bands_yaw[q],
pred_quant_pnts_yaw[q],
d_bands_yaw[q], bands_pitch[q], pred_real_bands_roll[q], pred_imag_bands_roll[q], pBits );
}
......@@ -1283,13 +1532,13 @@ static void ivas_SplitRenderer_quant_code(
/*-------------------------------------------------------------------------
* Function ivas_SplitRenderer_GetRotMd()
* Function isar_SplitRenderer_GetRotMd()
*
*
*------------------------------------------------------------------------*/
void ivas_SplitRenderer_GetRotMd(
BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i/o: binaural renderer handle */
static void isar_SplitRenderer_GetRotMd(
ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i/o: binaural renderer handle */
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
float Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */
float Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */
......@@ -1305,9 +1554,9 @@ void ivas_SplitRenderer_GetRotMd(
int16_t real_only = 0;
int16_t pos_idx, b, sf_idx, start_slot_idx, num_slots, num_subframes, ch_s_idx1, ch_s_idx2;
int16_t num_md_bands, num_poses;
const int16_t *pBand_grouping = ivas_split_rend_band_grouping;
const int16_t *pBand_grouping = isar_split_rend_band_grouping;
push_wmops( "ivas_SplitRenderer_GetRotMd" );
push_wmops( "isar_SplitRenderer_GetRotMd" );
num_md_bands = MAX_SPLIT_REND_MD_BANDS;
num_poses = pMultiBinPoseData->num_poses;
......@@ -1344,6 +1593,13 @@ void ivas_SplitRenderer_GetRotMd(
/* compute rotated signal covariance */
for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ )
{
if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_ROLL )
{
if ( b >= SPLIT_REND_RO_MD_BAND_THRESH )
{
real_only = 1;
}
}
ch_s_idx2 = ( pos_idx + 1 ) * BINAURAL_CHANNELS;
ComputeBandedCrossCov( Cldfb_RealBuffer_Ref_Binaural, Cldfb_ImagBuffer_Ref_Binaural, ch_s_idx1, Cldfb_RealBuffer_Ref_Binaural, Cldfb_ImagBuffer_Ref_Binaural, ch_s_idx2, cov_io_re, cov_io_im, BINAURAL_CHANNELS, pBand_grouping, num_slots, start_slot_idx, b, real_only );
......@@ -1360,27 +1616,31 @@ void ivas_SplitRenderer_GetRotMd(
/*-------------------------------------------------------------------------
* Function ivas_rend_CldfbSplitPreRendProcess()
* Function isar_rend_CldfbSplitPreRendProcess()
*
*
*------------------------------------------------------------------------*/
void ivas_rend_CldfbSplitPreRendProcess(
const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend,
void isar_rend_CldfbSplitPreRendProcess(
const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend,
const IVAS_QUATERNION headPosition,
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
IVAS_SPLIT_REND_BITS_HANDLE pBits,
ISAR_SPLIT_REND_BITS_HANDLE pBits,
const int32_t target_md_bits,
const int16_t low_res_pre_rend_rot,
const int16_t ro_md_flag )
{
push_wmops( "ivas_rend_CldfbSplitPreRendProcess" );
push_wmops( "isar_rend_CldfbSplitPreRendProcess" );
ivas_SplitRenderer_GetRotMd( hBinHrSplitPreRend, pMultiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, low_res_pre_rend_rot, ro_md_flag );
isar_SplitRenderer_GetRotMd( hBinHrSplitPreRend, pMultiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, low_res_pre_rend_rot, ro_md_flag );
ivas_SplitRenderer_quant_code( hBinHrSplitPreRend, headPosition, pMultiBinPoseData, pBits, low_res_pre_rend_rot, target_md_bits );
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
isar_SplitRenderer_quant_code( hBinHrSplitPreRend, headPosition, pMultiBinPoseData, pBits, low_res_pre_rend_rot, ro_md_flag, target_md_bits );
#else
isar_SplitRenderer_quant_code( hBinHrSplitPreRend, headPosition, pMultiBinPoseData, pBits, low_res_pre_rend_rot, target_md_bits );
#endif
#ifdef SPLIT_POSE_CORRECTION_DEBUG
float tmpCrendBuffer[2][L_FRAME48k], quant_val, step, minv, maxv;
......@@ -1461,7 +1721,7 @@ void ivas_rend_CldfbSplitPreRendProcess(
mvr2r( (float *) Cldfb_In_BinReal[1][sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES], (float *) Cldfb_RealBuffer_Binaural_5ms[1], MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX );
mvr2r( (float *) Cldfb_In_BinImag[0][sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES], (float *) Cldfb_ImagBuffer_Binaural_5ms[0], MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX );
mvr2r( (float *) Cldfb_In_BinImag[1][sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES], (float *) Cldfb_ImagBuffer_Binaural_5ms[1], MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX );
ivas_rend_CldfbSplitPostRendProcess( hBinHrSplitPreRend->hBinHrSplitPostRend, pMultiBinPoseData, QuaternionsPost[0], Cldfb_RealBuffer_Binaural_5ms, Cldfb_ImagBuffer_Binaural_5ms, tmpCrendBuffer, 1 );
isar_rend_CldfbSplitPostRendProcess( hBinHrSplitPreRend->hBinHrSplitPostRend, pMultiBinPoseData, QuaternionsPost[0], Cldfb_RealBuffer_Binaural_5ms, Cldfb_ImagBuffer_Binaural_5ms, tmpCrendBuffer, 1 );
{
float *pOut[2];
......@@ -1479,13 +1739,13 @@ void ivas_rend_CldfbSplitPreRendProcess(
/*-------------------------------------------------------------------------
* Function ivas_splitBinPreRendOpen()
* Function isar_splitBinPreRendOpen()
*
*
*------------------------------------------------------------------------*/
ivas_error ivas_splitBinPreRendOpen(
BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend,
ivas_error isar_splitBinPreRendOpen(
ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend,
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData
#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
,
......@@ -1493,14 +1753,14 @@ ivas_error ivas_splitBinPreRendOpen(
#endif
)
{
BIN_HR_SPLIT_PRE_REND_HANDLE hBinRend;
ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinRend;
#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
ivas_error error;
int16_t ch;
#endif
int16_t pos_idx, sf_idx, bandIdx;
if ( ( hBinRend = (BIN_HR_SPLIT_PRE_REND_HANDLE) malloc( sizeof( BIN_HR_SPLIT_PRE_REND ) ) ) == NULL )
if ( ( hBinRend = (ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE) malloc( sizeof( ISAR_BIN_HR_SPLIT_PRE_REND ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for bin split pre renderer Module \n" ) );
}
......@@ -1541,11 +1801,11 @@ ivas_error ivas_splitBinPreRendOpen(
set_pose_types( hBinRend->pose_type, pMultiBinPoseData );
ivas_split_rend_init_huff_cfg( &hBinRend->huff_cfg );
isar_split_rend_init_huff_cfg( &hBinRend->huff_cfg );
#ifdef SPLIT_POSE_CORRECTION_DEBUG
ivas_error error;
if ( ( error = ivas_splitBinPostRendOpen( &hBinRend->hBinHrSplitPostRend, pMultiBinPoseData, 48000 ) ) != IVAS_ERR_OK )
if ( ( error = isar_splitBinPostRendOpen( &hBinRend->hBinHrSplitPostRend, pMultiBinPoseData, 48000 ) ) != IVAS_ERR_OK )
{
return error;
}
......@@ -1558,13 +1818,13 @@ ivas_error ivas_splitBinPreRendOpen(
/*-------------------------------------------------------------------------
* Function ivas_splitBinPreRendClose()
* Function isar_splitBinPreRendClose()
*
*
*------------------------------------------------------------------------*/
void ivas_splitBinPreRendClose(
BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend )
void isar_splitBinPreRendClose(
ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend )
{
if ( ( *hBinHrSplitPreRend ) != NULL )
{
......@@ -1585,7 +1845,7 @@ void ivas_splitBinPreRendClose(
}
#endif
#ifdef SPLIT_POSE_CORRECTION_DEBUG
ivas_splitBinPostRendClose( &( *hBinHrSplitPreRend )->hBinHrSplitPostRend );
isar_splitBinPostRendClose( &( *hBinHrSplitPreRend )->hBinHrSplitPostRend );
#endif
free( ( *hBinHrSplitPreRend ) );
......@@ -1597,27 +1857,28 @@ void ivas_splitBinPreRendClose(
/*-------------------------------------------------------------------------*
* ivas_set_split_rend_ht_setup()
* isar_set_split_rend_ht_setup()
*
*
*-------------------------------------------------------------------------*/
void ivas_set_split_rend_ht_setup(
IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend,
COMBINED_ORIENTATION_HANDLE hCombinedOrientationData )
void isar_set_split_rend_ht_setup(
SPLIT_REND_WRAPPER *hSplitrend,
IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES],
float Rmat[MAX_PARAM_SPATIAL_SUBFRAMES][3][3] )
{
int16_t sf, i, j;
if ( hCombinedOrientationData != NULL && hSplitBinRend->splitrend.multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
if ( hSplitrend->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
{
for ( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
{
hCombinedOrientationData->Quaternions[sf] = hCombinedOrientationData->Quaternions[0];
Quaternions[sf] = Quaternions[0];
for ( i = 0; i < 3; i++ )
{
for ( j = 0; j < 3; j++ )
{
hCombinedOrientationData->Rmat[sf][i][j] = hCombinedOrientationData->Rmat[0][i][j];
Rmat[sf][i][j] = Rmat[0][i][j];
}
}
}
......@@ -1627,68 +1888,13 @@ void ivas_set_split_rend_ht_setup(
}
/*-------------------------------------------------------------------------*
* ivas_set_split_rend_setup()
*
* Setup IVAS split rendering
*-------------------------------------------------------------------------*/
ivas_error ivas_set_split_rend_setup(
IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend,
IVAS_SPLIT_REND_CONFIG_DATA *hSplitBinConfig,
COMBINED_ORIENTATION_HANDLE hCombinedOrientationData,
uint8_t *splitRendBitsBuf )
{
int16_t sf, i, j;
if ( ( hSplitBinRend->hSplitRendBits = (IVAS_SPLIT_REND_BITS_HANDLE) malloc( sizeof( IVAS_SPLIT_REND_BITS_DATA ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for split renderer Bits buffer\n" ) );
}
hSplitBinRend->hSplitRendBits->bits_buf = splitRendBitsBuf;
hSplitBinRend->hSplitRendBits->bits_read = 0;
hSplitBinRend->hSplitRendBits->bits_written = 0;
hSplitBinRend->hSplitRendBits->buf_len = IVAS_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES;
hSplitBinRend->hSplitRendBits->codec = IVAS_SPLIT_REND_CODEC_DEFAULT;
hSplitBinRend->hSplitRendBits->pose_correction = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE;
hSplitBinRend->hSplitRendBits->codec_frame_size_ms = 0;
if ( ( hSplitBinRend->hMultiBinCldfbData = (IVAS_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE) malloc( sizeof( IVAS_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA ) ) ) == NULL )
{
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for split rendering structure" );
}
ivas_renderSplitGetMultiBinPoseData( hSplitBinConfig, &hSplitBinRend->splitrend.multiBinPoseData, hCombinedOrientationData->sr_pose_pred_axis );
if ( hCombinedOrientationData != NULL && hSplitBinRend->splitrend.multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
{
for ( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
{
hCombinedOrientationData->Quaternions[sf] = hCombinedOrientationData->Quaternions[0];
for ( i = 0; i < 3; i++ )
{
for ( j = 0; j < 3; j++ )
{
hCombinedOrientationData->Rmat[sf][i][j] = hCombinedOrientationData->Rmat[0][i][j];
}
}
}
}
return IVAS_ERR_OK;
}
/*-------------------------------------------------------------------------
* Function ivas_init_split_rend_handles()
* Function isar_init_split_rend_handles()
*
*
*------------------------------------------------------------------------*/
void ivas_init_split_rend_handles(
void isar_init_split_rend_handles(
SPLIT_REND_WRAPPER *hSplitRendWrapper )
{
int16_t i;
......@@ -1698,58 +1904,88 @@ void ivas_init_split_rend_handles(
hSplitRendWrapper->hSplitBinLCLDEnc = NULL;
hSplitRendWrapper->hLc3plusEnc = NULL;
for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i )
{
hSplitRendWrapper->hTdRendHandles[i] = NULL;
}
for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i )
{
hSplitRendWrapper->lc3plusDelayBuffers[i] = NULL;
}
hSplitRendWrapper->lc3plusDelaySamples = 0;
ivas_init_multi_bin_pose_data( &hSplitRendWrapper->multiBinPoseData );
isar_init_multi_bin_pose_data( &hSplitRendWrapper->multiBinPoseData );
return;
}
/*-------------------------------------------------------------------------
* Function split_renderer_open_lc3plus()
*
*
*------------------------------------------------------------------------*/
static ivas_error split_renderer_open_lc3plus(
ivas_error split_renderer_open_lc3plus(
SPLIT_REND_WRAPPER *hSplitRendWrapper,
const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig,
const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig,
const int32_t OutSampleRate,
const int16_t num_subframes )
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
const IVAS_RENDER_FRAMESIZE isar_frame_size
#else
const int16_t num_subframes
#endif
)
{
ivas_error error;
int16_t i, delayBufferLength;
LC3PLUS_CONFIG config;
#if defined ISAR_BITSTREAM_UPDATE_LC3PLUS
int16_t isar_frame_size_ms;
if ( ( error = isar_framesize_to_ms( isar_frame_size, &isar_frame_size_ms ) ) != IVAS_ERR_OK )
{
return error;
}
#endif
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
/* Check configuration validity */
if ( isar_frame_size_ms < pSplitRendConfig->codec_frame_size_ms )
{
return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "SR codec frame doesn't fit in one output frame" );
}
#endif
config.lc3plus_frame_duration_us = pSplitRendConfig->codec_frame_size_ms * 1000;
config.ivas_frame_duration_us = ( pSplitRendConfig->dof == 0 ) ? config.lc3plus_frame_duration_us * num_subframes : 20000;
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
config.isar_frame_duration_us = ( pSplitRendConfig->dof == 0 ) ? config.lc3plus_frame_duration_us * num_subframes : 20000;
#endif
config.samplerate = OutSampleRate;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
config.isar_frame_duration_us = isar_frame_size_ms * 1000;
#endif
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
config.high_res_mode_enabled = ( pSplitRendConfig->lc3plus_highres != 0 );
#endif
config.channels = BINAURAL_CHANNELS;
if ( ( error = IVAS_LC3PLUS_ENC_Open( config, ivas_get_lc3plus_bitrate( pSplitRendConfig->splitRendBitRate, pSplitRendConfig->poseCorrectionMode, (int16_t) ( config.ivas_frame_duration_us / 1000 ) ), &hSplitRendWrapper->hLc3plusEnc ) ) != IVAS_ERR_OK )
if ( ( error = ISAR_LC3PLUS_ENC_Open( config,
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
isar_get_lcld_bitrate( pSplitRendConfig->splitRendBitRate, pSplitRendConfig->poseCorrectionMode ),
#else
isar_get_lc3plus_bitrate( pSplitRendConfig->splitRendBitRate, pSplitRendConfig->poseCorrectionMode, (int16_t) ( config.isar_frame_duration_us / 1000 ) ),
#endif
&hSplitRendWrapper->hLc3plusEnc ) ) != IVAS_ERR_OK )
{
return error;
}
/* This returns delay of entire LC3plus chain (enc + dec) */
if ( ( error = IVAS_LC3PLUS_ENC_GetDelay( hSplitRendWrapper->hLc3plusEnc, &hSplitRendWrapper->lc3plusDelaySamples ) ) != IVAS_ERR_OK )
if ( ( error = ISAR_LC3PLUS_ENC_GetDelay( hSplitRendWrapper->hLc3plusEnc, &hSplitRendWrapper->lc3plusDelaySamples ) ) != IVAS_ERR_OK )
{
return error;
}
/* Alocate buffers for delay compensation */
if ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LC3PLUS )
if ( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS )
{
delayBufferLength = (int16_t) ( OutSampleRate / (int32_t) FRAMES_PER_SECOND + hSplitRendWrapper->lc3plusDelaySamples );
for ( i = 0; i < hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++i )
......@@ -1785,231 +2021,21 @@ static ivas_error split_renderer_open_lc3plus(
/*-------------------------------------------------------------------------
* Function ivas_split_renderer_open()
* Function splitRendLc3plusEncodeAndWrite()
*
*
*------------------------------------------------------------------------*/
ivas_error ivas_split_renderer_open(
SPLIT_REND_WRAPPER *hSplitRendWrapper,
const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig,
const int32_t OutSampleRate,
const int16_t cldfb_in_flag,
const int16_t pcm_out_flag,
const int16_t num_subframes )
{
ivas_error error, ch, num_ch;
#ifndef SPLIT_REND_WITH_HEAD_ROT
CLDFB_TYPE cldfbMode;
ivas_error splitRendLc3plusEncodeAndWrite(
SPLIT_REND_WRAPPER *hSplitBin,
ISAR_SPLIT_REND_BITS_HANDLE pBits,
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
const int32_t available_bits,
#endif
uint8_t isCldfbNeeded = 0;
#ifndef SPLIT_REND_WITH_HEAD_ROT
cldfbMode = CLDFB_ANALYSIS;
#else
const int32_t SplitRendBitRate,
#endif
if ( ( error = ivas_split_rend_validate_config( pSplitRendConfig, pcm_out_flag ) ) != IVAS_ERR_OK )
{
return error;
}
if ( cldfb_in_flag == 0 )
{
isCldfbNeeded = 1;
#ifndef SPLIT_REND_WITH_HEAD_ROT
cldfbMode = CLDFB_ANALYSIS;
#endif
}
else if ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && cldfb_in_flag )
{
#ifdef SPLIT_REND_WITH_HEAD_ROT
isCldfbNeeded = 1;
#else
isCldfbNeeded = 1;
cldfbMode = CLDFB_SYNTHESIS;
#endif
}
else if ( pcm_out_flag && cldfb_in_flag )
{
#ifdef SPLIT_REND_WITH_HEAD_ROT
isCldfbNeeded = 1;
#else
isCldfbNeeded = 1;
cldfbMode = CLDFB_SYNTHESIS;
#endif
}
hSplitRendWrapper->hCldfbHandles = NULL;
if ( isCldfbNeeded )
{
if ( ( hSplitRendWrapper->hCldfbHandles = (CLDFB_HANDLES_WRAPPER_HANDLE) malloc( sizeof( CLDFB_HANDLES_WRAPPER ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CLDFB handles\n" ) );
}
num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS;
for ( ch = 0; ch < num_ch; ch++ )
{
hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL;
}
#ifdef SPLIT_REND_WITH_HEAD_ROT
for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
{
hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] = NULL;
}
#endif
num_ch = hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS;
for ( ch = 0; ch < num_ch; ch++ )
{
if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ),
#ifndef SPLIT_REND_WITH_HEAD_ROT
cldfbMode,
#else
CLDFB_ANALYSIS,
#endif
OutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK )
{
return error;
}
}
#ifdef SPLIT_REND_WITH_HEAD_ROT
for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
{
if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ), CLDFB_SYNTHESIS, OutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK )
{
return error;
}
}
#endif
}
if ( pSplitRendConfig->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
{
if ( ( error = ivas_splitBinPreRendOpen( &hSplitRendWrapper->hBinHrSplitPreRend, &hSplitRendWrapper->multiBinPoseData
#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
,
OutSampleRate
#endif
) ) != IVAS_ERR_OK )
{
return error;
}
}
if ( pcm_out_flag == 0 )
{
if ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LC3PLUS )
{
if ( ( error = split_renderer_open_lc3plus( hSplitRendWrapper, pSplitRendConfig, OutSampleRate, num_subframes ) ) != IVAS_ERR_OK )
{
return error;
}
}
else
{
int16_t iNumBlocksPerFrame;
iNumBlocksPerFrame = ( CLDFB_NO_COL_MAX * pSplitRendConfig->codec_frame_size_ms ) / 20;
if ( ( error = ivas_splitBinLCLDEncOpen( &hSplitRendWrapper->hSplitBinLCLDEnc, OutSampleRate, BINAURAL_CHANNELS, ivas_get_lcld_bitrate( pSplitRendConfig->splitRendBitRate, hSplitRendWrapper->multiBinPoseData.poseCorrectionMode ), iNumBlocksPerFrame, 1 ) ) != IVAS_ERR_OK )
{
return error;
}
}
}
return IVAS_ERR_OK;
}
/*-------------------------------------------------------------------------
* Function ivas_split_renderer_close()
*
*
*------------------------------------------------------------------------*/
void ivas_split_renderer_close(
SPLIT_REND_WRAPPER *hSplitBinRend )
{
int16_t i;
if ( hSplitBinRend->hBinHrSplitPreRend != NULL )
{
ivas_splitBinPreRendClose( &hSplitBinRend->hBinHrSplitPreRend );
}
if ( hSplitBinRend->hSplitBinLCLDEnc != NULL )
{
ivas_splitBinLCLDEncClose( &hSplitBinRend->hSplitBinLCLDEnc );
}
if ( hSplitBinRend->hCldfbHandles != NULL )
{
int16_t num_ch, ch;
num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS;
for ( ch = 0; ch < num_ch; ch++ )
{
if ( hSplitBinRend->hCldfbHandles->cldfbAna[ch] != NULL )
{
deleteCldfb( &hSplitBinRend->hCldfbHandles->cldfbAna[ch] );
hSplitBinRend->hCldfbHandles->cldfbAna[ch] = NULL;
}
}
#ifdef SPLIT_REND_WITH_HEAD_ROT
for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
{
if ( hSplitBinRend->hCldfbHandles->cldfbSyn[ch] != NULL )
{
deleteCldfb( &hSplitBinRend->hCldfbHandles->cldfbSyn[ch] );
hSplitBinRend->hCldfbHandles->cldfbSyn[ch] = NULL;
}
}
#endif
free( hSplitBinRend->hCldfbHandles );
hSplitBinRend->hCldfbHandles = NULL;
}
if ( hSplitBinRend->hLc3plusEnc != NULL )
{
IVAS_LC3PLUS_ENC_Close( &hSplitBinRend->hLc3plusEnc );
}
for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i )
{
if ( hSplitBinRend->lc3plusDelayBuffers[i] != NULL )
{
free( hSplitBinRend->lc3plusDelayBuffers[i] );
hSplitBinRend->lc3plusDelayBuffers[i] = NULL;
}
}
for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i )
{
if ( hSplitBinRend->hTdRendHandles[i] != NULL )
{
hSplitBinRend->hTdRendHandles[i]->HrFiltSet_p = NULL;
ivas_td_binaural_close( &hSplitBinRend->hTdRendHandles[i] );
}
}
return;
}
/*-------------------------------------------------------------------------
* Function splitRendLc3plusEncodeAndWrite()
*
*
*------------------------------------------------------------------------*/
static ivas_error splitRendLc3plusEncodeAndWrite(
SPLIT_REND_WRAPPER *hSplitBin,
IVAS_SPLIT_REND_BITS_HANDLE pBits,
const int32_t SplitRendBitRate,
float *in[] )
{
ivas_error error;
......@@ -2021,7 +2047,7 @@ static ivas_error splitRendLc3plusEncodeAndWrite(
/* Find next byte boundary and zero-pad to it */
while ( pBits->bits_written % 8 != 0 )
{
ivas_split_rend_bitstream_write_int32( pBits, 0L, 1 );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0L, 1 );
}
for ( i = 0; i < BINAURAL_CHANNELS * hSplitBin->multiBinPoseData.num_poses; ++i )
......@@ -2029,39 +2055,57 @@ static ivas_error splitRendLc3plusEncodeAndWrite(
channel_ptrs[i] = in[i];
}
if ( ( error = IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( hSplitBin->hLc3plusEnc, &lc3plusBitstreamSize ) ) != IVAS_ERR_OK )
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
if ( ( error = IVAS_LC3PLUS_ENC_SetBitrate( hSplitBin->hLc3plusEnc, available_bits * FRAMES_PER_SEC ) ) != IVAS_ERR_OK )
{
return error;
}
#endif
ivas_split_rend_bitstream_write_int32( pBits, ivas_get_lc3plus_bitrate_id( SplitRendBitRate ), 8 );
if ( ( error = ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( hSplitBin->hLc3plusEnc, &lc3plusBitstreamSize ) ) != IVAS_ERR_OK )
{
return error;
}
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
ISAR_SPLIT_REND_BITStream_write_int32( pBits, isar_get_lc3plus_bitrate_id( SplitRendBitRate ), 8 );
#endif
/* Write bitstream */
if ( ( error = IVAS_LC3PLUS_ENC_Encode( hSplitBin->hLc3plusEnc, channel_ptrs, &pBits->bits_buf[pBits->bits_written / 8] ) ) != IVAS_ERR_OK )
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
if ( ( error = ISAR_LC3PLUS_ENC_Encode( hSplitBin->hLc3plusEnc, channel_ptrs, &pBits->bits_buf[pBits->bits_written / 8], lc3plusBitstreamSize ) ) != IVAS_ERR_OK )
#else
if ( ( error = ISAR_LC3PLUS_ENC_Encode( hSplitBin->hLc3plusEnc, channel_ptrs, &pBits->bits_buf[pBits->bits_written / 8] ) ) != IVAS_ERR_OK )
#endif
{
return error;
}
pBits->bits_written += 8 * lc3plusBitstreamSize;
pBits->codec = IVAS_SPLIT_REND_CODEC_LC3PLUS;
pBits->codec = ISAR_SPLIT_REND_CODEC_LC3PLUS;
pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode;
pBits->codec_frame_size_ms = (int16_t) ( hSplitBin->hLc3plusEnc->config.lc3plus_frame_duration_us / 1000 );
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
pBits->isar_frame_size_ms = (int16_t) ( hSplitBin->hLc3plusEnc->config.isar_frame_duration_us / 1000 );
#endif
return IVAS_ERR_OK;
}
/*-------------------------------------------------------------------------
* Function ivas_renderMultiTDBinToSplitBinaural()
* Function isar_renderMultiTDBinToSplitBinaural()
*
*
*------------------------------------------------------------------------*/
static ivas_error ivas_renderMultiTDBinToSplitBinaural(
ivas_error isar_renderMultiTDBinToSplitBinaural(
SPLIT_REND_WRAPPER *hSplitBin,
const IVAS_QUATERNION headPosition,
const int32_t SplitRendBitRate,
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
const int16_t isar_frame_size_ms,
#endif
const int16_t codec_frame_size_ms,
IVAS_SPLIT_REND_BITS_HANDLE pBits,
ISAR_SPLIT_REND_BITS_HANDLE pBits,
const int16_t max_bands,
float *in[],
const int16_t low_res_pre_rend_rot,
......@@ -2069,7 +2113,11 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural(
const int16_t ro_md_flag )
{
ivas_error error;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
int32_t bit_len, available_bits, target_md_bits;
#else
int32_t bit_len, available_bits, target_md_bits, actual_md_bits;
#endif
int16_t num_cldfb_bands, ch, slot_idx, pos_idx, num_poses;
float Cldfb_In_BinReal[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
float Cldfb_In_BinImag[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
......@@ -2078,7 +2126,7 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural(
int16_t i;
int32_t num_slots;
push_wmops( "ivas_renderMultiTDBinToSplitBinaural" );
push_wmops( "isar_renderMultiTDBinToSplitBinaural" );
error = IVAS_ERR_OK;
num_poses = hSplitBin->multiBinPoseData.num_poses;
......@@ -2106,10 +2154,12 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural(
}
}
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
actual_md_bits = pBits->bits_written;
if ( ( hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) || ( !useLc3plus && !pcm_out_flag ) )
#endif
if ( ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) || ( !useLc3plus && !pcm_out_flag ) )
{
num_slots = ( hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ? CLDFB_NO_COL_MAX : ( hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations );
num_slots = ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ? CLDFB_NO_COL_MAX : ( hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations );
num_cldfb_bands = hSplitBin->hCldfbHandles->cldfbAna[0]->no_channels;
/* CLDFB Analysis*/
......@@ -2143,32 +2193,51 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural(
}
}
if ( hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
if ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
{
target_md_bits = ivas_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000;
target_md_bits = isar_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000;
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
actual_md_bits = pBits->bits_written;
#endif
ivas_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, pBits, target_md_bits, low_res_pre_rend_rot, ro_md_flag );
isar_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, pBits, target_md_bits, low_res_pre_rend_rot, ro_md_flag );
}
if ( pcm_out_flag == 0 )
{
pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode;
pBits->codec = useLc3plus ? IVAS_SPLIT_REND_CODEC_LC3PLUS : IVAS_SPLIT_REND_CODEC_LCLD;
pBits->codec = useLc3plus ? ISAR_SPLIT_REND_CODEC_LC3PLUS : ISAR_SPLIT_REND_CODEC_LCLD;
if ( !useLc3plus )
{
available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC );
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
available_bits -= pBits->bits_written;
#else
actual_md_bits = pBits->bits_written - actual_md_bits;
available_bits -= actual_md_bits;
#endif
pBits->codec_frame_size_ms = codec_frame_size_ms;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
pBits->isar_frame_size_ms = isar_frame_size_ms;
#endif
ivas_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal, Cldfb_In_BinImag, available_bits, pBits );
isar_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal, Cldfb_In_BinImag, available_bits, pBits );
}
else
{
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
available_bits = ( SplitRendBitRate / FRAMES_PER_SEC ) - pBits->bits_written;
if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, available_bits, in ) ) != IVAS_ERR_OK )
#else
available_bits = ( SplitRendBitRate / FRAMES_PER_SEC ) - pBits->bits_written;
if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, in ) ) != IVAS_ERR_OK )
#endif
#else
if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, SplitRendBitRate, in ) ) != IVAS_ERR_OK )
#endif
{
return error;
}
......@@ -2177,7 +2246,7 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural(
else
{
pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode;
pBits->codec = IVAS_SPLIT_REND_CODEC_NONE;
pBits->codec = ISAR_SPLIT_REND_CODEC_NONE;
}
/*zero pad*/
......@@ -2193,14 +2262,14 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural(
}
else
{
bit_len = hSplitBin->hLc3plusEnc->config.ivas_frame_duration_us / 1000;
bit_len = hSplitBin->hLc3plusEnc->config.isar_frame_duration_us / 1000;
bit_len = SplitRendBitRate * bit_len / 1000;
}
}
while ( pBits->bits_written < bit_len )
{
ivas_split_rend_bitstream_write_int32( pBits, 0L, 1 );
ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0L, 1 );
}
pop_wmops();
......@@ -2215,7 +2284,7 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural(
*
*------------------------------------------------------------------------*/
static void lc3plusTimeAlignCldfbPoseCorr(
void lc3plusTimeAlignCldfbPoseCorr(
SPLIT_REND_WRAPPER *hSplitBin,
float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] )
......@@ -2240,7 +2309,6 @@ static void lc3plusTimeAlignCldfbPoseCorr(
}
/* Delay existing columns by 2 slots */
/*TODO : shouldnt the delay be 7.5 ms ? 5ms + LC3plus delay */
for ( slot_idx = CLDFB_NO_COL_MAX - 2 - 1; slot_idx >= 0; --slot_idx )
{
mvr2r( Cldfb_In_BinReal[pose * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinReal[pose * BINAURAL_CHANNELS + ch][slot_idx + 2], CLDFB_NO_CHANNELS_MAX );
......@@ -2269,170 +2337,4 @@ static void lc3plusTimeAlignCldfbPoseCorr(
return;
}
/*-------------------------------------------------------------------------
* Function ivas_renderMultiBinToSplitBinaural()
*
*
*------------------------------------------------------------------------*/
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 )
{
ivas_error error;
int32_t bit_len, target_md_bits, actual_md_bits, available_bits;
error = IVAS_ERR_OK;
push_wmops( "ivas_renderMultiBinToSplitBinaural" );
if ( hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
{
set_fix_rotation_mat( hSplitBin->hBinHrSplitPreRend->fix_pos_rot_mat, &hSplitBin->multiBinPoseData );
set_pose_types( hSplitBin->hBinHrSplitPreRend->pose_type, &hSplitBin->multiBinPoseData );
}
/* Needs to be done at runtime. If this was in another API function,
* there would be no guarantee that the user did not change
* the split rendering config before calling the main rendering function */
if ( ( error = ivas_split_rend_choose_default_codec( &splitCodec, &codec_frame_size_ms, cldfb_in_flag, pcm_out_flag, 0 ) ) != IVAS_ERR_OK )
{
return error;
}
if ( cldfb_in_flag == 0 )
{
/*TD input*/
/*if CLDFB handles have been allocated then assume valid multi binaural input in out[][] buffer and perform CLDFB analysis*/
error = ivas_renderMultiTDBinToSplitBinaural( hSplitBin, headPosition, SplitRendBitRate, codec_frame_size_ms, pBits, max_bands, output, low_res_pre_rend_rot, pcm_out_flag, ro_md_flag );
pop_wmops();
return error;
}
if ( splitCodec == IVAS_SPLIT_REND_CODEC_LC3PLUS && hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
{
/* Time-align pose correction to delay of LC3plus */
lc3plusTimeAlignCldfbPoseCorr( hSplitBin, Cldfb_In_BinReal, Cldfb_In_BinImag );
}
actual_md_bits = pBits->bits_written;
if ( hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
{
target_md_bits = ivas_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000;
actual_md_bits = pBits->bits_written;
ivas_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, pBits, target_md_bits, low_res_pre_rend_rot, ro_md_flag );
}
if ( pcm_out_flag == 0 )
{
pBits->codec = splitCodec;
pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode;
if ( splitCodec == IVAS_SPLIT_REND_CODEC_LCLD )
{
available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC );
actual_md_bits = pBits->bits_written - actual_md_bits;
available_bits -= actual_md_bits;
pBits->codec_frame_size_ms = codec_frame_size_ms;
ivas_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal, Cldfb_In_BinImag, available_bits, pBits );
}
else
{
int16_t ch, slot_idx, num_slots, ivas_fs;
ivas_fs = (int16_t) hSplitBin->hLc3plusEnc->config.ivas_frame_duration_us / 1000;
num_slots = (int16_t) ( CLDFB_NO_COL_MAX * ivas_fs ) / 20;
/* CLDFB synthesis of main pose */
for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
{
float *Cldfb_In_BinReal_p[CLDFB_NO_COL_MAX];
float *Cldfb_In_BinImag_p[CLDFB_NO_COL_MAX];
for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ )
{
Cldfb_In_BinReal_p[slot_idx] = Cldfb_In_BinReal[ch][slot_idx];
Cldfb_In_BinImag_p[slot_idx] = Cldfb_In_BinImag[ch][slot_idx];
}
#ifndef SPLIT_REND_WITH_HEAD_ROT
cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbAna[0]->no_channels * CLDFB_NO_COL_MAX, hSplitBin->hCldfbHandles->cldfbAna[ch] );
#else
cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * num_slots, hSplitBin->hCldfbHandles->cldfbSyn[ch] );
#endif
}
if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, SplitRendBitRate, output ) ) != IVAS_ERR_OK )
{
return error;
}
}
}
else
{
int16_t ch, slot_idx;
/* CLDFB synthesis of main pose */
for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
{
float *Cldfb_In_BinReal_p[CLDFB_NO_COL_MAX];
float *Cldfb_In_BinImag_p[CLDFB_NO_COL_MAX];
for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ )
{
Cldfb_In_BinReal_p[slot_idx] = Cldfb_In_BinReal[ch][slot_idx];
Cldfb_In_BinImag_p[slot_idx] = Cldfb_In_BinImag[ch][slot_idx];
}
#ifndef SPLIT_REND_WITH_HEAD_ROT
cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbAna[0]->no_channels * CLDFB_NO_COL_MAX, hSplitBin->hCldfbHandles->cldfbAna[ch] );
#else
cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * CLDFB_NO_COL_MAX, hSplitBin->hCldfbHandles->cldfbSyn[ch] );
#endif
}
pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode;
pBits->codec = IVAS_SPLIT_REND_CODEC_NONE;
}
/*zero pad*/
if ( pcm_out_flag )
{
bit_len = SplitRendBitRate / FRAMES_PER_SEC;
}
else
{
if ( splitCodec == IVAS_SPLIT_REND_CODEC_LCLD )
{
bit_len = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC );
}
else
{
bit_len = hSplitBin->hLc3plusEnc->config.ivas_frame_duration_us / 1000;
bit_len = SplitRendBitRate * bit_len / 1000;
}
}
while ( pBits->bits_written < bit_len )
{
ivas_split_rend_bitstream_write_int32( pBits, 0L, 1 );
}
pop_wmops();
return error;
}
#endif
......@@ -35,15 +35,9 @@
#ifdef SPLIT_REND_WITH_HEAD_ROT
#include <math.h>
#include "ivas_prot.h"
#include "prot.h"
#include "cnst.h"
#include "ivas_cnst.h"
#include "ivas_rom_rend.h"
#include "ivas_rom_com.h"
#include "ivas_rom_dec.h"
#include "ivas_rom_binauralRenderer.h"
#include "lib_rend.h"
#include "ivas_prot_rend.h"
#include "isar_rom_post_rend.h"
#include "lib_isar_post_rend.h"
#include "isar_prot.h"
#ifdef DEBUGGING
#include "debug.h"
#endif
......@@ -51,12 +45,12 @@
/*-------------------------------------------------------------------------
* Function ivas_mat_mult_2by2_complex()
* Function isar_mat_mult_2by2_complex()
*
*
*------------------------------------------------------------------------*/
void ivas_mat_mult_2by2_complex(
void isar_mat_mult_2by2_complex(
float in_re1[2][2],
float in_im1[2][2],
float in_re2[2][2],
......@@ -86,13 +80,13 @@ void ivas_mat_mult_2by2_complex(
/*-------------------------------------------------------------------------
* Function ivas_split_rend_bitstream_init()
* Function ISAR_SPLIT_REND_BITStream_init()
*
*
*------------------------------------------------------------------------*/
void ivas_split_rend_bitstream_init(
IVAS_SPLIT_REND_BITS_HANDLE pBits,
void ISAR_SPLIT_REND_BITStream_init(
ISAR_SPLIT_REND_BITS_HANDLE pBits,
const int32_t buf_len_bytes,
uint8_t *pbuf )
{
......@@ -106,13 +100,13 @@ void ivas_split_rend_bitstream_init(
/*-------------------------------------------------------------------------
* Function ivas_split_rend_huffman_dec_init_min_max_len()
* Function isar_split_rend_huffman_dec_init_min_max_len()
*
*
*------------------------------------------------------------------------*/
void ivas_split_rend_huffman_dec_init_min_max_len(
ivas_split_rend_huffman_cfg_t *p_huff_cfg )
void isar_split_rend_huffman_dec_init_min_max_len(
isar_split_rend_huffman_cfg_t *p_huff_cfg )
{
int16_t i, code_len;
const int32_t *codebook;
......@@ -166,14 +160,14 @@ static int16_t is_idx_present(
/*-------------------------------------------------------------------------
* Function ivas_split_huff_get_idx_trav_list()
* Function isar_split_huff_get_idx_trav_list()
*
*
*------------------------------------------------------------------------*/
static void ivas_split_huff_get_idx_trav_list(
static void isar_split_huff_get_idx_trav_list(
int16_t *idx_list,
ivas_split_rend_huffman_cfg_t *p_huff_cfg )
isar_split_rend_huffman_cfg_t *p_huff_cfg )
{
int16_t i, j, min_idx;
int32_t min_bits;
......@@ -206,49 +200,49 @@ static void ivas_split_huff_get_idx_trav_list(
/*-------------------------------------------------------------------------
* Function ivas_split_rend_init_huff_cfg()
* Function isar_split_rend_init_huff_cfg()
*
*
*------------------------------------------------------------------------*/
void ivas_split_rend_init_huff_cfg(
BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg )
void isar_split_rend_init_huff_cfg(
ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg )
{
pHuff_cfg->pred[0].codebook = &ivas_split_rend_huff_pred31_consts[0][0];
pHuff_cfg->pred[0].sym_len = IVAS_SPLIT_REND_PRED_31QUANT_PNTS;
ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred[0] );
ivas_split_huff_get_idx_trav_list( pHuff_cfg->pred_idx_trav[0], &pHuff_cfg->pred[0] );
pHuff_cfg->pred[0].codebook = &isar_split_rend_huff_pred31_consts[0][0];
pHuff_cfg->pred[0].sym_len = ISAR_SPLIT_REND_PRED_31QUANT_PNTS;
isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred[0] );
isar_split_huff_get_idx_trav_list( pHuff_cfg->pred_idx_trav[0], &pHuff_cfg->pred[0] );
pHuff_cfg->pred_base2_code_len[0] = (int16_t) ceilf( log2f( pHuff_cfg->pred[0].sym_len ) );
pHuff_cfg->pred[1].codebook = &ivas_split_rend_huff_pred63_consts[0][0];
pHuff_cfg->pred[1].sym_len = IVAS_SPLIT_REND_PRED_63QUANT_PNTS;
ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred[1] );
ivas_split_huff_get_idx_trav_list( pHuff_cfg->pred_idx_trav[1], &pHuff_cfg->pred[1] );
pHuff_cfg->pred[1].codebook = &isar_split_rend_huff_pred63_consts[0][0];
pHuff_cfg->pred[1].sym_len = ISAR_SPLIT_REND_PRED_63QUANT_PNTS;
isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred[1] );
isar_split_huff_get_idx_trav_list( pHuff_cfg->pred_idx_trav[1], &pHuff_cfg->pred[1] );
pHuff_cfg->pred_base2_code_len[1] = (int16_t) ceilf( log2f( pHuff_cfg->pred[1].sym_len ) );
pHuff_cfg->pred_roll.codebook = &ivas_split_rend_huff_roll_pred_consts[0][0];
pHuff_cfg->pred_roll.sym_len = IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS;
ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred_roll );
ivas_split_huff_get_idx_trav_list( pHuff_cfg->pred_roll_idx_trav, &pHuff_cfg->pred_roll );
pHuff_cfg->pred_roll.codebook = &isar_split_rend_huff_roll_pred_consts[0][0];
pHuff_cfg->pred_roll.sym_len = ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS;
isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred_roll );
isar_split_huff_get_idx_trav_list( pHuff_cfg->pred_roll_idx_trav, &pHuff_cfg->pred_roll );
pHuff_cfg->pred_roll_base2_code_len = (int16_t) ceilf( log2f( pHuff_cfg->pred_roll.sym_len ) );
pHuff_cfg->gd.codebook = &ivas_split_rend_huff_d_consts[0][0];
pHuff_cfg->gd.sym_len = IVAS_SPLIT_REND_D_QUANT_PNTS;
ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->gd );
ivas_split_huff_get_idx_trav_list( pHuff_cfg->gd_idx_trav, &pHuff_cfg->gd );
pHuff_cfg->gd.codebook = &isar_split_rend_huff_d_consts[0][0];
pHuff_cfg->gd.sym_len = ISAR_SPLIT_REND_D_QUANT_PNTS;
isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->gd );
isar_split_huff_get_idx_trav_list( pHuff_cfg->gd_idx_trav, &pHuff_cfg->gd );
pHuff_cfg->gd_base2_code_len = (int16_t) ceilf( log2f( pHuff_cfg->gd.sym_len ) );
pHuff_cfg->p_gd.codebook = &ivas_split_rend_huff_p_d_consts[0][0];
pHuff_cfg->p_gd.sym_len = IVAS_SPLIT_REND_D_QUANT_PNTS;
ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->p_gd );
ivas_split_huff_get_idx_trav_list( pHuff_cfg->p_gd_idx_trav, &pHuff_cfg->p_gd );
pHuff_cfg->p_gd.codebook = &isar_split_rend_huff_p_d_consts[0][0];
pHuff_cfg->p_gd.sym_len = ISAR_SPLIT_REND_D_QUANT_PNTS;
isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->p_gd );
isar_split_huff_get_idx_trav_list( pHuff_cfg->p_gd_idx_trav, &pHuff_cfg->p_gd );
pHuff_cfg->p_gd_base2_code_len = (int16_t) ceilf( log2f( pHuff_cfg->p_gd.sym_len ) );
pHuff_cfg->p_gd_diff.codebook = &ivas_split_rend_huff_p_d_diff_consts[0][0];
pHuff_cfg->p_gd_diff.sym_len = IVAS_SPLIT_REND_D_QUANT_PNTS;
ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->p_gd_diff );
ivas_split_huff_get_idx_trav_list( pHuff_cfg->p_gd_diff_idx_trav, &pHuff_cfg->p_gd_diff );
pHuff_cfg->p_gd_diff.codebook = &isar_split_rend_huff_p_d_diff_consts[0][0];
pHuff_cfg->p_gd_diff.sym_len = ISAR_SPLIT_REND_D_QUANT_PNTS;
isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->p_gd_diff );
isar_split_huff_get_idx_trav_list( pHuff_cfg->p_gd_diff_idx_trav, &pHuff_cfg->p_gd_diff );
pHuff_cfg->p_gd_diff_base2_code_len = (int16_t) ceilf( log2f( pHuff_cfg->p_gd_diff.sym_len ) );
return;
......@@ -292,7 +286,7 @@ void set_fix_rotation_mat(
*------------------------------------------------------------------------*/
void set_pose_types(
IVAS_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1],
ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1],
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData )
{
int16_t pos_idx;
......@@ -343,12 +337,12 @@ int16_t wrap_a(
/*-------------------------------------------------------------------------
* Function ivas_SplitRenderer_getdiagdiff()
* Function isar_SplitRenderer_getdiagdiff()
*
*
*------------------------------------------------------------------------*/
void ivas_SplitRenderer_getdiagdiff(
void isar_SplitRenderer_getdiagdiff(
int16_t in_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
int16_t out_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],
const int16_t sign,
......@@ -367,13 +361,13 @@ void ivas_SplitRenderer_getdiagdiff(
/*-------------------------------------------------------------------------
* Function ivas_split_rend_bitstream_read_int32()
* Function ISAR_SPLIT_REND_BITStream_read_int32()
*
*
*------------------------------------------------------------------------*/
int32_t ivas_split_rend_bitstream_read_int32(
IVAS_SPLIT_REND_BITS_HANDLE pBits,
int32_t ISAR_SPLIT_REND_BITStream_read_int32(
ISAR_SPLIT_REND_BITS_HANDLE pBits,
const int32_t bits )
{
int32_t val, k, bit_val;
......@@ -397,13 +391,13 @@ int32_t ivas_split_rend_bitstream_read_int32(
/*-------------------------------------------------------------------------
* Function ivas_split_rend_bitstream_write_int32()
* Function ISAR_SPLIT_REND_BITStream_write_int32()
*
*
*------------------------------------------------------------------------*/
void ivas_split_rend_bitstream_write_int32(
IVAS_SPLIT_REND_BITS_HANDLE pBits,
void ISAR_SPLIT_REND_BITStream_write_int32(
ISAR_SPLIT_REND_BITS_HANDLE pBits,
const int32_t val,
const int32_t bits )
{
......@@ -439,12 +433,12 @@ void ivas_split_rend_bitstream_write_int32(
#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
/*-------------------------------------------------------------------------
* ivas_mat_mult_2by2_complex()
* isar_log_cldfb2wav_data()
*
*
*------------------------------------------------------------------------*/
void ivas_log_cldfb2wav_data(
void isar_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,
......@@ -484,12 +478,12 @@ void ivas_log_cldfb2wav_data(
/*-------------------------------------------------------------------------
* Function ivas_get_split_rend_md_target_brate()
* Function isar_get_split_rend_md_target_brate()
*
*
*------------------------------------------------------------------------*/
int32_t ivas_get_split_rend_md_target_brate(
int32_t isar_get_split_rend_md_target_brate(
const int32_t SplitRendBitRate,
const int16_t pcm_out_flag )
{
......@@ -530,16 +524,16 @@ int32_t ivas_get_split_rend_md_target_brate(
/*-------------------------------------------------------------------------
* Function ivas_get_lcld_bitrate()
* Function isar_get_lcld_bitrate()
*
*
*------------------------------------------------------------------------*/
int32_t ivas_get_lcld_bitrate(
int32_t isar_get_lcld_bitrate(
const int32_t SplitRendBitRate,
const IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode )
const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode )
{
if ( poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
if ( poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
{
switch ( SplitRendBitRate )
{
......@@ -570,24 +564,25 @@ int32_t ivas_get_lcld_bitrate(
}
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
/*-------------------------------------------------------------------------
* Function ivas_get_lc3plus_bitrate()
* Function isar_get_lc3plus_bitrate()
*
*
*------------------------------------------------------------------------*/
int32_t ivas_get_lc3plus_bitrate(
int32_t isar_get_lc3plus_bitrate(
const int32_t SplitRendBitRate,
IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode,
ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode,
const int16_t split_prerender_frame_size_ms )
{
if ( poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
if ( poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
{
int32_t inBandMdBps = (int32_t) ( 8 * 1000 / split_prerender_frame_size_ms );
return ivas_get_lcld_bitrate( SplitRendBitRate, poseCorrectionMode ) - inBandMdBps;
return isar_get_lcld_bitrate( SplitRendBitRate, poseCorrectionMode ) - inBandMdBps;
}
if ( poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE )
if ( poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE )
{
return SplitRendBitRate;
}
......@@ -599,12 +594,12 @@ int32_t ivas_get_lc3plus_bitrate(
/*-------------------------------------------------------------------------
* Function ivas_get_lc3plus_bitrate_id()
* Function isar_get_lc3plus_bitrate_id()
*
*
*------------------------------------------------------------------------*/
int8_t ivas_get_lc3plus_bitrate_id(
int8_t isar_get_lc3plus_bitrate_id(
const int32_t SplitRendBitRate )
{
switch ( SplitRendBitRate )
......@@ -640,14 +635,14 @@ int8_t ivas_get_lc3plus_bitrate_id(
/*-------------------------------------------------------------------------
* Function ivas_mat_mult_2by2_complex()
* Function isar_get_lc3plus_size_from_id()
*
*
*------------------------------------------------------------------------*/
int32_t ivas_get_lc3plus_size_from_id(
int32_t isar_get_lc3plus_size_from_id(
const int8_t SplitRendBitRateId,
const IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode,
const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode,
const int16_t split_prerender_frame_size_ms )
{
int32_t bitrate;
......@@ -686,21 +681,22 @@ int32_t ivas_get_lc3plus_size_from_id(
}
}
bitrate = ivas_get_lc3plus_bitrate( bitrate, poseCorrectionMode, split_prerender_frame_size_ms );
bitrate = isar_get_lc3plus_bitrate( bitrate, poseCorrectionMode, split_prerender_frame_size_ms );
/* Return size in bytes */
return (int32_t) ( bitrate * split_prerender_frame_size_ms / 1000 / 8 );
}
#endif
/*-------------------------------------------------------------------------
* Function ivas_split_rend_validate_config()
* Function isar_split_rend_validate_config()
*
*
*------------------------------------------------------------------------*/
ivas_error ivas_split_rend_validate_config(
const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig,
ivas_error isar_split_rend_validate_config(
const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig,
const int16_t is_pcm_out )
{
/* Valid DOF range is 0-3 */
......@@ -710,26 +706,26 @@ ivas_error ivas_split_rend_validate_config(
}
/* Only CLDFB pose correction supports HQ mode */
if ( pSplitRendConfig->poseCorrectionMode != IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB && pSplitRendConfig->hq_mode != 0 )
if ( pSplitRendConfig->poseCorrectionMode != ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB && pSplitRendConfig->hq_mode != 0 )
{
return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Only CLDFB pose correction supports HQ mode" );
}
/* Split rendering with no pose correction - 0 DOF and pose correction NONE must only ever be set together */
if ( ( pSplitRendConfig->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE && pSplitRendConfig->dof != 0 ) ||
( pSplitRendConfig->poseCorrectionMode != IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE && pSplitRendConfig->dof == 0 ) )
if ( ( pSplitRendConfig->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE && pSplitRendConfig->dof != 0 ) ||
( pSplitRendConfig->poseCorrectionMode != ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE && pSplitRendConfig->dof == 0 ) )
{
return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "0 DOF and pose correction NONE must only ever be set together" );
}
if ( pSplitRendConfig->codec_frame_size_ms != 0 ) /* 0 means "default for current codec", will be set to actual value at a later stage */
{
if ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LCLD && pSplitRendConfig->codec_frame_size_ms != 5 && pSplitRendConfig->codec_frame_size_ms != 10 && pSplitRendConfig->codec_frame_size_ms != 20 )
if ( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LCLD && pSplitRendConfig->codec_frame_size_ms != 5 && pSplitRendConfig->codec_frame_size_ms != 10 && pSplitRendConfig->codec_frame_size_ms != 20 )
{
return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Invalid framing for LCLD codec" );
}
if ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && ( pSplitRendConfig->codec_frame_size_ms != 5 && pSplitRendConfig->codec_frame_size_ms != 10 ) )
if ( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS && ( pSplitRendConfig->codec_frame_size_ms != 5 && pSplitRendConfig->codec_frame_size_ms != 10 ) )
{
return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Invalid framing for LC3plus codec" );
}
......@@ -755,14 +751,19 @@ ivas_error ivas_split_rend_validate_config(
break;
case SPLIT_REND_384k:
case SPLIT_REND_512k:
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
case SPLIT_REND_768k:
#endif
/* Always valid */
break;
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
case SPLIT_REND_768k:
if ( pSplitRendConfig->dof == 0 && pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LC3PLUS )
if ( pSplitRendConfig->dof == 0 && pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS )
{
return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Bitrate is too high for LC3plus with 0 DOF" );
}
break;
#endif
default:
return IVAS_ERR_LC3PLUS_INVALID_BITRATE;
}
......@@ -771,24 +772,45 @@ ivas_error ivas_split_rend_validate_config(
{
if ( pSplitRendConfig->dof == 1 )
{
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
if ( pSplitRendConfig->splitRendBitRate < 34000 )
{
return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "1DOF metadata needs atleast 34 kbps" );
}
#else
if ( pSplitRendConfig->splitRendBitRate < 50000 )
{
return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "1DOF metadata needs atleast 50 kbps" );
}
#endif
}
else if ( pSplitRendConfig->dof == 2 )
{
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
if ( pSplitRendConfig->splitRendBitRate < 50000 )
{
return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "2DOF metadata needs atleast 50 kbps" );
}
#else
if ( pSplitRendConfig->splitRendBitRate < 66000 )
{
return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "2DOF metadata needs atleast 66 kbps" );
}
#endif
}
else if ( pSplitRendConfig->dof == 3 )
{
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
if ( pSplitRendConfig->splitRendBitRate < 82000 )
{
return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "3DOF metadata needs atleast 82 kbps" );
}
#else
if ( pSplitRendConfig->splitRendBitRate < 128000 )
{
return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "3DOF metadata needs atleast 128 kbps" );
}
#endif
}
}
......@@ -797,39 +819,48 @@ ivas_error ivas_split_rend_validate_config(
/*-------------------------------------------------------------------------
* Function ivas_split_rend_get_quant_params()
* Function isar_split_rend_get_quant_params()
*
*
*------------------------------------------------------------------------*/
void ivas_split_rend_get_quant_params(
void isar_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 )
int16_t pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
int16_t pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
int16_t pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
float pred_quantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
float pred_1byquantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
int16_t d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
int16_t bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
int16_t pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
int16_t pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS],
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
const int16_t ro_flag,
#endif
int16_t *num_quant_strats
#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
,
int16_t *num_complex_bands
#endif
)
{
int16_t q;
*num_quant_strats = IVAS_SPLIT_REND_NUM_QUANT_STRATS;
*num_quant_strats = ISAR_SPLIT_REND_NUM_QUANT_STRATS;
#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
*num_complex_bands = COMPLEX_MD_BAND_THRESH_LOW;
assert( *num_complex_bands <= num_md_bands );
#endif
pred_quant_pnts_yaw[0] = IVAS_SPLIT_REND_PRED_63QUANT_PNTS;
pred_quantstep_yaw[0] = IVAS_SPLIT_REND_PRED63_Q_STEP;
pred_1byquantstep_yaw[0] = IVAS_SPLIT_REND_PRED63_1BYQ_STEP;
pred_quant_pnts_yaw[0] = ISAR_SPLIT_REND_PRED_63QUANT_PNTS;
pred_quantstep_yaw[0] = ISAR_SPLIT_REND_PRED63_Q_STEP;
pred_1byquantstep_yaw[0] = ISAR_SPLIT_REND_PRED63_1BYQ_STEP;
for ( q = 1; q < *num_quant_strats; q++ )
{
pred_quant_pnts_yaw[q] = IVAS_SPLIT_REND_PRED_31QUANT_PNTS;
pred_quantstep_yaw[q] = IVAS_SPLIT_REND_PRED31_Q_STEP;
pred_1byquantstep_yaw[q] = IVAS_SPLIT_REND_PRED31_1BYQ_STEP;
pred_quant_pnts_yaw[q] = ISAR_SPLIT_REND_PRED_31QUANT_PNTS;
pred_quantstep_yaw[q] = ISAR_SPLIT_REND_PRED31_Q_STEP;
pred_1byquantstep_yaw[q] = ISAR_SPLIT_REND_PRED31_1BYQ_STEP;
}
for ( q = 0; q < *num_quant_strats; q++ )
......@@ -837,16 +868,40 @@ void ivas_split_rend_get_quant_params(
pred_real_bands_yaw[q] = num_md_bands;
pred_real_bands_roll[q] = num_md_bands;
}
#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
pred_imag_bands_yaw[0] = num_md_bands;
pred_imag_bands_roll[0] = num_md_bands;
pred_imag_bands_yaw[1] = num_md_bands;
pred_imag_bands_roll[1] = num_md_bands;
for ( q = 2; q < *num_quant_strats; q++ )
{
pred_imag_bands_yaw[q] = ( q < ( *num_quant_strats - 1 ) ) ? num_md_bands : *num_complex_bands;
pred_imag_bands_roll[q] = *num_complex_bands;
}
#else
if ( ro_flag )
{
for ( q = 0; q < *num_quant_strats; q++ )
{
pred_imag_bands_yaw[q] = SPLIT_REND_RO_MD_BAND_THRESH;
}
}
else
{
for ( q = 0; q < *num_quant_strats - 2; q++ )
{
pred_imag_bands_yaw[q] = num_md_bands;
}
pred_imag_bands_yaw[( *num_quant_strats - 2 )] = COMPLEX_MD_BAND_THRESH_HIGH;
pred_imag_bands_yaw[( *num_quant_strats - 1 )] = COMPLEX_MD_BAND_THRESH_LOW;
}
for ( q = 0; q < *num_quant_strats; q++ )
{
pred_imag_bands_roll[q] = SPLIT_REND_RO_MD_BAND_THRESH;
}
#endif
for ( q = 0; q < *num_quant_strats; q++ )
{
......@@ -857,17 +912,110 @@ void ivas_split_rend_get_quant_params(
return;
}
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
/*-------------------------------------------------------------------------
* Function isar_renderSplitGetRot_axisNumBits()
*
*
*------------------------------------------------------------------------*/
int16_t isar_renderSplitGetRot_axisNumBits(
const int16_t dof )
{
int16_t num_bits;
if ( dof < 3 )
{
num_bits = 2;
}
else
{
num_bits = 0;
}
return num_bits;
}
/*-------------------------------------------------------------------------
* Function isar_renderSplitGetRot_axisFromCode()
*
*
*------------------------------------------------------------------------*/
ISAR_SPLIT_REND_ROT_AXIS isar_renderSplitGetRot_axisFromCode(
const int16_t dof,
const int16_t code )
{
ISAR_SPLIT_REND_ROT_AXIS rot_axis;
if ( dof == 1 )
{
rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) code;
}
else if ( dof == 2 )
{
if ( code == 0 )
{
rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) code;
}
else
{
rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) ( code - 1 ) + YAW_PITCH;
}
}
else
{
rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) DEFAULT_AXIS;
}
return rot_axis;
}
/*-------------------------------------------------------------------------
* Function ivas_renderSplitGetMultiBinPoseData()
* Function isar_renderSplitGetCodeFromRot_axis()
*
*
*------------------------------------------------------------------------*/
void ivas_renderSplitGetMultiBinPoseData(
const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config,
int16_t isar_renderSplitGetCodeFromRot_axis(
const int16_t dof,
const ISAR_SPLIT_REND_ROT_AXIS rot_axis,
int16_t *num_bits )
{
int16_t code = 0;
if ( dof == 1 )
{
code = (int16_t) rot_axis;
}
else if ( dof == 2 )
{
if ( rot_axis == DEFAULT_AXIS )
{
code = (int16_t) rot_axis;
}
else
{
code = (int16_t) ( rot_axis - YAW_PITCH ) + 1;
}
}
else
{
code = (int16_t) DEFAULT_AXIS;
}
*num_bits = isar_renderSplitGetRot_axisNumBits( dof );
return code;
}
#endif
/*-------------------------------------------------------------------------
* Function isar_renderSplitGetMultiBinPoseData()
*
*
*------------------------------------------------------------------------*/
void isar_renderSplitGetMultiBinPoseData(
const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config,
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
const IVAS_SPLIT_REND_ROT_AXIS rot_axis )
const ISAR_SPLIT_REND_ROT_AXIS rot_axis )
{
int16_t pos_idx, num_yaw_poses, num_pitch_poses, num_roll_poses;
const float *relative_yaw_angles;
......@@ -887,9 +1035,9 @@ void ivas_renderSplitGetMultiBinPoseData(
num_roll_poses = 0;
/* defaults for all DOF except 3DOF HQ */
relative_yaw_angles = ivas_split_rend_relative_yaw_pos_angles_hq;
relative_pitch_angles = ivas_split_rend_relative_pitch_pos_angles_hq;
relative_roll_angles = ivas_split_rend_relative_roll_pos_angles_hq;
relative_yaw_angles = isar_split_rend_relative_yaw_pos_angles_hq;
relative_pitch_angles = isar_split_rend_relative_pitch_pos_angles_hq;
relative_roll_angles = isar_split_rend_relative_roll_pos_angles_hq;
if ( pSplit_rend_config->dof == 1 )
{
......@@ -922,15 +1070,19 @@ void ivas_renderSplitGetMultiBinPoseData(
switch ( rot_axis )
{
case DEFAULT_AXIS:
#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
case YAW:
case PITCH:
#endif
case YAW_PITCH:
{
num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES;
num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES;
break;
}
#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
case ROLL:
#endif
case YAW_ROLL:
{
num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES;
......@@ -953,18 +1105,18 @@ void ivas_renderSplitGetMultiBinPoseData(
{
if ( pSplit_rend_config->hq_mode == 1 )
{
relative_yaw_angles = ivas_split_rend_relative_yaw_pos_angles_hq;
relative_pitch_angles = ivas_split_rend_relative_pitch_pos_angles_hq;
relative_roll_angles = ivas_split_rend_relative_roll_pos_angles_hq;
relative_yaw_angles = isar_split_rend_relative_yaw_pos_angles_hq;
relative_pitch_angles = isar_split_rend_relative_pitch_pos_angles_hq;
relative_roll_angles = isar_split_rend_relative_roll_pos_angles_hq;
num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES;
num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES;
num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES;
}
else
{
relative_yaw_angles = ivas_split_rend_relative_yaw_pos_angles;
relative_pitch_angles = ivas_split_rend_relative_pitch_pos_angles;
relative_roll_angles = ivas_split_rend_relative_roll_pos_angles;
relative_yaw_angles = isar_split_rend_relative_yaw_pos_angles;
relative_pitch_angles = isar_split_rend_relative_pitch_pos_angles;
relative_roll_angles = isar_split_rend_relative_roll_pos_angles;
num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES;
num_pitch_poses = 1;
num_roll_poses = 1;
......@@ -998,19 +1150,19 @@ void ivas_renderSplitGetMultiBinPoseData(
/*-------------------------------------------------------------------------
* Function ivas_renderSplitUpdateNoCorrectionPoseData()
* Function isar_renderSplitUpdateNoCorrectionPoseData()
*
*
*------------------------------------------------------------------------*/
void ivas_renderSplitUpdateNoCorrectionPoseData(
const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config,
void isar_renderSplitUpdateNoCorrectionPoseData(
const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config,
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData )
{
pMultiBinPoseData->num_poses = 1;
assert( pSplit_rend_config->dof == 0 );
pMultiBinPoseData->dof = pSplit_rend_config->dof;
assert( pSplit_rend_config->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE );
assert( pSplit_rend_config->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE );
pMultiBinPoseData->poseCorrectionMode = pSplit_rend_config->poseCorrectionMode;
return;
......@@ -1018,12 +1170,12 @@ void ivas_renderSplitUpdateNoCorrectionPoseData(
/*-------------------------------------------------------------------------
* Function ivas_init_multi_bin_pose_data()
* Function isar_init_multi_bin_pose_data()
*
*
*------------------------------------------------------------------------*/
void ivas_init_multi_bin_pose_data(
void isar_init_multi_bin_pose_data(
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData )
{
int16_t pos_idx;
......@@ -1042,15 +1194,43 @@ void ivas_init_multi_bin_pose_data(
return;
}
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
ivas_error isar_framesize_to_ms(
const IVAS_RENDER_FRAMESIZE frame_size, /* i : frame size enum */
int16_t *ms /* o : frame size in ms */
)
{
switch ( frame_size )
{
case IVAS_RENDER_FRAMESIZE_5MS:
*ms = 5;
break;
case IVAS_RENDER_FRAMESIZE_10MS:
*ms = 10;
break;
case IVAS_RENDER_FRAMESIZE_20MS:
*ms = 20;
break;
default:
return IVAS_ERROR( IVAS_ERR_INTERNAL, "Unsupported ISAR frame size" );
}
return IVAS_ERR_OK;
}
#endif
/*-------------------------------------------------------------------------
* Function ivas_split_rend_choose_default_codec()
* Function isar_split_rend_choose_default_codec()
*
*
*------------------------------------------------------------------------*/
ivas_error ivas_split_rend_choose_default_codec(
IVAS_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */
ivas_error isar_split_rend_choose_default_codec(
ISAR_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
int16_t *pIsar_frame_size_ms, /* i/o: pointer to isar frame size setting */
#endif
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 */
......@@ -1059,35 +1239,39 @@ ivas_error ivas_split_rend_choose_default_codec(
{
if ( pcm_out_flag == 0 )
{
if ( *pCodec == IVAS_SPLIT_REND_CODEC_DEFAULT )
if ( *pCodec == ISAR_SPLIT_REND_CODEC_DEFAULT )
{
*pCodec = cldfb_in_flag ? IVAS_SPLIT_REND_CODEC_LCLD : IVAS_SPLIT_REND_CODEC_LC3PLUS;
*pCodec = cldfb_in_flag ? ISAR_SPLIT_REND_CODEC_LCLD : ISAR_SPLIT_REND_CODEC_LC3PLUS;
}
}
else
{
*pCodec = IVAS_SPLIT_REND_CODEC_NONE;
*pCodec = ISAR_SPLIT_REND_CODEC_NONE;
}
if ( *pCodec_frame_size_ms == 0 ) /* codec frame size hasn't been set yet - use default for current configuration */
{
switch ( *pCodec )
{
case IVAS_SPLIT_REND_CODEC_LCLD:
case ISAR_SPLIT_REND_CODEC_LCLD:
*pCodec_frame_size_ms = num_subframes * 5;
break;
case IVAS_SPLIT_REND_CODEC_LC3PLUS:
case IVAS_SPLIT_REND_CODEC_NONE:
case ISAR_SPLIT_REND_CODEC_LC3PLUS:
case ISAR_SPLIT_REND_CODEC_NONE:
*pCodec_frame_size_ms = 5;
break;
default:
return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Unknown split codec value" );
}
}
return IVAS_ERR_OK;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
if ( *pIsar_frame_size_ms == 0 ) /* isar frame size hasn't been set yet - use default for current configuration */
{
*pIsar_frame_size_ms = 20;
}
#endif
return IVAS_ERR_OK;
}
/*-------------------------------------------------------------------*
* Function get_bit()
......@@ -1101,3 +1285,5 @@ int32_t get_bit(
{
return ( state & ( 1 << bit_id ) );
}
#endif
/******************************************************************************************************
(C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
contributors to this repository. All Rights Reserved.
This software is protected by copyright law and by international treaties.
The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
contributors to this repository retain full ownership rights in their respective contributions in
the software. This notice grants no license of any kind, including but not limited to patent
license, nor is any license granted by implication, estoppel or otherwise.
Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
contributions.
This software is provided "AS IS", without any express or implied warranties. The software is in the
development stage. It is intended exclusively for experts who have experience with such software and
solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
and fitness for a particular purpose are hereby disclaimed and excluded.
Any dispute, controversy or claim arising under or in relation to providing this software shall be
submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
the United Nations Convention on Contracts on the International Sales of Goods.
*******************************************************************************************************/
#ifndef ISAR_STAT_H
#define ISAR_STAT_H
#include <stdint.h>
#include "options.h"
#include "stat_com.h"
#include "ivas_stat_com.h"
#ifdef SPLIT_REND_WITH_HEAD_ROT
#include "isar_lcld_prot.h"
#include "isar_lc3plus_enc.h"
#include "isar_lc3plus_dec.h"
#include "isar_cnst.h"
/*-------------------------------------------------------------------*
* ISAR post rend constants
*-------------------------------------------------------------------*/
#define MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL ( MAX_BUFFER_LENGTH_PER_CHANNEL * 2 )
#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 )
/*-------------------------------------------------------------------*
* ISAR post rend structs
*-------------------------------------------------------------------*/
typedef struct
{
int8_t headRotEnabled;
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];
ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis;
} ISAR_POST_REND_HeadRotData;
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 isar_split_rend_huffman_cfg_t
{
const int32_t *codebook;
int16_t min_len;
int16_t max_len;
int16_t sym_len;
} isar_split_rend_huffman_cfg_t;
typedef struct isar_binaural_head_rot_split_rendering_huff_struct
{
isar_split_rend_huffman_cfg_t pred[2];
int16_t pred_idx_trav[2][ISAR_SPLIT_REND_PRED_63QUANT_PNTS];
int16_t pred_base2_code_len[2];
isar_split_rend_huffman_cfg_t pred_roll;
int16_t pred_roll_idx_trav[ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS];
int16_t pred_roll_base2_code_len;
isar_split_rend_huffman_cfg_t gd;
int16_t gd_base2_code_len;
int16_t gd_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS];
isar_split_rend_huffman_cfg_t p_gd;
int16_t p_gd_base2_code_len;
int16_t p_gd_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS];
isar_split_rend_huffman_cfg_t p_gd_diff;
int16_t p_gd_diff_base2_code_len;
int16_t p_gd_diff_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS];
} ISAR_BIN_HR_SPLIT_REND_HUFF, *ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE;
/* binaural split rendering head rotation data structure */
typedef struct isar_binaural_head_rot_split_rendering_md_struct
{
float pred_mat_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
float pred_mat_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS
float pred_mat_re2[BINAURAL_CHANNELS];
#endif
float gd;
float gd2;
int16_t pred_mat_re_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
int16_t pred_mat_im_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
int16_t gd_idx;
int16_t gd2_idx;
} ISAR_BIN_HR_SPLIT_REND_MD, *ISAR_BIN_HR_SPLIT_REND_MD_HANDLE;
typedef struct isar_binaural_head_rot_split_pre_rendering_struct
{
ISAR_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];
ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1];
ISAR_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];
#endif
#ifdef SPLIT_POSE_CORRECTION_DEBUG
BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend;
#endif
} ISAR_BIN_HR_SPLIT_PRE_REND, *ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE;
/*----------------------------------------------------------------------------------*
* Output configuration for renderer (e.g. DirAC, MASA, Binaural Renderer...)
*----------------------------------------------------------------------------------*/
typedef struct isar_binaural_head_rot_split_rendering_lcld_enc_struct
{
void *pLcld_enc;
int16_t iChannels;
LCLDEncoder *psLCLDEncoder;
float ***pppfLCLDReal;
float ***pppfLCLDImag;
#ifdef CLDFB_DEBUG
FILE *cldfbIn;
int16_t numFrame;
#endif
int16_t iNumIterations;
int16_t iNumBlocks;
} ISAR_BIN_HR_SPLIT_LCLD_ENC, *ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE;
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];
float xf_bet[2][CLDFB_NO_CHANNELS_MAX][CLDFB_PLC_XF];
} ISAR_CLDFB_PLC, *ISAR_CLDFB_PLC_HANDLE;
typedef struct
{
ISAR_CLDFB_PLC CldfbPLC_state;
int16_t prev_bfi;
int16_t bf_count;
int16_t iNumSubSets;
} ISAR_SPLIT_REND_PLC_STRUCT, *ISAR_SPLIT_REND_PLC_HANDLE;
typedef struct isar_binaural_head_rot_split_rendering_lcld_dec_struct
{
void *pLcld_dec;
int32_t iChannels;
LCLDDecoder *psLCLDDecoder;
float ***pppfDecLCLDReal;
float ***pppfDecLCLDImag;
#ifdef CLDFB_DEBUG
FILE *cldfbOut;
int16_t numFrame;
#endif
ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC;
int16_t iNumBlocks;
int16_t iNumIterations;
} ISAR_BIN_HR_SPLIT_LCLD_DEC, *ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE;
typedef struct isar_binaural_head_rot_split_post_rendering_struct
{
ISAR_BIN_HR_SPLIT_REND_MD rot_md[MAX_HEAD_ROT_POSES][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS];
IVAS_QUATERNION QuaternionsPre[MAX_PARAM_SPATIAL_SUBFRAMES];
int16_t low_Res;
float fix_pos_rot_mat[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS];
ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1];
ISAR_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];
float mixer_mat_im[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS];
float gd_mem[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS];
#else
float mixer_mat_re[1][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS];
float mixer_mat_im[1][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS];
float gd_mem[1][MAX_SPLIT_REND_MD_BANDS];
#endif
int16_t cf_flag;
HANDLE_CLDFB_FILTER_BANK cldfbAna[BINAURAL_CHANNELS];
HANDLE_CLDFB_FILTER_BANK cldfbSyn[BINAURAL_CHANNELS];
#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
HANDLE_CLDFB_FILTER_BANK cldfbSynReconsBinDec[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS];
#endif
} ISAR_BIN_HR_SPLIT_POST_REND, *ISAR_BIN_HR_SPLIT_POST_REND_HANDLE;
typedef struct
{
int16_t num_poses;
float relative_head_poses[MAX_HEAD_ROT_POSES][3];
int16_t dof;
int16_t hq_mode;
ISAR_SPLIT_REND_ROT_AXIS rot_axis;
ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode;
} MULTI_BIN_REND_POSE_DATA;
typedef struct
{
MULTI_BIN_REND_POSE_DATA multiBinPoseData;
ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend;
ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec;
int16_t first_good_frame_received;
ISAR_LC3PLUS_DEC_HANDLE hLc3plusDec;
} ISAR_SPLIT_POST_REND_WRAPPER;
typedef struct
{
MULTI_BIN_REND_POSE_DATA multiBinPoseData;
ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend;
ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc;
CLDFB_HANDLES_WRAPPER_HANDLE hCldfbHandles;
ISAR_LC3PLUS_ENC_HANDLE hLc3plusEnc;
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;
#endif
#endif /* ISAR_STAT_H */
/******************************************************************************************************
(C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
contributors to this repository. All Rights Reserved.
This software is protected by copyright law and by international treaties.
The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
contributors to this repository retain full ownership rights in their respective contributions in
the software. This notice grants no license of any kind, including but not limited to patent
license, nor is any license granted by implication, estoppel or otherwise.
Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
contributions.
This software is provided "AS IS", without any express or implied warranties. The software is in the
development stage. It is intended exclusively for experts who have experience with such software and
solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
and fitness for a particular purpose are hereby disclaimed and excluded.
Any dispute, controversy or claim arising under or in relation to providing this software shall be
submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
the United Nations Convention on Contracts on the International Sales of Goods.
*******************************************************************************************************/
#include "options.h"
#include "lib_isar_post_rend.h"
#include "isar_stat.h"
#include "isar_prot.h"
#include "prot.h"
#include "ivas_prot.h"
#ifndef SPLIT_REND_WITH_HEAD_ROT
int32_t ISAR_POST_REND_void_func( void )
{
return 0;
}
#else
#include "ivas_prot_rend.h"
#include <assert.h>
#include <math.h>
#include "wmc_auto.h"
/*-------------------------------------------------------------------*
* Local constants
*-------------------------------------------------------------------*/
/*-------------------------------------------------------------------*
* Local types
*-------------------------------------------------------------------*/
/* EFAP wrapper to simplify writing panning gains to a vector that includes LFE channels */
typedef struct
{
EFAP_HANDLE hEfap;
AUDIO_CONFIG speakerConfig;
const LSSETUP_CUSTOM_STRUCT *pCustomLsSetup; /* Pointer to main custom LS struct from renderer handle - doesn't need freeing */
} EFAP_WRAPPER;
/* Lightweight helper struct that gathers all information required for rendering
* any config to any other config. Used to simplify signatures of rendering functions.
*
* This struct should store ONLY CONST POINTERS to data existing elsewhere.
* Storing pointers instead of data itself ensures that no additional updates
* are required when any of these are changed in the renderer. Making the pointers
* const ensures that this data is only read, but not modified by the rendering functions. */
typedef struct
{
const int32_t *pOutSampleRate;
const AUDIO_CONFIG *pOutConfig;
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
const LSSETUP_CUSTOM_STRUCT *pCustomLsOut;
const EFAP_WRAPPER *pEfapOutWrapper;
#endif
const ISAR_POST_REND_HeadRotData *pHeadRotData;
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
const RENDER_CONFIG_HANDLE *hhRendererConfig;
#endif
const int16_t *pSplitRendBFI;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRenderConfig;
#endif
} rendering_context;
/* Common base for input structs */
typedef struct
{
AUDIO_CONFIG inConfig;
ISAR_POST_REND_InputId id;
IVAS_REND_AudioBuffer inputBuffer;
float gain; /* Linear, not in dB */
rendering_context ctx;
int32_t numNewSamplesPerChannel; /* Used to keep track how much new audio was fed before rendering current frame */
} input_base;
typedef struct
{
input_base base;
ISAR_SPLIT_POST_REND_WRAPPER splitPostRendWrapper;
float *bufferData;
int16_t numCachedSamples; /* Number of decoded samples in bufferData that have not yet been played out */
ISAR_POST_REND_BitstreamBuffer *hBits;
} input_split_post_rend;
struct ISAR_POST_REND
{
int32_t sampleRateOut;
IVAS_LIMITER_HANDLE hLimiter;
#ifdef DEBUGGING
int32_t numClipping; /* Counter of clipped output samples */
#endif
input_split_post_rend inputsSplitPost[RENDERER_MAX_BIN_INPUTS];
AUDIO_CONFIG inputConfig;
AUDIO_CONFIG outputConfig;
ISAR_POST_REND_HeadRotData headRotData;
int16_t splitRendBFI;
int8_t rendererConfigEnabled;
ISAR_SPLIT_REND_CONFIG_DATA splitRenderConfig;
int16_t num_subframes;
};
/*-------------------------------------------------------------------*
* getAudioConfigType()
*
*
*-------------------------------------------------------------------*/
ISAR_POST_REND_AudioConfigType isar_getAudioConfigType(
const AUDIO_CONFIG config )
{
ISAR_POST_REND_AudioConfigType type;
switch ( config )
{
case IVAS_AUDIO_CONFIG_BINAURAL:
case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM:
case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED:
type = ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL;
break;
default:
type = ISAR_POST_REND_AUDIO_CONFIG_TYPE_UNKNOWN;
break;
}
return type;
}
/*-------------------------------------------------------------------*
* Local function prototypes
*-------------------------------------------------------------------*/
/*-------------------------------------------------------------------*
* Local functions
*-------------------------------------------------------------------*/
static ivas_error allocateInputBaseBufferData(
float **data,
const int16_t data_size )
{
*data = (float *) malloc( data_size * sizeof( float ) );
if ( *data == NULL )
{
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for input base buffer data" );
}
return IVAS_ERR_OK;
}
static void freeInputBaseBufferData(
float **data )
{
if ( *data != NULL )
{
free( *data );
*data = NULL;
}
return;
}
static IVAS_QUATERNION quaternionInit(
void )
{
IVAS_QUATERNION q;
q.w = 1.0f;
q.x = q.y = q.z = 0.0f;
return q;
}
static void convertBitsBufferToInternalBitsBuff(
const ISAR_POST_REND_BitstreamBuffer outBits,
ISAR_SPLIT_REND_BITS_HANDLE hBits )
{
hBits->bits_buf = outBits.bits;
hBits->bits_read = outBits.config.bitsRead;
hBits->bits_written = outBits.config.bitsWritten;
hBits->buf_len = outBits.config.bufLenInBytes;
hBits->codec = outBits.config.codec;
hBits->pose_correction = outBits.config.poseCorrection;
hBits->codec_frame_size_ms = outBits.config.codec_frame_size_ms;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
hBits->isar_frame_size_ms = outBits.config.isar_frame_size_ms;
hBits->lc3plus_highres = outBits.config.lc3plusHighRes;
#endif
return;
}
static void convertInternalBitsBuffToBitsBuffer(
ISAR_POST_REND_BitstreamBuffer *hOutBits,
const ISAR_SPLIT_REND_BITS_DATA bits )
{
hOutBits->bits = bits.bits_buf;
hOutBits->config.bitsRead = bits.bits_read;
hOutBits->config.bitsWritten = bits.bits_written;
hOutBits->config.bufLenInBytes = bits.buf_len;
hOutBits->config.codec = bits.codec;
hOutBits->config.poseCorrection = bits.pose_correction;
hOutBits->config.codec_frame_size_ms = bits.codec_frame_size_ms;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
hOutBits->config.isar_frame_size_ms = bits.isar_frame_size_ms;
hOutBits->config.lc3plusHighRes = bits.lc3plus_highres;
#endif
return;
}
static void copyBufferTo2dArray(
const IVAS_REND_AudioBuffer buffer,
float array[][L_FRAME48k] )
{
uint32_t smplIdx;
uint32_t chnlIdx;
const float *readPtr;
assert( ( buffer.config.is_cldfb == 0 ) && "for CLDFB input call copyBufferToCLDFBarray()" );
readPtr = buffer.data;
for ( chnlIdx = 0; chnlIdx < (uint32_t) buffer.config.numChannels; ++chnlIdx )
{
for ( smplIdx = 0; smplIdx < (uint32_t) buffer.config.numSamplesPerChannel; ++smplIdx )
{
array[chnlIdx][smplIdx] = *readPtr++;
}
}
return;
}
static void accumulate2dArrayToBuffer(
float array[][L_FRAME48k],
const IVAS_REND_AudioBuffer *buffer )
{
int16_t smplIdx, chnlIdx;
float *writePtr;
writePtr = buffer->data;
for ( chnlIdx = 0; chnlIdx < buffer->config.numChannels; ++chnlIdx )
{
for ( smplIdx = 0; smplIdx < buffer->config.numSamplesPerChannel; ++smplIdx )
{
*writePtr++ += array[chnlIdx][smplIdx];
}
}
return;
}
/*-------------------------------------------------------------------*
* limitRendererOutput()
*
* In-place saturation control for multichannel buffers with adaptive release time
*-------------------------------------------------------------------*/
#ifndef DISABLE_LIMITER
/*! r: number of clipped output samples */
static int32_t limitRendererOutput(
IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */
float *output, /* i/o: I/O buffer */
const int16_t output_frame, /* i : number of samples per channel in the buffer */
const float threshold /* i : signal amplitude above which limiting starts to be applied */
)
{
int16_t i;
float **channels;
int16_t num_channels;
int32_t numClipping = 0;
/* return early if given bad parameters */
if ( hLimiter == NULL || output == NULL || output_frame <= 0 )
{
return 0;
}
channels = hLimiter->channel_ptrs;
num_channels = hLimiter->num_channels;
for ( i = 0; i < num_channels; ++i )
{
channels[i] = output + i * output_frame;
}
limiter_process( hLimiter, output_frame, threshold, 0, NULL );
/* Apply clipping to buffer in case the limiter let through some samples > 1.0f */
for ( i = 0; i < output_frame * num_channels; ++i )
{
#ifdef DEBUGGING
if ( output[i] < INT16_MIN || output[i] > INT16_MAX )
{
++numClipping;
}
#endif
output[i] = min( max( INT16_MIN, output[i] ), INT16_MAX );
}
return numClipping;
}
#endif
/*-------------------------------------------------------------------*
* validateOutputSampleRate()
*
*
*-------------------------------------------------------------------*/
static ivas_error validateOutputSampleRate(
const int32_t sampleRate,
const AUDIO_CONFIG outConfig )
{
if ( ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) && sampleRate != 48000 )
{
return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "Error: Only 48kHz output sampling rate is supported for split rendering." );
}
else
{
/* Otherwise rendering to binaural, support the same set as IVAS decoder */
switch ( sampleRate )
{
case 8000:
case 16000:
case 32000:
case 48000:
return IVAS_ERR_OK;
}
return IVAS_ERR_INVALID_SAMPLING_RATE;
}
}
/*-------------------------------------------------------------------*
* Local functions
*-------------------------------------------------------------------*/
static ivas_error initLimiter(
IVAS_LIMITER_HANDLE *phLimiter,
const int16_t numChannels,
const int32_t sampleRate )
{
ivas_error error;
/* If re-initializing with unchanged values, return early */
if ( *phLimiter != NULL && ( *phLimiter )->num_channels == numChannels && ( *phLimiter )->sampling_rate == sampleRate )
{
return IVAS_ERR_OK;
}
/* Support re-init: close if already allocated */
if ( *phLimiter != NULL )
{
ivas_limiter_close( phLimiter );
}
if ( ( error = ivas_limiter_open( phLimiter, numChannels, sampleRate ) ) != IVAS_ERR_OK )
{
return error;
}
return IVAS_ERR_OK;
}
static ivas_error initHeadRotation(
ISAR_POST_REND_HANDLE hIvasRend )
{
int16_t i, crossfade_len;
float tmp;
/* Head rotation is enabled by default */
hIvasRend->headRotData.headRotEnabled = 1;
/* Initialize 5ms crossfade */
crossfade_len = L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES;
tmp = 1.f / ( crossfade_len - 1 );
for ( i = 0; i < crossfade_len; i++ )
{
hIvasRend->headRotData.crossfade[i] = i * tmp;
}
/* Initialize with unit quaternions */
for ( i = 0; i < hIvasRend->num_subframes; ++i )
{
hIvasRend->headRotData.headPositions[i] = quaternionInit();
}
hIvasRend->headRotData.sr_pose_pred_axis = DEFAULT_AXIS;
return IVAS_ERR_OK;
}
static void initRendInputBase(
input_base *inputBase,
const AUDIO_CONFIG inConfig,
const IVAS_REND_InputId id,
const rendering_context rendCtx,
float *dataBuf,
const int16_t dataBufSize )
{
inputBase->inConfig = inConfig;
inputBase->id = id;
inputBase->gain = 1.0f;
inputBase->ctx = rendCtx;
inputBase->numNewSamplesPerChannel = 0;
inputBase->inputBuffer.config.numSamplesPerChannel = 0;
inputBase->inputBuffer.config.numChannels = 0;
inputBase->inputBuffer.data = dataBuf;
if ( inputBase->inputBuffer.data != NULL )
{
set_zero( inputBase->inputBuffer.data, dataBufSize );
}
return;
}
static rendering_context getRendCtx(
ISAR_POST_REND_HANDLE hIvasRend )
{
rendering_context ctx;
/* Note: when refactoring this, always take the ADDRESS of a member of the
* renderer struct, so that the context stores a POINTER to the member, even
* if the member is a pointer or handle itself. */
ctx.pOutConfig = &hIvasRend->outputConfig;
ctx.pOutSampleRate = &hIvasRend->sampleRateOut;
ctx.pHeadRotData = &hIvasRend->headRotData;
ctx.pSplitRendBFI = &hIvasRend->splitRendBFI;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
ctx.pSplitRenderConfig = &hIvasRend->splitRenderConfig;
#endif
return ctx;
}
static ivas_error getRendInputNumChannels(
const void *rendInput,
int16_t *numInChannels )
{
/* Using a void pointer for this function to be reusable for any input type (input_ism, input_mc, input_sba).
Assumptions: - input_base is always the first member in the input struct */
(void) rendInput;
*numInChannels = 2;
return IVAS_ERR_OK;
}
static ivas_error updateSplitPostRendPanGains(
input_split_post_rend *inputSplitPostRend,
const AUDIO_CONFIG outConfig,
ISAR_SPLIT_REND_CONFIG_DATA *hRendCfg
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
,
int16_t num_subframes
#endif
)
{
ivas_error error;
rendering_context rendCtx;
LC3PLUS_CONFIG config;
int16_t iNumBlocksPerFrame, iNumLCLDIterationsPerFrame;
(void) outConfig;
rendCtx = inputSplitPostRend->base.ctx;
isar_renderSplitGetMultiBinPoseData( hRendCfg, &inputSplitPostRend->splitPostRendWrapper.multiBinPoseData, rendCtx.pHeadRotData->sr_pose_pred_axis );
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
config.high_res_mode_enabled = ( hRendCfg->lc3plus_highres != 0 );
#endif
config.lc3plus_frame_duration_us = hRendCfg->codec_frame_size_ms * 1000;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
config.isar_frame_duration_us = hRendCfg->isar_frame_size_ms * 1000;
#else
if ( num_subframes != MAX_PARAM_SPATIAL_SUBFRAMES )
{
if ( hRendCfg->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS )
{
config.isar_frame_duration_us = ( hRendCfg->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ? config.lc3plus_frame_duration_us * num_subframes : 20000;
}
else
{
config.isar_frame_duration_us = ( hRendCfg->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ? config.lc3plus_frame_duration_us : 20000;
}
iNumLCLDIterationsPerFrame = 1;
}
else
{
config.isar_frame_duration_us = 20000;
}
#endif
if ( hRendCfg->codec_frame_size_ms > 0 )
{
iNumLCLDIterationsPerFrame = (int16_t) config.isar_frame_duration_us / ( 1000 * hRendCfg->codec_frame_size_ms );
iNumLCLDIterationsPerFrame = max( 1, iNumLCLDIterationsPerFrame );
iNumBlocksPerFrame = CLDFB_NO_COL_MAX * hRendCfg->codec_frame_size_ms / 20;
}
else
{
iNumLCLDIterationsPerFrame = 1;
iNumBlocksPerFrame = CLDFB_NO_COL_MAX;
}
config.channels = BINAURAL_CHANNELS;
config.samplerate = *inputSplitPostRend->base.ctx.pOutSampleRate;
if ( hRendCfg->codec == ISAR_SPLIT_REND_CODEC_LCLD )
{
if ( ( error = isar_splitBinLCLDDecOpen( &inputSplitPostRend->splitPostRendWrapper.hSplitBinLCLDDec, *inputSplitPostRend->base.ctx.pOutSampleRate, BINAURAL_CHANNELS, iNumBlocksPerFrame, iNumLCLDIterationsPerFrame ) ) != IVAS_ERR_OK )
{
return error;
}
}
else if ( hRendCfg->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS )
{
if ( ( error = ISAR_LC3PLUS_DEC_Open( config,
&inputSplitPostRend->splitPostRendWrapper.hLc3plusDec ) ) != IVAS_ERR_OK )
{
return error;
}
}
if ( ( error = isar_splitBinPostRendOpen( &inputSplitPostRend->splitPostRendWrapper.hBinHrSplitPostRend, &inputSplitPostRend->splitPostRendWrapper.multiBinPoseData, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK )
{
return error;
}
return IVAS_ERR_OK;
}
static ivas_error setRendInputActiveSplitPostRend(
void *input,
const AUDIO_CONFIG inConfig,
const IVAS_REND_InputId id,
ISAR_SPLIT_REND_CONFIG_DATA *hRendCfg
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
,
const int16_t num_subframes
#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
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
,
num_subframes
#endif
) ) != IVAS_ERR_OK )
{
return error;
}
return IVAS_ERR_OK;
}
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 )
{
isar_splitBinPostRendClose( &inputSplitRend->splitPostRendWrapper.hBinHrSplitPostRend );
}
if ( inputSplitRend->splitPostRendWrapper.hSplitBinLCLDDec != NULL )
{
isar_splitBinLCLDDecClose( &inputSplitRend->splitPostRendWrapper.hSplitBinLCLDDec );
}
if ( inputSplitRend->splitPostRendWrapper.hLc3plusDec != NULL )
{
ISAR_LC3PLUS_DEC_Close( &inputSplitRend->splitPostRendWrapper.hLc3plusDec );
}
return;
}
/*-------------------------------------------------------------------------
* ISAR_POST_REND_open()
*
*
*------------------------------------------------------------------------*/
ivas_error ISAR_POST_REND_open(
ISAR_POST_REND_HANDLE *phIvasRend, /* i/o: Pointer to renderer handle */
const int32_t outputSampleRate, /* i : output sampling rate */
const IVAS_AUDIO_CONFIG outConfig, /* i : output audio config */
const bool asHrtfBinary, /* i : load hrtf binary file */
const int16_t nonDiegeticPan, /* i : non-diegetic object flag */
const float nonDiegeticPanGain, /* i : non-diegetic panning gain */
const int16_t num_subframes /* i : number of subframes */
)
{
int16_t i;
ISAR_POST_REND_HANDLE hIvasRend;
ivas_error error;
int16_t numOutChannels;
(void) asHrtfBinary;
(void) nonDiegeticPan;
(void) nonDiegeticPanGain;
/* Validate function arguments */
if ( phIvasRend == NULL )
{
return IVAS_ERR_UNEXPECTED_NULL_POINTER;
}
if ( ( error = validateOutputSampleRate( outputSampleRate, outConfig ) ) != IVAS_ERR_OK )
{
return error;
}
*phIvasRend = (ISAR_POST_REND_HANDLE) malloc( sizeof( struct ISAR_POST_REND ) );
if ( *phIvasRend == NULL )
{
return IVAS_ERR_FAILED_ALLOC;
}
hIvasRend = *phIvasRend;
hIvasRend->sampleRateOut = outputSampleRate;
hIvasRend->outputConfig = outConfig;
hIvasRend->hLimiter = NULL;
hIvasRend->num_subframes = 1;
#ifdef DEBUGGING
hIvasRend->numClipping = 0;
#endif
hIvasRend->num_subframes = num_subframes;
/* Initialize limiter */
if ( ( error = ISAR_POST_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK )
{
return error;
}
if ( ( error = initLimiter( &hIvasRend->hLimiter, numOutChannels, outputSampleRate ) ) != IVAS_ERR_OK )
{
return error;
}
/* Initialize headrotation data */
if ( ( error = initHeadRotation( hIvasRend ) ) != IVAS_ERR_OK )
{
return error;
}
/* Initialize inputs */
for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i )
{
initRendInputBase( &hIvasRend->inputsSplitPost[i].base, IVAS_AUDIO_CONFIG_INVALID, 0, getRendCtx( hIvasRend ), NULL, 0 );
isar_init_split_post_rend_handles( &hIvasRend->inputsSplitPost[i].splitPostRendWrapper );
hIvasRend->splitRendBFI = 0;
hIvasRend->inputsSplitPost[i].bufferData = NULL;
}
return IVAS_ERR_OK;
}
/*-------------------------------------------------------------------*
* ISAR_POST_REND_NumOutChannels()
*
*
*-------------------------------------------------------------------*/
ivas_error ISAR_POST_REND_NumOutChannels(
ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */
int16_t *numOutChannels /* o : number of output channels */
)
{
/* Validate function arguments */
if ( hIvasRend == NULL || numOutChannels == NULL )
{
return IVAS_ERR_UNEXPECTED_NULL_POINTER;
}
*numOutChannels = 2;
return IVAS_ERR_OK;
}
static IVAS_REND_InputId makeInputId(
AUDIO_CONFIG config,
const int32_t inputIndex )
{
/* Put config type in second byte (from LSB), put index + 1 in first byte
*
* Index is incremented here so that a valid ID can never be 0. */
return (IVAS_REND_InputId) ( ( ( (uint32_t) isar_getAudioConfigType( config ) ) << 8 ) | ( inputIndex + 1 ) );
}
static ivas_error getInputById(
ISAR_POST_REND_HANDLE hIvasRend,
const IVAS_REND_InputId inputId,
void **ppInput )
{
int32_t inputIndex;
IVAS_REND_AudioConfigType configType;
input_base *pInputBase;
/* Reverse makeInputId() */
inputIndex = ( inputId & 0xFF ) - 1;
configType = ( inputId & 0xFF00 ) >> 8;
/* Validate values derived from input ID */
if ( inputIndex < 0 )
{
return IVAS_ERR_INVALID_INPUT_ID;
}
switch ( configType )
{
case ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL:
if ( inputIndex > RENDERER_MAX_BIN_INPUTS )
{
return IVAS_ERR_INVALID_INPUT_ID;
}
pInputBase = &hIvasRend->inputsSplitPost[inputIndex].base;
break;
default:
return IVAS_ERR_INVALID_INPUT_ID;
}
/* Ensure input ID matches and that input is active */
if ( pInputBase->id != inputId || pInputBase->inConfig == IVAS_AUDIO_CONFIG_INVALID )
{
return IVAS_ERR_INVALID_INPUT_ID;
}
/* Validation done, set value via output parameter */
*ppInput = pInputBase;
return IVAS_ERR_OK;
}
/*-------------------------------------------------------------------*
* ISAR_POST_REND_SetInputGain()
*
*
*-------------------------------------------------------------------*/
ivas_error ISAR_POST_REND_SetInputGain(
ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
const ISAR_POST_REND_InputId inputId, /* i : ID of the input */
const float gain /* i : linear gain (not in dB) */
)
{
input_base *inputBase;
ivas_error error;
/* Validate function arguments */
if ( hIvasRend == NULL )
{
return IVAS_ERR_UNEXPECTED_NULL_POINTER;
}
if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK )
{
printf( "Hoo\n" );
return error;
}
inputBase->gain = gain;
return IVAS_ERR_OK;
}
static ivas_error getConstInputById(
ISAR_POST_REND_CONST_HANDLE hIvasRend,
const ISAR_POST_REND_InputId inputId,
const void **ppInput )
{
int32_t inputIndex;
IVAS_REND_AudioConfigType configType;
const input_base *pInputBase;
/* Reverse makeInputId() */
inputIndex = ( inputId & 0xFF ) - 1;
configType = ( inputId & 0xFF00 ) >> 8;
/* Validate values derived from input ID */
if ( inputIndex < 0 )
{
return IVAS_ERR_INVALID_INPUT_ID;
}
switch ( configType )
{
case ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL:
if ( inputIndex > RENDERER_MAX_BIN_INPUTS )
{
return IVAS_ERR_INVALID_INPUT_ID;
}
pInputBase = &hIvasRend->inputsSplitPost[inputIndex].base;
break;
default:
return IVAS_ERR_INVALID_INPUT_ID;
}
/* Ensure input ID matches and that input is active */
if ( pInputBase->id != inputId || pInputBase->inConfig == IVAS_AUDIO_CONFIG_INVALID )
{
return IVAS_ERR_INVALID_INPUT_ID;
}
/* Validation done, set value via output parameter */
*ppInput = pInputBase;
return IVAS_ERR_OK;
}
static ivas_error findFreeInputSlot(
const void *inputs,
const int32_t inputStructSize,
const int32_t maxInputs,
int32_t *inputIndex )
{
/* Using a void pointer and a separately provided size is a hack for this function
to be reusable for arrays of any input type (input_ism, input_mc, input_sba, input_masa).
Assumptions:
- input_base is always the first member in the input struct
- provided size is correct
*/
int32_t i;
bool canAddInput;
const uint8_t *pByte;
const input_base *pInputBase;
canAddInput = false;
/* Find first unused input in array */
for ( i = 0, pByte = inputs; i < maxInputs; ++i, pByte += inputStructSize )
{
pInputBase = (const input_base *) pByte;
if ( pInputBase->inConfig == IVAS_AUDIO_CONFIG_INVALID )
{
*inputIndex = i;
canAddInput = true;
break;
}
}
if ( !canAddInput )
{
return IVAS_ERR_TOO_MANY_INPUTS;
}
return IVAS_ERR_OK;
}
/*-------------------------------------------------------------------*
* ISAR_POST_REND_AddInput()
*
*
*-------------------------------------------------------------------*/
ivas_error ISAR_POST_REND_AddInput(
ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
const IVAS_AUDIO_CONFIG inConfig, /* i : audio config for a new input */
ISAR_POST_REND_InputId *inputId /* o : ID of the new input */
)
{
ivas_error error;
int32_t maxNumInputsOfType;
void *inputsArray;
int32_t inputStructSize;
ivas_error ( *activateInput )( void *, AUDIO_CONFIG, IVAS_REND_InputId, ISAR_SPLIT_REND_CONFIG_DATA *
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
,
int16_t
#endif
);
int32_t inputIndex;
/* Validate function arguments */
if ( hIvasRend == NULL || inputId == NULL )
{
return IVAS_ERR_UNEXPECTED_NULL_POINTER;
}
switch ( isar_getAudioConfigType( inConfig ) )
{
case ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL:
maxNumInputsOfType = RENDERER_MAX_BIN_INPUTS;
inputsArray = hIvasRend->inputsSplitPost;
inputStructSize = sizeof( *hIvasRend->inputsSplitPost );
activateInput = setRendInputActiveSplitPostRend;
break;
default:
return IVAS_ERR_INVALID_INPUT_FORMAT;
}
/* Find first free input in array corresponding to input type */
if ( ( error = findFreeInputSlot( inputsArray, inputStructSize, maxNumInputsOfType, &inputIndex ) ) != IVAS_ERR_OK )
{
return error;
}
*inputId = makeInputId( inConfig, inputIndex );
if ( ( error = activateInput( (uint8_t *) inputsArray + inputStructSize * inputIndex, inConfig, *inputId, &hIvasRend->splitRenderConfig
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
,
hIvasRend->num_subframes
#endif
) ) != IVAS_ERR_OK )
{
return error;
}
return IVAS_ERR_OK;
}
/*-------------------------------------------------------------------*
* ISAR_POST_REND_GetInputNumChannels()
*
*
*-------------------------------------------------------------------*/
ivas_error ISAR_POST_REND_GetInputNumChannels(
ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */
const ISAR_POST_REND_InputId inputId, /* i : ID of the input */
int16_t *numChannels /* o : number of channels of the input */
)
{
ivas_error error;
const input_base *pInput;
/* Validate function arguments */
if ( hIvasRend == NULL || numChannels == NULL )
{
return IVAS_ERR_UNEXPECTED_NULL_POINTER;
}
if ( ( error = getConstInputById( hIvasRend, inputId, (const void **) &pInput ) ) != IVAS_ERR_OK )
{
return error;
}
if ( ( error = getRendInputNumChannels( pInput, numChannels ) ) != IVAS_ERR_OK )
{
return error;
}
return IVAS_ERR_OK;
}
/*-------------------------------------------------------------------*
* ISAR_POST_REND_GetDelay()
*
*
*-------------------------------------------------------------------*/
ivas_error ISAR_POST_REND_GetDelay(
ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer state */
int16_t *nSamples, /* o : Renderer delay in samples */
int32_t *timeScale /* o : Time scale of the delay, equal to renderer output sampling rate */
)
{
int16_t i;
int32_t latency_ns;
int32_t max_latency_ns;
/* Validate function arguments */
if ( hIvasRend == NULL || nSamples == NULL || timeScale == NULL )
{
return IVAS_ERR_UNEXPECTED_NULL_POINTER;
}
*timeScale = hIvasRend->sampleRateOut;
*nSamples = 0;
max_latency_ns = 0;
/* Compute the maximum delay across all inputs */
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;
ISAR_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 == ISAR_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 );
}
}
*nSamples = (int16_t) roundf( (float) max_latency_ns * *timeScale / 1000000000.f );
return IVAS_ERR_OK;
}
/*-------------------------------------------------------------------*
* ISAR_POST_REND_FeedInputAudio()
*
*
*-------------------------------------------------------------------*/
ivas_error ISAR_POST_REND_FeedInputAudio(
ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
const ISAR_POST_REND_InputId inputId, /* i : ID of the input */
const ISAR_POST_REND_ReadOnlyAudioBuffer inputAudio /* i : buffer with input audio */
)
{
ivas_error error;
input_base *inputBase;
int16_t numInputChannels;
int16_t cldfb2tdSampleFact;
/* Validate function arguments */
if ( hIvasRend == NULL || inputAudio.data == NULL )
{
return IVAS_ERR_UNEXPECTED_NULL_POINTER;
}
cldfb2tdSampleFact = ( inputAudio.config.is_cldfb ) ? 2 : 1;
if ( inputAudio.config.numSamplesPerChannel <= 0 || ( MAX_BUFFER_LENGTH_PER_CHANNEL < inputAudio.config.numSamplesPerChannel && inputAudio.config.is_cldfb == 0 ) ||
( ( MAX_BUFFER_LENGTH_PER_CHANNEL * cldfb2tdSampleFact ) < inputAudio.config.numSamplesPerChannel && inputAudio.config.is_cldfb == 1 ) )
{
return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Buffer size outside of supported range" );
}
if ( inputAudio.config.numChannels <= 0 || MAX_INPUT_CHANNELS < inputAudio.config.numChannels )
{
return IVAS_ERR_WRONG_NUM_CHANNELS;
}
if ( isar_getAudioConfigType( hIvasRend->outputConfig ) == ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL &&
hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED &&
hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM &&
( inputAudio.config.numSamplesPerChannel * 1000 / cldfb2tdSampleFact ) != ( BINAURAL_RENDERING_FRAME_SIZE_MS * hIvasRend->num_subframes ) * hIvasRend->sampleRateOut )
{
return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Binaural rendering requires specific frame size" );
}
if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK )
{
printf( "Foo\n" );
return error;
}
if ( ( error = getRendInputNumChannels( inputBase, &numInputChannels ) ) != IVAS_ERR_OK )
{
return error;
}
if ( numInputChannels != inputAudio.config.numChannels )
{
return IVAS_ERR_WRONG_NUM_CHANNELS;
}
inputBase->inputBuffer.config = inputAudio.config;
mvr2r( inputAudio.data, inputBase->inputBuffer.data, inputAudio.config.numSamplesPerChannel * inputAudio.config.numChannels );
inputBase->numNewSamplesPerChannel = inputAudio.config.numSamplesPerChannel / cldfb2tdSampleFact;
return IVAS_ERR_OK;
}
/*-------------------------------------------------------------------*
* ISAR_POST_REND_InitConfig()
*
*
*-------------------------------------------------------------------*/
ivas_error ISAR_POST_REND_InitConfig(
ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
const AUDIO_CONFIG outAudioConfig /* i : output audioConfig */
)
{
bool rendererConfigEnabled;
rendererConfigEnabled = ( isar_getAudioConfigType( outAudioConfig ) == ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL );
if ( rendererConfigEnabled )
{
hIvasRend->rendererConfigEnabled = 1;
}
else
{
hIvasRend->rendererConfigEnabled = 0;
}
if ( rendererConfigEnabled )
{
hIvasRend->splitRenderConfig.splitRendBitRate = SPLIT_REND_768k;
hIvasRend->splitRenderConfig.dof = 3;
hIvasRend->splitRenderConfig.hq_mode = 0;
hIvasRend->splitRenderConfig.codec_delay_ms = 0;
hIvasRend->splitRenderConfig.codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
hIvasRend->splitRenderConfig.isar_frame_size_ms = 0; /* 0 means "use default for selected codec" */
#endif
hIvasRend->splitRenderConfig.codec = ISAR_SPLIT_REND_CODEC_DEFAULT;
hIvasRend->splitRenderConfig.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB;
hIvasRend->splitRenderConfig.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_DEFAULT;
}
return IVAS_ERR_OK;
}
/*-------------------------------------------------------------------*
* ISAR_POST_REND_GetRenderConfig()
*
*
*-------------------------------------------------------------------*/
int16_t ISAR_POST_REND_GetRenderConfig(
ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS decoder handle */
const ISAR_SPLIT_REND_CONFIG_HANDLE splitRenderConfig /* o : Render configuration handle */
)
{
ISAR_SPLIT_REND_CONFIG_DATA hRCin;
if ( hIvasRend == NULL )
{
return IVAS_ERR_UNEXPECTED_NULL_POINTER;
}
hRCin = hIvasRend->splitRenderConfig;
splitRenderConfig->splitRendBitRate = SPLIT_REND_768k;
splitRenderConfig->dof = 3;
splitRenderConfig->hq_mode = 0;
splitRenderConfig->codec_delay_ms = 0;
splitRenderConfig->codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
splitRenderConfig->isar_frame_size_ms = 0; /* 0 means "use default for selected codec" */
#endif
splitRenderConfig->codec = ISAR_SPLIT_REND_CODEC_DEFAULT;
splitRenderConfig->poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB;
splitRenderConfig->rendererSelection = hRCin.rendererSelection;
return IVAS_ERR_OK;
}
/*-------------------------------------------------------------------*
* ISAR_POST_REND_FeedSplitBinauralBitstream()
*
*
*-------------------------------------------------------------------*/
ivas_error ISAR_POST_REND_FeedSplitBinauralBitstream(
ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
const IVAS_REND_InputId inputId, /* i : ID of the input */
ISAR_POST_REND_BitstreamBuffer *hBits /* i : buffer for input bitstream */
)
{
ivas_error error;
input_base *inputBase;
input_split_post_rend *inputSplitPostRend;
/* Validate function arguments */
if ( hIvasRend == NULL || hBits == NULL )
{
return IVAS_ERR_UNEXPECTED_NULL_POINTER;
}
if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK )
{
printf( "Goo\n" );
return error;
}
inputSplitPostRend = (input_split_post_rend *) inputBase;
inputSplitPostRend->hBits = hBits;
return IVAS_ERR_OK;
}
/*-------------------------------------------------------------------*
* ISAR_POST_REND_SetHeadRotation()
*
*
*-------------------------------------------------------------------*/
ivas_error ISAR_POST_REND_SetHeadRotation(
ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */
const IVAS_VECTOR3 Pos, /* i : listener positions for next rendering call */
const ISAR_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering */
const int16_t sf_idx /* i : subframe index */
)
{
IVAS_QUATERNION rotQuat;
/* Validate function arguments */
if ( hIvasRend == NULL )
{
return IVAS_ERR_UNEXPECTED_NULL_POINTER;
}
if ( isar_getAudioConfigType( hIvasRend->outputConfig ) != ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL )
{
/* Head rotation can be set only with binaural output */
return IVAS_ERR_INVALID_OUTPUT_FORMAT;
}
hIvasRend->headRotData.headRotEnabled = 1;
/* check for Euler angle signaling */
if ( headRot.w == -3.0f )
{
Euler2Quat( deg2rad( headRot.x ), deg2rad( headRot.y ), deg2rad( headRot.z ), &rotQuat );
}
else
{
rotQuat = headRot;
}
hIvasRend->headRotData.headPositions[sf_idx] = rotQuat;
hIvasRend->headRotData.Pos[sf_idx] = Pos;
hIvasRend->headRotData.sr_pose_pred_axis = rot_axis;
return IVAS_ERR_OK;
}
/*-------------------------------------------------------------------*
* ISAR_POST_REND_SetSplitRendBFI()
*
*
*-------------------------------------------------------------------*/
ivas_error ISAR_POST_REND_SetSplitRendBFI(
ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
const int16_t bfi /* i: BFI flag */
)
{
hIvasRend->splitRendBFI = bfi;
return IVAS_ERR_OK;
}
/*-------------------------------------------------------------------*
* Local functions
*-------------------------------------------------------------------*/
static ivas_error splitBinLc3plusDecode(
ISAR_SPLIT_POST_REND_WRAPPER *hSplitBin,
ISAR_SPLIT_REND_BITS_HANDLE bits,
float outputBuffer[BINAURAL_CHANNELS][L_FRAME48k],
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
ISAR_SPLIT_REND_POSE_CORRECTION_MODE pose_correction,
#endif
const int16_t SplitRendBFI )
{
ivas_error error;
float *channel_ptrs[MAX_HEAD_ROT_POSES * 2];
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
int32_t lc3plusBitstreamSize;
#else
int32_t lc3plusBitrateId, lc3plusBitstreamSize;
#endif
push_wmops( "splitBinLc3plusDecode" );
assert( hSplitBin->hLc3plusDec != NULL );
for ( int16_t i = 0; i < BINAURAL_CHANNELS * hSplitBin->multiBinPoseData.num_poses; ++i )
{
channel_ptrs[i] = outputBuffer[i];
}
if ( SplitRendBFI == 0 )
{
/* Find next byte boundary */
while ( bits->bits_read % 8 != 0 )
{
++bits->bits_read;
}
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
/* Size is in bytes */
assert( ( bits->bits_written - bits->bits_read ) % 8 == 0 );
lc3plusBitstreamSize = ( bits->bits_written - bits->bits_read ) / 8;
#else
/* Read LC3plus bitstream size info */
lc3plusBitrateId = ISAR_SPLIT_REND_BITStream_read_int32( bits, 8 );
lc3plusBitstreamSize = isar_get_lc3plus_size_from_id( (int8_t) lc3plusBitrateId, pose_correction, (int16_t) ( hSplitBin->hLc3plusDec->config.isar_frame_duration_us / 1000 ) );
#endif
if ( ( error = ISAR_LC3PLUS_DEC_Decode( hSplitBin->hLc3plusDec, &bits->bits_buf[bits->bits_read / 8], lc3plusBitstreamSize, channel_ptrs ) ) != IVAS_ERR_OK )
{
return error;
}
}
else
{
if ( ( error = ISAR_LC3PLUS_DEC_Conceal( hSplitBin->hLc3plusDec, 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,
const int16_t num_subframes )
{
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;
ISAR_SPLIT_REND_BITS_DATA bits;
float tmpCrendBuffer[BINAURAL_CHANNELS][L_FRAME48k];
float tmpCrendBuffer_sf[BINAURAL_CHANNELS][L_FRAME48k];
ISAR_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;
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
uint32_t ivas_frame_duration_us;
#endif
int16_t iNumBlocksPerFrame, iNumLCLDIterationsPerFrame;
const ISAR_POST_REND_HeadRotData *pHeadRotData;
isPostRendInputCldfb = 0;
push_wmops( "renderSplitBinauralWithPostRot" );
error = IVAS_ERR_OK;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
if ( outAudio.config.numSamplesPerChannel / *splitBinInput->base.ctx.pOutSampleRate > splitBinInput->hBits->config.isar_frame_size_ms )
{
return IVAS_ERR_INTERNAL_FATAL;
}
#endif
pHeadRotData = splitBinInput->base.ctx.pHeadRotData;
hSplitBin = &splitBinInput->splitPostRendWrapper;
convertBitsBufferToInternalBitsBuff( *splitBinInput->hBits, &bits );
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
ivas_frame_duration_us = 20000;
if ( splitBinInput->splitPostRendWrapper.hLc3plusDec != NULL )
{
ivas_frame_duration_us = splitBinInput->splitPostRendWrapper.hLc3plusDec->config.isar_frame_duration_us;
}
#endif
iNumLCLDIterationsPerFrame = 1;
iNumBlocksPerFrame = CLDFB_NO_COL_MAX;
if ( splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec != NULL )
{
iNumBlocksPerFrame = splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec->iNumBlocks;
iNumLCLDIterationsPerFrame = splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec->iNumIterations;
}
outBufNumSamplesPerChannel = outAudio.config.numSamplesPerChannel / num_subframes;
for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
{
QuaternionsPost[sf_idx] = pHeadRotData->headPositions[sf_idx];
}
if ( !SplitRendBFI )
{
hSplitBin->first_good_frame_received = 1;
}
if ( hSplitBin->first_good_frame_received == 1 )
{
if ( bits.pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
{
if ( !SplitRendBFI )
{
#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
isar_splitBinPostRendMdDec( &bits, hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData, hSplitBin->hBinHrSplitPreRend );
#else
isar_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 == ISAR_SPLIT_REND_CODEC_LCLD )
{
isPostRendInputCldfb = 1;
}
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
numSamplesPerChannelCacheSize = (int16_t) ( *splitBinInput->base.ctx.pOutSampleRate * bits.isar_frame_size_ms / 1000 ) - outBufNumSamplesPerChannel;
#else
preRendFrameSize_ms = (int16_t) ( ivas_frame_duration_us ) / 1000;
numSamplesPerChannelCacheSize = (int16_t) ( *splitBinInput->base.ctx.pOutSampleRate * ( preRendFrameSize_ms - bits.codec_frame_size_ms ) / 1000 );
#endif
outBufNumColPerChannel = MAX_PARAM_SPATIAL_SUBFRAMES;
numColPerChannelCacheSize = ( iNumBlocksPerFrame * iNumLCLDIterationsPerFrame ) - outBufNumColPerChannel;
for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
{
if ( splitBinInput->numCachedSamples == 0 )
{
if ( bits.codec == ISAR_SPLIT_REND_CODEC_LCLD )
{
isar_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,
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
bits.pose_correction,
#endif
SplitRendBFI ) ) != IVAS_ERR_OK )
{
return error;
}
/* cache the remaining decoded audio */
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 == ISAR_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 )
{
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
preRendFrameSize_ms = splitBinInput->base.ctx.pSplitRenderConfig->isar_frame_size_ms;
#else
preRendFrameSize_ms = (int16_t) ( ivas_frame_duration_us ) / 1000;
#endif
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 < num_subframes; sf_idx++ )
{
if ( bits.pose_correction == ISAR_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 == ISAR_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 );
isar_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 renderInputSplitBin(
input_split_post_rend *splitBinInput,
const AUDIO_CONFIG outConfig,
IVAS_REND_AudioBuffer outAudio,
const int16_t SplitRendBFI,
const int16_t num_subframes )
{
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 );
switch ( outConfig )
{
case IVAS_AUDIO_CONFIG_BINAURAL:
error = renderSplitBinauralWithPostRot( splitBinInput, outAudio, SplitRendBFI, num_subframes );
break;
default:
return IVAS_ERR_INVALID_OUTPUT_FORMAT;
}
return error;
}
static ivas_error renderActiveInputsSplitBin(
ISAR_POST_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, hIvasRend->num_subframes ) ) != IVAS_ERR_OK )
{
return error;
}
}
return IVAS_ERR_OK;
}
/*-------------------------------------------------------------------*
* ISAR_POST_REND_getSamples()
*
*
*-------------------------------------------------------------------*/
ivas_error ISAR_POST_REND_getSamples(
ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */
)
{
ivas_error error;
int16_t numOutChannels;
int16_t cldfb2tdSampleFact;
/* Validate function arguments */
if ( hIvasRend == NULL || outAudio.data == NULL )
{
return IVAS_ERR_UNEXPECTED_NULL_POINTER;
}
cldfb2tdSampleFact = ( outAudio.config.is_cldfb ) ? 2 : 1;
if ( outAudio.config.numSamplesPerChannel <= 0 || ( MAX_BUFFER_LENGTH_PER_CHANNEL < outAudio.config.numSamplesPerChannel && outAudio.config.is_cldfb == 0 ) ||
( ( MAX_BUFFER_LENGTH_PER_CHANNEL * cldfb2tdSampleFact ) < outAudio.config.numSamplesPerChannel && outAudio.config.is_cldfb == 1 ) )
{
return IVAS_ERR_INVALID_BUFFER_SIZE;
}
if ( outAudio.config.numChannels <= 0 || MAX_OUTPUT_CHANNELS < outAudio.config.numChannels )
{
return IVAS_ERR_WRONG_NUM_CHANNELS;
}
if ( isar_getAudioConfigType( hIvasRend->outputConfig ) == ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL &&
( outAudio.config.numSamplesPerChannel * 1000 / cldfb2tdSampleFact ) != ( hIvasRend->num_subframes * BINAURAL_RENDERING_FRAME_SIZE_MS ) * hIvasRend->sampleRateOut )
{
return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Binaural rendering requires specific frame size" );
}
if ( ( error = ISAR_POST_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK )
{
return error;
}
if ( numOutChannels != outAudio.config.numChannels && hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
{
return IVAS_ERR_WRONG_NUM_CHANNELS;
}
/* Clear original output buffer */
set_zero( outAudio.data, outAudio.config.numChannels * outAudio.config.numSamplesPerChannel );
if ( ( error = renderActiveInputsSplitBin( hIvasRend, outAudio ) ) != IVAS_ERR_OK )
{
return error;
}
#ifndef DISABLE_LIMITER
#ifdef DEBUGGING
hIvasRend->numClipping +=
#endif
limitRendererOutput( hIvasRend->hLimiter, outAudio.data, outAudio.config.numSamplesPerChannel, IVAS_LIMITER_THRESHOLD );
#endif
return IVAS_ERR_OK;
}
/*-------------------------------------------------------------------*
* ISAR_POST_REND_GetSplitBinauralSamples()
*
*
*-------------------------------------------------------------------*/
ivas_error ISAR_POST_REND_GetSplitBinauralSamples(
ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */
bool *needNewFrame )
{
ivas_error error;
if ( ( error = ISAR_POST_REND_getSamples( hIvasRend, outAudio ) ) != IVAS_ERR_OK )
{
return error;
}
*needNewFrame = hIvasRend->inputsSplitPost[0].numCachedSamples == 0;
return IVAS_ERR_OK;
}
/*-------------------------------------------------------------------*
* ISAR_POST_REND_Close()
*
*
*-------------------------------------------------------------------*/
void ISAR_POST_REND_Close(
ISAR_POST_REND_HANDLE *phIvasRend /* i/o: Pointer to renderer handle */
)
{
uint16_t i;
ISAR_POST_REND_HANDLE hIvasRend;
/* Validate function arguments */
if ( phIvasRend == NULL || *phIvasRend == NULL )
{
return;
}
hIvasRend = *phIvasRend;
for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i )
{
clearInputSplitRend( &hIvasRend->inputsSplitPost[i] );
}
ivas_limiter_close( &hIvasRend->hLimiter );
free( hIvasRend );
*phIvasRend = NULL;
return;
}
ivas_error ISAR_REND_SetSplitRendBitstreamHeader(
ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */
const ISAR_SPLIT_REND_CODEC codec, /* o: codec setting */
const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, /* o: pose correction mode */
const int16_t codec_frame_size_ms /* i: codec frame size setting */
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
,
const int16_t isar_frame_size_ms, /* i: isar codec frame size setting */
const int16_t lc3plus_highres /* i: LC3plus Hig-Res setting. Ignored if codec is not LC3plus */
#endif
)
{
if ( hIvasRend == NULL )
{
return IVAS_ERR_UNEXPECTED_NULL_POINTER;
}
hIvasRend->splitRenderConfig.codec = codec;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
hIvasRend->splitRenderConfig.isar_frame_size_ms = isar_frame_size_ms;
#endif
hIvasRend->splitRenderConfig.codec_frame_size_ms = codec_frame_size_ms;
hIvasRend->splitRenderConfig.poseCorrectionMode = poseCorrection;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
hIvasRend->splitRenderConfig.lc3plus_highres = lc3plus_highres;
#endif
return IVAS_ERR_OK;
}
#ifdef DEBUGGING
/*-------------------------------------------------------------------*
* ISAR_POST_REND_GetNoCLipping()
*
*
*-------------------------------------------------------------------*/
int32_t ISAR_POST_REND_GetNoCLipping(
ISAR_POST_REND_HANDLE hIvasRend )
{
return hIvasRend->numClipping;
}
int32_t ISAR_POST_REND_GetCntFramesLimited(
ISAR_POST_REND_CONST_HANDLE hIvasRend )
{
if ( hIvasRend->hLimiter == NULL )
{
return 0;
}
return hIvasRend->hLimiter->cnt_frames_limited;
}
#endif
#endif
/******************************************************************************************************
(C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
contributors to this repository. All Rights Reserved.
This software is protected by copyright law and by international treaties.
The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
contributors to this repository retain full ownership rights in their respective contributions in
the software. This notice grants no license of any kind, including but not limited to patent
license, nor is any license granted by implication, estoppel or otherwise.
Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
contributions.
This software is provided "AS IS", without any express or implied warranties. The software is in the
development stage. It is intended exclusively for experts who have experience with such software and
solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
and fitness for a particular purpose are hereby disclaimed and excluded.
Any dispute, controversy or claim arising under or in relation to providing this software shall be
submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
the United Nations Convention on Contracts on the International Sales of Goods.
*******************************************************************************************************/
#ifndef LIB_ISAR_POST_REND_H
#define LIB_ISAR_POST_REND_H
#include <stdbool.h>
#include "common_api_types.h"
#ifndef SPLIT_REND_WITH_HEAD_ROT
int32_t ISAR_POST_REND_void_func( void );
#else
/*---------------------------------------------------------------------*
* Renderer constants
*---------------------------------------------------------------------*/
#define RENDERER_MAX_ISAR_MD_INPUTS 1
#define RENDERER_MAX_BIN_INPUTS 1
/*---------------------------------------------------------------------*
* Renderer structures
*---------------------------------------------------------------------*/
typedef struct
{
int32_t bufLenInBytes;
int32_t bitsWritten;
int32_t bitsRead;
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 lc3plusHighRes;
#endif
} ISAR_POST_REND_BitstreamBufferConfig;
typedef struct
{
ISAR_POST_REND_BitstreamBufferConfig config;
uint8_t *bits;
} ISAR_POST_REND_BitstreamBuffer;
typedef enum
{
ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL = 0,
ISAR_POST_REND_AUDIO_CONFIG_TYPE_UNKNOWN,
} ISAR_POST_REND_AudioConfigType;
typedef struct
{
IVAS_REND_AudioBufferConfig config;
const float *data;
} ISAR_POST_REND_ReadOnlyAudioBuffer;
typedef struct ISAR_POST_REND *ISAR_POST_REND_HANDLE;
typedef struct ISAR_POST_REND const *ISAR_POST_REND_CONST_HANDLE;
typedef uint16_t ISAR_POST_REND_InputId;
typedef enum _ISAR_POST_REND_COMPLEXITY_LEVEL
{
ISAR_POST_REND_COMPLEXITY_LEVEL_ONE = 1,
ISAR_POST_REND_COMPLEXITY_LEVEL_TWO = 2,
ISAR_POST_REND_COMPLEXITY_LEVEL_THREE = 3
} ISAR_POST_REND_COMPLEXITY_LEVEL;
/* clang-format off */
/*----------------------------------------------------------------------------------*
* Renderer function prototypes
*----------------------------------------------------------------------------------*/
/* Functions to be called before rendering */
ivas_error ISAR_POST_REND_open(
ISAR_POST_REND_HANDLE *phIvasRend, /* i/o: Pointer to renderer handle */
const int32_t outputSampleRate, /* i : output sampling rate */
const IVAS_AUDIO_CONFIG outConfig, /* i : output audio config */
const bool asHrtfBinary, /* i : load hrtf binary file */
const int16_t nonDiegeticPan, /* i : non-diegetic object flag */
const float nonDiegeticPanGain, /* i : non-diegetic panning gain */
const int16_t num_subframes /* i : number of subframes */
);
/* Functions to be called before/during rendering */
ivas_error ISAR_POST_REND_NumOutChannels(
ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */
int16_t *numOutChannels /* o : number of output channels */
);
ivas_error ISAR_POST_REND_AddInput(
ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
const IVAS_AUDIO_CONFIG inConfig, /* i : audio config for a new input */
ISAR_POST_REND_InputId *inputId /* o : ID of the new input */
);
ivas_error ISAR_POST_REND_SetInputGain(
ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
const ISAR_POST_REND_InputId inputId, /* i : ID of the input */
const float gain /* i : linear gain (not in dB) */
);
ivas_error ISAR_POST_REND_GetInputNumChannels(
ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */
const ISAR_POST_REND_InputId inputId, /* i : ID of the input */
int16_t *numChannels /* o : number of channels of the input */
);
ivas_error ISAR_POST_REND_GetDelay(
ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */
int16_t *nSamples, /* o : Renderer delay in samples */
int32_t *timeScale /* o : Time scale of the delay, equal to renderer output sampling rate */
);
/* Functions to be called during rendering */
ivas_error ISAR_POST_REND_FeedInputAudio(
ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
const ISAR_POST_REND_InputId inputId, /* i : ID of the input */
const ISAR_POST_REND_ReadOnlyAudioBuffer inputAudio /* i : buffer with input audio */
);
ivas_error ISAR_POST_REND_InitConfig(
ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
const IVAS_AUDIO_CONFIG outAudioConfig /* i : output audioConfig */
);
int16_t ISAR_POST_REND_GetRenderConfig(
ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS decoder handle */
const ISAR_SPLIT_REND_CONFIG_HANDLE splitRenderConfig /* o : Render configuration handle */
);
ivas_error ISAR_POST_REND_FeedSplitBinauralBitstream(
ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
const ISAR_POST_REND_InputId inputId, /* i : ID of the input */
ISAR_POST_REND_BitstreamBuffer *hBits /* i : buffer for input bitstream */
);
ivas_error ISAR_POST_REND_GetSplitBinauralSamples(
ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */
bool* needNewFrame
);
ivas_error ISAR_POST_REND_SetHeadRotation(
ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */
const IVAS_VECTOR3 Pos, /* i : listener positions for next rendering call */
const ISAR_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering*/
const int16_t sf_idx /* i : subframe index */
);
ivas_error ISAR_POST_REND_SetSplitRendBFI(
ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
const int16_t bfi /* i: BFI flag */
);
ivas_error ISAR_POST_REND_getSamples(
ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */
IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */
);
/* Functions to be called after rendering */
void ISAR_POST_REND_Close(
ISAR_POST_REND_HANDLE* phIvasRend /* i/o: Pointer to renderer handle */
);
ivas_error ISAR_REND_SetSplitRendBitstreamHeader(
ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */
const ISAR_SPLIT_REND_CODEC codec, /* o: codec setting */
const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, /* o: pose correction mode */
const int16_t codec_frame_size_ms /* i: codec frame size setting */
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
,
const int16_t isar_frame_size_ms, /* i: isar frame size setting */
const int16_t lc3plus_highres /* i: LC3plus Hig-Res setting. Ignored if codec is not LC3plus */
#endif
);
#ifdef DEBUGGING
int32_t ISAR_POST_REND_GetNoCLipping(
ISAR_POST_REND_HANDLE hIvasRend /* i : Renderer handle */
);
int32_t ISAR_POST_REND_GetCntFramesLimited(
ISAR_POST_REND_CONST_HANDLE hIvasRend /* i : Renderer handle */
);
#endif
#endif /* SPLIT_REND_WITH_HEAD_ROT */
/* clang-format on */
#endif /* LIB_ISAR_POST_REND_H */
/******************************************************************************************************
(C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
contributors to this repository. All Rights Reserved.
This software is protected by copyright law and by international treaties.
The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
contributors to this repository retain full ownership rights in their respective contributions in
the software. This notice grants no license of any kind, including but not limited to patent
license, nor is any license granted by implication, estoppel or otherwise.
Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
contributions.
This software is provided "AS IS", without any express or implied warranties. The software is in the
development stage. It is intended exclusively for experts who have experience with such software and
solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
and fitness for a particular purpose are hereby disclaimed and excluded.
Any dispute, controversy or claim arising under or in relation to providing this software shall be
submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
the United Nations Convention on Contracts on the International Sales of Goods.
*******************************************************************************************************/
#include <stdint.h>
#include "options.h"
#include <math.h>
#include "ivas_prot.h"
#include "prot.h"
#include "ivas_cnst.h"
#include "isar_rom_post_rend.h"
#include "lib_isar_pre_rend.h"
#include "isar_prot.h"
#ifdef DEBUGGING
#include "debug.h"
#endif
#include "wmc_auto.h"
#ifndef SPLIT_REND_WITH_HEAD_ROT
int32_t ISAR_PRE_REND_void_func( void )
{
return 0;
}
#else
/*-------------------------------------------------------------------*
* Local constants
*-------------------------------------------------------------------*/
/*-------------------------------------------------------------------*
* Local types
*-------------------------------------------------------------------*/
/*-------------------------------------------------------------------*
* Local function prototypes
*-------------------------------------------------------------------*/
/*-------------------------------------------------------------------*
* Local functions
*-------------------------------------------------------------------*/
/*-------------------------------------------------------------------------
* Function ISAR_PRE_REND_open()
*
*
*------------------------------------------------------------------------*/
ivas_error ISAR_PRE_REND_open(
SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renerer handle */
ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, /* i/o: Split renderer pre-renerer config */
const int32_t output_Fs, /* i: output sampling rate */
const int16_t cldfb_in_flag, /* i: Flag to indicate CLDFB or time doamin input */
const int16_t pcm_out_flag, /* i: Flag to indicate PCM output */
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
const IVAS_RENDER_FRAMESIZE ivas_frame_size, /* i: IVAS frame size */
#else
const int16_t num_subframes, /* i: number of subframes */
#endif
const int16_t mixed_td_cldfb_flag /* i: Flag to indicate combined TD and CLDFB input */
)
{
ivas_error error, ch, num_ch;
uint8_t isCldfbNeeded = 0;
int16_t cldfb_in_flag_local = cldfb_in_flag;
if ( ( error = isar_split_rend_choose_default_codec( &( pSplitRendConfig->codec ),
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
&pSplitRendConfig->isar_frame_size_ms,
#endif
&pSplitRendConfig->codec_frame_size_ms,
cldfb_in_flag_local,
pcm_out_flag, (int16_t)
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
ivas_frame_size
#else
num_subframes
#endif
) ) != IVAS_ERR_OK )
{
return error;
}
if ( mixed_td_cldfb_flag )
{
cldfb_in_flag_local = 0;
}
if ( ( error = isar_split_rend_validate_config( pSplitRendConfig, pcm_out_flag ) ) != IVAS_ERR_OK )
{
return error;
}
if ( cldfb_in_flag_local == 0 )
{
isCldfbNeeded = 1;
}
else if ( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS && cldfb_in_flag_local )
{
isCldfbNeeded = 1;
}
else if ( pcm_out_flag && cldfb_in_flag_local )
{
isCldfbNeeded = 1;
}
hSplitBinRend->hCldfbHandles = NULL;
if ( isCldfbNeeded )
{
if ( ( hSplitBinRend->hCldfbHandles = (CLDFB_HANDLES_WRAPPER_HANDLE) malloc( sizeof( CLDFB_HANDLES_WRAPPER ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CLDFB handles\n" ) );
}
num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS;
for ( ch = 0; ch < num_ch; ch++ )
{
hSplitBinRend->hCldfbHandles->cldfbAna[ch] = NULL;
}
for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
{
hSplitBinRend->hCldfbHandles->cldfbSyn[ch] = NULL;
}
num_ch = hSplitBinRend->multiBinPoseData.num_poses * BINAURAL_CHANNELS;
for ( ch = 0; ch < num_ch; ch++ )
{
if ( ( error = openCldfb( &( hSplitBinRend->hCldfbHandles->cldfbAna[ch] ),
CLDFB_ANALYSIS,
output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK )
{
return error;
}
}
for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
{
if ( ( error = openCldfb( &( hSplitBinRend->hCldfbHandles->cldfbSyn[ch] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK )
{
return error;
}
}
}
if ( pSplitRendConfig->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
{
if ( ( error = isar_splitBinPreRendOpen( &hSplitBinRend->hBinHrSplitPreRend, &hSplitBinRend->multiBinPoseData
#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
,
OutSampleRate
#endif
) ) != IVAS_ERR_OK )
{
return error;
}
}
if ( pcm_out_flag == 0 )
{
if ( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS )
{
if ( ( error = split_renderer_open_lc3plus( hSplitBinRend, pSplitRendConfig, output_Fs,
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
ivas_frame_size
#else
num_subframes
#endif
) ) != IVAS_ERR_OK )
{
return error;
}
}
else
{
int16_t iNumBlocksPerFrame;
iNumBlocksPerFrame = ( CLDFB_NO_COL_MAX * pSplitRendConfig->codec_frame_size_ms ) / 20;
if ( ( error = isar_splitBinLCLDEncOpen( &hSplitBinRend->hSplitBinLCLDEnc, output_Fs, BINAURAL_CHANNELS, isar_get_lcld_bitrate( pSplitRendConfig->splitRendBitRate, hSplitBinRend->multiBinPoseData.poseCorrectionMode ), iNumBlocksPerFrame, 1 ) ) != IVAS_ERR_OK )
{
return error;
}
}
}
return IVAS_ERR_OK;
}
/*-------------------------------------------------------------------------
* Function ISAR_PRE_REND_close()
*
*
*------------------------------------------------------------------------*/
void ISAR_PRE_REND_close(
SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renerer handle */
IVAS_REND_AudioBuffer *pSplitRendEncBuffer /* i/o: Split renderer data buffer */
)
{
int16_t i;
if ( hSplitBinRend->hBinHrSplitPreRend != NULL )
{
isar_splitBinPreRendClose( &hSplitBinRend->hBinHrSplitPreRend );
}
if ( hSplitBinRend->hSplitBinLCLDEnc != NULL )
{
isar_splitBinLCLDEncClose( &hSplitBinRend->hSplitBinLCLDEnc );
}
if ( hSplitBinRend->hCldfbHandles != NULL )
{
int16_t num_ch, ch;
num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS;
for ( ch = 0; ch < num_ch; ch++ )
{
if ( hSplitBinRend->hCldfbHandles->cldfbAna[ch] != NULL )
{
deleteCldfb( &hSplitBinRend->hCldfbHandles->cldfbAna[ch] );
hSplitBinRend->hCldfbHandles->cldfbAna[ch] = NULL;
}
}
for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
{
if ( hSplitBinRend->hCldfbHandles->cldfbSyn[ch] != NULL )
{
deleteCldfb( &hSplitBinRend->hCldfbHandles->cldfbSyn[ch] );
hSplitBinRend->hCldfbHandles->cldfbSyn[ch] = NULL;
}
}
free( hSplitBinRend->hCldfbHandles );
hSplitBinRend->hCldfbHandles = NULL;
}
if ( hSplitBinRend->hLc3plusEnc != NULL )
{
ISAR_LC3PLUS_ENC_Close( &hSplitBinRend->hLc3plusEnc );
}
for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i )
{
if ( hSplitBinRend->lc3plusDelayBuffers[i] != NULL )
{
free( hSplitBinRend->lc3plusDelayBuffers[i] );
hSplitBinRend->lc3plusDelayBuffers[i] = NULL;
}
}
if ( pSplitRendEncBuffer != NULL )
{
if ( pSplitRendEncBuffer->data != NULL )
{
free( pSplitRendEncBuffer->data );
pSplitRendEncBuffer->data = NULL;
}
pSplitRendEncBuffer->config.numChannels = 0;
pSplitRendEncBuffer->config.numSamplesPerChannel = 0;
}
return;
}
/*-------------------------------------------------------------------------*
* ISAR_PRE_REND_GetMultiBinPoseData()
*
*
*-------------------------------------------------------------------------*/
void ISAR_PRE_REND_GetMultiBinPoseData(
const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, /* i: Split renderer pre-renerer config */
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */
const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i: Rotation axis */
)
{
isar_renderSplitGetMultiBinPoseData( pSplit_rend_config, pMultiBinPoseData, rot_axis );
}
/*-------------------------------------------------------------------------
* Function ISAR_PRE_REND_MultiBinToSplitBinaural()
*
*
*------------------------------------------------------------------------*/
ivas_error ISAR_PRE_REND_MultiBinToSplitBinaural(
SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renerer handle */
const IVAS_QUATERNION headPosition, /* i: head rotation QUATERNION */
const int32_t SplitRendBitRate, /* i: Split renderer bitrate */
ISAR_SPLIT_REND_CODEC splitCodec, /* i/o: Split renderer codec */
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
const int16_t isar_frame_size_ms, /* i: ISAR framesize */
#endif
int16_t codec_frame_size_ms, /* i/o: ISAR transport codec framesize */
ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits struct handle */
float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB real buffer */
float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB imag buffer */
const int16_t max_bands, /* i: CLDFB bands */
float *output[], /* i/o: PCM in/out buffer */
const int16_t low_res_pre_rend_rot, /* i: low time resolution pre-renderer flag */
const int16_t cldfb_in_flag, /* i: Flag to indicate CLDFB or time doamin input */
const int16_t pcm_out_flag, /* i: Flag to indicate PCM output */
const int16_t ro_md_flag /* i: Flag to indicate real only metadata for yaw */
)
{
ivas_error error;
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
int32_t bit_len, target_md_bits, available_bits;
#else
int32_t bit_len, target_md_bits, actual_md_bits, available_bits;
#endif
error = IVAS_ERR_OK;
push_wmops( "isar_pre_rend_MultiBinToSplitBinaural" );
if ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
{
set_fix_rotation_mat( hSplitBin->hBinHrSplitPreRend->fix_pos_rot_mat, &hSplitBin->multiBinPoseData );
set_pose_types( hSplitBin->hBinHrSplitPreRend->pose_type, &hSplitBin->multiBinPoseData );
}
if ( cldfb_in_flag == 0 )
{
/*TD input*/
/*if CLDFB handles have been allocated then assume valid multi binaural input in out[][] buffer and perform CLDFB analysis*/
error = isar_renderMultiTDBinToSplitBinaural( hSplitBin,
headPosition,
SplitRendBitRate,
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
isar_frame_size_ms,
#endif
codec_frame_size_ms,
pBits,
max_bands,
output,
low_res_pre_rend_rot,
pcm_out_flag,
ro_md_flag );
pop_wmops();
return error;
}
if ( splitCodec == ISAR_SPLIT_REND_CODEC_LC3PLUS && hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
{
/* Time-align pose correction to delay of LC3plus */
lc3plusTimeAlignCldfbPoseCorr( hSplitBin, Cldfb_In_BinReal, Cldfb_In_BinImag );
}
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
actual_md_bits = pBits->bits_written;
#endif
if ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB )
{
target_md_bits = isar_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000;
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
actual_md_bits = pBits->bits_written;
#endif
isar_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, pBits, target_md_bits, low_res_pre_rend_rot, ro_md_flag );
}
if ( pcm_out_flag == 0 )
{
pBits->codec = splitCodec;
pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode;
if ( splitCodec == ISAR_SPLIT_REND_CODEC_LCLD )
{
available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC );
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
available_bits -= pBits->bits_written;
#else
actual_md_bits = pBits->bits_written - actual_md_bits;
available_bits -= actual_md_bits;
#endif
pBits->codec_frame_size_ms = codec_frame_size_ms;
isar_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal, Cldfb_In_BinImag, available_bits, pBits );
}
else
{
int16_t ch, slot_idx, num_slots, ivas_fs;
ivas_fs = (int16_t) hSplitBin->hLc3plusEnc->config.isar_frame_duration_us / 1000;
num_slots = (int16_t) ( CLDFB_NO_COL_MAX * ivas_fs ) / 20;
/* CLDFB synthesis of main pose */
for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
{
float *Cldfb_In_BinReal_p[CLDFB_NO_COL_MAX];
float *Cldfb_In_BinImag_p[CLDFB_NO_COL_MAX];
for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ )
{
Cldfb_In_BinReal_p[slot_idx] = Cldfb_In_BinReal[ch][slot_idx];
Cldfb_In_BinImag_p[slot_idx] = Cldfb_In_BinImag[ch][slot_idx];
}
cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * num_slots, hSplitBin->hCldfbHandles->cldfbSyn[ch] );
}
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
available_bits = ( SplitRendBitRate / FRAMES_PER_SEC ) - pBits->bits_written;
if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, available_bits, output ) ) != IVAS_ERR_OK )
#else
if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, SplitRendBitRate, output ) ) != IVAS_ERR_OK )
#endif
{
return error;
}
}
}
else
{
int16_t ch, slot_idx;
/* CLDFB synthesis of main pose */
for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
{
float *Cldfb_In_BinReal_p[CLDFB_NO_COL_MAX];
float *Cldfb_In_BinImag_p[CLDFB_NO_COL_MAX];
for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ )
{
Cldfb_In_BinReal_p[slot_idx] = Cldfb_In_BinReal[ch][slot_idx];
Cldfb_In_BinImag_p[slot_idx] = Cldfb_In_BinImag[ch][slot_idx];
}
cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * CLDFB_NO_COL_MAX, hSplitBin->hCldfbHandles->cldfbSyn[ch] );
}
pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode;
pBits->codec = ISAR_SPLIT_REND_CODEC_NONE;
}
/*zero pad*/
if ( pcm_out_flag )
{
bit_len = SplitRendBitRate / FRAMES_PER_SEC;
}
else
{
if ( splitCodec == ISAR_SPLIT_REND_CODEC_LCLD )
{
bit_len = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC );
}
else
{
bit_len = hSplitBin->hLc3plusEnc->config.isar_frame_duration_us / 1000;
bit_len = SplitRendBitRate * bit_len / 1000;
}
}
while ( pBits->bits_written < bit_len )
{
ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0L, 1 );
}
pop_wmops();
return error;
}
#endif
......@@ -30,86 +30,62 @@
*******************************************************************************************************/
For the IVAS Readme.txt, please refer to Readme.txt.
This readme_split_rendering.txt describes a usage of the binaural split
rendering feature in the IVAS codec. This feature is implemented as part of
the following two separate programs:
IVAS_dec Decoder
IVAS_rend Renderer
INSTALLING THE SOFTWARE
=======================
Same as described in Readme.txt while the structure looks as follows:
.
`-- c-code
|-- Makefile
|-- Workspace_msvc
|-- apps
|-- lib_com
|-- lib_debug
|-- lib_dec
|-- lib_enc
|-- lib_lc3plus
|-- lib_rend
|-- lib_util
|-- readme.txt
|-- readme_split_rendering.txt
RUNNING THE SOFTWARE
====================
The usage of the "IVAS_cod" program:
------------------------------------
Same as described in Readme.txt.
The usage of the "IVAS_dec" program:
------------------------------------
Same as described in Readme.txt while more command-line options are avilable.
Usage for IVAS: IVAS_dec.exe [Options] OutputConf Fs bitstream_file output_file
Additional options:
-------------------
OutputConf : Output configuration: MONO, STEREO, 5_1, 7_1, 5_1_2, 5_1_4, 7_1_4, FOA,
HOA2, HOA3, BINAURAL, BINAURAL_ROOM_IR, BINAURAL_ROOM_REVERB,
BINAURAL_SPLIT_CODED, BINAURAL_SPLIT_PCM, EXT
-om File : Coded metadata File for BINAURAL_SPLIT_PCM output mode
The usage of the "IVAS_rend" program:
-------------------------------------
Same as described in Readme.txt while more command-line options are avilable.
Usage: IVAS_rend [options]
Additional options:
-------------------
-om File : Coded metadata File for BINAURAL_SPLIT_PCM output mode
-im File : Coded metadata File for BINAURAL_SPLIT_PCM input mode
-prbfi File : Split rendering option: bfi File
RUNNING THE SELF TEST
=====================
Same as described in Readme.txt except of the renderer configuration text file which
can additionally be used to configure the pre-rendering step of the split binaural
renderer. All split renderer parameters are optional.
The detailed syntax of the renderer configuration text can be found in 3GPP TS 26.258.
#ifndef LIB_ISAR_PRE_REND_H
#define LIB_ISAR_PRE_REND_H
#include "isar_stat.h"
#include "isar_prot.h"
#ifndef SPLIT_REND_WITH_HEAD_ROT
int32_t ISAR_PRE_REND_void_func( void );
#else
ivas_error ISAR_PRE_REND_open(
SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renerer handle */
ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, /* i/o: Split renderer pre-renerer config */
const int32_t output_Fs, /* i: output sampling rate */
const int16_t cldfb_in_flag, /* i: Flag to indicate CLDFB or time doamin input */
const int16_t pcm_out_flag, /* i: Flag to indicate PCM output */
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
const IVAS_RENDER_FRAMESIZE ivas_frame_size, /* i: IVAS frame size */
#else
const int16_t num_subframes, /* i: number of subframes */
#endif
const int16_t mixed_td_cldfb_flag /* i: Flag to indicate combined TD and CLDFB input */
);
void ISAR_PRE_REND_close(
SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renerer handle */
IVAS_REND_AudioBuffer *pSplitRendEncBuffer /* i/o: Split renderer data buffer */
);
void ISAR_PRE_REND_GetMultiBinPoseData(
const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, /* i: Split renderer pre-renerer config */
MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */
const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i: Rotation axis */
);
ivas_error ISAR_PRE_REND_MultiBinToSplitBinaural(
SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renerer handle */
const IVAS_QUATERNION headPosition, /* i: head rotation QUATERNION */
const int32_t SplitRendBitRate, /* i: Split renderer bitrate */
ISAR_SPLIT_REND_CODEC splitCodec, /* i/o: Split renderer codec */
#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS
const int16_t isar_frame_size_ms, /* i: ISAR framesize */
#endif
int16_t codec_frame_size_ms, /* i/o: ISAR transport codec framesize */
ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits struct handle */
float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB real buffer */
float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB imag buffer */
const int16_t max_bands, /* i: CLDFB bands */
float *output[], /* i/o: PCM in/out buffer */
const int16_t low_res_pre_rend_rot, /* i: low time resolution pre-renderer flag */
const int16_t cldfb_in_flag, /* i: Flag to indicate CLDFB or time doamin input */
const int16_t pcm_out_flag, /* i: Flag to indicate PCM output */
const int16_t ro_md_flag /* i: Flag to indicate real only metadata for yaw */
);
#endif
#endif /* LIB_ISAR_PRE_REND_H */
DisableFormat: true
SortIncludes: Never
/******************************************************************************
* ETSI TS 103 634 V1.4.3 *
* ETSI TS 103 634 V1.5.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
......@@ -7,8 +7,8 @@
* estoppel or otherwise. *
******************************************************************************/
#include "options.h"
#include "wmc_auto.h"
#include "functions.h"
void processAdjustGlobalGain_fl(LC3_INT* gg_idx, LC3_INT gg_idx_min, LC3_INT gg_idx_off, LC3_FLOAT* gain, LC3_INT target, LC3_INT nBits, LC3_INT* gainChange, LC3_INT fs_idx
......@@ -18,11 +18,7 @@ void processAdjustGlobalGain_fl(LC3_INT* gg_idx, LC3_INT gg_idx_min, LC3_INT gg_
LC3_FLOAT delta;
LC3_INT delta2;
LC3_INT gg_idx_inc;
#ifdef CR8_G_ADD_75MS
LC3_FLOAT factor;
#else
LC3_INT factor;
#endif
if (frame_dms == 25)
{
......@@ -36,12 +32,10 @@ void processAdjustGlobalGain_fl(LC3_INT* gg_idx, LC3_INT gg_idx_min, LC3_INT gg_
{
factor = 2;
}
#ifdef CR8_G_ADD_75MS
else if (frame_dms == 75)
{
factor = 1.2;
}
#endif
else
{
factor = 1;
......
/******************************************************************************
* ETSI TS 103 634 V1.4.3 *
* ETSI TS 103 634 V1.5.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
......@@ -7,8 +7,8 @@
* estoppel or otherwise. *
******************************************************************************/
#include "options.h"
#include "wmc_auto.h"
#include "stdint.h"
#include <assert.h>
#include <stdlib.h>
......@@ -714,7 +714,6 @@ LC3_INT32 fec_decoder(LC3_UINT8 *iobuf, LC3_INT16 slot_bytes, LC3_INT32 *data_by
if (*bfi == 1)
{
return ERROR_REPORT_BEC_MASK;
}
......
/******************************************************************************
* ETSI TS 103 634 V1.4.3 *
* ETSI TS 103 634 V1.5.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
......@@ -7,8 +7,8 @@
* estoppel or otherwise. *
******************************************************************************/
#include "options.h"
#include "wmc_auto.h"
#include "functions.h"
void processApplyGlobalGain_fl(LC3_FLOAT x[], LC3_INT xLen, LC3_INT global_gain_idx, LC3_INT global_gain_off)
......
/******************************************************************************
* ETSI TS 103 634 V1.4.3 *
* ETSI TS 103 634 V1.5.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
......@@ -7,8 +7,8 @@
* estoppel or otherwise. *
******************************************************************************/
#include "options.h"
#include "wmc_auto.h"
#include "functions.h"
static void ac_shift_fl(Encoder_State_fl* st);
......@@ -18,105 +18,17 @@ static void write_uint_forward_fl(Encoder_State_fl* st, LC3_INT val, LC3_INT num
static void ari_enc_init(Encoder_State_fl* st, LC3_UINT8* bytes, LC3_INT* bp_side, LC3_INT* mask_side);
static LC3_INT sign(LC3_INT x);
#ifdef CR9_SIMPLIFY_ARI_DECODER
static void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* bit);
#else
static void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* bit, LC3_INT *bp, Decoder_State_fl* st_fl, LC3_INT from_left);
#endif
#ifdef CR9_SIMPLIFY_ARI_DECODER
static void ac_dec_init_fl(LC3_UINT8* ptr, LC3_INT* bp, Decoder_State_fl* st_fl, LC3_INT from_left, LC3_INT mask_side, LC3_INT *bp_side);
#else
static void ac_dec_init_fl(LC3_UINT8* ptr, LC3_INT* bp, Decoder_State_fl* st_fl, LC3_INT from_left, LC3_INT mask_side, LC3_INT *bp_side);
#endif
#ifdef CR9_SIMPLIFY_ARI_DECODER
static LC3_INT32 ac_decode_fl(Decoder_State_fl* st, const LC3_INT16* sym_freq, LC3_INT32 num_sym, LC3_UINT8* ptr, LC3_INT32* bp, LC3_INT32 from_left, LC3_INT32 mask_side, LC3_INT32 *bp_side, LC3_INT16 cur_bin);
#else
static LC3_INT ac_decode_fl(Decoder_State_fl* st, LC3_INT* sym_freq, LC3_INT* cum_freq, LC3_INT num_sym, LC3_UINT8* ptr, LC3_INT* bp, LC3_INT from_left, LC3_INT mask_side, LC3_INT *bp_side);
#endif
#ifdef CR9_SIMPLIFY_ARI_DECODER
static LC3_INT16 pc_check_bytes(LC3_INT32* bp, Decoder_State_fl* st_fl, LC3_INT32 from_left, LC3_INT32 mask_side, LC3_INT32 *bp_side, LC3_INT16 cur_bin);
#else
static void pc_check_bytes(LC3_INT32* bp, Decoder_State_fl* st_fl, LC3_INT32 from_left, LC3_INT32 mask_side, LC3_INT32 *bp_side);
#endif
static void calculate_nfseed(LC3_INT *x, LC3_INT L_spec, LC3_INT *nf_seed);
static void findNonZero(LC3_INT* in, LC3_INT len, LC3_INT* outLen);
#ifndef CR9_SIMPLIFY_ARI_DECODER
static void ac_freq(LC3_INT pki, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym);
static void tns_coef_freq(LC3_INT k, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym);
static void tns_order_freq(LC3_INT enable_lpc_weighting, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym);
void ac_freq(LC3_INT pki, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym)
{
LC3_INT i = 0, j = 0;
*numsym = 18 - 1;
j = 0;
for (i = 1; i <= *numsym; i++) {
symfreq[j] = ari_spec_cumfreq_fl[pki][i];
j++;
}
for (i = 0; i < *numsym; i++) {
symfreq[i] -= ari_spec_cumfreq_fl[pki][i];
}
for (i = 0; i < *numsym; i++) {
cumfreq[i] = ari_spec_cumfreq_fl[pki][i];
}
}
void tns_coef_freq(LC3_INT k, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym)
{
LC3_INT i = 0, j = 0;
*numsym = 18 - 1;
j = 0;
for (i = 1; i <= *numsym; i++) {
symfreq[j] = ari_tns_freq_cf[k][i];
j++;
}
for (i = 0; i < *numsym; i++) {
symfreq[i] -= ari_tns_freq_cf[k][i];
}
for (i = 0; i < *numsym; i++) {
cumfreq[i] = ari_tns_freq_cf[k][i];
}
}
void tns_order_freq(LC3_INT enable_lpc_weighting, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym)
{
LC3_INT i = 0, j = 0;
*numsym = 8;
j = 0;
for (i = 1; i < 9; i++) {
symfreq[j] = ari_tns_order_cf[enable_lpc_weighting][i];
j++;
}
for (i = 0; i < *numsym; i++) {
symfreq[i] -= ari_tns_order_cf[enable_lpc_weighting][i];
}
for (i = 0; i < *numsym; i++) {
cumfreq[i] = ari_tns_order_cf[enable_lpc_weighting][i];
}
}
#endif
void findNonZero(LC3_INT* in, LC3_INT len, LC3_INT* outLen)
{
LC3_INT i = 0, j = 0;
......@@ -146,7 +58,6 @@ void calculate_nfseed(LC3_INT *x, LC3_INT L_spec, LC3_INT *nf_seed)
}
}
#ifdef CR9_SIMPLIFY_ARI_DECODER
static LC3_INT16 pc_check_bytes(LC3_INT32* bp, Decoder_State_fl* st_fl, LC3_INT32 from_left, LC3_INT32 mask_side, LC3_INT32 *bp_side, LC3_INT16 cur_bin)
{
LC3_INT32 bp_local, bp_side_local, offset;
......@@ -240,95 +151,6 @@ static LC3_INT16 pc_check_bytes(LC3_INT32* bp, Decoder_State_fl* st_fl, LC3_INT3
return 0;
}
#else
static void pc_check_bytes(LC3_INT32* bp, Decoder_State_fl* st_fl, LC3_INT32 from_left, LC3_INT32 mask_side, LC3_INT32 *bp_side)
{
LC3_INT32 bp_local, bp_side_local, offset;
if (st_fl->pc_bytes > 0)
{
if (!from_left && mask_side != 1)
{
return;
}
if (st_fl->pc_c_bp_side > 0 && *bp_side < 0)
{
assert(mask_side == 1);
assert(st_fl->pc_b_right != -1);
*bp_side = st_fl->pc_b_right;
return;
}
bp_local = *bp;
bp_side_local = *bp_side;
if (from_left)
{
if (mask_side == 1)
{
bp_side_local = bp_side_local + 1;
}
} else {
bp_local = bp_local - 1;
}
if (st_fl->pc_b_right == -1)
{
offset = -1;
if (!st_fl->pc_enc)
{
offset = offset + st_fl->pc_bytes;
}
if ((bp_side_local + offset - bp_local) == st_fl->pc_bytes)
{
st_fl->pc_b_left = bp_local + 1;
st_fl->pc_b_right = bp_side_local - 1;
if (st_fl->pc_enc)
{
st_fl->pc_return = 1;
return;
}
}
}
if (!st_fl->pc_enc && st_fl->pc_b_right > -1)
{
if (from_left && *bp == st_fl->pc_b_left)
{
*bp = 0;
st_fl->pc_c_bp = 1;
}
if (!from_left && bp_side_local == st_fl->pc_b_right)
{
*bp_side = st_fl->pc_bytes - 1;
st_fl->pc_c_bp_side = 1;
}
if (st_fl->pc_bfi == 2)
{
if ((st_fl->pc_c_bp && (*bp + 1) >= st_fl->pc_be_bp_left) || (st_fl->pc_c_bp_side && (*bp_side + 1) <= st_fl->pc_be_bp_right))
{
st_fl->pc_bbi = 2;
} else if ((st_fl->pc_c_bp && *bp >= 0) || (st_fl->pc_c_bp_side && *bp_side <= (st_fl->pc_bytes - 1)))
{
st_fl->pc_bbi = 1;
}
}
}
}
return;
}
#endif
#ifdef CR9_SIMPLIFY_ARI_DECODER
void ac_dec_init_fl(LC3_UINT8* ptr, LC3_INT* bp, Decoder_State_fl* st_fl, LC3_INT from_left, LC3_INT mask_side, LC3_INT *bp_side)
{
LC3_INT i;
......@@ -354,34 +176,7 @@ void ac_dec_init_fl(LC3_UINT8* ptr, LC3_INT* bp, Decoder_State_fl* st_fl, LC3_IN
st_fl->BER_detect = 0;
}
#else
void ac_dec_init_fl(LC3_UINT8* ptr, LC3_INT* bp, Decoder_State_fl* st_fl, LC3_INT from_left, LC3_INT mask_side, LC3_INT *bp_side)
{
LC3_INT i = 0;
if (!st_fl->pc_enc)
{
*bp = *bp + st_fl->pc_bytes;
}
st_fl->ac_low_fl = 0;
st_fl->ac_range_fl = (LC3_UINT32)pow(2, 24) - (LC3_UINT32)1;
for (i = 0; i < 3; i++) {
pc_check_bytes(bp, st_fl, from_left, mask_side, bp_side);
st_fl->ac_low_fl = (st_fl->ac_low_fl << 8) + (LC3_UINT32)ptr[*bp];
*bp = *bp + 1;
}
st_fl->BER_detect = 0;
}
#endif
/* Returns val */
#ifdef CR9_SIMPLIFY_ARI_DECODER
LC3_INT32 ac_decode_fl(Decoder_State_fl* st, const LC3_INT16* freq, LC3_INT32 num_sym, LC3_UINT8* ptr, LC3_INT32* bp, LC3_INT32 from_left, LC3_INT32 mask_side, LC3_INT32 *bp_side, LC3_INT16 cur_bin)
{
LC3_INT val, tmp, symfreq_loc;
......@@ -427,46 +222,6 @@ LC3_INT32 ac_decode_fl(Decoder_State_fl* st, const LC3_INT16* freq, LC3_INT32 nu
return val;
}
#else
LC3_INT ac_decode_fl(Decoder_State_fl* st, LC3_INT* sym_freq, LC3_INT* cum_freq, LC3_INT num_sym, LC3_UINT8* ptr, LC3_INT* bp, LC3_INT from_left, LC3_INT mask_side, LC3_INT *bp_side)
{
LC3_INT val = 0, tmp = 0;
tmp = st->ac_range_fl >> 10;
if (st->ac_low_fl >= (LC3_UINT32)(tmp << 10)) {
st->BER_detect = 1;
}
val = num_sym - 1;
while (st->ac_low_fl < (LC3_UINT32)(tmp * cum_freq[val])) {
val--;
}
st->ac_low_fl = st->ac_low_fl - tmp * cum_freq[val];
st->ac_range_fl = tmp * sym_freq[val];
while (st->ac_range_fl < pow(2, 16)) {
st->ac_low_fl = st->ac_low_fl << 8;
st->ac_low_fl = ((LC3_INT)st->ac_low_fl) & ((LC3_INT)(pow(2, 24) - 1));
pc_check_bytes(bp, st, from_left, mask_side, bp_side);
st->ac_low_fl = st->ac_low_fl + ptr[*bp];
*bp = *bp + 1;
st->ac_range_fl = st->ac_range_fl << 8;
}
return val;
}
#endif
#ifdef CR9_SIMPLIFY_ARI_DECODER
void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* bit)
{
if (ptr[*bp_side] & *mask_side) {
......@@ -483,33 +238,6 @@ void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT*
}
}
#else
void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* bit, LC3_INT *bp, Decoder_State_fl* st_fl, LC3_INT from_left)
{
*bit = 0;
UNUSED(bp);
UNUSED(st_fl);
UNUSED(from_left);
if (ptr[*bp_side] & *mask_side) {
*bit = 1;
} else {
*bit = 0;
}
if (*mask_side == 128) {
*mask_side = 1;
*bp_side = *bp_side - 1;
} else {
*mask_side = *mask_side * 2;
}
}
#endif
#ifdef CR9_SIMPLIFY_ARI_DECODER
void processAriDecoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side, LC3_INT L_spec, LC3_INT fs_idx, LC3_INT enable_lpc_weighting,
LC3_INT tns_numfilters, LC3_INT lsbMode, LC3_INT lastnz, LC3_INT* bfi, LC3_INT* tns_order, LC3_INT fac_ns_idx,
LC3_INT gg_idx, uint8_t * resBits, LC3_INT* x, LC3_INT* nf_seed, LC3_INT* tns_idx, LC3_INT* zero_frame, LC3_INT numbytes,
......@@ -937,550 +665,6 @@ bail:
(void)0;
}
#else
void processAriDecoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side, LC3_INT L_spec, LC3_INT fs_idx, LC3_INT enable_lpc_weighting,
LC3_INT tns_numfilters, LC3_INT lsbMode, LC3_INT lastnz, LC3_INT* bfi, LC3_INT* tns_order, LC3_INT fac_ns_idx,
LC3_INT gg_idx, uint8_t * resBits, LC3_INT* x, LC3_INT* nf_seed, LC3_INT* tns_idx, LC3_INT* zero_frame, LC3_INT numbytes,
LC3_INT* nbits_residual, LC3_INT* residualPresent, LC3_INT frame_dms,
LC3_INT32 n_pc, LC3_INT32 be_bp_left, LC3_INT32 be_bp_right, LC3_INT32 enc, LC3_INT32 *b_left, LC3_INT32 *spec_inv_idx,
LC3_INT hrmode
)
{
Decoder_State_fl st;
LC3_INT a = 0, b = 0, t = 0, bp = 0;
LC3_INT c = 0;
LC3_INT nbits_side = 0, extra_bits = 0;
LC3_UINT8* ptr = NULL;
LC3_INT n = 0, k = 0, lev = 0;
LC3_INT max_lev = 0, tmp = 0;
LC3_INT sym_freq[MAX_LEN] = {0}, cum_freq[MAX_LEN] = {0}, numsym = 0, bit = 0, lev1 = 0, pki = 0, sym = 0,
save_lev[MAX_LEN] = {0}, idx_len = 0, total_bits = 0, nbits_ari = 0, rateFlag = 0;
total_bits = 8 * numbytes;
memset(&st, 0, sizeof(st));
st.pc_bytes = (n_pc + 1) >> 1;
st.pc_b_left = numbytes + 1;
st.pc_b_right = -1;
st.pc_enc = enc;
st.pc_bfi = *bfi;
st.pc_be_bp_left = floor(be_bp_left / 8);
st.pc_be_bp_right = floor(be_bp_right / 8) - 1;
*spec_inv_idx = L_spec + 1;
assert(st.pc_be_bp_right < st.pc_bytes || st.pc_bytes == 0);
/* Rate flag */
if (fs_idx != 5)
{
if (total_bits > (160 + fs_idx * 160)) {
rateFlag = 512;
}
}
/* Init */
c = 0;
t = 0;
bp = 0;
*b_left = -1;
ptr = bytes;
/* Start Decoding */
ac_dec_init_fl(ptr, &bp, &st, 1, mask_side, &bp_side);
/* Decode TNS data */
tmp = MAXLAG;
if (frame_dms == 25)
{
tmp /= 2;
}
if (frame_dms == 50)
{
tmp /= 2;
}
/* Decode TNS data */
for (n = 0; n < tns_numfilters; n++) {
if (tns_order[n] > 0) {
tns_order_freq(enable_lpc_weighting, sym_freq, cum_freq, &numsym);
tns_order[n] = ac_decode_fl(&st, sym_freq, cum_freq, numsym, ptr, &bp, 1, mask_side, &bp_side);
if (st.pc_return)
{
*b_left = st.pc_b_left;
return;
}
tns_order[n] = tns_order[n] + 1;
if (tns_order[n] > tmp)
{
st.BER_detect = 1;
}
if (st.pc_bbi == 1)
{
spec_inv_idx = 0;
} else if (st.pc_bbi == 2)
{
st.BER_detect = 1;
}
for (k = 0; k < tns_order[n]; k++) {
if (bp_side < bp)
{
*bfi = 1;
return;
}
tns_coef_freq(k, sym_freq, cum_freq, &numsym);
tns_idx[n * 8 + k] = ac_decode_fl(&st, sym_freq, cum_freq, numsym, ptr, &bp, 1, mask_side, &bp_side);
if (st.pc_return)
{
*b_left = st.pc_b_left;
return;
}
if (st.pc_bbi == 1)
{
spec_inv_idx = 0;
} else if (st.pc_bbi == 2)
{
st.BER_detect = 1;
}
}
}
}
if (st.BER_detect > 0) {
*bfi = 1;
return;
}
/* Spectral data */
for (k = 0; k < lastnz; k = k + 2) {
/* Context */
t = c + rateFlag;
if (k > L_spec / 2) {
t = t + 256;
}
/* Decode amplitude */
x[k] = 0;
x[k + 1] = 0;
if (hrmode == 1) {
max_lev = 13 + 8;
} else {
max_lev = 13;
}
for (lev = 0; lev <= max_lev; lev++) {
lev1 = MIN(lev, 3);
pki = ari_spec_lookup_fl[t + lev1 * 1024];
ac_freq(pki, sym_freq, cum_freq, &numsym);
sym = ac_decode_fl(&st, sym_freq, cum_freq, numsym, ptr, &bp, 1, mask_side, &bp_side);
if (st.pc_return)
{
*b_left = st.pc_b_left;
return;
}
if (st.pc_bbi == 1)
{
*spec_inv_idx = MIN(*spec_inv_idx, k);
} else if (st.pc_bbi == 2)
{
*spec_inv_idx = k;
x[k] = 0;
x[k + 1] = 0;
calculate_nfseed(x, k, nf_seed);
return;
}
if (sym < 16) {
break;
}
if (lsbMode == 0 || lev > 0) {
pc_check_bytes(&bp, &st, 0, mask_side, &bp_side);
read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0);
if (st.pc_return)
{
*b_left = st.pc_b_left;
return;
}
if (st.pc_bbi == 2)
{
*spec_inv_idx = k;
x[k] = 0;
x[k + 1] = 0;
calculate_nfseed(x, k, nf_seed);
return;
}
x[k] = x[k] + (bit << lev);
pc_check_bytes(&bp, &st, 0, mask_side, &bp_side);
read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0);
if (st.pc_return)
{
*b_left = st.pc_b_left;
return;
}
if (st.pc_bbi == 2)
{
*spec_inv_idx = k;
x[k] = 0;
x[k + 1] = 0;
calculate_nfseed(x, k, nf_seed);
return;
}
x[k + 1] = x[k + 1] + (bit << lev);
}
}
if ((lev - 1) == 13 && sym == 16)
{
st.BER_detect = 1;
}
if (hrmode == 0) {
lev = MIN(lev, 13);
}
if (lsbMode == 1) {
save_lev[k] = lev;
}
a = sym & 3;
b = sym >> 2;
x[k] = x[k] + (a << lev);
x[k + 1] = x[k + 1] + (b << lev);
/* Decode signs */
if (x[k] > 0) {
pc_check_bytes(&bp, &st, 0, mask_side, &bp_side);
read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0);
if (st.pc_return)
{
*b_left = st.pc_b_left;
return;
}
if (st.pc_bbi == 2)
{
*spec_inv_idx = k;
x[k] = 0;
x[k + 1] = 0;
calculate_nfseed(x, k, nf_seed);
return;
}
if (bit == 1) {
x[k] = -x[k];
}
}
if (x[k + 1] > 0) {
pc_check_bytes(&bp, &st, 0, mask_side, &bp_side);
read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0);
if (st.pc_return)
{
*b_left = st.pc_b_left;
return;
}
if (st.pc_bbi == 2)
{
*spec_inv_idx = k + 1;
x[k + 1] = 0;
calculate_nfseed(x, k, nf_seed);
return;
}
if (bit == 1) {
x[k + 1] = -x[k + 1];
}
}
/* Context */
lev1 = MIN(lev, 3);
if (lev1 <= 1) {
t = 1 + (a + b) * (lev1 + 1);
} else {
t = 12 + lev1;
}
c = (c & 15) * 16 + t;
if (((bp - bp_side) > 3 && (st.pc_c_bp == st.pc_c_bp_side))) {
if ((0 < *spec_inv_idx) && (*spec_inv_idx < (L_spec + 1)))
{
*bfi = 2;
calculate_nfseed(x, k, nf_seed);
return;
}
*bfi = 1;
return;
}
if (st.BER_detect > 0)
{
if ((0 < *spec_inv_idx) && (*spec_inv_idx < (L_spec + 1)))
{
*bfi = 2;
calculate_nfseed(x, k, nf_seed);
return;
}
*bfi = 1;
return;
}
}
/* Residual bits */
nbits_side = total_bits - (8 * bp_side + 8 - (31 - clz_func(mask_side)));
nbits_ari = (bp - 3) * 8;
extra_bits = 25 - (31 - clz_func(st.ac_range_fl));
if (enc == 0)
{
if (st.pc_c_bp == 0)
{
nbits_ari = (bp - st.pc_bytes - 3) * 8;
} else {
nbits_ari = (bp + st.pc_b_left - st.pc_bytes - 3) * 8;
}
if (st.pc_c_bp_side != 0)
{
nbits_side = total_bits - 8 * (st.pc_b_left) + 8 * (st.pc_bytes - bp_side) - (8 - LC3_LOGTWO(mask_side));
}
}
*nbits_residual = total_bits - (nbits_side + nbits_ari + extra_bits);
if (*nbits_residual < 0) {
if ((0 < *spec_inv_idx) && (*spec_inv_idx < (L_spec + 1)))
{
*bfi = 2;
calculate_nfseed(x, k, nf_seed);
return;
}
*bfi = 1;
return;
}
if (lsbMode == 0) {
findNonZero(x, L_spec, &idx_len);
if (hrmode)
{
idx_len *= EXT_RES_ITER_MAX;
}
*nbits_residual = MIN(*nbits_residual, idx_len);
*residualPresent = 1;
memset(resBits, 0, MAX_RESBITS_LEN);
for (k = 0; k < *nbits_residual; k++) {
pc_check_bytes(&bp, &st, 0, mask_side, &bp_side);
read_bit_fl(ptr, &mask_side, &bp_side, &tmp, &bp, &st, 0);
if (st.pc_return)
{
*b_left = st.pc_b_left;
return;
}
if (st.pc_bbi == 2)
{
*bfi = 0;
memset(resBits, 0, sizeof(uint8_t) * (*nbits_residual));
calculate_nfseed(x, k, nf_seed);
return;
}
resBits[k >> 3] |= tmp << (k & 7);
}
} else {
for (k = 0; k < lastnz; k = k + 2) {
if (save_lev[k] > 0) {
if (*nbits_residual == 0) {
break;
}
pc_check_bytes(&bp, &st, 0, mask_side, &bp_side);
read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0);
if (st.pc_return)
{
*b_left = st.pc_b_left;
return;
}
if (st.pc_bbi == 2)
{
*bfi = 0;
memset(resBits, 0, sizeof(LC3_INT32) * (*nbits_residual));
calculate_nfseed(x, k, nf_seed);
return;
}
*nbits_residual = *nbits_residual - 1;
if (bit == 1) {
if (x[k] > 0) {
x[k] = x[k] + 1;
} else if (x[k] < 0) {
x[k] = x[k] - 1;
} else {
if (*nbits_residual == 0) {
break;
}
pc_check_bytes(&bp, &st, 0, mask_side, &bp_side);
read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0);
if (st.pc_return)
{
*b_left = st.pc_b_left;
return;
}
if (st.pc_bbi == 2)
{
*bfi = 0;
memset(resBits, 0, sizeof(LC3_INT32) * (*nbits_residual));
calculate_nfseed(x, k, nf_seed);
return;
}
*nbits_residual = *nbits_residual - 1;
if (bit == 0) {
x[k] = 1;
} else {
x[k] = -1;
}
}
}
if (*nbits_residual == 0) {
break;
}
pc_check_bytes(&bp, &st, 0, mask_side, &bp_side);
read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0);
if (st.pc_return)
{
*b_left = st.pc_b_left;
return;
}
if (st.pc_bbi == 2)
{
*bfi = 0;
memset(resBits, 0, sizeof(LC3_INT32) * (*nbits_residual));
calculate_nfseed(x, k, nf_seed);
return;
}
*nbits_residual = *nbits_residual - 1;
if (bit == 1) {
if (x[k + 1] > 0) {
x[k + 1] = x[k + 1] + 1;
} else if (x[k + 1] < 0) {
x[k + 1] = x[k + 1] - 1;
} else {
if (*nbits_residual == 0) {
break;
}
pc_check_bytes(&bp, &st, 0, mask_side, &bp_side);
read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0);
if (st.pc_return)
{
*b_left = st.pc_b_left;
return;
}
if (st.pc_bbi == 2)
{
*bfi = 0;
memset(resBits, 0, sizeof(LC3_INT32) * (*nbits_residual));
calculate_nfseed(x, k, nf_seed);
return;
}
*nbits_residual = *nbits_residual - 1;
if (bit == 0) {
x[k + 1] = 1;
} else {
x[k + 1] = -1;
}
}
}
}
}
}
/* Noise-filling seed */
calculate_nfseed(x, L_spec, nf_seed);
/* Zero frame flag */
if (lastnz == 2 && x[0] == 0 && x[1] == 0 && gg_idx == 0 && fac_ns_idx == 7) {
*zero_frame = 1;
} else {
*zero_frame = 0;
}
if (enc)
{
if (st.pc_bytes > 0)
{
if (st.pc_b_left > numbytes)
{
*b_left = bp_side - st.pc_bytes;
}
}
}
if ((*bfi == 2) && (*spec_inv_idx == (L_spec + 1)))
{
*bfi = 0;
}
*spec_inv_idx = *spec_inv_idx - 1;
}
#endif
void ac_encode_fl(Encoder_State_fl* st, LC3_INT sym_freq, LC3_INT cum_freq)
{
LC3_INT r;
......
/******************************************************************************
* ETSI TS 103 634 V1.4.3 *
* ETSI TS 103 634 V1.5.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
......@@ -7,8 +7,8 @@
* estoppel or otherwise. *
******************************************************************************/
#include "options.h"
#include "wmc_auto.h"
#include "functions.h"
void attack_detector_fl(LC3_FLOAT* in, LC3_INT frame_size, LC3_INT fs, LC3_INT* lastAttackPosition, LC3_FLOAT* accNrg, LC3_INT* attackFlag,
......
/******************************************************************************
* ETSI TS 103 634 V1.4.3 *
* ETSI TS 103 634 V1.5.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
......@@ -7,11 +7,11 @@
* estoppel or otherwise. *
******************************************************************************/
#ifndef CLIB_H
#define CLIB_H
#include "options.h"
#include "wmc_auto.h"
#include <assert.h>
#include <inttypes.h>
#include <limits.h>
......
/******************************************************************************
* ETSI TS 103 634 V1.4.3 *
* ETSI TS 103 634 V1.5.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
......@@ -7,8 +7,8 @@
* estoppel or otherwise. *
******************************************************************************/
 
#include "options.h"
#include "wmc_auto.h"
#include "functions.h"
 
/* DCT */
......@@ -999,7 +999,6 @@ const LC3_INT BW_cutoff_bits_all[MAX_BW_BANDS_NUMBER] = {0, 1, 2, 2, 3, 0};
const LC3_INT BW_cutoff_bin_all_5ms[MAX_BW_BANDS_NUMBER] = {40, 80, 120, 160, 200, 200};
const LC3_INT BW_cutoff_bin_all_2_5ms[MAX_BW_BANDS_NUMBER] = {20, 40, 60, 80, 100, 100};
 
#ifdef CR8_G_ADD_75MS
const LC3_INT BW_cutoff_bin_all_7_5ms[] = {60, 120, 180, 240, 300, 300};
const LC3_INT bands_number_7_5ms_HR [] = {60, 64, 64, 64, 64, 64};
const LC3_INT bands_number_7_5ms [] = {60, 64, 64, 64, 64};
......@@ -1022,7 +1021,6 @@ const LC3_INT* BW_warp_idx_start_all_7_5ms[4] = {BW_warp_idx_start_16k_7_5ms, BW
BW_warp_idx_start_32k_7_5ms, BW_warp_idx_start_48k_7_5ms};
const LC3_INT* BW_warp_idx_stop_all_7_5ms[4] = {BW_warp_idx_stop_16k_7_5ms, BW_warp_idx_stop_24k_7_5ms,
BW_warp_idx_stop_32k_7_5ms, BW_warp_idx_stop_48k_7_5ms};
#endif
 
/* Arithmetic coding */
const LC3_INT tns_cf[8][18] = {{0, 1, 6, 21, 52, 106, 192, 289, 409, 568, 720, 831, 935, 994, 1016, 1022, 1023, 1024},
......@@ -1038,9 +1036,6 @@ const LC3_INT tns_freq_cf[2][9] = {{0, 3, 12, 35, 89, 200, 390, 658, 1024}, {0,
 
/* MDCT Windows */
 
#ifdef CR8_G_ADD_75MS
const LC3_FLOAT MDCT_HRA_WINDOW_480_7_5ms[720] = {
0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00,
......@@ -3403,7 +3398,6 @@ const LC3_FLOAT MDCT_WINDOW_480_7_5ms[720] = {0.00172152668161197,
0,
0,
0};
#endif /* #ifdef CR8_G_ADD_75MS */
 
const LC3_FLOAT MDCT_WINDOW_80_2_5ms[40] = {
6.737914289329320e-03, 2.732289618100209e-02, 6.163560962361236e-02, 1.119125037883055e-01, 1.787053464784875e-01,
......@@ -5487,12 +5481,10 @@ const LC3_FLOAT* MDCT_WINS_10ms[2][6] = {
{NULL, NULL, NULL, NULL, MDCT_HRA_WINDOW_480_10ms, MDCT_HRA_WINDOW_960_10ms}};
const LC3_INT MDCT_la_zeroes[6] = {30, 60, 90, 120, 180, 360};
 
#ifdef CR8_G_ADD_75MS
const LC3_FLOAT* MDCT_WINS_7_5ms[2][6] = {
{MDCT_WINDOW_80_7_5ms, MDCT_WINDOW_160_7_5ms, MDCT_WINDOW_240_7_5ms, MDCT_WINDOW_320_7_5ms, MDCT_WINDOW_480_7_5ms, NULL},
{NULL , NULL , NULL , NULL , MDCT_HRA_WINDOW_480_7_5ms, MDCT_HRA_WINDOW_960_7_5ms}};
const LC3_INT32 MDCT_la_zeroes_7_5ms[6] = {14, 28, 42, 56, 84, 168};
#endif
 
const LC3_FLOAT* MDCT_WINS_2_5ms[2][6] = {
{MDCT_WINDOW_80_2_5ms, MDCT_WINDOW_160_2_5ms, MDCT_WINDOW_240_2_5ms, MDCT_WINDOW_320_2_5ms, MDCT_WINDOW_480_2_5ms,
......@@ -5623,7 +5615,6 @@ const LC3_INT* ACC_COEFF_PER_BAND_5ms[5] = {ACC_COEFF_PER_BAND_8_5ms, ACC_COEFF_
ACC_COEFF_PER_BAND_24_5ms, ACC_COEFF_PER_BAND_32_5ms,
ACC_COEFF_PER_BAND_48_5ms};
 
#ifdef CR8_G_ADD_75MS
const LC3_INT ACC_COEFF_PER_BAND_8_7_5ms[61] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
......@@ -5703,17 +5694,14 @@ const LC3_INT ACC_COEFF_PER_BAND_PLC_96_7_5ms[81] = {
const LC3_INT* ACC_COEFF_PER_BAND_PLC_7_5ms[] = {
ACC_COEFF_PER_BAND_PLC_8_7_5ms, ACC_COEFF_PER_BAND_PLC_16_7_5ms, ACC_COEFF_PER_BAND_PLC_24_7_5ms,
ACC_COEFF_PER_BAND_PLC_32_7_5ms, ACC_COEFF_PER_BAND_PLC_48_7_5ms, ACC_COEFF_PER_BAND_PLC_96_7_5ms};
#endif
 
/* Near Nyquist detector */
const LC3_INT NN_thresh = 30;
/* Tone detector */
#ifdef CR8_E_TONE_DETECTOR
const LC3_INT32 TD_HR_thresh_10ms = 83402;
const LC3_INT32 TD_HR_thresh_7_5ms = 743496;
const LC3_INT32 TD_HR_thresh_5ms = 382564;
const LC3_INT32 TD_HR_thresh_2_5ms = 301695;
#endif // CR8_E_TONE_DETECTOR
 
 
const LC3_INT32 xavg_N_grp[5] = { 4, 5, 6, 7, 8 };
......@@ -5721,16 +5709,8 @@ const LC3_INT32 xavg_N_grp[5] = { 4, 5, 6, 7, 8 };
 
const LC3_INT32 gwlpr[MAX_LGW+1] = { 1, 3*QUOT_LPR_LTR, 5*QUOT_LPR_LTR, 9*QUOT_LPR_LTR, 17*QUOT_LPR_LTR, 33*QUOT_LPR_LTR, 49*QUOT_LPR_LTR, 65*QUOT_LPR_LTR, 81*QUOT_LPR_LTR, 97*QUOT_LPR_LTR};
 
#ifdef CR8_A_PLC_FADEOUT_TUNING
/* PLC_FADEOUT_TUNING, extended table ranging from 30 ms to 140 ms */
const LC3_INT16 fade_scheme_tab[24 / 2][3] = {
#if 0
/* burst_att_thresh indicates when muting POW_ATT_TABLE[att_per_frame_idx] should be used first time it is 1.0 though */
/* burst_att_thresh ==2 --> gains [ 1.0, 32767/32768.0(first table value used) , first muted, .... ]*/
/* burst_att_thresh ==5 --> gains [ 1.0, 1.0, 1,0 1,0, 32767/32768.0(first table value used) , first muted,... ]*/
/* beta_mute_thr ==4 --> start of final attenuation attenuate AvgMix */
#endif
/* tabled {att_per_frame_idx_p3dB , burst_att_thresh, beta_mute_thr } */
{ 1, 2, 0 + 2 + 2 }, /* 30 ms, 0.3 dB delta att in slow mutephase nominal_fadeout=0 */
{ 1, 3, 0 + 3 + 2 }, /* 40 ms, 0.3 dB delta att in slow mutephase */
......@@ -5746,17 +5726,9 @@ const LC3_INT16 fade_scheme_tab[24 / 2][3] = {
{ 11, 6, 15 + 6 },/* 140 ms, 0.3 dB delta att in slow mutephase nominal 3GPP */
 
};
#if 0
/*fade_scheme_tab[ind][0] att_per _fram_index , "points" to first column in POW_ATT TABLES */
/*fade_scheme_tab[ind][1] is burst_att_thresh, the number of non_muted 1.0 gain frames */
/*fade_scheme_tab[ind][2] is beta_mute_thr, the location of the start of final muting */
#endif
 
/*compressed ATH Abolute hearing THreshold function weights at band borders */
const LC3_FLOAT scATHFx[MAX_LGW - 2] = { .455444335937500 , 0.930755615234375 , 0.973083496093750 , 0.999969482421875 , 0.908508300781250 , 0.775665283203125 , 0.5 };
#endif
 
const LC3_FLOAT PhECU_whr16ms_NB[128]={
8.000000000000002e-02, 8.393536376804722e-02, 9.567411990702857e-02, 1.150154150448081e-01, 1.416283142591582e-01,
......@@ -6340,7 +6312,7 @@ const LC3_INT* ACC_COEFF_PER_BAND_PLC_5ms[] = {
 
const LC3_INT32 mdct_grp_bins[10] = { 4, 14, 24, 44, 84, 164, 244, 324, 404, 484 };
 
#if defined(CR8_A_PLC_FADEOUT_TUNING)
const LC3_INT16 plc_fadeout_param_maxlen[4] = {800, 400, 266, 200};
const LC3_INT16 plc_fadeout_param_maxbytes[4] = {27, 14, 9, 7};
#endif
const LC3_INT16 PLC_FADEOUT_TYPE_2_SELECTOR = 10; /* can take values from 0 to 10, default is 10 for longer fadeout */
/******************************************************************************
* ETSI TS 103 634 V1.4.3 *
* ETSI TS 103 634 V1.5.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
......@@ -7,11 +7,11 @@
* estoppel or otherwise. *
******************************************************************************/
#ifndef CONSTANTS_H
#define CONSTANTS_H
#include "options.h"
#include "wmc_auto.h"
#include "defines.h"
#include "structs.h"
......@@ -113,7 +113,6 @@ extern const LC3_INT bands_number_2_5ms_HR[6];
extern const LC3_INT BW_cutoff_bin_all_2_5ms[MAX_BW_BANDS_NUMBER];
extern const LC3_INT bands_number_2_5ms[5];
extern const LC3_INT BW_warp_idx_start_16k_5ms[4];
extern const LC3_INT BW_warp_idx_stop_16k_5ms[4];
extern const LC3_INT BW_warp_idx_start_24k_5ms[4];
......@@ -131,7 +130,6 @@ extern const LC3_INT BW_cutoff_bin_all_5ms_HR[MAX_BW_BANDS_NUMBER];
extern const LC3_INT BW_cutoff_bin_all[MAX_BW_BANDS_NUMBER];
extern const LC3_INT BW_cutoff_bits_all[MAX_BW_BANDS_NUMBER];
#ifdef CR8_G_ADD_75MS
extern const LC3_INT BW_cutoff_bin_all_7_5ms[MAX_BW_BANDS_NUMBER];
extern const LC3_INT bands_number_7_5ms[6];
extern const LC3_INT bands_number_7_5ms_HR[6];
......@@ -139,7 +137,6 @@ extern const LC3_INT* BW_warp_idx_start_all_7_5ms[4];
extern const LC3_INT* BW_warp_idx_stop_all_7_5ms[4];
extern const LC3_INT brickwall_dist_7_5ms[4];
extern const LC3_INT* ACC_COEFF_PER_BAND_PLC_7_5ms[];
#endif
/* Arithmetic coding */
extern const LC3_INT tns_cf[8][18];
......@@ -171,10 +168,8 @@ extern const LC3_FLOAT MDCT_WINDOW_480_5ms[480];
extern const LC3_FLOAT* MDCT_WINS_5ms[2][6];
extern const LC3_INT MDCT_la_zeroes_5ms[6];
#ifdef CR8_G_ADD_75MS
extern const LC3_FLOAT* MDCT_WINS_7_5ms[2][6];
extern const LC3_INT32 MDCT_la_zeroes_7_5ms[6];
#endif
extern const LC3_INT MDCT_WINDOWS_LENGTHS_10ms[6];
extern const LC3_INT MDCT_WINDOWS_LENGTHS_7_5ms[6];
......@@ -188,10 +183,8 @@ extern const LC3_INT* ACC_COEFF_PER_BAND_HR[6];
extern const LC3_INT* ACC_COEFF_PER_BAND_2_5ms_HR[6];
extern const LC3_INT* ACC_COEFF_PER_BAND_2_5ms[5];
#ifdef CR8_G_ADD_75MS
extern const LC3_INT* ACC_COEFF_PER_BAND_7_5ms_HR[6];
extern const LC3_INT* ACC_COEFF_PER_BAND_7_5ms[5];
#endif
extern const LC3_INT* ACC_COEFF_PER_BAND_5ms_HR[6];
extern const LC3_INT* ACC_COEFF_PER_BAND_5ms[5];
......@@ -199,20 +192,16 @@ extern const LC3_INT* ACC_COEFF_PER_BAND_5ms[5];
/* Near Nyquist detector */
extern const LC3_INT NN_thresh;
/* Tone detector */
#ifdef CR8_E_TONE_DETECTOR
extern const LC3_INT32 TD_HR_thresh_10ms;
extern const LC3_INT32 TD_HR_thresh_7_5ms;
extern const LC3_INT32 TD_HR_thresh_5ms;
extern const LC3_INT32 TD_HR_thresh_2_5ms;
#endif // CR8_E_TONE_DETECTOR
extern const LC3_INT32 xavg_N_grp[5];
extern const LC3_FLOAT *hannOla_wins[5];
extern const LC3_INT32 gwlpr[MAX_LGW+1];
#ifdef CR8_A_PLC_FADEOUT_TUNING
extern const LC3_INT16 fade_scheme_tab[24 / 2][3];
extern const LC3_FLOAT scATHFx[MAX_LGW - 2];
#endif
extern const LC3_INT32 mdct_grp_bins[10];
extern const LC3_FLOAT* PhECU_whr16ms_wins[5];
......@@ -229,9 +218,7 @@ extern const LC3_FLOAT plc_tdc_lpc_48[17];
extern const LC3_FLOAT plc_tdc_lpc_96[17];
extern const LC3_FLOAT plc_tdc_lpc_8_25ms[9];
#if defined(CR8_A_PLC_FADEOUT_TUNING)
extern const LC3_INT16 plc_fadeout_param_maxlen[4];
extern const LC3_INT16 plc_fadeout_param_maxbytes[4];
#endif
extern const LC3_INT16 PLC_FADEOUT_TYPE_2_SELECTOR;
#endif /* CONSTANTS_H */
/******************************************************************************
* ETSI TS 103 634 V1.4.3 *
* ETSI TS 103 634 V1.5.1 *
* Low Complexity Communication Codec Plus (LC3plus) *
* *
* Copyright licence is solely granted through ETSI Intellectual Property *
......@@ -7,8 +7,8 @@
* estoppel or otherwise. *
******************************************************************************/
#include "options.h"
#include "wmc_auto.h"
#include "functions.h"
void process_cutoff_bandwidth(LC3_FLOAT *d_fl, LC3_INT len, LC3_INT bw_bin)
......