Skip to content
GitLab
Explore
Sign in
Show whitespace changes
Inline
Side-by-side
lib_
rend/ivas
_splitRend_lcld_enc.c
→
lib_
isar/isar
_splitRend_lcld_enc.c
View file @
bea683b3
...
...
@@ -33,7 +33,7 @@
#include
<stdint.h>
#include
"options.h"
#ifdef SPLIT_REND_WITH_HEAD_ROT
#include
"i
vas
_prot
_rend
.h"
#include
"i
sar
_prot.h"
#include
"ivas_prot.h"
#ifdef DEBUGGING
#include
"debug.h"
...
...
@@ -42,23 +42,23 @@
/*-------------------------------------------------------------------------
* Function i
vas
_splitBinLCLDEncOpen()
* Function i
sar
_splitBinLCLDEncOpen()
*
*
*------------------------------------------------------------------------*/
ivas_error
i
vas
_splitBinLCLDEncOpen
(
BIN_HR_SPLIT_LCLD_ENC_HANDLE
*
hSplitBinLCLDEnc
,
ivas_error
i
sar
_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 i
vas
_splitBinLCLDEncClose()
* Function i
sar
_splitBinLCLDEncClose()
*
*
*------------------------------------------------------------------------*/
void
i
vas
_splitBinLCLDEncClose
(
BIN_HR_SPLIT_LCLD_ENC_HANDLE
*
hSplitBinLCLDEnc
)
void
i
sar
_splitBinLCLDEncClose
(
ISAR_
BIN_HR_SPLIT_LCLD_ENC_HANDLE
*
hSplitBinLCLDEnc
)
{
if
(
(
*
hSplitBinLCLDEnc
)
!=
NULL
)
{
...
...
@@ -151,20 +151,20 @@ void ivas_splitBinLCLDEncClose(
/*-------------------------------------------------------------------------
* Function i
vas
_splitBinLCLDEncProcess()
* Function i
sar
_splitBinLCLDEncProcess()
*
*
*------------------------------------------------------------------------*/
void
i
vas
_splitBinLCLDEncProcess
(
BIN_HR_SPLIT_LCLD_ENC_HANDLE
hSplitBinLCLDEnc
,
void
i
sar
_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
,
I
VAS
_SPLIT_REND_BITS_HANDLE
pBits
)
I
SAR
_SPLIT_REND_BITS_HANDLE
pBits
)
{
int32_t
iBitsWritten
,
itr
,
available_bits_itr
,
rem_itr
,
available_bits_local
;
push_wmops
(
"i
vas
_splitBinLCLDEncProcess"
);
push_wmops
(
"i
sar
_splitBinLCLDEncProcess"
);
assert
(
hSplitBinLCLDEnc
!=
NULL
);
assert
(
Cldfb_In_Real
!=
NULL
);
...
...
lib_
rend/ivas
_splitRendererPLC.c
→
lib_
isar/isar
_splitRendererPLC.c
View file @
bea683b3
...
...
@@ -37,7 +37,7 @@
#include
"ivas_prot.h"
#include
"prot.h"
#include
"ivas_cnst.h"
#include
"i
vas
_prot
_rend
.h"
#include
"i
sar
_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
.
0
f
/
START_VAL_AVG_LEN
;
start_imag
*=
1
.
0
f
/
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 i
vas
_splitBinRendPLCOpen()
* Function i
sar
_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 i
vas
_splitBinRendPLCClose()
* Function i
sar
_splitBinRendPLCClose()
*
*
*------------------------------------------------------------------------*/
void
i
vas
_splitBinRendPLCClose
(
SPLIT_REND_PLC_HANDLE
*
phSplitRendPLC
)
void
i
sar
_splitBinRendPLCClose
(
ISAR_
SPLIT_REND_PLC_HANDLE
*
phSplitRendPLC
)
{
if
(
(
*
phSplitRendPLC
)
!=
NULL
)
{
...
...
@@ -397,13 +361,13 @@ void ivas_splitBinRendPLCClose(
/*-------------------------------------------------------------------------
* Function i
vas
_splitBinRendPLCsaveState()
* Function i
sar
_splitBinRendPLCsaveState()
*
*
*------------------------------------------------------------------------*/
void
i
vas
_splitBinRendPLCsaveState
(
SPLIT_REND_PLC_HANDLE
hSplitRendPLC
,
void
i
sar
_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 i
vas
_splitBinRendPLC_xf()
* Function i
sar
_splitBinRendPLC_xf()
*
* Cross-fade of preceding bad frame into good frame
*------------------------------------------------------------------------*/
void
i
vas
_splitBinRendPLC_xf
(
SPLIT_REND_PLC_HANDLE
hSplitRendPLC
,
void
i
sar
_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 i
vas
_splitBinRendPLC()
* Function i
sar
_splitBinRendPLC()
*
* Conceal bad frame
*------------------------------------------------------------------------*/
void
i
vas
_splitBinRendPLC
(
SPLIT_REND_PLC_HANDLE
hSplitRendPLC
,
void
i
sar
_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
.
0
f
-
(
i
+
1
.
0
f
)
/
(
CLDFB_PLC_XF
+
1
.
0
f
);
}
#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
}
}
...
...
lib_
rend/ivas
_splitRendererPost.c
→
lib_
isar/isar
_splitRendererPost.c
View file @
bea683b3
...
...
@@ -39,30 +39,41 @@
#endif
#include
"ivas_prot.h"
#include
"prot.h"
#include
"i
vas
_rom_
dec
.h"
#include
"i
vas
_prot
_rend
.h"
#include
"i
sar
_rom_
post_rend
.h"
#include
"i
sar
_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
);
/*-------------------------------------------------------------------------
* i
vas
_splitBinPostRendOpen()
* i
sar
_splitBinPostRendOpen()
*
*
*------------------------------------------------------------------------*/
ivas_error
i
vas
_splitBinPostRendOpen
(
BIN_HR_SPLIT_POST_REND_HANDLE
*
hBinHrSplitPostRend
,
ivas_error
i
sar
_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
);
i
vas
_split_rend_init_huff_cfg
(
&
hBinRend
->
huff_cfg
);
i
sar
_split_rend_init_huff_cfg
(
&
hBinRend
->
huff_cfg
);
*
hBinHrSplitPostRend
=
hBinRend
;
return
IVAS_ERR_OK
;
...
...
@@ -117,13 +128,13 @@ ivas_error ivas_splitBinPostRendOpen(
/*-------------------------------------------------------------------------
* i
vas
_splitBinPostRendClose()
* i
sar
_splitBinPostRendClose()
*
*
*------------------------------------------------------------------------*/
void
i
vas
_splitBinPostRendClose
(
BIN_HR_SPLIT_POST_REND_HANDLE
*
hBinHrSplitPostRend
)
void
i
sar
_splitBinPostRendClose
(
ISAR_
BIN_HR_SPLIT_POST_REND_HANDLE
*
hBinHrSplitPostRend
)
{
int16_t
ch
;
...
...
@@ -165,14 +176,14 @@ void ivas_splitBinPostRendClose(
/*-----------------------------------------------------------------------------------------*
* Function i
vas
_split_rend_huffman_decode_opt()
* Function i
sar
_split_rend_huffman_decode_opt()
*
*
*-----------------------------------------------------------------------------------------*/
static
int16_t
i
vas
_split_rend_huffman_decode_opt
(
i
vas
_split_rend_huffman_cfg_t
*
huff_cfg
,
I
VAS
_SPLIT_REND_BITS_HANDLE
pBits
,
static
int16_t
i
sar
_split_rend_huffman_decode_opt
(
i
sar
_split_rend_huffman_cfg_t
*
huff_cfg
,
I
SAR
_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_bits
tream_read_int32
(
pBits
,
num_bits_read
);
code
|=
ISAR_SPLIT_REND_BITS
tream_read_int32
(
pBits
,
num_bits_read
);
}
if
(
code
==
code_b
)
...
...
@@ -211,15 +222,15 @@ static int16_t ivas_split_rend_huffman_decode_opt(
}
/*-----------------------------------------------------------------------------------------*
* Function i
vas
_split_rend_unquant_md()
* Function i
sar
_split_rend_unquant_md()
*
*
*-----------------------------------------------------------------------------------------*/
static
void
i
vas
_split_rend_unquant_md
(
BIN_HR_SPLIT_REND_MD_HANDLE
hMd
,
I
VAS
_SPLIT_REND_POSE_TYPE
pose_type
,
int16_t
real_only
,
static
void
i
sar
_split_rend_unquant_md
(
ISAR_
BIN_HR_SPLIT_REND_MD_HANDLE
hMd
,
I
SAR
_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
.
0
f
:
0
.
0
f
);
}
}
#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
(
I
VAS
_SPLIT_REND_D_1BYQ_STEP
*
I
VAS
_SPLIT_REND_D_MIN_VAL
);
gd_idx_min
=
(
int16_t
)
roundf
(
I
SAR
_SPLIT_REND_D_1BYQ_STEP
*
I
SAR
_SPLIT_REND_D_MIN_VAL
);
hMd
->
gd_idx
+=
gd_idx_min
;
hMd
->
gd
=
hMd
->
gd_idx
*
I
VAS
_SPLIT_REND_D_Q_STEP
;
hMd
->
gd
=
hMd
->
gd_idx
*
I
SAR
_SPLIT_REND_D_Q_STEP
;
}
else
if
(
pose_type
==
LR_GAIN_ONLY
)
{
gd_idx_min
=
(
int16_t
)
roundf
(
I
VAS
_SPLIT_REND_PITCH_G_1BYQ_STEP
*
I
VAS
_SPLIT_REND_PITCH_G_MIN_VAL
);
gd_idx_min
=
(
int16_t
)
roundf
(
I
SAR
_SPLIT_REND_PITCH_G_1BYQ_STEP
*
I
SAR
_SPLIT_REND_PITCH_G_MIN_VAL
);
hMd
->
gd_idx
+=
gd_idx_min
;
hMd
->
gd
=
hMd
->
gd_idx
*
I
VAS
_SPLIT_REND_PITCH_G_Q_STEP
;
hMd
->
gd
=
hMd
->
gd_idx
*
I
SAR
_SPLIT_REND_PITCH_G_Q_STEP
;
hMd
->
gd2_idx
+=
gd_idx_min
;
hMd
->
gd2
=
hMd
->
gd2_idx
*
I
VAS
_SPLIT_REND_PITCH_G_Q_STEP
;
hMd
->
gd2
=
hMd
->
gd2_idx
*
I
SAR
_SPLIT_REND_PITCH_G_Q_STEP
;
}
else
{
...
...
@@ -286,14 +320,14 @@ static void ivas_split_rend_unquant_md(
/*-----------------------------------------------------------------------------------------*
* Function i
vas
_splitBinPostRendMdBase2Dec()
* Function i
sar
_splitBinPostRendMdBase2Dec()
*
*
*-----------------------------------------------------------------------------------------*/
static
void
i
vas
_splitBinPostRendMdBase2Dec
(
I
VAS
_SPLIT_REND_BITS_HANDLE
pBits
,
BIN_HR_SPLIT_POST_REND_HANDLE
hBinHrSplitPostRend
,
static
void
i
sar
_splitBinPostRendMdBase2Dec
(
I
SAR
_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
==
I
VAS
_SPLIT_REND_PRED_63QUANT_PNTS
)
if
(
pred_quant_pnts_yaw
==
I
SAR
_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_bits
tream_read_int32
(
pBits
,
pred_code_len
);
code
=
(
int16_t
)
ISAR_SPLIT_REND_BITS
tream_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_bits
tream_read_int32
(
pBits
,
gd_code_len
);
code
=
(
int16_t
)
ISAR_SPLIT_REND_BITS
tream_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_bits
tream_read_int32
(
pBits
,
p_gd_code_len
);
code
=
(
int16_t
)
ISAR_SPLIT_REND_BITS
tream_read_int32
(
pBits
,
p_gd_code_len
);
hMd
->
gd_idx
=
code
+
min_p_gd_idx
;
code
=
(
int16_t
)
ivas_split_rend_bits
tream_read_int32
(
pBits
,
p_gd_code_len
);
code
=
(
int16_t
)
ISAR_SPLIT_REND_BITS
tream_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_bits
tream_read_int32
(
pBits
,
pred_roll_code_len
);
code
=
(
int16_t
)
ISAR_SPLIT_REND_BITS
tream_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 i
vas
_splitBinPostRendMdHuffDec()
* Function i
sar
_splitBinPostRendMdHuffDec()
*
*
*-----------------------------------------------------------------------------------------*/
static
void
i
vas
_splitBinPostRendMdHuffDec
(
I
VAS
_SPLIT_REND_BITS_HANDLE
pBits
,
BIN_HR_SPLIT_POST_REND_HANDLE
hBinHrSplitPostRend
,
static
void
i
sar
_splitBinPostRendMdHuffDec
(
I
SAR
_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
==
I
VAS
_SPLIT_REND_PRED_63QUANT_PNTS
)
if
(
pred_quant_pnts_yaw
==
I
SAR
_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
[(
I
VAS
_SPLIT_REND_ROLL_PRED_QUANT_PNTS
-
1
)
*
3
];
max_pred_roll_idx
=
(
int16_t
)
pHuff_cfg
->
pred_roll
.
codebook
[(
I
SAR
_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
]
);
}
}
i
vas
_SplitRenderer_getdiagdiff
(
sym_adj_idx
,
hMd
->
pred_mat_re_idx
,
1
,
min_pred_idx
,
max_pred_idx
);
i
sar
_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
]
);
}
}
i
vas
_SplitRenderer_getdiagdiff
(
sym_adj_idx
,
hMd
->
pred_mat_im_idx
,
-
1
,
min_pred_idx
,
max_pred_idx
);
i
sar
_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
=
i
vas
_split_rend_huffman_decode_opt
(
&
pHuff_cfg
->
p_gd
,
pBits
,
pHuff_cfg
->
p_gd_idx_trav
);
hMd
->
gd2_idx
=
i
sar
_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
);
}
}
i
vas
_SplitRenderer_getdiagdiff
(
sym_adj_idx
,
hMd
->
pred_mat_re_idx
,
1
,
min_pred_roll_idx
,
max_pred_roll_idx
);
i
sar
_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 i
vas
_splitBinPostRendMdDec()
* Function i
sar
_splitBinPostRendMdDec()
*
*
*-----------------------------------------------------------------------------------------*/
void
i
vas
_splitBinPostRendMdDec
(
I
VAS
_SPLIT_REND_BITS_HANDLE
pBits
,
BIN_HR_SPLIT_POST_REND_HANDLE
hBinHrSplitPostRend
,
void
i
sar
_splitBinPostRendMdDec
(
I
SAR
_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
[
I
VAS
_SPLIT_REND_NUM_QUANT_STRATS
];
float
pred_1byquantstep_yaw
[
I
VAS
_SPLIT_REND_NUM_QUANT_STRATS
];
float
pred_quantstep_yaw
[
I
VAS
_SPLIT_REND_NUM_QUANT_STRATS
];
int16_t
pred_quant_pnts_yaw
[
I
SAR
_SPLIT_REND_NUM_QUANT_STRATS
];
float
pred_1byquantstep_yaw
[
I
SAR
_SPLIT_REND_NUM_QUANT_STRATS
];
float
pred_quantstep_yaw
[
I
SAR
_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
i
vas
_renderSplitGetMultiBinPoseData
(
&
split_rend_config
,
pMultiBinPoseData
,
rot_axis
);
i
sar
_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
.
0
f
;
angle
=
(
int16_t
)
ivas_split_rend_bits
tream_read_int32
(
pBits
,
I
VAS
_SPLIT_REND_HEAD_POSE_BITS
);
angle
=
(
int16_t
)
ISAR_SPLIT_REND_BITS
tream_read_int32
(
pBits
,
I
SAR
_SPLIT_REND_HEAD_POSE_BITS
);
angle
-=
180
;
hBinHrSplitPostRend
->
QuaternionsPre
[
sf_idx
].
x
=
(
float
)
angle
;
angle
=
(
int16_t
)
ivas_split_rend_bits
tream_read_int32
(
pBits
,
I
VAS
_SPLIT_REND_HEAD_POSE_BITS
);
angle
=
(
int16_t
)
ISAR_SPLIT_REND_BITS
tream_read_int32
(
pBits
,
I
SAR
_SPLIT_REND_HEAD_POSE_BITS
);
angle
-=
180
;
hBinHrSplitPostRend
->
QuaternionsPre
[
sf_idx
].
y
=
(
float
)
angle
;
angle
=
(
int16_t
)
ivas_split_rend_bits
tream_read_int32
(
pBits
,
I
VAS
_SPLIT_REND_HEAD_POSE_BITS
);
angle
=
(
int16_t
)
ISAR_SPLIT_REND_BITS
tream_read_int32
(
pBits
,
I
SAR
_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_bits
tream_read_int32
(
pBits
,
1
);
quant_strat
=
ivas_split_rend_bits
tream_read_int32
(
pBits
,
quant_strat_bits
);
is_huff_coding
=
ISAR_SPLIT_REND_BITS
tream_read_int32
(
pBits
,
1
);
quant_strat
=
ISAR_SPLIT_REND_BITS
tream_read_int32
(
pBits
,
quant_strat_bits
);
if
(
is_huff_coding
==
0
)
{
i
vas
_splitBinPostRendMdBase2Dec
(
i
sar
_splitBinPostRendMdBase2Dec
(
pBits
,
hBinHrSplitPostRend
,
pMultiBinPoseData
,
num_subframes
,
...
...
@@ -640,7 +847,7 @@ void ivas_splitBinPostRendMdDec(
}
else
{
i
vas
_splitBinPostRendMdHuffDec
(
i
sar
_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
];
i
vas
_split_rend_unquant_md
(
hMd
,
PRED_ONLY
,
0
,
hBinHrSplitPostRend
->
fix_pos_rot_mat
[
pos_idx
],
pred_quantstep_yaw
[
quant_strat
]
);
i
sar
_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
];
i
vas
_split_rend_unquant_md
(
hMd
,
PRED_ONLY
,
1
,
hBinHrSplitPostRend
->
fix_pos_rot_mat
[
pos_idx
],
pred_quantstep_yaw
[
quant_strat
]
);
i
sar
_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
];
i
vas
_split_rend_unquant_md
(
hMd
,
COM_GAIN_ONLY
,
1
,
hBinHrSplitPostRend
->
fix_pos_rot_mat
[
pos_idx
],
0
);
i
sar
_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
];
i
vas
_split_rend_unquant_md
(
hMd
,
LR_GAIN_ONLY
,
1
,
hBinHrSplitPostRend
->
fix_pos_rot_mat
[
pos_idx
],
0
);
i
sar
_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
];
i
vas
_split_rend_unquant_md
(
hMd
,
PRED_ROLL_ONLY
,
0
,
hBinHrSplitPostRend
->
fix_pos_rot_mat
[
pos_idx
],
I
VAS
_SPLIT_REND_PRED_ROLL_Q_STEP
);
i
sar
_split_rend_unquant_md
(
hMd
,
PRED_ROLL_ONLY
,
0
,
hBinHrSplitPostRend
->
fix_pos_rot_mat
[
pos_idx
],
I
SAR
_SPLIT_REND_PRED_ROLL_Q_STEP
);
}
for
(
;
b
<
pred_real_bands_roll
[
quant_strat
];
b
++
)
{
hMd
=
&
hBinHrSplitPostRend
->
rot_md
[
pos_idx
][
sf_idx
][
b
];
i
vas
_split_rend_unquant_md
(
hMd
,
PRED_ROLL_ONLY
,
1
,
hBinHrSplitPostRend
->
fix_pos_rot_mat
[
pos_idx
],
I
VAS
_SPLIT_REND_PRED_ROLL_Q_STEP
);
i
sar
_split_rend_unquant_md
(
hMd
,
PRED_ROLL_ONLY
,
1
,
hBinHrSplitPostRend
->
fix_pos_rot_mat
[
pos_idx
],
I
SAR
_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
);
i
vas
_mat_mult_2by2_complex
(
mix_mat_re
,
mix_mat_im
,
mix_mat_re3
,
mix_mat_im3
,
mix_mat_re1
,
mix_mat_im1
);
i
sar
_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 i
vas
_SplitRenderer_PostRenderer()
* Function i
sar
_SplitRenderer_PostRenderer()
*
*
*-----------------------------------------------------------------------------------------*/
void
i
vas
_SplitRenderer_PostRenderer
(
BIN_HR_SPLIT_POST_REND_HANDLE
hBinPostRenderer
,
/* i/o: binaural renderer handle */
static
void
i
sar
_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
=
i
vas
_split_rend_band_grouping
;
const
int16_t
*
pBand_grouping
=
i
sar
_split_rend_band_grouping
;
num_md_bands
=
MAX_SPLIT_REND_MD_BANDS
;
push_wmops
(
"i
vas
_SplitRenderer_PostRenderer"
);
push_wmops
(
"i
sar
_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
.
0
f
)
/
MAX_PARAM_SPATIAL_SUBFRAMES
;
fade
=
min
(
fade
,
1
.
0
f
);
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"
);
i
vas
_log_cldfb2wav_data
(
i
sar
_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 i
vas
_rend_CldfbSplitPostRendProcessTdIn()
* Function i
sar
_rend_CldfbSplitPostRendProcessTdIn()
*
*
*-----------------------------------------------------------------------------------------*/
static
void
i
vas
_rend_CldfbSplitPostRendProcessTdIn
(
BIN_HR_SPLIT_POST_REND_HANDLE
hBinHrSplitPostRend
,
static
void
i
sar
_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(
}
}
i
vas
_SplitRenderer_PostRenderer
(
hBinHrSplitPostRend
,
pMultiBinPoseData
,
Cldfb_RealBuffer_Binaural
,
Cldfb_ImagBuffer_Binaural
,
QuaternionPost
);
i
sar
_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 i
vas
_rend_CldfbSplitPostRendProcess()
* Function i
sar
_rend_CldfbSplitPostRendProcess()
*
*
*-----------------------------------------------------------------------------------------*/
void
i
vas
_rend_CldfbSplitPostRendProcess
(
BIN_HR_SPLIT_POST_REND_HANDLE
hBinHrSplitPostRend
,
void
i
sar
_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
(
"i
vas
_rend_CldfbSplitPostRendProcess"
);
push_wmops
(
"i
sar
_rend_CldfbSplitPostRendProcess"
);
num_cldfb_bands
=
hBinHrSplitPostRend
->
cldfbSyn
[
0
]
->
no_channels
;
if
(
cldfb_in_flag
==
0
)
{
i
vas
_rend_CldfbSplitPostRendProcessTdIn
(
hBinHrSplitPostRend
,
pMultiBinPoseData
,
QuaternionPost
,
output
);
i
sar
_rend_CldfbSplitPostRendProcessTdIn
(
hBinHrSplitPostRend
,
pMultiBinPoseData
,
QuaternionPost
,
output
);
pop_wmops
();
return
;
}
i
vas
_SplitRenderer_PostRenderer
(
hBinHrSplitPostRend
,
pMultiBinPoseData
,
Cldfb_RealBuffer_Binaural
,
Cldfb_ImagBuffer_Binaural
,
QuaternionPost
);
i
sar
_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 i
vas
_init_split_post_rend_handles()
* Function i
sar
_init_split_post_rend_handles()
*
*
*-----------------------------------------------------------------------------------------*/
void
i
vas
_init_split_post_rend_handles
(
SPLIT_POST_REND_WRAPPER
*
hSplitRendWrapper
)
void
i
sar
_init_split_post_rend_handles
(
ISAR_
SPLIT_POST_REND_WRAPPER
*
hSplitRendWrapper
)
{
hSplitRendWrapper
->
hBinHrSplitPostRend
=
NULL
;
hSplitRendWrapper
->
hSplitBinLCLDDec
=
NULL
;
hSplitRendWrapper
->
hLc3plusDec
=
NULL
;
i
vas
_init_multi_bin_pose_data
(
&
hSplitRendWrapper
->
multiBinPoseData
);
i
sar
_init_multi_bin_pose_data
(
&
hSplitRendWrapper
->
multiBinPoseData
);
hSplitRendWrapper
->
first_good_frame_received
=
0
;
return
;
...
...
lib_
rend/ivas
_splitRendererPre.c
→
lib_
isar/isar
_splitRendererPre.c
View file @
bea683b3
...
...
@@ -39,9 +39,9 @@
#endif
#include
"ivas_prot.h"
#include
"prot.h"
#include
"i
vas_cnst
.h"
#include
"
ivas_rom_dec
.h"
#include
"i
vas
_prot
_rend
.h"
#include
"i
sar_rom_post_rend
.h"
#include
"
lib_isar_pre_rend
.h"
#include
"i
sar
_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
i
vas
_calc_mat_det_2by2_complex
(
static
void
i
sar
_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
i
vas
_is_mat_inv_2by2_complex
(
static
int16_t
i
sar
_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
;
i
vas
_calc_mat_det_2by2_complex
(
in_re
,
in_im
,
&
det_re
,
&
det_im
);
i
sar
_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
i
vas
_calc_mat_inv_2by2_complex
(
static
void
i
sar
_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
;
i
vas
_calc_mat_det_2by2_complex
(
in_re
,
in_im
,
&
det_re
,
&
det_im
);
i
sar
_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
.
0001
f
);
}
if
(
i
vas
_is_mat_inv_2by2_complex
(
cov_ii_local_re
,
cov_ii_im
)
)
if
(
i
sar
_is_mat_inv_2by2_complex
(
cov_ii_local_re
,
cov_ii_im
)
)
{
i
vas
_calc_mat_inv_2by2_complex
(
cov_ii_local_re
,
cov_ii_im
,
cov_ii_inv_re
,
cov_ii_inv_im
);
i
vas
_mat_mult_2by2_complex
(
cov_ii_inv_re
,
cov_ii_inv_im
,
cov_io_re
,
cov_io_im
,
pred_mat_re
,
pred_mat_im
);
i
sar
_calc_mat_inv_2by2_complex
(
cov_ii_local_re
,
cov_ii_im
,
cov_ii_inv_re
,
cov_ii_inv_im
);
i
sar
_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 */
i
vas
_mat_mult_2by2_complex
(
dmx_mat_conj_re
,
dmx_mat_conj_im
,
cov_ii_re
,
cov_ii_im
,
temp_mat_re
,
temp_mat_im
);
i
vas
_mat_mult_2by2_complex
(
temp_mat_re
,
temp_mat_im
,
pred_mat_re
,
pred_mat_im
,
postpred_cov_re
,
postpred_cov_im
);
i
sar
_mat_mult_2by2_complex
(
dmx_mat_conj_re
,
dmx_mat_conj_im
,
cov_ii_re
,
cov_ii_im
,
temp_mat_re
,
temp_mat_im
);
i
sar
_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
i
vas
_split_rend_huffman_encode
(
i
vas
_split_rend_huffman_cfg_t
*
huff_cfg
,
int16_t
in
,
static
void
i
sar
_split_rend_huffman_encode
(
i
sar
_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
i
vas
_split_rend_quant_md
(
BIN_HR_SPLIT_REND_MD_HANDLE
hMd
,
IVAS
_SPLIT_REND_POSE_TYPE
pose_type
,
int16_t
real_only
,
static
void
i
sar
_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
.
0
f
;
hMd
->
pred_mat_re
[
0
][
1
]
=
0
.
0
f
;
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
.
0
f
:
0
.
0
f
);
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
.
0
f
;
}
}
#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
(
I
VAS
_SPLIT_REND_PRED_MAX_VAL
,
max
(
quant_val
,
I
VAS
_SPLIT_REND_PRED_MIN_VAL
)
);
quant_val
=
min
(
I
SAR
_SPLIT_REND_PRED_MAX_VAL
,
max
(
quant_val
,
I
SAR
_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
(
I
VAS
_SPLIT_REND_PRED_MAX_VAL
,
max
(
hMd
->
pred_mat_im
[
ch1
][
ch2
],
I
VAS
_SPLIT_REND_PRED_MIN_VAL
)
);
quant_val
=
min
(
I
SAR
_SPLIT_REND_PRED_MAX_VAL
,
max
(
hMd
->
pred_mat_im
[
ch1
][
ch2
],
I
SAR
_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
(
I
VAS
_SPLIT_REND_D_MAX_VAL
,
max
(
hMd
->
gd
,
I
VAS
_SPLIT_REND_D_MIN_VAL
)
);
gd_idx_min
=
(
int16_t
)
roundf
(
I
VAS
_SPLIT_REND_D_1BYQ_STEP
*
I
VAS
_SPLIT_REND_D_MIN_VAL
);
hMd
->
gd_idx
=
(
int16_t
)
roundf
(
I
VAS
_SPLIT_REND_D_1BYQ_STEP
*
quant_val
);
hMd
->
gd
=
hMd
->
gd_idx
*
I
VAS
_SPLIT_REND_D_Q_STEP
;
quant_val
=
min
(
I
SAR
_SPLIT_REND_D_MAX_VAL
,
max
(
hMd
->
gd
,
I
SAR
_SPLIT_REND_D_MIN_VAL
)
);
gd_idx_min
=
(
int16_t
)
roundf
(
I
SAR
_SPLIT_REND_D_1BYQ_STEP
*
I
SAR
_SPLIT_REND_D_MIN_VAL
);
hMd
->
gd_idx
=
(
int16_t
)
roundf
(
I
SAR
_SPLIT_REND_D_1BYQ_STEP
*
quant_val
);
hMd
->
gd
=
hMd
->
gd_idx
*
I
SAR
_SPLIT_REND_D_Q_STEP
;
hMd
->
gd_idx
=
hMd
->
gd_idx
-
gd_idx_min
;
}
else
if
(
pose_type
==
LR_GAIN_ONLY
)
{
quant_val
=
min
(
I
VAS
_SPLIT_REND_PITCH_G_MAX_VAL
,
max
(
hMd
->
gd
,
I
VAS
_SPLIT_REND_PITCH_G_MIN_VAL
)
);
gd_idx_min
=
(
int16_t
)
roundf
(
I
VAS
_SPLIT_REND_PITCH_G_1BYQ_STEP
*
I
VAS
_SPLIT_REND_PITCH_G_MIN_VAL
);
hMd
->
gd_idx
=
(
int16_t
)
roundf
(
I
VAS
_SPLIT_REND_PITCH_G_1BYQ_STEP
*
quant_val
);
quant_val
=
min
(
I
SAR
_SPLIT_REND_PITCH_G_MAX_VAL
,
max
(
hMd
->
gd
,
I
SAR
_SPLIT_REND_PITCH_G_MIN_VAL
)
);
gd_idx_min
=
(
int16_t
)
roundf
(
I
SAR
_SPLIT_REND_PITCH_G_1BYQ_STEP
*
I
SAR
_SPLIT_REND_PITCH_G_MIN_VAL
);
hMd
->
gd_idx
=
(
int16_t
)
roundf
(
I
SAR
_SPLIT_REND_PITCH_G_1BYQ_STEP
*
quant_val
);
hMd
->
gd_idx
=
hMd
->
gd_idx
-
gd_idx_min
;
quant_val
=
min
(
I
VAS
_SPLIT_REND_PITCH_G_MAX_VAL
,
max
(
hMd
->
gd2
,
I
VAS
_SPLIT_REND_PITCH_G_MIN_VAL
)
);
hMd
->
gd2_idx
=
(
int16_t
)
roundf
(
I
VAS
_SPLIT_REND_PITCH_G_1BYQ_STEP
*
quant_val
);
quant_val
=
min
(
I
SAR
_SPLIT_REND_PITCH_G_MAX_VAL
,
max
(
hMd
->
gd2
,
I
SAR
_SPLIT_REND_PITCH_G_MIN_VAL
)
);
hMd
->
gd2_idx
=
(
int16_t
)
roundf
(
I
SAR
_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
.
0
f
;
}
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
I
VAS
_SPLIT_REND_POSE_TYPE
pose_type
,
ISAR_
BIN_HR_SPLIT_REND_MD_HANDLE
hMd
,
const
I
SAR
_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
.
0
f
;
hMd
->
pred_mat_re
[
0
][
1
]
=
0
.
0
f
;
}
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
.
0
f
/
(
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
[
I
VAS
_SPLIT_REND_NUM_QUANT_STRATS
],
const
int16_t
pred_imag_bands_yaw
[
I
VAS
_SPLIT_REND_NUM_QUANT_STRATS
],
int16_t
pred_quant_pnts_yaw
[
I
VAS
_SPLIT_REND_NUM_QUANT_STRATS
],
const
int16_t
d_bands_yaw
[
I
VAS
_SPLIT_REND_NUM_QUANT_STRATS
],
const
int16_t
bands_pitch
[
I
VAS
_SPLIT_REND_NUM_QUANT_STRATS
],
const
int16_t
pred_real_bands_roll
[
I
VAS
_SPLIT_REND_NUM_QUANT_STRATS
],
const
int16_t
pred_imag_bands_roll
[
I
VAS
_SPLIT_REND_NUM_QUANT_STRATS
],
int32_t
base2bits
[
I
VAS
_SPLIT_REND_NUM_QUANT_STRATS
]
)
const
int16_t
pred_real_bands_yaw
[
I
SAR
_SPLIT_REND_NUM_QUANT_STRATS
],
const
int16_t
pred_imag_bands_yaw
[
I
SAR
_SPLIT_REND_NUM_QUANT_STRATS
],
int16_t
pred_quant_pnts_yaw
[
I
SAR
_SPLIT_REND_NUM_QUANT_STRATS
],
const
int16_t
d_bands_yaw
[
I
SAR
_SPLIT_REND_NUM_QUANT_STRATS
],
const
int16_t
bands_pitch
[
I
SAR
_SPLIT_REND_NUM_QUANT_STRATS
],
const
int16_t
pred_real_bands_roll
[
I
SAR
_SPLIT_REND_NUM_QUANT_STRATS
],
const
int16_t
pred_imag_bands_roll
[
I
SAR
_SPLIT_REND_NUM_QUANT_STRATS
],
int32_t
base2bits
[
I
SAR
_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
[
I
VAS
_SPLIT_REND_NUM_QUANT_STRATS
];
int16_t
pred_yaw_bits
[
I
SAR
_SPLIT_REND_NUM_QUANT_STRATS
];
I
VAS
_SPLIT_REND_POSE_TYPE
pose_type
;
I
SAR
_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
(
I
VAS
_SPLIT_REND_ROLL_PRED_QUANT_PNTS
)
);
pred_roll_bits
=
(
int16_t
)
ceilf
(
log2f
(
I
SAR
_SPLIT_REND_ROLL_PRED_QUANT_PNTS
)
);
d_gain_bits
=
(
int16_t
)
ceilf
(
log2f
(
I
VAS
_SPLIT_REND_D_QUANT_PNTS
)
);
d_gain_bits
=
(
int16_t
)
ceilf
(
log2f
(
I
SAR
_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
i
vas
_SplitRenderer_code_md_base2
(
const
BIN_HR_SPLIT_PRE_REND_HANDLE
hBinHrSplitPreRend
,
static
void
i
sar
_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
,
I
VAS
_SPLIT_REND_BITS_HANDLE
pBits
)
I
SAR
_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
==
I
VAS
_SPLIT_REND_PRED_63QUANT_PNTS
)
if
(
pred_quant_pnts_yaw
==
I
SAR
_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_bits
tream_write_int32
(
pBits
,
code
,
pred_code_len
);
ISAR_SPLIT_REND_BITS
tream_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_bits
tream_write_int32
(
pBits
,
code
,
pred_code_len
);
ISAR_SPLIT_REND_BITS
tream_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_bits
tream_write_int32
(
pBits
,
code
,
gd_code_len
);
ISAR_SPLIT_REND_BITS
tream_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_bits
tream_write_int32
(
pBits
,
code
,
p_gd_code_len
);
ISAR_SPLIT_REND_BITS
tream_write_int32
(
pBits
,
code
,
p_gd_code_len
);
code
=
hMd
->
gd2_idx
-
min_p_gd_idx
;
ivas_split_rend_bits
tream_write_int32
(
pBits
,
code
,
p_gd_code_len
);
ISAR_SPLIT_REND_BITS
tream_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_bits
tream_write_int32
(
pBits
,
code
,
pred_roll_code_len
);
ISAR_SPLIT_REND_BITS
tream_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
i
vas
_SplitRenderer_code_md_huff
(
const
BIN_HR_SPLIT_PRE_REND_HANDLE
hBinHrSplitPreRend
,
static
void
i
sar
_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
,
I
VAS
_SPLIT_REND_BITS_HANDLE
pBits
)
I
SAR
_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
==
I
VAS
_SPLIT_REND_PRED_63QUANT_PNTS
)
if
(
pred_quant_pnts_yaw
==
I
SAR
_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
[(
I
VAS
_SPLIT_REND_ROLL_PRED_QUANT_PNTS
-
1
)
*
3
];
max_pred_roll_idx
=
(
int16_t
)
pHuff_cfg
->
pred_roll
.
codebook
[(
I
SAR
_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
];
i
vas
_SplitRenderer_getdiagdiff
(
hMd
->
pred_mat_re_idx
,
sym_adj_idx
,
-
1
,
min_pred_idx
,
max_pred_idx
);
i
sar
_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
++
)
{
i
vas
_split_rend_huffman_encode
(
&
pHuff_cfg
->
pred
[
pred_cb_idx
],
sym_adj_idx
[
ch1
][
ch2
],
&
code
,
&
len
);
ivas_split_rend_bits
tream_write_int32
(
pBits
,
code
,
len
);
i
sar
_split_rend_huffman_encode
(
&
pHuff_cfg
->
pred
[
pred_cb_idx
],
sym_adj_idx
[
ch1
][
ch2
],
&
code
,
&
len
);
ISAR_SPLIT_REND_BITS
tream_write_int32
(
pBits
,
code
,
len
);
}
}
}
for
(
b
=
0
;
b
<
pred_imag_bands_yaw
;
b
++
)
{
hMd
=
&
hBinHrSplitPreRend
->
rot_md
[
pos_idx
][
sf_idx
][
b
];
i
vas
_SplitRenderer_getdiagdiff
(
hMd
->
pred_mat_im_idx
,
sym_adj_idx
,
1
,
min_pred_idx
,
max_pred_idx
);
i
sar
_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
];
i
vas
_split_rend_huffman_encode
(
&
pHuff_cfg
->
gd
,
hMd
->
gd_idx
,
&
code
,
&
len
);
ivas_split_rend_bits
tream_write_int32
(
pBits
,
code
,
len
);
i
sar
_split_rend_huffman_encode
(
&
pHuff_cfg
->
gd
,
hMd
->
gd_idx
,
&
code
,
&
len
);
ISAR_SPLIT_REND_BITS
tream_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
];
i
vas
_split_rend_huffman_encode
(
&
pHuff_cfg
->
p_gd
,
hMd
->
gd_idx
,
&
code
,
&
len
);
ivas_split_rend_bits
tream_write_int32
(
pBits
,
code
,
len
);
i
sar
_split_rend_huffman_encode
(
&
pHuff_cfg
->
p_gd
,
hMd
->
gd_idx
,
&
code
,
&
len
);
ISAR_SPLIT_REND_BITS
tream_write_int32
(
pBits
,
code
,
len
);
i
vas
_split_rend_huffman_encode
(
&
pHuff_cfg
->
p_gd
,
hMd
->
gd2_idx
,
&
code
,
&
len
);
ivas_split_rend_bits
tream_write_int32
(
pBits
,
code
,
len
);
i
sar
_split_rend_huffman_encode
(
&
pHuff_cfg
->
p_gd
,
hMd
->
gd2_idx
,
&
code
,
&
len
);
ISAR_SPLIT_REND_BITS
tream_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
++
)
{
i
vas
_split_rend_huffman_encode
(
&
pHuff_cfg
->
pred_roll
,
sym_adj_idx
[
ch1
][
ch2
],
&
code
,
&
len
);
ivas_split_rend_bits
tream_write_int32
(
pBits
,
code
,
len
);
i
sar
_split_rend_huffman_encode
(
&
pHuff_cfg
->
pred_roll
,
sym_adj_idx
[
ch1
][
ch2
],
&
code
,
&
len
);
ISAR_SPLIT_REND_BITS
tream_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
i
vas
_SplitRenderer_quant_code
(
const
BIN_HR_SPLIT_PRE_REND_HANDLE
hBinHrSplitPreRend
,
static
void
i
sar
_SplitRenderer_quant_code
(
const
ISAR_
BIN_HR_SPLIT_PRE_REND_HANDLE
hBinHrSplitPreRend
,
const
IVAS_QUATERNION
headPosition
,
MULTI_BIN_REND_POSE_DATA
*
pMultiBinPoseData
,
I
VAS
_SPLIT_REND_BITS_HANDLE
pBits
,
I
SAR
_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_bits
tream_write_int32
(
pBits
,
angle
,
I
VAS
_SPLIT_REND_HEAD_POSE_BITS
);
ISAR_SPLIT_REND_BITS
tream_write_int32
(
pBits
,
angle
,
I
SAR
_SPLIT_REND_HEAD_POSE_BITS
);
angle
=
(
int16_t
)
roundf
(
head_pos_euler
.
y
);
angle
+=
180
;
ivas_split_rend_bits
tream_write_int32
(
pBits
,
angle
,
I
VAS
_SPLIT_REND_HEAD_POSE_BITS
);
ISAR_SPLIT_REND_BITS
tream_write_int32
(
pBits
,
angle
,
I
SAR
_SPLIT_REND_HEAD_POSE_BITS
);
angle
=
(
int16_t
)
roundf
(
head_pos_euler
.
z
);
angle
+=
180
;
ivas_split_rend_bits
tream_write_int32
(
pBits
,
angle
,
I
VAS
_SPLIT_REND_HEAD_POSE_BITS
);
ISAR_SPLIT_REND_BITS
tream_write_int32
(
pBits
,
angle
,
I
SAR
_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
];
i
vas
_split_rend_quant_md
(
hMd
,
PRED_ONLY
,
0
,
hBinHrSplitPreRend
->
fix_pos_rot_mat
[
pos_idx
],
pred_1byquantstep_yaw
[
q
]
);
i
sar
_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
];
i
vas
_split_rend_quant_md
(
hMd
,
PRED_ONLY
,
1
,
hBinHrSplitPreRend
->
fix_pos_rot_mat
[
pos_idx
],
pred_1byquantstep_yaw
[
q
]
);
i
sar
_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
];
i
vas
_split_rend_quant_md
(
hMd
,
COM_GAIN_ONLY
,
1
,
hBinHrSplitPreRend
->
fix_pos_rot_mat
[
pos_idx
],
0
);
i
sar
_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
];
i
vas
_split_rend_quant_md
(
hMd
,
LR_GAIN_ONLY
,
1
,
hBinHrSplitPreRend
->
fix_pos_rot_mat
[
pos_idx
],
0
);
i
sar
_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
];
i
vas
_split_rend_quant_md
(
hMd
,
PRED_ROLL_ONLY
,
0
,
hBinHrSplitPreRend
->
fix_pos_rot_mat
[
pos_idx
],
I
VAS
_SPLIT_REND_PRED_ROLL_1BYQ_STEP
);
i
sar
_split_rend_quant_md
(
hMd
,
PRED_ROLL_ONLY
,
0
,
hBinHrSplitPreRend
->
fix_pos_rot_mat
[
pos_idx
],
I
SAR
_SPLIT_REND_PRED_ROLL_1BYQ_STEP
);
}
for
(
;
b
<
pred_real_bands_roll
[
q
];
b
++
)
{
hMd
=
&
hBinHrSplitPreRend
->
rot_md
[
pos_idx
][
sf_idx
][
b
];
i
vas
_split_rend_quant_md
(
hMd
,
PRED_ROLL_ONLY
,
1
,
hBinHrSplitPreRend
->
fix_pos_rot_mat
[
pos_idx
],
I
VAS
_SPLIT_REND_PRED_ROLL_1BYQ_STEP
);
i
sar
_split_rend_quant_md
(
hMd
,
PRED_ROLL_ONLY
,
1
,
hBinHrSplitPreRend
->
fix_pos_rot_mat
[
pos_idx
],
I
SAR
_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_bits
tream_write_int32
(
pBits
,
1
,
1
);
ivas_split_rend_bits
tream_write_int32
(
pBits
,
q
,
quant_strat_bits
);
ISAR_SPLIT_REND_BITS
tream_write_int32
(
pBits
,
1
,
1
);
ISAR_SPLIT_REND_BITS
tream_write_int32
(
pBits
,
q
,
quant_strat_bits
);
huff_bits
=
pBits
->
bits_written
;
i
vas
_SplitRenderer_code_md_huff
(
i
sar
_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_bits
tream_write_int32
(
pBits
,
0
,
1
);
ivas_split_rend_bits
tream_write_int32
(
pBits
,
q
,
quant_strat_bits
);
ISAR_SPLIT_REND_BITS
tream_write_int32
(
pBits
,
0
,
1
);
ISAR_SPLIT_REND_BITS
tream_write_int32
(
pBits
,
q
,
quant_strat_bits
);
i
vas
_SplitRenderer_code_md_base2
(
hBinHrSplitPreRend
,
pMultiBinPoseData
,
num_subframes
,
pred_real_bands_yaw
[
q
],
pred_imag_bands_yaw
[
q
],
i
sar
_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 i
vas
_SplitRenderer_GetRotMd()
* Function i
sar
_SplitRenderer_GetRotMd()
*
*
*------------------------------------------------------------------------*/
void
i
vas
_SplitRenderer_GetRotMd
(
BIN_HR_SPLIT_PRE_REND_HANDLE
hBinHrSplitPreRend
,
/* i/o: binaural renderer handle */
static
void
i
sar
_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
=
i
vas
_split_rend_band_grouping
;
const
int16_t
*
pBand_grouping
=
i
sar
_split_rend_band_grouping
;
push_wmops
(
"i
vas
_SplitRenderer_GetRotMd"
);
push_wmops
(
"i
sar
_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 i
vas
_rend_CldfbSplitPreRendProcess()
* Function i
sar
_rend_CldfbSplitPreRendProcess()
*
*
*------------------------------------------------------------------------*/
void
i
vas
_rend_CldfbSplitPreRendProcess
(
const
BIN_HR_SPLIT_PRE_REND_HANDLE
hBinHrSplitPreRend
,
void
i
sar
_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
],
I
VAS
_SPLIT_REND_BITS_HANDLE
pBits
,
I
SAR
_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
(
"i
vas
_rend_CldfbSplitPreRendProcess"
);
push_wmops
(
"i
sar
_rend_CldfbSplitPreRendProcess"
);
i
vas
_SplitRenderer_GetRotMd
(
hBinHrSplitPreRend
,
pMultiBinPoseData
,
Cldfb_In_BinReal
,
Cldfb_In_BinImag
,
low_res_pre_rend_rot
,
ro_md_flag
);
i
sar
_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
);
i
vas
_rend_CldfbSplitPostRendProcess
(
hBinHrSplitPreRend
->
hBinHrSplitPostRend
,
pMultiBinPoseData
,
QuaternionsPost
[
0
],
Cldfb_RealBuffer_Binaural_5ms
,
Cldfb_ImagBuffer_Binaural_5ms
,
tmpCrendBuffer
,
1
);
i
sar
_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 i
vas
_splitBinPreRendOpen()
* Function i
sar
_splitBinPreRendOpen()
*
*
*------------------------------------------------------------------------*/
ivas_error
i
vas
_splitBinPreRendOpen
(
BIN_HR_SPLIT_PRE_REND_HANDLE
*
hBinHrSplitPreRend
,
ivas_error
i
sar
_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
);
i
vas
_split_rend_init_huff_cfg
(
&
hBinRend
->
huff_cfg
);
i
sar
_split_rend_init_huff_cfg
(
&
hBinRend
->
huff_cfg
);
#ifdef SPLIT_POSE_CORRECTION_DEBUG
ivas_error
error
;
if
(
(
error
=
i
vas
_splitBinPostRendOpen
(
&
hBinRend
->
hBinHrSplitPostRend
,
pMultiBinPoseData
,
48000
)
)
!=
IVAS_ERR_OK
)
if
(
(
error
=
i
sar
_splitBinPostRendOpen
(
&
hBinRend
->
hBinHrSplitPostRend
,
pMultiBinPoseData
,
48000
)
)
!=
IVAS_ERR_OK
)
{
return
error
;
}
...
...
@@ -1558,13 +1818,13 @@ ivas_error ivas_splitBinPreRendOpen(
/*-------------------------------------------------------------------------
* Function i
vas
_splitBinPreRendClose()
* Function i
sar
_splitBinPreRendClose()
*
*
*------------------------------------------------------------------------*/
void
i
vas
_splitBinPreRendClose
(
BIN_HR_SPLIT_PRE_REND_HANDLE
*
hBinHrSplitPreRend
)
void
i
sar
_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
i
vas
_splitBinPostRendClose
(
&
(
*
hBinHrSplitPreRend
)
->
hBinHrSplitPostRend
);
i
sar
_splitBinPostRendClose
(
&
(
*
hBinHrSplitPreRend
)
->
hBinHrSplitPostRend
);
#endif
free
(
(
*
hBinHrSplitPreRend
)
);
...
...
@@ -1597,27 +1857,28 @@ void ivas_splitBinPreRendClose(
/*-------------------------------------------------------------------------*
* i
vas
_set_split_rend_ht_setup()
* i
sar
_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
&&
hSplit
BinR
end
->
splitrend
.
multiBinPoseData
.
poseCorrectionMode
==
I
VAS
_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB
)
if
(
hSplit
r
end
->
multiBinPoseData
.
poseCorrectionMode
==
I
SAR
_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 i
vas
_init_split_rend_handles()
* Function i
sar
_init_split_rend_handles()
*
*
*------------------------------------------------------------------------*/
void
i
vas
_init_split_rend_handles
(
void
i
sar
_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
;
i
vas
_init_multi_bin_pose_data
(
&
hSplitRendWrapper
->
multiBinPoseData
);
i
sar
_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
I
VAS
_SPLIT_REND_CONFIG_DATA
*
pSplitRendConfig
,
const
I
SAR
_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
=
I
VAS
_LC3PLUS_ENC_GetDelay
(
hSplitRendWrapper
->
hLc3plusEnc
,
&
hSplitRendWrapper
->
lc3plusDelaySamples
)
)
!=
IVAS_ERR_OK
)
if
(
(
error
=
I
SAR
_LC3PLUS_ENC_GetDelay
(
hSplitRendWrapper
->
hLc3plusEnc
,
&
hSplitRendWrapper
->
lc3plusDelaySamples
)
)
!=
IVAS_ERR_OK
)
{
return
error
;
}
/* Alocate buffers for delay compensation */
if
(
pSplitRendConfig
->
codec
==
I
VAS
_SPLIT_REND_CODEC_LC3PLUS
)
if
(
pSplitRendConfig
->
codec
==
I
SAR
_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
_r
end
erer_open
()
* Function split
R
end
Lc3plusEncodeAndWrite
()
*
*
*------------------------------------------------------------------------*/
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_bits
tream_write_int32
(
pBits
,
0L
,
1
);
ISAR_SPLIT_REND_BITS
tream_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
=
I
VAS
_SPLIT_REND_CODEC_LC3PLUS
;
pBits
->
codec
=
I
SAR
_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 i
vas
_renderMultiTDBinToSplitBinaural()
* Function i
sar
_renderMultiTDBinToSplitBinaural()
*
*
*------------------------------------------------------------------------*/
static
ivas_error
i
vas
_renderMultiTDBinToSplitBinaural
(
ivas_error
i
sar
_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
,
I
VAS
_SPLIT_REND_BITS_HANDLE
pBits
,
I
SAR
_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
(
"i
vas
_renderMultiTDBinToSplitBinaural"
);
push_wmops
(
"i
sar
_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
==
I
VAS
_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB
)
?
CLDFB_NO_COL_MAX
:
(
hSplitBin
->
hSplitBinLCLDEnc
->
iNumBlocks
*
hSplitBin
->
hSplitBinLCLDEnc
->
iNumIterations
);
num_slots
=
(
hSplitBin
->
multiBinPoseData
.
poseCorrectionMode
==
I
SAR
_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
==
I
VAS
_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB
)
if
(
hSplitBin
->
multiBinPoseData
.
poseCorrectionMode
==
I
SAR
_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB
)
{
target_md_bits
=
i
vas
_get_split_rend_md_target_brate
(
SplitRendBitRate
,
pcm_out_flag
)
*
L_FRAME48k
/
48000
;
target_md_bits
=
i
sar
_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
i
vas
_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
);
i
sar
_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
?
I
VAS
_SPLIT_REND_CODEC_LC3PLUS
:
I
VAS
_SPLIT_REND_CODEC_LCLD
;
pBits
->
codec
=
useLc3plus
?
I
SAR
_SPLIT_REND_CODEC_LC3PLUS
:
I
SAR
_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
i
vas
_splitBinLCLDEncProcess
(
hSplitBin
->
hSplitBinLCLDEnc
,
Cldfb_In_BinReal
,
Cldfb_In_BinImag
,
available_bits
,
pBits
);
i
sar
_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
=
I
VAS
_SPLIT_REND_CODEC_NONE
;
pBits
->
codec
=
I
SAR
_SPLIT_REND_CODEC_NONE
;
}
/*zero pad*/
...
...
@@ -2193,14 +2262,14 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural(
}
else
{
bit_len
=
hSplitBin
->
hLc3plusEnc
->
config
.
i
vas
_frame_duration_us
/
1000
;
bit_len
=
hSplitBin
->
hLc3plusEnc
->
config
.
i
sar
_frame_duration_us
/
1000
;
bit_len
=
SplitRendBitRate
*
bit_len
/
1000
;
}
}
while
(
pBits
->
bits_written
<
bit_len
)
{
ivas_split_rend_bits
tream_write_int32
(
pBits
,
0L
,
1
);
ISAR_SPLIT_REND_BITS
tream_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
lib_
rend/ivas
_splitRenderer_utils.c
→
lib_
isar/isar
_splitRenderer_utils.c
View file @
bea683b3
...
...
@@ -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 i
vas
_mat_mult_2by2_complex()
* Function i
sar
_mat_mult_2by2_complex()
*
*
*------------------------------------------------------------------------*/
void
i
vas
_mat_mult_2by2_complex
(
void
i
sar
_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_bits
tream_init()
* Function
ISAR_SPLIT_REND_BITS
tream_init()
*
*
*------------------------------------------------------------------------*/
void
ivas_split_rend_bits
tream_init
(
I
VAS
_SPLIT_REND_BITS_HANDLE
pBits
,
void
ISAR_SPLIT_REND_BITS
tream_init
(
I
SAR
_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 i
vas
_split_rend_huffman_dec_init_min_max_len()
* Function i
sar
_split_rend_huffman_dec_init_min_max_len()
*
*
*------------------------------------------------------------------------*/
void
i
vas
_split_rend_huffman_dec_init_min_max_len
(
i
vas
_split_rend_huffman_cfg_t
*
p_huff_cfg
)
void
i
sar
_split_rend_huffman_dec_init_min_max_len
(
i
sar
_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 i
vas
_split_huff_get_idx_trav_list()
* Function i
sar
_split_huff_get_idx_trav_list()
*
*
*------------------------------------------------------------------------*/
static
void
i
vas
_split_huff_get_idx_trav_list
(
static
void
i
sar
_split_huff_get_idx_trav_list
(
int16_t
*
idx_list
,
i
vas
_split_rend_huffman_cfg_t
*
p_huff_cfg
)
i
sar
_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 i
vas
_split_rend_init_huff_cfg()
* Function i
sar
_split_rend_init_huff_cfg()
*
*
*------------------------------------------------------------------------*/
void
i
vas
_split_rend_init_huff_cfg
(
BIN_HR_SPLIT_REND_HUFF_HANDLE
pHuff_cfg
)
void
i
sar
_split_rend_init_huff_cfg
(
ISAR_
BIN_HR_SPLIT_REND_HUFF_HANDLE
pHuff_cfg
)
{
pHuff_cfg
->
pred
[
0
].
codebook
=
&
i
vas
_split_rend_huff_pred31_consts
[
0
][
0
];
pHuff_cfg
->
pred
[
0
].
sym_len
=
I
VAS
_SPLIT_REND_PRED_31QUANT_PNTS
;
i
vas
_split_rend_huffman_dec_init_min_max_len
(
&
pHuff_cfg
->
pred
[
0
]
);
i
vas
_split_huff_get_idx_trav_list
(
pHuff_cfg
->
pred_idx_trav
[
0
],
&
pHuff_cfg
->
pred
[
0
]
);
pHuff_cfg
->
pred
[
0
].
codebook
=
&
i
sar
_split_rend_huff_pred31_consts
[
0
][
0
];
pHuff_cfg
->
pred
[
0
].
sym_len
=
I
SAR
_SPLIT_REND_PRED_31QUANT_PNTS
;
i
sar
_split_rend_huffman_dec_init_min_max_len
(
&
pHuff_cfg
->
pred
[
0
]
);
i
sar
_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
=
&
i
vas
_split_rend_huff_pred63_consts
[
0
][
0
];
pHuff_cfg
->
pred
[
1
].
sym_len
=
I
VAS
_SPLIT_REND_PRED_63QUANT_PNTS
;
i
vas
_split_rend_huffman_dec_init_min_max_len
(
&
pHuff_cfg
->
pred
[
1
]
);
i
vas
_split_huff_get_idx_trav_list
(
pHuff_cfg
->
pred_idx_trav
[
1
],
&
pHuff_cfg
->
pred
[
1
]
);
pHuff_cfg
->
pred
[
1
].
codebook
=
&
i
sar
_split_rend_huff_pred63_consts
[
0
][
0
];
pHuff_cfg
->
pred
[
1
].
sym_len
=
I
SAR
_SPLIT_REND_PRED_63QUANT_PNTS
;
i
sar
_split_rend_huffman_dec_init_min_max_len
(
&
pHuff_cfg
->
pred
[
1
]
);
i
sar
_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
=
&
i
vas
_split_rend_huff_roll_pred_consts
[
0
][
0
];
pHuff_cfg
->
pred_roll
.
sym_len
=
I
VAS
_SPLIT_REND_ROLL_PRED_QUANT_PNTS
;
i
vas
_split_rend_huffman_dec_init_min_max_len
(
&
pHuff_cfg
->
pred_roll
);
i
vas
_split_huff_get_idx_trav_list
(
pHuff_cfg
->
pred_roll_idx_trav
,
&
pHuff_cfg
->
pred_roll
);
pHuff_cfg
->
pred_roll
.
codebook
=
&
i
sar
_split_rend_huff_roll_pred_consts
[
0
][
0
];
pHuff_cfg
->
pred_roll
.
sym_len
=
I
SAR
_SPLIT_REND_ROLL_PRED_QUANT_PNTS
;
i
sar
_split_rend_huffman_dec_init_min_max_len
(
&
pHuff_cfg
->
pred_roll
);
i
sar
_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
=
&
i
vas
_split_rend_huff_d_consts
[
0
][
0
];
pHuff_cfg
->
gd
.
sym_len
=
I
VAS
_SPLIT_REND_D_QUANT_PNTS
;
i
vas
_split_rend_huffman_dec_init_min_max_len
(
&
pHuff_cfg
->
gd
);
i
vas
_split_huff_get_idx_trav_list
(
pHuff_cfg
->
gd_idx_trav
,
&
pHuff_cfg
->
gd
);
pHuff_cfg
->
gd
.
codebook
=
&
i
sar
_split_rend_huff_d_consts
[
0
][
0
];
pHuff_cfg
->
gd
.
sym_len
=
I
SAR
_SPLIT_REND_D_QUANT_PNTS
;
i
sar
_split_rend_huffman_dec_init_min_max_len
(
&
pHuff_cfg
->
gd
);
i
sar
_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
=
&
i
vas
_split_rend_huff_p_d_consts
[
0
][
0
];
pHuff_cfg
->
p_gd
.
sym_len
=
I
VAS
_SPLIT_REND_D_QUANT_PNTS
;
i
vas
_split_rend_huffman_dec_init_min_max_len
(
&
pHuff_cfg
->
p_gd
);
i
vas
_split_huff_get_idx_trav_list
(
pHuff_cfg
->
p_gd_idx_trav
,
&
pHuff_cfg
->
p_gd
);
pHuff_cfg
->
p_gd
.
codebook
=
&
i
sar
_split_rend_huff_p_d_consts
[
0
][
0
];
pHuff_cfg
->
p_gd
.
sym_len
=
I
SAR
_SPLIT_REND_D_QUANT_PNTS
;
i
sar
_split_rend_huffman_dec_init_min_max_len
(
&
pHuff_cfg
->
p_gd
);
i
sar
_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
=
&
i
vas
_split_rend_huff_p_d_diff_consts
[
0
][
0
];
pHuff_cfg
->
p_gd_diff
.
sym_len
=
I
VAS
_SPLIT_REND_D_QUANT_PNTS
;
i
vas
_split_rend_huffman_dec_init_min_max_len
(
&
pHuff_cfg
->
p_gd_diff
);
i
vas
_split_huff_get_idx_trav_list
(
pHuff_cfg
->
p_gd_diff_idx_trav
,
&
pHuff_cfg
->
p_gd_diff
);
pHuff_cfg
->
p_gd_diff
.
codebook
=
&
i
sar
_split_rend_huff_p_d_diff_consts
[
0
][
0
];
pHuff_cfg
->
p_gd_diff
.
sym_len
=
I
SAR
_SPLIT_REND_D_QUANT_PNTS
;
i
sar
_split_rend_huffman_dec_init_min_max_len
(
&
pHuff_cfg
->
p_gd_diff
);
i
sar
_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
(
I
VAS
_SPLIT_REND_POSE_TYPE
pose_type
[
MAX_HEAD_ROT_POSES
-
1
],
I
SAR
_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 i
vas
_SplitRenderer_getdiagdiff()
* Function i
sar
_SplitRenderer_getdiagdiff()
*
*
*------------------------------------------------------------------------*/
void
i
vas
_SplitRenderer_getdiagdiff
(
void
i
sar
_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_bits
tream_read_int32()
* Function
ISAR_SPLIT_REND_BITS
tream_read_int32()
*
*
*------------------------------------------------------------------------*/
int32_t
ivas_split_rend_bits
tream_read_int32
(
I
VAS
_SPLIT_REND_BITS_HANDLE
pBits
,
int32_t
ISAR_SPLIT_REND_BITS
tream_read_int32
(
I
SAR
_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_bits
tream_write_int32()
* Function
ISAR_SPLIT_REND_BITS
tream_write_int32()
*
*
*------------------------------------------------------------------------*/
void
ivas_split_rend_bits
tream_write_int32
(
I
VAS
_SPLIT_REND_BITS_HANDLE
pBits
,
void
ISAR_SPLIT_REND_BITS
tream_write_int32
(
I
SAR
_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
/*-------------------------------------------------------------------------
* i
vas_mat_mult_2by2_complex
()
* i
sar_log_cldfb2wav_data
()
*
*
*------------------------------------------------------------------------*/
void
i
vas
_log_cldfb2wav_data
(
void
i
sar
_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 i
vas
_get_split_rend_md_target_brate()
* Function i
sar
_get_split_rend_md_target_brate()
*
*
*------------------------------------------------------------------------*/
int32_t
i
vas
_get_split_rend_md_target_brate
(
int32_t
i
sar
_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 i
vas
_get_lcld_bitrate()
* Function i
sar
_get_lcld_bitrate()
*
*
*------------------------------------------------------------------------*/
int32_t
i
vas
_get_lcld_bitrate
(
int32_t
i
sar
_get_lcld_bitrate
(
const
int32_t
SplitRendBitRate
,
const
I
VAS
_SPLIT_REND_POSE_CORRECTION_MODE
poseCorrectionMode
)
const
I
SAR
_SPLIT_REND_POSE_CORRECTION_MODE
poseCorrectionMode
)
{
if
(
poseCorrectionMode
==
I
VAS
_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB
)
if
(
poseCorrectionMode
==
I
SAR
_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB
)
{
switch
(
SplitRendBitRate
)
{
...
...
@@ -570,24 +564,25 @@ int32_t ivas_get_lcld_bitrate(
}
#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS
/*-------------------------------------------------------------------------
* Function i
vas
_get_lc3plus_bitrate()
* Function i
sar
_get_lc3plus_bitrate()
*
*
*------------------------------------------------------------------------*/
int32_t
i
vas
_get_lc3plus_bitrate
(
int32_t
i
sar
_get_lc3plus_bitrate
(
const
int32_t
SplitRendBitRate
,
I
VAS
_SPLIT_REND_POSE_CORRECTION_MODE
poseCorrectionMode
,
I
SAR
_SPLIT_REND_POSE_CORRECTION_MODE
poseCorrectionMode
,
const
int16_t
split_prerender_frame_size_ms
)
{
if
(
poseCorrectionMode
==
I
VAS
_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB
)
if
(
poseCorrectionMode
==
I
SAR
_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB
)
{
int32_t
inBandMdBps
=
(
int32_t
)
(
8
*
1000
/
split_prerender_frame_size_ms
);
return
i
vas
_get_lcld_bitrate
(
SplitRendBitRate
,
poseCorrectionMode
)
-
inBandMdBps
;
return
i
sar
_get_lcld_bitrate
(
SplitRendBitRate
,
poseCorrectionMode
)
-
inBandMdBps
;
}
if
(
poseCorrectionMode
==
I
VAS
_SPLIT_REND_POSE_CORRECTION_MODE_NONE
)
if
(
poseCorrectionMode
==
I
SAR
_SPLIT_REND_POSE_CORRECTION_MODE_NONE
)
{
return
SplitRendBitRate
;
}
...
...
@@ -599,12 +594,12 @@ int32_t ivas_get_lc3plus_bitrate(
/*-------------------------------------------------------------------------
* Function i
vas
_get_lc3plus_bitrate_id()
* Function i
sar
_get_lc3plus_bitrate_id()
*
*
*------------------------------------------------------------------------*/
int8_t
i
vas
_get_lc3plus_bitrate_id
(
int8_t
i
sar
_get_lc3plus_bitrate_id
(
const
int32_t
SplitRendBitRate
)
{
switch
(
SplitRendBitRate
)
...
...
@@ -640,14 +635,14 @@ int8_t ivas_get_lc3plus_bitrate_id(
/*-------------------------------------------------------------------------
* Function i
vas_mat_mult_2by2_complex
()
* Function i
sar_get_lc3plus_size_from_id
()
*
*
*------------------------------------------------------------------------*/
int32_t
i
vas
_get_lc3plus_size_from_id
(
int32_t
i
sar
_get_lc3plus_size_from_id
(
const
int8_t
SplitRendBitRateId
,
const
I
VAS
_SPLIT_REND_POSE_CORRECTION_MODE
poseCorrectionMode
,
const
I
SAR
_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
=
i
vas
_get_lc3plus_bitrate
(
bitrate
,
poseCorrectionMode
,
split_prerender_frame_size_ms
);
bitrate
=
i
sar
_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 i
vas
_split_rend_validate_config()
* Function i
sar
_split_rend_validate_config()
*
*
*------------------------------------------------------------------------*/
ivas_error
i
vas
_split_rend_validate_config
(
const
I
VAS
_SPLIT_REND_CONFIG_DATA
*
pSplitRendConfig
,
ivas_error
i
sar
_split_rend_validate_config
(
const
I
SAR
_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
!=
I
VAS
_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB
&&
pSplitRendConfig
->
hq_mode
!=
0
)
if
(
pSplitRendConfig
->
poseCorrectionMode
!=
I
SAR
_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
==
I
VAS
_SPLIT_REND_POSE_CORRECTION_MODE_NONE
&&
pSplitRendConfig
->
dof
!=
0
)
||
(
pSplitRendConfig
->
poseCorrectionMode
!=
I
VAS
_SPLIT_REND_POSE_CORRECTION_MODE_NONE
&&
pSplitRendConfig
->
dof
==
0
)
)
if
(
(
pSplitRendConfig
->
poseCorrectionMode
==
I
SAR
_SPLIT_REND_POSE_CORRECTION_MODE_NONE
&&
pSplitRendConfig
->
dof
!=
0
)
||
(
pSplitRendConfig
->
poseCorrectionMode
!=
I
SAR
_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
==
I
VAS
_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
==
I
SAR
_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
==
I
VAS
_SPLIT_REND_CODEC_LC3PLUS
&&
(
pSplitRendConfig
->
codec_frame_size_ms
!=
5
&&
pSplitRendConfig
->
codec_frame_size_ms
!=
10
)
)
if
(
pSplitRendConfig
->
codec
==
I
SAR
_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
==
I
VAS
_SPLIT_REND_CODEC_LC3PLUS
)
if
(
pSplitRendConfig
->
dof
==
0
&&
pSplitRendConfig
->
codec
==
I
SAR
_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 i
vas
_split_rend_get_quant_params()
* Function i
sar
_split_rend_get_quant_params()
*
*
*------------------------------------------------------------------------*/
void
i
vas
_split_rend_get_quant_params
(
void
i
sar
_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
]
=
I
VAS
_SPLIT_REND_PRED_63QUANT_PNTS
;
pred_quantstep_yaw
[
0
]
=
I
VAS
_SPLIT_REND_PRED63_Q_STEP
;
pred_1byquantstep_yaw
[
0
]
=
I
VAS
_SPLIT_REND_PRED63_1BYQ_STEP
;
pred_quant_pnts_yaw
[
0
]
=
I
SAR
_SPLIT_REND_PRED_63QUANT_PNTS
;
pred_quantstep_yaw
[
0
]
=
I
SAR
_SPLIT_REND_PRED63_Q_STEP
;
pred_1byquantstep_yaw
[
0
]
=
I
SAR
_SPLIT_REND_PRED63_1BYQ_STEP
;
for
(
q
=
1
;
q
<
*
num_quant_strats
;
q
++
)
{
pred_quant_pnts_yaw
[
q
]
=
I
VAS
_SPLIT_REND_PRED_31QUANT_PNTS
;
pred_quantstep_yaw
[
q
]
=
I
VAS
_SPLIT_REND_PRED31_Q_STEP
;
pred_1byquantstep_yaw
[
q
]
=
I
VAS
_SPLIT_REND_PRED31_1BYQ_STEP
;
pred_quant_pnts_yaw
[
q
]
=
I
SAR
_SPLIT_REND_PRED_31QUANT_PNTS
;
pred_quantstep_yaw
[
q
]
=
I
SAR
_SPLIT_REND_PRED31_Q_STEP
;
pred_1byquantstep_yaw
[
q
]
=
I
SAR
_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 i
vas
_renderSplitGet
MultiBinPoseData
()
* Function i
sar
_renderSplitGet
CodeFromRot_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
I
VAS
_SPLIT_REND_ROT_AXIS
rot_axis
)
const
I
SAR
_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
=
i
vas
_split_rend_relative_yaw_pos_angles_hq
;
relative_pitch_angles
=
i
vas
_split_rend_relative_pitch_pos_angles_hq
;
relative_roll_angles
=
i
vas
_split_rend_relative_roll_pos_angles_hq
;
relative_yaw_angles
=
i
sar
_split_rend_relative_yaw_pos_angles_hq
;
relative_pitch_angles
=
i
sar
_split_rend_relative_pitch_pos_angles_hq
;
relative_roll_angles
=
i
sar
_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
=
i
vas
_split_rend_relative_yaw_pos_angles_hq
;
relative_pitch_angles
=
i
vas
_split_rend_relative_pitch_pos_angles_hq
;
relative_roll_angles
=
i
vas
_split_rend_relative_roll_pos_angles_hq
;
relative_yaw_angles
=
i
sar
_split_rend_relative_yaw_pos_angles_hq
;
relative_pitch_angles
=
i
sar
_split_rend_relative_pitch_pos_angles_hq
;
relative_roll_angles
=
i
sar
_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
=
i
vas
_split_rend_relative_yaw_pos_angles
;
relative_pitch_angles
=
i
vas
_split_rend_relative_pitch_pos_angles
;
relative_roll_angles
=
i
vas
_split_rend_relative_roll_pos_angles
;
relative_yaw_angles
=
i
sar
_split_rend_relative_yaw_pos_angles
;
relative_pitch_angles
=
i
sar
_split_rend_relative_pitch_pos_angles
;
relative_roll_angles
=
i
sar
_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 i
vas
_renderSplitUpdateNoCorrectionPoseData()
* Function i
sar
_renderSplitUpdateNoCorrectionPoseData()
*
*
*------------------------------------------------------------------------*/
void
i
vas
_renderSplitUpdateNoCorrectionPoseData
(
const
I
VAS
_SPLIT_REND_CONFIG_DATA
*
pSplit_rend_config
,
void
i
sar
_renderSplitUpdateNoCorrectionPoseData
(
const
I
SAR
_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
==
I
VAS
_SPLIT_REND_POSE_CORRECTION_MODE_NONE
);
assert
(
pSplit_rend_config
->
poseCorrectionMode
==
I
SAR
_SPLIT_REND_POSE_CORRECTION_MODE_NONE
);
pMultiBinPoseData
->
poseCorrectionMode
=
pSplit_rend_config
->
poseCorrectionMode
;
return
;
...
...
@@ -1018,12 +1170,12 @@ void ivas_renderSplitUpdateNoCorrectionPoseData(
/*-------------------------------------------------------------------------
* Function i
vas
_init_multi_bin_pose_data()
* Function i
sar
_init_multi_bin_pose_data()
*
*
*------------------------------------------------------------------------*/
void
i
vas
_init_multi_bin_pose_data
(
void
i
sar
_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 i
vas
_split_rend_choose_default_codec()
* Function i
sar
_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
==
I
VAS
_SPLIT_REND_CODEC_DEFAULT
)
if
(
*
pCodec
==
I
SAR
_SPLIT_REND_CODEC_DEFAULT
)
{
*
pCodec
=
cldfb_in_flag
?
I
VAS
_SPLIT_REND_CODEC_LCLD
:
I
VAS
_SPLIT_REND_CODEC_LC3PLUS
;
*
pCodec
=
cldfb_in_flag
?
I
SAR
_SPLIT_REND_CODEC_LCLD
:
I
SAR
_SPLIT_REND_CODEC_LC3PLUS
;
}
}
else
{
*
pCodec
=
I
VAS
_SPLIT_REND_CODEC_NONE
;
*
pCodec
=
I
SAR
_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
I
VAS
_SPLIT_REND_CODEC_LCLD
:
case
I
SAR
_SPLIT_REND_CODEC_LCLD
:
*
pCodec_frame_size_ms
=
num_subframes
*
5
;
break
;
case
I
VAS
_SPLIT_REND_CODEC_LC3PLUS
:
case
I
VAS
_SPLIT_REND_CODEC_NONE
:
case
I
SAR
_SPLIT_REND_CODEC_LC3PLUS
:
case
I
SAR
_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
lib_isar/isar_stat.h
0 → 100644
View file @
bea683b3
/******************************************************************************************************
(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 */
lib_isar/lib_isar_post_rend.c
0 → 100644
View file @
bea683b3
/******************************************************************************************************
(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
.
0
f
;
q
.
x
=
q
.
y
=
q
.
z
=
0
.
0
f
;
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
.
0
f
;
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
.
0
f
)
{
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
lib_isar/lib_isar_post_rend.h
0 → 100644
View file @
bea683b3
/******************************************************************************************************
(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 */
lib_isar/lib_isar_pre_rend.c
0 → 100644
View file @
bea683b3
/******************************************************************************************************
(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
readme_split_rendering.txt
→
lib_isar/lib_isar_pre_rend.h
View file @
bea683b3
...
...
@@ -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 */
lib_lc3plus/.clang-format
View file @
bea683b3
DisableFormat: true
SortIncludes: Never
lib_lc3plus/adjust_global_gain.c
View file @
bea683b3
/******************************************************************************
* 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
;
...
...
lib_lc3plus/al_fec_fl.c
View file @
bea683b3
/******************************************************************************
* 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
;
}
...
...
lib_lc3plus/apply_global_gain.c
View file @
bea683b3
/******************************************************************************
* 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
)
...
...
lib_lc3plus/ari_codec.c
View file @
bea683b3
/******************************************************************************
* 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
;
...
...
lib_lc3plus/attack_detector.c
View file @
bea683b3
/******************************************************************************
* 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
,
...
...
lib_lc3plus/clib.h
View file @
bea683b3
/******************************************************************************
* 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>
...
...
lib_lc3plus/constants.c
View file @
bea683b3
/******************************************************************************
* 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 */
lib_lc3plus/constants.h
View file @
bea683b3
/******************************************************************************
* 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 */
lib_lc3plus/cutoff_bandwidth.c
View file @
bea683b3
/******************************************************************************
* 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
)
...
...
Prev
1
2
3
4
5
6
7
8
9
10
…
14
Next