Skip to content
......@@ -116,6 +116,11 @@ static Word16 interpolator_table_16k_q15[] = {
28672, 29082, 29491, 29901, 30310, 30720, 31130, 31539, 31949, 32358
};
/*-------------------------------------------------------------------------
* Local functions
*------------------------------------------------------------------------*/
/**
* Calculate mantissa (Q31) * gain (Q31).
*
......@@ -123,7 +128,12 @@ static Word16 interpolator_table_16k_q15[] = {
* Adjust the result so that accuracy of the mantissa multiplication is maximixed
* and the corresponding exponent is minimized.
*/
static Word32 mult32_mantissa_fx( Word32 mantissa, Word32 gain, Word16 exp, Word16 *exp_result )
static Word32 mult32_mantissa_fx(
const Word32 mantissa,
const Word32 gain,
const Word16 exp,
Word16 *exp_result )
{
Word64 mult = W_mult_32_32( mantissa, gain ); // Q31 * Q31 -> Q63
Word16 norm = W_norm( mult );
......@@ -133,10 +143,16 @@ static Word32 mult32_mantissa_fx( Word32 mantissa, Word32 gain, Word16 exp, Word
return result;
}
/**
* Calculate re^2 + im^2 using exponent (Q0) and mantissa (Q31) format.
*/
static Word32 sample_energy_fx( Word32 re_m, Word16 re_e, Word32 im_m, Word16 im_e, Word16 *exp_result )
static Word32 sample_energy_fx(
const Word32 re_m,
const Word16 re_e,
const Word32 im_m,
const Word16 im_e,
Word16 *exp_result )
{
Word16 re_exp = add( re_e, re_e );
Word32 re_mult = mult32_mantissa_fx( re_m, re_m, re_exp, &re_exp );
......@@ -149,10 +165,18 @@ static Word32 sample_energy_fx( Word32 re_m, Word16 re_e, Word32 im_m, Word16 im
return BASOP_Util_Add_Mant32Exp( re_mult, re_exp, im_mult, im_exp, exp_result );
}
/**
* Accumulate sum of re^2 + im^2 over the specified length using exponent (Q0) and mantissa (Q31) format.
*/
static void sample_energy_acc_fx( Word32 *re_m, Word16 *re_e, Word32 *im_m, Word16 *im_e, Word32 *out_m, Word16 *out_e, Word16 len )
static void sample_energy_acc_fx(
Word32 *re_m,
Word16 *re_e,
Word32 *im_m,
Word16 *im_e,
Word32 *out_m,
Word16 *out_e,
const Word16 len )
{
Word16 i;
......@@ -168,16 +192,18 @@ static void sample_energy_acc_fx( Word32 *re_m, Word16 *re_e, Word32 *im_m, Word
*out_m = BASOP_Util_Add_Mant32Exp( *out_m, *out_e, mantissa, exp, out_e );
move32();
}
return;
}
// Multiplication of vector (comprising of exponent and mantissa parts) by constant value (Q31)
static void v_multc_exp_mantissa_fx(
const Word32 *in_mantissa,
const Word16 *in_exp,
Word32 c,
const Word32 c,
Word32 *out_mantissa,
Word16 *out_exp,
Word16 len )
const Word16 len )
{
Word16 i;
......@@ -186,16 +212,18 @@ static void v_multc_exp_mantissa_fx(
out_mantissa[i] = mult32_mantissa_fx( in_mantissa[i], c, in_exp[i], &out_exp[i] );
move32();
}
return;
}
// Multiplication of vector (comprising of exponent and mantissa parts) by constant acumulate to the output
static void v_multc_acc_exp_mantissa_fx(
const Word32 *in_mantissa,
const Word16 *in_exp,
Word32 c,
const Word32 c,
Word32 *out_mantissa,
Word16 *out_exp,
Word16 len )
const Word16 len )
{
Word16 i;
......@@ -205,15 +233,23 @@ static void v_multc_acc_exp_mantissa_fx(
Word32 mantissa = mult32_mantissa_fx( in_mantissa[i], c, in_exp[i], &exp );
move32();
out_mantissa[i] = BASOP_Util_Add_Mant32Exp( out_mantissa[i], out_exp[i],
mantissa, exp, &out_exp[i] );
out_mantissa[i] = BASOP_Util_Add_Mant32Exp( out_mantissa[i], out_exp[i], mantissa, exp, &out_exp[i] );
move32();
}
return;
}
// Calculate min( 4, sqrtf( target / proto ) )
// target and proto values are expressed using exponent and mantissa
static Word32 get_processing_gain_fx( Word32 proto_m, Word16 proto_e, Word32 target_m, Word16 target_e, Word16 *exp )
static Word32 get_processing_gain_fx(
const Word32 proto_m,
const Word16 proto_e,
const Word32 target_m,
const Word16 target_e,
Word16 *exp )
{
Word16 b = extract_h( proto_m );
IF( EQ_16( b, 0 ) )
......@@ -244,7 +280,12 @@ static Word32 get_processing_gain_fx( Word32 proto_m, Word16 proto_e, Word32 tar
return sqrt_mantissa;
}
static void mantissa_exp_to_qvalue( Word16 *exp, Word32 *output, Word16 target_exp, Word16 len )
static void mantissa_exp_to_qvalue(
Word16 *exp,
Word32 *output,
const Word16 target_exp,
const Word16 len )
{
Word16 bin;
......@@ -261,11 +302,12 @@ static void mantissa_exp_to_qvalue( Word16 *exp, Word32 *output, Word16 target_e
output[bin] = W_sat_l( W_shr( output[bin], shift ) );
}
}
return;
}
#endif
/*-------------------------------------------------------------------*
* ivas_omasa_data_open()
*
......@@ -375,6 +417,7 @@ ivas_error ivas_omasa_data_open_fx(
move32();
}
#endif
st_ivas->hMasaIsmData = hMasaIsmData;
return IVAS_ERR_OK;
......@@ -408,6 +451,7 @@ void ivas_omasa_data_close_fx(
free( ( *hMasaIsmData )->delayBuffer_fx );
( *hMasaIsmData )->delayBuffer_fx = NULL;
}
#ifdef NONBE_FIX_984_OMASA_EXT_OUTPUT
IF( ( *hMasaIsmData )->hExtData != NULL )
{
......@@ -416,6 +460,7 @@ void ivas_omasa_data_close_fx(
move32();
}
#endif
free( *hMasaIsmData );
*hMasaIsmData = NULL;
......@@ -565,6 +610,7 @@ ivas_error ivas_omasa_dec_config_fx(
/* ISM MD reconfig. */
n_MD = 0;
move16();
#ifdef NONBE_FIX_984_OMASA_EXT_OUTPUT
IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
{
......@@ -697,12 +743,13 @@ ivas_error ivas_omasa_dec_config_fx(
IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
{
/* Allocate TD renderer for the objects in DISC mode */
IF( st_ivas->hBinRendererTd == NULL )
if ( st_ivas->hBinRendererTd == NULL )
{
IF( NE_32( ( error = ivas_td_binaural_open_fx( st_ivas, SrcInd, num_src ) ), IVAS_ERR_OK ) )
{
return error;
}
IF( EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
{
IF( NE_32( ( error = ivas_reverb_open_fx( &st_ivas->hReverb, st_ivas->hHrtfStatistics, st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ), IVAS_ERR_OK ) )
......@@ -713,10 +760,17 @@ ivas_error ivas_omasa_dec_config_fx(
}
/* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */
#ifdef FIX_1161_REDUCE_OMASA_HEAP
IF( NE_32( ( error = ivas_omasa_objects_delay_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
{
return error;
}
#else
IF( NE_32( ( error = ivas_omasa_separate_object_renderer_open( st_ivas ) ), IVAS_ERR_OK ) )
{
return error;
}
#endif
}
ELSE
{
......@@ -725,6 +779,7 @@ ivas_error ivas_omasa_dec_config_fx(
/* TD renderer handle */
ivas_td_binaural_close_fx( &st_ivas->hBinRendererTd );
}
/* ISM renderer handle + ISM data handle */
ivas_omasa_separate_object_renderer_close( st_ivas );
}
......@@ -742,6 +797,13 @@ ivas_error ivas_omasa_dec_config_fx(
IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
{
/* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */
#ifdef FIX_1161_REDUCE_OMASA_HEAP
IF( NE_32( ( error = ivas_omasa_objects_delay_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
{
return error;
}
#endif
IF( NE_32( ( error = ivas_omasa_separate_object_renderer_open( st_ivas ) ), IVAS_ERR_OK ) )
{
return error;
......@@ -753,6 +815,7 @@ ivas_error ivas_omasa_dec_config_fx(
ivas_omasa_separate_object_renderer_close( st_ivas );
}
}
#ifdef NONBE_FIX_984_OMASA_EXT_OUTPUT
IF( EQ_32( st_ivas->renderer_type, RENDERER_OMASA_MIX_EXT ) )
{
......@@ -779,23 +842,27 @@ ivas_error ivas_omasa_dec_config_fx(
move32();
/* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */
#ifdef FIX_1161_REDUCE_OMASA_HEAP
IF( NE_32( ( error = ivas_omasa_objects_delay_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
{
return error;
}
#else
error = ivas_omasa_render_objects_from_mix_open_fx( st_ivas );
move32();
IF( NE_32( error, IVAS_ERR_OK ) )
{
return error;
}
#endif
error = ivas_spat_hSpatParamRendCom_config_fx( &st_ivas->hSpatParamRendCom,
common_rend_config_flag, 0,
st_ivas->ivas_format, st_ivas->mc_mode, st_ivas->hDecoderConfig->output_Fs, 0, 0 );
move32();
IF( NE_32( error, IVAS_ERR_OK ) )
IF( NE_32( ( error = ivas_spat_hSpatParamRendCom_config_fx( &st_ivas->hSpatParamRendCom, common_rend_config_flag, 0, st_ivas->ivas_format, st_ivas->mc_mode, st_ivas->hDecoderConfig->output_Fs, 0, 0 ) ), IVAS_ERR_OK ) )
{
return error;
}
}
#endif
/*-----------------------------------------------------------------*
* TD Decorrelator
*-----------------------------------------------------------------*/
......@@ -949,6 +1016,7 @@ void ivas_set_surplus_brate_dec(
*
* decode ISM metadata in OMASA format
*--------------------------------------------------------------------------*/
ivas_error ivas_omasa_ism_metadata_dec_fx(
Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
const Word32 ism_total_brate, /* i : ISM total bitrate */
......@@ -967,6 +1035,7 @@ ivas_error ivas_omasa_ism_metadata_dec_fx(
move16();
*nchan_transport_ism = st_ivas->nchan_ism;
move16();
IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
{
*nchan_ism = 1;
......@@ -981,6 +1050,7 @@ ivas_error ivas_omasa_ism_metadata_dec_fx(
*nchan_transport_ism = 1;
move16();
}
#ifdef NONBE_FIX_984_OMASA_EXT_OUTPUT
test();
#endif
......@@ -1050,8 +1120,7 @@ ivas_error ivas_omasa_ism_metadata_dec_fx(
}
}
#ifdef NONBE_FIX_984_OMASA_EXT_OUTPUT
ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) &&
EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) && EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
{
azimuth_ism = extract_l( L_shr_r( L_abs( st_ivas->hIsmMetaData[0]->azimuth_fx ), 22 ) );
if ( st_ivas->hIsmMetaData[0]->azimuth_fx < 0 )
......@@ -1106,7 +1175,7 @@ void ivas_omasa_dirac_rend_jbm_fx(
Word32 data_separated_objects[MAX_NUM_OBJECTS][L_FRAME48k];
test();
if ( !st_ivas->hDecoderConfig->Opt_tsm )
IF( !st_ivas->hDecoderConfig->Opt_tsm )
{
*nSamplesRendered = min( nSamplesAsked, st_ivas->hTcBuffer->n_samples_available );
......@@ -1125,7 +1194,6 @@ void ivas_omasa_dirac_rend_jbm_fx(
}
}
subframes_rendered = st_ivas->hSpatParamRendCom->subframes_rendered;
move16();
slots_rendered = st_ivas->hSpatParamRendCom->slots_rendered;
......@@ -1148,6 +1216,7 @@ void ivas_omasa_dirac_rend_jbm_fx(
return;
}
/*--------------------------------------------------------------------------*
* ivas_omasa_dirac_td_binaural_render()
*
......@@ -1288,7 +1357,8 @@ void ivas_omasa_rearrange_channels_fx(
* Open structures, reserve memory, and init values.
*-------------------------------------------------------------------------*/
ivas_error ivas_omasa_combine_separate_ism_with_masa_open_fx( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
ivas_error ivas_omasa_combine_separate_ism_with_masa_open_fx(
Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
)
{
Word16 i;
......@@ -1331,8 +1401,7 @@ ivas_error ivas_omasa_combine_separate_ism_with_masa_open_fx( Decoder_Struct *st
move16();
move32();
st_ivas->hIsmRendererData->interpolator_fx =
(Word16 *) malloc( sizeof( Word16 ) * st_ivas->hIsmRendererData->interpolator_len );
st_ivas->hIsmRendererData->interpolator_fx = (Word16 *) malloc( sizeof( Word16 ) * st_ivas->hIsmRendererData->interpolator_len );
IF( st_ivas->hIsmRendererData->interpolator_fx == NULL )
{
......@@ -1353,6 +1422,7 @@ ivas_error ivas_omasa_combine_separate_ism_with_masa_open_fx( Decoder_Struct *st
return IVAS_ERR_OK;
}
/*--------------------------------------------------------------------------*
* ivas_omasa_combine_separate_ism_with_masa_fx()
*
......@@ -1363,8 +1433,8 @@ void ivas_omasa_combine_separate_ism_with_masa_fx(
Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
Word32 *output[], /* i/o: output synthesis signal */
Word16 *output_q, /* i/o: output Q value */
const int16_t nchan_ism, /* i : number of ISMs */
const int16_t output_frame /* i : output frame length per channel */
const Word16 nchan_ism, /* i : number of ISMs */
const Word16 output_frame /* i : output frame length per channel */
)
{
Word16 n, sf, band, k;
......@@ -1608,9 +1678,20 @@ void ivas_omasa_combine_separate_ism_with_masa_fx(
{
set_zero_fx( output[add( MASA_MAX_TRANSPORT_CHANNELS, n )], output_frame );
}
return;
}
#ifdef FIX_1161_REDUCE_OMASA_HEAP
/*-------------------------------------------------------------------------*
* ivas_omasa_objects_delay_open()
*
* Open structures, reserve memory, and init values for dela buffers of objects.
*-------------------------------------------------------------------------*/
ivas_error ivas_omasa_objects_delay_open_fx(
#else
/*-------------------------------------------------------------------------*
* ivas_omasa_render_objects_from_mix_open_fx()
*
......@@ -1618,14 +1699,29 @@ void ivas_omasa_combine_separate_ism_with_masa_fx(
*-------------------------------------------------------------------------*/
ivas_error ivas_omasa_render_objects_from_mix_open_fx(
#endif
Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
)
{
Word16 i;
Word32 size;
#ifdef FIX_1161_REDUCE_OMASA_HEAP
test();
IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
{
st_ivas->hMasaIsmData->delayBuffer_nchan = 1;
move16();
}
ELSE
{
st_ivas->hMasaIsmData->delayBuffer_nchan = st_ivas->nchan_ism;
move16();
}
#else
st_ivas->hMasaIsmData->delayBuffer_nchan = 1;
move16();
#endif
st_ivas->hMasaIsmData->delayBuffer_size = extract_l( Mult_32_16( st_ivas->hDecoderConfig->output_Fs,
OMASA_DELAYFRAMES_PER_SEC_Q15 ) );
......@@ -1666,8 +1762,8 @@ ivas_error ivas_omasa_render_objects_from_mix_open_fx(
void ivas_omasa_render_objects_from_mix_fx(
Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
Word32 *output[], /* o : output synthesis signal */
const int16_t nchan_ism, /* i : number of ISMs */
const int16_t output_frame, /* i : output frame length per channel */
const Word16 nchan_ism, /* i : number of ISMs */
const Word16 output_frame, /* i : output frame length per channel */
Word16 *output_q /* i/o: output Q value */
)
{
......@@ -2120,5 +2216,7 @@ void ivas_omasa_render_objects_from_mix_fx(
hExtData->prev_idx_separated_ism = st_ivas->hMasaIsmData->idx_separated_ism;
move16();
return;
}
#endif
......@@ -815,11 +815,13 @@ void ivas_sba_dec_digest_tc_fx(
{
ivas_dirac_dec_set_md_map_fx( st_ivas, nCldfbSlots );
}
test();
IF( EQ_16( st_ivas->ivas_format, SBA_FORMAT ) || EQ_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
{
ivas_spar_dec_digest_tc_fx( st_ivas, st_ivas->nchan_transport, nCldfbSlots, nSamplesForRendering );
}
test();
IF( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->useTdDecorr )
{
......
......@@ -980,9 +980,11 @@ typedef struct ivas_masa_ism_data_structure
Word32 **delayBuffer_fx; /* Q11 */
Word16 delayBuffer_size;
Word16 delayBuffer_nchan;
#ifdef NONBE_FIX_984_OMASA_EXT_OUTPUT
MASA_ISM_EXT_DATA_HANDLE hExtData;
#endif
} MASA_ISM_DATA, *MASA_ISM_DATA_HANDLE;
......
......@@ -43,11 +43,14 @@
#include "ivas_prot_fx.h"
#include "ivas_rom_com_fx.h"
/*-------------------------------------------------------------------*
* Local constants
*-------------------------------------------------------------------*/
#define DFT2TD_CORR_THRESH_FX 1932735283
/*-------------------------------------------------------------------*
* Function allocate_CoreCoder_TCX()
*
......@@ -361,6 +364,7 @@ static void cpy_tcx_ltp_data_fx(
*
* Dynamically allocate/deallocate data structures depending on the actual CPE mode
*-------------------------------------------------------------------*/
ivas_error stereo_memory_dec_fx(
const Word32 ivas_total_brate, /* i : IVAS total bitrate Q0*/
CPE_DEC_HANDLE hCPE, /* i : CPE decoder structure */
......@@ -1092,6 +1096,7 @@ ivas_error stereo_memory_dec_fx(
* Synchronize upmixed DFT/TD/MDCT stereo synthesis to match the overall delay of 32ms
* Handling of TD stereo <-> DFT stereo transitions
*-------------------------------------------------------------------*/
void synchro_synthesis_fx(
const Word32 ivas_total_brate, /* i : IVAS total bitrate Q0*/
CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */
......@@ -1263,7 +1268,12 @@ void synchro_synthesis_fx(
test();
test();
test();
#ifdef NONBE_1289_STEREO_SW_TO_MONO
test();
IF( ( !use_cldfb_for_last_dft && NE_16( hCPE->last_element_mode, IVAS_CPE_DFT ) && !sba_dirac_stereo_flag && NE_16( dft_mono_brate_switch, -1 ) ) || EQ_16( dft_mono_brate_switch, 1 ) )
#else
IF( ( NE_16( hCPE->last_element_mode, IVAS_CPE_DFT ) && !sba_dirac_stereo_flag && NE_16( dft_mono_brate_switch, -1 ) ) || EQ_16( dft_mono_brate_switch, 1 ) )
#endif
{
Word32 *pPrev_synth_fx;
Word32 inv_fade_len_fx = 0;
......@@ -1679,18 +1689,22 @@ void synchro_synthesis_fx(
return;
}
/*-------------------------------------------------------------------*
* Function stereo_switching_dec()
*
* Handling of memories in case of CPE modes switching
*-------------------------------------------------------------------*/
Word32 side_gain_table[32 + 1] = { -ONE_IN_Q31, -2040109440, -1932735232, -1825361152, -1717986944,
static Word32 side_gain_table[32 + 1] = {
-ONE_IN_Q31, -2040109440, -1932735232, -1825361152, -1717986944,
-1610612736, -1503238528, -1395864320, -1288490240, -1181115904, -1073741824,
-966367616, -858993408, -751619200, -644245120, -536870912, -429496704,
-322122496, -214748288, -107374208, 0, 107374336, 214748416,
322122496, 429496832, 536870912, 644245248, 751619328, 858993408,
966367744, 1073741824, 1181116160, 1288490240 };
966367744, 1073741824, 1181116160, 1288490240
};
void stereo_switching_dec(
CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */
const Word32 ivas_total_brate /* i : IVAS total bitrate Q0*/
......@@ -2042,11 +2056,14 @@ void stereo_switching_dec(
return;
}
/*-------------------------------------------------------------------*
* Function stereo_td2dft_update()
*
* update OLA buffers - needed for switching from TD stereo to DFT stereo
*-------------------------------------------------------------------*/
void stereo_td2dft_update_fx(
CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */
const Word16 n, /* i : channel number Q0*/
......@@ -2190,11 +2207,14 @@ void stereo_td2dft_update_fx(
return;
}
/*-------------------------------------------------------------------*
* Function stereo_mdct2dft_update()
*
* update OLA buffers - needed for switching from MDCT stereo to DFT stereo
*-------------------------------------------------------------------*/
void stereo_mdct2dft_update_fx(
CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */
Word32 output0_fx[], /* i/o: synthesis @internal Fs, ch0 Q11*/
......@@ -2215,6 +2235,7 @@ void stereo_mdct2dft_update_fx(
fade_len = extract_l( Mpy_32_32( imult3216( st->output_Fs, STEREO_MDCT2DFT_FADE_LEN_48k ), 44740 ) ); // 1/48000 = 44740 (Q31) /* Q0 */
fade_len_LB = extract_l( Mpy_32_32( imult3216( 3 * STEREO_MDCT2DFT_FADE_LEN_48k * FRAMES_PER_SEC, st->L_frame ), 44740 ) ); // 1/48000 = 44740 (Q31) /* Q0 */
SWITCH( st->output_Fs )
{
case 16000:
......@@ -2230,6 +2251,7 @@ void stereo_mdct2dft_update_fx(
move32();
BREAK;
}
FOR( i = 0; i < fade_len; i++ )
{
Word32 descen_gain;
......@@ -2359,6 +2381,7 @@ static Word32 ncross_corr_self_fx(
quo_e = add( sub( sub( 40, q_cc ), q_prod ), quo_e );
c_c_fx_return = L_shl_sat( num, quo_e ); // Q31
}
return c_c_fx_return;
}
......
......@@ -1504,7 +1504,11 @@ static void singularVectorsAccumulationLeft_fx(
FOR( k = nCh + 1; k < nChannelsL; k++ ) /* nChannelsL */
{
#ifdef FIX_ISSUE_1811_EXCEEDING_W_SHIFTS
acc = W_add( acc, W_shr( prod[k], s_min( 63, sub( max_e, prod_e[k] ) ) ) );
#else
acc = W_add( acc, W_shr( prod[k], sub( max_e, prod_e[k] ) ) );
#endif
}
Word16 acc_e = W_norm( acc );
acc = W_shl( acc, acc_e );
......
......@@ -1993,11 +1993,13 @@ ivas_error IVAS_DEC_GetNumObjects(
is_masa_ism = 0;
move16();
#endif
test();
IF( hIvasDec == NULL || hIvasDec->st_ivas == NULL )
{
return IVAS_ERR_UNEXPECTED_NULL_POINTER;
}
#ifdef NONBE_FIX_984_OMASA_EXT_OUTPUT
IF( hIvasDec->st_ivas->hMasa != NULL )
{
......@@ -2007,6 +2009,7 @@ ivas_error IVAS_DEC_GetNumObjects(
move16();
}
}
test();
test();
test();
......@@ -2053,6 +2056,7 @@ ivas_error IVAS_DEC_GetFormat(
*format = IVAS_DEC_BS_UNKOWN;
}
move32();
#ifdef NONBE_FIX_984_OMASA_EXT_OUTPUT
test();
if ( EQ_32( *format, IVAS_DEC_BS_MASA ) && EQ_32( hIvasDec->st_ivas->hMasa->config.input_ivas_format, MASA_ISM_FORMAT ) )
......@@ -2061,6 +2065,7 @@ ivas_error IVAS_DEC_GetFormat(
move32();
}
#endif
return IVAS_ERR_OK;
}
......@@ -2173,9 +2178,11 @@ ivas_error IVAS_DEC_GetObjectMetadata(
ISM_METADATA_HANDLE hIsmMeta;
#ifdef NONBE_FIX_984_OMASA_EXT_OUTPUT
Word16 is_masa_ism;
is_masa_ism = 0;
move16();
#endif
test();
IF( hIvasDec == NULL || hIvasDec->st_ivas == NULL )
{
......@@ -2183,6 +2190,7 @@ ivas_error IVAS_DEC_GetObjectMetadata(
}
st_ivas = hIvasDec->st_ivas;
#ifdef NONBE_FIX_984_OMASA_EXT_OUTPUT
IF( hIvasDec->st_ivas->hMasa != NULL )
{
......@@ -2192,6 +2200,7 @@ ivas_error IVAS_DEC_GetObjectMetadata(
move16();
}
}
test();
test();
test();
......@@ -2214,6 +2223,7 @@ ivas_error IVAS_DEC_GetObjectMetadata(
}
hIsmMeta = st_ivas->hIsmMetaData[objectIdx];
#ifdef NONBE_FIX_984_OMASA_EXT_OUTPUT
test();
test();
......@@ -2928,6 +2938,7 @@ ivas_error IVAS_DEC_GetDelay(
out_fs_fx = FS_48K_IN_NS_Q31;
}
move32();
#ifdef NONBE_FIX_984_OMASA_EXT_OUTPUT
nSamples[1] = NS2SA_FX2( hDecoderConfig->output_Fs, get_delay_fx( DEC, hDecoderConfig->output_Fs, st_ivas->ivas_format, st_ivas->cldfbSynDec[0], (Word16) EQ_16( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ) );
move16();
......
......@@ -197,14 +197,6 @@ void ivas_decision_matrix_enc_fx(
move16();
}
}
test();
test();
test();
test();
test();
test();
#ifdef DEBUG_FORCE_DIR
if ( st->force_dir[0] != '\0' )
{
......@@ -217,14 +209,26 @@ void ivas_decision_matrix_enc_fx(
#endif
/* do not allow TD stereo ACELP core -> DFT stereo TCX core switching as it is on the WC complexity path */
test();
test();
test();
test();
test();
test();
if ( ( ( st->last_core == ACELP_CORE && EQ_16( last_element_mode, IVAS_CPE_TD ) && EQ_16( st->element_mode, IVAS_CPE_DFT ) ) || ( EQ_16( st->tdm_LRTD_flag, 1 ) && LE_32( st->total_brate, IVAS_16k4 ) ) ) && EQ_16( st->core, TCX_20_CORE ) && LE_32( st->total_brate, MAX_ACELP_BRATE ) ) /* Override TCX in case of LRTD && primary channel has low bitrate*/
{
st->core = ACELP_CORE;
move16();
}
/* sanity check: highest bitrates in ISM */
test();
#ifdef NONBE_1240_FIX_CORE_SELECTION_ISM_SW
test();
if ( st->is_ism_format && st->tcxonly && GT_32( st->total_brate, MAX_ACELP_BRATE_ISM ) )
#else
if ( st->is_ism_format && st->tcxonly )
#endif
{
st->core = TCX_20_CORE;
move16();
......
......@@ -187,10 +187,12 @@ void ivas_write_format_sid_fx(
ind = SID_ISM;
move16();
BREAK;
#ifndef FIX_1209_SID_SIGNALING
case MC_FORMAT:
ind = SID_MULTICHANNEL;
move16();
BREAK;
#endif
case SBA_FORMAT:
SWITCH( element_mode )
{
......
This diff is collapsed.
......@@ -233,19 +233,39 @@ void ivas_mct_core_enc_fx(
Word16 i, cpe_id, n, nAvailBits;
Word16 nCPE;
Word32 *orig_spectrum_fx[MCT_MAX_CHANNELS][2]; /* Pointers to MDCT output for a short block (L/R) */
#ifdef NONBE_FIX_1097_SBA_DTX_BRATE_SWITCHING_ENC
Word32 powerSpecMsInv_long_cpe0_fx[CPE_CHANNELS][L_FRAME_PLUS];
Word32 inv_spectrum_long_cpe0_fx[CPE_CHANNELS][L_FRAME_PLUS];
Word32 powerSpec_long_cpe0_fx[CPE_CHANNELS][L_FRAME_PLUS];
Word32 powerSpec_long_fx[MCT_MAX_CHANNELS - CPE_CHANNELS][L_FRAME48k];
Word32 inv_spectrum_long_fx[MCT_MAX_CHANNELS - CPE_CHANNELS][L_FRAME48k]; /* quantized MDCT spectrum, inv ms mask mdst spectrum, scratch for MS spectra in the MS decision */
Word32 powerSpecMsInv_long_fx[MCT_MAX_CHANNELS - CPE_CHANNELS][L_FRAME48k]; /* MS inv power spectrum, also inverse MDST spectrum */
#else
Word32 powerSpec_fx[MCT_MAX_CHANNELS][L_FRAME48k];
#endif
Word16 exp_powerSpec[MCT_MAX_CHANNELS][N_MAX + L_MDCT_OVLP_MAX];
Word32 mdst_fx;
#ifndef NONBE_FIX_1097_SBA_DTX_BRATE_SWITCHING_ENC
Word32 powerSpecMsInv_long_fx[MCT_MAX_CHANNELS][L_FRAME48k]; /* MS inv power spectrum, also inverse MDST spectrum */
#endif
#ifdef NONBE_FIX_1097_SBA_DTX_BRATE_SWITCHING_ENC
Word32 *powerSpec_fx[MCT_MAX_CHANNELS];
#endif
Word32 *powerSpecMsInv_fx[MCT_MAX_CHANNELS][2];
Word32 *inv_mdst_spectrum_fx[MCT_MAX_CHANNELS][2];
Word32 *inv_spectrum_fx[MCT_MAX_CHANNELS][2];
Word32 *mdst_spectrum_fx[MCT_MAX_CHANNELS][2] = { { NULL } };
#ifndef NONBE_FIX_1097_SBA_DTX_BRATE_SWITCHING_ENC
Word32 inv_spectrum_long_fx[MCT_MAX_CHANNELS][L_FRAME48k]; /* quantized MDCT spectrum, inv ms mask mdst spectrum, scratch for MS spectra in the MS decision */
#endif
Word16 total_side_bits;
Word16 chBitRatios[MCT_MAX_CHANNELS];
Word16 q_powSpec[MCT_MAX_CHANNELS], q_spec, q_origSpec, tmp_s;
#ifdef NONBE_FIX_1097_SBA_DTX_BRATE_SWITCHING_ENC
Word16 tmp_q_powSpec[L_FRAME_PLUS], tmp_q_powSpecInv[MCT_MAX_CHANNELS][L_FRAME_PLUS], *tmp_q_psi[MCT_MAX_CHANNELS][2];
#else
Word16 tmp_q_powSpec[L_FRAME48k], tmp_q_powSpecInv[MCT_MAX_CHANNELS][L_FRAME48k], *tmp_q_psi[MCT_MAX_CHANNELS][2];
#endif
Word64 W_tmp;
Encoder_State *sts[MCT_MAX_CHANNELS];
Encoder_State *st;
......@@ -270,6 +290,61 @@ void ivas_mct_core_enc_fx(
nCPE = add( nCPE, 1 );
}
#ifdef NONBE_FIX_1097_SBA_DTX_BRATE_SWITCHING_ENC
/* point first CPE channels to longer buffers where switching from ACELP to TCX may occur in SBA with DTX (total memory saving)*/
FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
{
set32_fx( inv_spectrum_long_cpe0_fx[ch], 0, L_FRAME_PLUS );
set32_fx( powerSpec_long_cpe0_fx[ch], 0, L_FRAME_PLUS ); // tmp_q_powSpec
set32_fx( powerSpecMsInv_long_cpe0_fx[ch], 0, L_FRAME_PLUS ); // tmp_q_powSpecInv
inv_mdst_spectrum_fx[ch][0] = powerSpecMsInv_fx[ch][0] = powerSpecMsInv_long_cpe0_fx[ch];
inv_mdst_spectrum_fx[ch][1] = powerSpecMsInv_fx[ch][1] = powerSpecMsInv_long_cpe0_fx[ch] + N_TCX10_MAX;
set16_fx( tmp_q_powSpecInv[ch], 63, L_FRAME_PLUS );
tmp_q_psi[ch][0] = tmp_q_powSpecInv[ch];
tmp_q_psi[ch][1] = &tmp_q_powSpecInv[ch][N_TCX10_MAX];
inv_spectrum_fx[ch][0] = inv_spectrum_long_cpe0_fx[ch];
inv_spectrum_fx[ch][1] = inv_spectrum_long_cpe0_fx[ch] + N_TCX10_MAX;
powerSpec_fx[ch] = powerSpec_long_cpe0_fx[ch];
}
FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
{
q_powSpec[ch] = 0;
move16();
set16_fx( exp_powerSpec[ch], 0, N_MAX + L_MDCT_OVLP_MAX );
}
FOR( ch = CPE_CHANNELS; ch < nChannels; ch++ )
{
set32_fx( inv_spectrum_long_fx[ch - CPE_CHANNELS], 0, L_FRAME48k );
set32_fx( powerSpec_long_fx[ch - CPE_CHANNELS], 0, L_FRAME48k ); // tmp_q_powSpec
set32_fx( powerSpecMsInv_long_fx[ch - CPE_CHANNELS], 0, L_FRAME48k ); // tmp_q_powSpecInv
inv_mdst_spectrum_fx[ch][0] = powerSpecMsInv_fx[ch][0] = powerSpecMsInv_long_fx[ch - CPE_CHANNELS];
inv_mdst_spectrum_fx[ch][1] = powerSpecMsInv_fx[ch][1] = powerSpecMsInv_long_fx[ch - CPE_CHANNELS] + N_TCX10_MAX;
set16_fx( tmp_q_powSpecInv[ch], 63, L_FRAME48k );
tmp_q_psi[ch][0] = tmp_q_powSpecInv[ch];
tmp_q_psi[ch][1] = &tmp_q_powSpecInv[ch][N_TCX10_MAX];
inv_spectrum_fx[ch][0] = inv_spectrum_long_fx[ch - CPE_CHANNELS];
inv_spectrum_fx[ch][1] = inv_spectrum_long_fx[ch - CPE_CHANNELS] + N_TCX10_MAX;
powerSpec_fx[ch] = powerSpec_long_fx[ch - CPE_CHANNELS];
}
FOR( ch = CPE_CHANNELS; ch < MCT_MAX_CHANNELS; ch++ )
{
q_powSpec[ch] = 0;
move16();
set16_fx( exp_powerSpec[ch], 0, N_MAX + L_MDCT_OVLP_MAX );
}
set16_fx( tmp_q_powSpec, 63, L_FRAME_PLUS );
#else
FOR( ch = 0; ch < MCT_MAX_CHANNELS; ch++ )
{
set32_fx( powerSpecMsInv_long_fx[ch], 0, L_FRAME48k );
......@@ -295,6 +370,7 @@ void ivas_mct_core_enc_fx(
}
set16_fx( tmp_q_powSpec, 63, L_FRAME48k );
#endif
FOR( ( cpe_id = 0, i = 0 ); cpe_id < nCPE; cpe_id++ )
{
......
......@@ -983,7 +983,11 @@ void mctStereoIGF_enc_fx(
Encoder_State **sts, /* i/o: encoder state structure */
Word32 *orig_spectrum_fx[MCT_MAX_CHANNELS][2], /* i : MDCT spectrum for ITF */
Word16 q_origSpec, /* i : Q for MDCT spectrum */
#ifdef NONBE_FIX_1097_SBA_DTX_BRATE_SWITCHING_ENC
Word32 *powerSpec_fx[MCT_MAX_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum,or estimate */
#else
Word32 powerSpec_fx[MCT_MAX_CHANNELS][L_FRAME48k], /* i/o: MDCT^2 + MDST^2 spectrum,or estimate */
#endif
Word16 q_powerSpec[MCT_MAX_CHANNELS], /* i : Q for powSpec_fx */
Word32 *powerSpecMsInv_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : same as powerSpec_fx but for inverse spect.*/
Word16 *q_powerSpecMsInv[MCT_MAX_CHANNELS][NB_DIV], /* i : Q for powSpecMsInv_fx */
......
......@@ -1964,7 +1964,11 @@ void ivas_mdct_core_whitening_enc_fx(
move64();
FOR( i = 0; i < NB_DIV; i++ )
{
#ifdef FIX_ISSUE_1811_EXCEEDING_W_SHIFTS
chE_tot_fx = W_add( W_shr( chE_fx[i], s_min( 63, sub( chE_q[i], q ) ) ), chE_tot_fx );
#else
chE_tot_fx = W_add( W_shr( chE_fx[i], sub( chE_q[i], q ) ), chE_tot_fx );
#endif
}
IF( GT_16( q, Q24 ) )
{
......
......@@ -51,9 +51,11 @@
#define OMASA_FEC_MAX 5
/*-------------------------------------------------------------------------
* Local function prototypes
*------------------------------------------------------------------------*/
static void ivas_omasa_param_est_enc_fx(
OMASA_ENC_HANDLE hOMasa,
OMASA_ENCODER_DATA_HANDLE hOmasaData,
......@@ -99,6 +101,8 @@ void computeIntensityVector_enc_fx(
Word16 inp_q );
static void computeReferencePower_omasa_ivas_fx( const Word16 *band_grouping, Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], Word32 Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], Word32 *reference_power, const Word16 enc_param_start_band, const Word16 num_freq_bands, Word16 q_Cldfb, Word16 q_reference_power[CLDFB_NO_CHANNELS_MAX] );
/*--------------------------------------------------------------------------*
* ivas_omasa_enc_open()
*
......@@ -217,13 +221,13 @@ ivas_error ivas_omasa_enc_open_fx(
return error;
}
/*--------------------------------------------------------------------------*
* ivas_omasa_enc_close()
*
* Close OMASA handle
*--------------------------------------------------------------------------*/
void ivas_omasa_enc_close_fx(
OMASA_ENC_HANDLE *hOMasa /* i/o: encoder OMASA handle */
)
......@@ -268,11 +272,13 @@ void ivas_omasa_enc_close_fx(
return;
}
/*--------------------------------------------------------------------------*
* ivas_omasa_enc_config()
*
* oMASA encoder configuration
*--------------------------------------------------------------------------*/
ivas_error ivas_omasa_enc_config_fx(
Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */
)
......@@ -356,6 +362,7 @@ ivas_error ivas_omasa_enc_config_fx(
ivas_write_format_fx( st_ivas );
/* OMASA encoder handle */
test();
test();
IF( NE_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) && st_ivas->hOMasa == NULL )
......@@ -371,6 +378,24 @@ ivas_error ivas_omasa_enc_config_fx(
st_ivas->hOMasa = NULL;
}
#ifdef FIX_1161_REDUCE_OMASA_HEAP
/* OMASA energy handle */
test();
test();
IF( NE_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) && st_ivas->hMasa->data.hOmasaData->hOmasaEnergy == NULL )
{
IF( ( st_ivas->hMasa->data.hOmasaData->hOmasaEnergy = (OMASA_ENCODER_ENERGY_HANDLE) malloc( sizeof( OMASA_ENCODER_ENERGY_STATE ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA energy handle\n" ) );
}
}
ELSE IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) && st_ivas->hMasa->data.hOmasaData->hOmasaEnergy != NULL )
{
free( st_ivas->hMasa->data.hOmasaData->hOmasaEnergy );
st_ivas->hMasa->data.hOmasaData->hOmasaEnergy = NULL;
}
#endif
st_ivas->hCPE[0]->element_brate = L_sub( ivas_total_brate, ism_total_brate );
move32();
......@@ -406,6 +431,7 @@ ivas_error ivas_omasa_enc_config_fx(
*
* Frame-by-frame config for oMASA
*--------------------------------------------------------------------------*/
void ivas_omasa_set_config_fx(
OMASA_ENC_HANDLE hOMasa, /* i/o: OMASA encoder handle */
MASA_ENCODER_HANDLE hMasa, /* i : MASA encoder handle */
......@@ -483,6 +509,7 @@ void ivas_omasa_set_config_fx(
*
* Main OMASA encoding function
*--------------------------------------------------------------------------*/
void ivas_omasa_enc_fx(
OMASA_ENC_HANDLE hOMasa, /* i/o: OMASA encoder handle */
MASA_ENCODER_HANDLE hMasa, /* i/o: MASA encoder handle */
......@@ -514,6 +541,7 @@ void ivas_omasa_enc_fx(
UWord8 fade_out_separate_object;
UWord8 fade_in_separate_object;
Word32 temp32; /*temp32_e*/
/* Estimate broadband energies */
nchan_all_inp = add( nchan_ism, nchan_transport );
set_zero_fx( broadband_energy_fx, nchan_all_inp );
......@@ -878,6 +906,7 @@ void ivas_set_ism_importance_interformat_fx(
return;
}
/*--------------------------------------------------------------------------*
* ivas_set_surplus_brate_enc()
*
......@@ -951,7 +980,7 @@ Word16 ivas_omasa_ener_brate_fx(
const Word32 ivas_total_brate, /* i : IVAS total bitrate */
Word32 *data_f[], /* i : Input / transport audio signals data_e*/
const Word16 input_frame, /* i : Input frame size */
Word16 data_e /*i:exponent for data_f */
const Word16 data_e /* i : exponent for data_f */
)
{
Word16 i, flag_omasa_ener_brate;
......@@ -959,6 +988,7 @@ Word16 ivas_omasa_ener_brate_fx(
Word16 energy_ism_e, energy_masa_e;
Word32 temp_32;
Word16 temp, temp_e;
flag_omasa_ener_brate = 0;
energy_ism_e = 0;
energy_masa_e = 0;
......@@ -1017,6 +1047,7 @@ Word16 ivas_omasa_ener_brate_fx(
return flag_omasa_ener_brate;
}
/*--------------------------------------------------------------------------*
* Local functions
*--------------------------------------------------------------------------*/
......@@ -1067,6 +1098,9 @@ static void ivas_omasa_param_est_enc_fx(
Word32 temp;
Word16 temp_e;
Word16 q_intensity_real_fx[MASA_FREQUENCY_BANDS], q_reference_power_fx[CLDFB_NO_CHANNELS_MAX];
#ifdef FIX_1161_REDUCE_OMASA_HEAP
OMASA_ENCODER_ENERGY_HANDLE hOmasaEnergy = hOmasaData->hOmasaEnergy;
#endif
ref_exp = 0;
norm_buff = MAX16B;
......@@ -1133,8 +1167,14 @@ static void ivas_omasa_param_est_enc_fx(
move16();
move16();
}
#ifdef FIX_1161_REDUCE_OMASA_HEAP
set_zero_fx( hOmasaEnergy->energy_ism_fx[block_m_idx], num_freq_bands );
set16_fx( hOmasaEnergy->energy_ism_fx_e[block_m_idx], 0, num_freq_bands );
#else
set_zero_fx( hOmasaData->energy_ism_fx[block_m_idx], num_freq_bands );
set16_fx( hOmasaData->energy_ism_fx_e[block_m_idx], 0, num_freq_bands );
#endif
FOR( ts = mrange[0]; ts < mrange[1]; ts++ )
{
norm_buff = MAX16B;
......@@ -1174,7 +1214,11 @@ static void ivas_omasa_param_est_enc_fx(
{
temp = L_add( Mpy_32_32( Chnl_RealBuffer_fx[k][j], Chnl_RealBuffer_fx[k][j] ), Mpy_32_32( Chnl_ImagBuffer_fx[k][j], Chnl_ImagBuffer_fx[k][j] ) );
temp_e = sub( 62, shl( q, 1 ) );
#ifdef FIX_1161_REDUCE_OMASA_HEAP
hOmasaEnergy->energy_ism_fx[block_m_idx][i] = BASOP_Util_Add_Mant32Exp( hOmasaEnergy->energy_ism_fx[block_m_idx][i], hOmasaEnergy->energy_ism_fx_e[block_m_idx][i], temp, temp_e, &hOmasaEnergy->energy_ism_fx_e[block_m_idx][i] ); /*2q-31*/
#else
hOmasaData->energy_ism_fx[block_m_idx][i] = BASOP_Util_Add_Mant32Exp( hOmasaData->energy_ism_fx[block_m_idx][i], hOmasaData->energy_ism_fx_e[block_m_idx][i], temp, temp_e, &hOmasaData->energy_ism_fx_e[block_m_idx][i] ); /*2q-31*/
#endif
move32();
}
}
......@@ -1334,6 +1378,7 @@ static void ivas_omasa_param_est_enc_fx(
move32();
move32();
}
return;
}
......@@ -1362,6 +1407,10 @@ static void ivas_omasa_energy_and_ratio_est_fx(
Word16 norm_Chnl;
Word16 temp_e; /* to store temporary exp*/
Word16 energy_ratio_ism_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS]; /*q30*/
#ifdef FIX_1161_REDUCE_OMASA_HEAP
OMASA_ENCODER_ENERGY_HANDLE hOmasaEnergy = hOmasaData->hOmasaEnergy;
#endif
num_freq_bands = hOMasa->nbands;
l_ts = shr( input_frame, 4 ); /*input_frame / CLDFB_NO_COL_MAX*/
q_cldfb = q_data;
......@@ -1369,6 +1418,7 @@ static void ivas_omasa_energy_and_ratio_est_fx(
move16(); /*q_cldfb*/
set_zero_fx( &Chnl_RealBuffer_fx[0][0], MAX_NUM_OBJECTS * CLDFB_NO_CHANNELS_MAX );
set_zero_fx( &Chnl_ImagBuffer_fx[0][0], MAX_NUM_OBJECTS * CLDFB_NO_CHANNELS_MAX );
/* do processing over all CLDFB time slots */
FOR( block_m_idx = 0; block_m_idx < hOMasa->nSubframes; block_m_idx++ )
{
......@@ -1380,11 +1430,21 @@ static void ivas_omasa_energy_and_ratio_est_fx(
/* Reset variable */
FOR( i = 0; i < hOMasa->nbands; i++ )
{
#ifdef FIX_1161_REDUCE_OMASA_HEAP
set_zero_fx( hOmasaEnergy->energy_ratio_ism_fx[block_m_idx][i], nchan_ism );
#else
set_zero_fx( hOmasaData->energy_ratio_ism_fx[block_m_idx][i], nchan_ism );
#endif
set16_fx( energy_ratio_ism_e[block_m_idx][i], 0, nchan_ism );
}
#ifdef FIX_1161_REDUCE_OMASA_HEAP
set_zero_fx( hOmasaEnergy->energy_ism_fx[block_m_idx], num_freq_bands );
set16_fx( hOmasaEnergy->energy_ism_fx_e[block_m_idx], 0, num_freq_bands );
#else
set_zero_fx( hOmasaData->energy_ism_fx[block_m_idx], num_freq_bands );
set16_fx( hOmasaData->energy_ism_fx_e[block_m_idx], 0, num_freq_bands );
#endif
/* Compute CLDFB */
FOR( ts = mrange[0]; ts < mrange[1]; ts++ )
{
......@@ -1409,6 +1469,7 @@ static void ivas_omasa_energy_and_ratio_est_fx(
scale_sig32( Chnl_ImagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, norm_Chnl );
}
q_cldfb = add( q_cldfb, norm_Chnl );
/* Compute energy */
FOR( i = 0; i < num_freq_bands; i++ )
{
......@@ -1428,8 +1489,13 @@ static void ivas_omasa_energy_and_ratio_est_fx(
tmp64 = W_shl( tmp64, tmpNorm );
tftile_energy_fx = W_extract_h( tmp64 );
tftile_energy_e = sub( tftile_energy_e, tmpNorm );
#ifdef FIX_1161_REDUCE_OMASA_HEAP
hOmasaEnergy->energy_ism_fx[block_m_idx][i] = BASOP_Util_Add_Mant32Exp( hOmasaEnergy->energy_ism_fx[block_m_idx][i], hOmasaEnergy->energy_ism_fx_e[block_m_idx][i], tftile_energy_fx, tftile_energy_e, &hOmasaEnergy->energy_ism_fx_e[block_m_idx][i] );
hOmasaEnergy->energy_ratio_ism_fx[block_m_idx][i][k] = BASOP_Util_Add_Mant32Exp( hOmasaEnergy->energy_ratio_ism_fx[block_m_idx][i][k], energy_ratio_ism_e[block_m_idx][i][k], tftile_energy_fx, tftile_energy_e, &energy_ratio_ism_e[block_m_idx][i][k] );
#else
hOmasaData->energy_ism_fx[block_m_idx][i] = BASOP_Util_Add_Mant32Exp( hOmasaData->energy_ism_fx[block_m_idx][i], hOmasaData->energy_ism_fx_e[block_m_idx][i], tftile_energy_fx, tftile_energy_e, &hOmasaData->energy_ism_fx_e[block_m_idx][i] );
hOmasaData->energy_ratio_ism_fx[block_m_idx][i][k] = BASOP_Util_Add_Mant32Exp( hOmasaData->energy_ratio_ism_fx[block_m_idx][i][k], energy_ratio_ism_e[block_m_idx][i][k], tftile_energy_fx, tftile_energy_e, &energy_ratio_ism_e[block_m_idx][i][k] );
#endif
move32();
move32();
}
......@@ -1444,6 +1510,15 @@ static void ivas_omasa_energy_and_ratio_est_fx(
move64();
FOR( j = 0; j < nchan_ism; j++ )
{
#ifdef FIX_1161_REDUCE_OMASA_HEAP
hOmasaEnergy->energy_ratio_ism_fx[block_m_idx][i][j] = L_deposit_h( BASOP_Util_Divide3232_Scale( hOmasaEnergy->energy_ratio_ism_fx[block_m_idx][i][j], L_add( hOmasaEnergy->energy_ism_fx[block_m_idx][i], EPSILON_FX ), &temp_e ) );
move32();
temp_e = add( temp_e, sub( energy_ratio_ism_e[block_m_idx][i][j], hOmasaEnergy->energy_ism_fx_e[block_m_idx][i] ) );
hOmasaEnergy->energy_ratio_ism_fx[block_m_idx][i][j] = L_shl( hOmasaEnergy->energy_ratio_ism_fx[block_m_idx][i][j], sub( temp_e, 1 ) ); /* scaling to q30 */
move32();
ism_ratio_sum_fx = W_add( ism_ratio_sum_fx, hOmasaEnergy->energy_ratio_ism_fx[block_m_idx][i][j] );
#else
hOmasaData->energy_ratio_ism_fx[block_m_idx][i][j] = L_deposit_h( BASOP_Util_Divide3232_Scale( hOmasaData->energy_ratio_ism_fx[block_m_idx][i][j], L_add( hOmasaData->energy_ism_fx[block_m_idx][i], EPSILON_FX ), &temp_e ) );
move32();
temp_e = add( temp_e, sub( energy_ratio_ism_e[block_m_idx][i][j], hOmasaData->energy_ism_fx_e[block_m_idx][i] ) );
......@@ -1451,13 +1526,18 @@ static void ivas_omasa_energy_and_ratio_est_fx(
hOmasaData->energy_ratio_ism_fx[block_m_idx][i][j] = L_shl( hOmasaData->energy_ratio_ism_fx[block_m_idx][i][j], sub( temp_e, 1 ) ); /* scaling to q30 */
move32();
ism_ratio_sum_fx = W_add( ism_ratio_sum_fx, hOmasaData->energy_ratio_ism_fx[block_m_idx][i][j] );
#endif
}
IF( ism_ratio_sum_fx == 0 )
{
Word16 temp_ism_ratio = BASOP_Util_Divide1616_Scale( 1, nchan_ism, &temp_e );
FOR( j = 0; j < nchan_ism; j++ )
{
#ifdef FIX_1161_REDUCE_OMASA_HEAP
hOmasaEnergy->energy_ratio_ism_fx[block_m_idx][i][j] = L_shl( temp_ism_ratio, add( temp_e, 15 ) ); /*scaling to q30*/
#else
hOmasaData->energy_ratio_ism_fx[block_m_idx][i][j] = L_shl( temp_ism_ratio, add( temp_e, 15 ) ); /*scaling to q30*/
#endif
move32();
}
}
......@@ -1572,6 +1652,7 @@ void computeIntensityVector_enc_fx(
}
norm = 63;
move16();
IF( intensity_real64[0][i] != 0 )
{
norm = s_min( norm, W_norm( intensity_real64[0][i] ) );
......@@ -1597,6 +1678,7 @@ void computeIntensityVector_enc_fx(
return;
}
static void computeReferencePower_omasa_ivas_fx(
const Word16 *band_grouping, /* i : Band grouping for estimation */
Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal Q6*/
......
......@@ -877,13 +877,27 @@ typedef struct ivas_omasa_enc_state_structure
} OMASA_ENC_STATE, *OMASA_ENC_HANDLE;
#ifdef FIX_1161_REDUCE_OMASA_HEAP
typedef struct ivas_omasa_encoder_energy_struct
{
Word32 energy_ism_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
Word16 energy_ism_fx_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
Word32 energy_ratio_ism_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS];
Word32 q_energy_ratio_ism_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS]; /* Q30 */
typedef struct ivas_omasa_encoder_one_data_struct
} OMASA_ENCODER_ENERGY_STATE, *OMASA_ENCODER_ENERGY_HANDLE;
#endif
typedef struct ivas_omasa_encoder_data_struct
{
#ifdef FIX_1161_REDUCE_OMASA_HEAP
OMASA_ENCODER_ENERGY_HANDLE hOmasaEnergy;
#else
Word32 energy_ism_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
Word16 energy_ism_fx_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
Word32 energy_ratio_ism_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS]; /*q30*/
Word32 q_energy_ratio_ism_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS]; /* Q30 */
#endif
Word32 masa_to_total_energy_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; /* Q30 */
Word16 lp_noise_CPE_fx; /* LP filtered total noise estimation Q8 */
......
......@@ -2473,7 +2473,11 @@ void noise_est_ivas_fx(
}
num = div_s( num, den ); // Q15+ExpNum-ExpDen
#ifdef FIX_ISSUE_1811_EXCEEDING_W_SHIFTS
w_tmp = W_shl( num, s_min( 63, sub( q_fr_bands, sub( ExpNum, ExpDen ) ) ) ); // q_fr_bands+15
#else
w_tmp = W_shl( num, sub( q_fr_bands, sub( ExpNum, ExpDen ) ) ); // q_fr_bands+15
#endif
w_sum_num = W_add( w_sum_num, w_tmp );
pt1++;
......
......@@ -583,7 +583,11 @@ void swb_pre_proc_fx(
IF( NE_16( st_fx->last_extl, SWB_BWE ) && NE_16( st_fx->last_extl, FB_BWE ) )
{
/* resample 48 kHz to 32kHz */
#ifdef NONBE_1244_FIX_SWB_BWE_MEMORY
IF( ( st_fx->last_bwidth == FB && st_fx->element_mode == EVS_MONO ) || ( EQ_16( st_fx->bwidth, FB ) && st_fx->element_mode > EVS_MONO ) ) // note: once EVS i CR fixed, the condition will simplify to "if ( st->bwidth == FB )" only
#else
IF( EQ_16( st_fx->last_bwidth, FB ) )
#endif
{
inner_frame = L_FRAME48k;
inner_Fs = 48000;
......@@ -986,7 +990,11 @@ void swb_pre_proc_ivas_fx(
IF( NE_16( st->last_extl, SWB_BWE ) && NE_16( st->last_extl, FB_BWE ) )
{
/* resample 48 kHz to 32kHz */
#ifdef NONBE_1244_FIX_SWB_BWE_MEMORY
IF( ( st->last_bwidth == FB && st->element_mode == EVS_MONO ) || ( EQ_16( st->bwidth, FB ) && st->element_mode > EVS_MONO ) ) // note: once EVS i CR fixed, the condition will simplify to "if ( st->bwidth == FB )" only
#else
IF( EQ_16( st->last_bwidth, FB ) )
#endif
{
inner_frame = L_FRAME48k;
move16();
......
......@@ -2509,7 +2509,12 @@ void tcx_noise_factor_ivas_fx(
Word16 i, k, win, segmentOffset, j;
Word32 sqErrorNrg = 0, n;
move32();
#ifdef FIX_1781_SPECTRAL_GAPS
Word32 inv_gain2, tilt_factor;
Word16 inv_gain2_e, nTransWidth_1, exp_sqErrorNrg = 0;
#else
Word16 inv_gain2, inv_gain2_e, tilt_factor, nTransWidth_1, exp_sqErrorNrg = 0;
#endif
move16();
Word32 accu1, accu2, tmp32;
Word16 tmp1, tmp2, s;
......@@ -2539,13 +2544,25 @@ void tcx_noise_factor_ivas_fx(
/* tilt_factor = 1.0f /(float)pow(max(0.375f, tiltCompFactor), 1.0f/(float)L_frame); */
tmp32 = BASOP_Util_Log2( L_deposit_h( s_max( 0x3000, tiltCompFactor ) ) ); /* 6Q25 */
tmp32 = L_shr( Mpy_32_16_1( tmp32, negate( tmp1 ) ), 6 );
#ifdef FIX_1781_SPECTRAL_GAPS
tilt_factor = BASOP_Util_InvLog2( L_sub( tmp32, 0x2000000 ) ); /* 1Q30 */
#else
tilt_factor = round_fx( BASOP_Util_InvLog2( L_sub( tmp32, 0x2000000 ) ) ); /* 1Q14 */
#endif
/* inv_gain2 = 1.0f / ((float)(nTransWidth * nTransWidth) * gain_tcx); */
tmp32 = L_mult( imult1616( nTransWidth, nTransWidth ), gain_tcx ); /* 15Q16 */
#ifdef FIX_1781_SPECTRAL_GAPS
inv_gain2 = BASOP_Util_Divide3232_Scale_newton( MAX_32, tmp32, &inv_gain2_e );
#else
inv_gain2 = BASOP_Util_Divide3232_Scale( MAX_32, tmp32, &inv_gain2_e );
#endif
inv_gain2_e = add( inv_gain2_e, sub( 0, add( 15, gain_tcx_e ) ) );
#ifdef FIX_1781_SPECTRAL_GAPS
inv_gain2 = L_shr( inv_gain2, 2 ); /* 2 bits headroom */
#else
inv_gain2 = shr( inv_gain2, 2 ); /* 2 bits headroom */
#endif
inv_gain2_e = add( inv_gain2_e, 2 );
/* find last nonzero line below iFirstLine, use it as start offset */
......@@ -2571,7 +2588,11 @@ void tcx_noise_factor_ivas_fx(
/* inv_gain2 *= (float)pow(tilt_factor, (float)i); */
FOR( k = 0; k < i; k++ )
{
#ifdef FIX_1781_SPECTRAL_GAPS
inv_gain2 = L_shl( Mpy_32_32( inv_gain2, tilt_factor ), 1 );
#else
inv_gain2 = shl( mult( inv_gain2, tilt_factor ), 1 );
#endif
}
i = add( i, 1 );
......@@ -2639,7 +2660,11 @@ void tcx_noise_factor_ivas_fx(
FOR( ; i < lowpassLine; i++ )
{
#ifdef FIX_1781_SPECTRAL_GAPS
inv_gain2 = L_shl( Mpy_32_32( inv_gain2, tilt_factor ), 1 );
#else
inv_gain2 = shl( mult( inv_gain2, tilt_factor ), 1 );
#endif
IF( sqQ[i] != 0 ) /* current line is not zero, so reset pointers */
{
......@@ -2707,8 +2732,12 @@ void tcx_noise_factor_ivas_fx(
win = add( win, 1 );
}
/* update segment sum: magnitudes scaled by smoothing function */
#ifdef FIX_1781_SPECTRAL_GAPS
sqQ[i] = Mpy_32_32( imult3216( L_abs( x_orig[i] ), win ), inv_gain2 );
#else
sqQ[i] = Mpy_32_16_1( imult3216( L_abs( x_orig[i] ), win ), inv_gain2 );
move32();
#endif
exp_spQ[i] = add( x_orig_e, inv_gain2_e );
move16();
}
......
......@@ -4007,10 +4007,17 @@ static void matrixTransp1Mul_fx(
{
FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ )
{
#ifdef FIX_ISSUE_1811_EXCEEDING_W_SHIFTS
outRe_fx[chA][chB] = W_extract_h( W_shl( tmp_outRe_fx[chA][chB], s_max( -63, sub( q_common, q_tmp_outRe_fx[chA][chB] ) ) ) );
move32();
outIm_fx[chA][chB] = W_extract_h( W_shl( tmp_outIm_fx[chA][chB], s_max( -63, sub( q_common, q_tmp_outIm_fx[chA][chB] ) ) ) );
move32();
#else
outRe_fx[chA][chB] = W_extract_h( W_shl( tmp_outRe_fx[chA][chB], sub( q_common, q_tmp_outRe_fx[chA][chB] ) ) );
move32();
outIm_fx[chA][chB] = W_extract_h( W_shl( tmp_outIm_fx[chA][chB], sub( q_common, q_tmp_outIm_fx[chA][chB] ) ) );
move32();
#endif
}
}
*q_out = sub( q_common, 32 );
......
......@@ -1620,11 +1620,11 @@ void ivas_create_masa_out_meta_fx(
Word32 surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated surround coherence */
Word16 energyRatio_q,
Word16 spreadCoherence_q,
Word16 surroundingCoherence_q
)
Word16 surroundingCoherence_q )
{
#ifndef FIX_1121_MASA_DESCRIPTOR
const UWord8 ivasmasaFormatDescriptor[8] = { 0x49, 0x56, 0x41, 0x53, 0x4D, 0x41, 0x53, 0x41 }; /* "IVASMASA" */
#endif
Word16 i, sf, band;
UWord8 numFrequencyBands;
UWord8 numDirections;
......
......@@ -459,7 +459,12 @@ ivas_error ivas_td_binaural_renderer_unwrap_fx(
}
/* Render subframe */
#ifdef NONBE_FIX_1196_TD_HEADTRACKING_INTERPOLATION
IF( NE_32( ( error = TDREND_GetMix_fx( hBinRendererTd, output_fx, subframe_length, subframe_idx ) ), IVAS_ERR_OK ) )
#else
IF( NE_32( ( error = TDREND_GetMix_fx( hBinRendererTd, output_fx, subframe_length, subframe_idx, ism_md_subframe_update ) ), IVAS_ERR_OK ) )
#endif
{
return error;
}
......@@ -502,8 +507,12 @@ ivas_error TDREND_GetMix_fx(
BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */
Word32 *output[], /* i/o: ISM object synth / rendered output in 0,1 Q11 */
const Word16 subframe_length, /* i/o: subframe length */
#ifdef NONBE_FIX_1196_TD_HEADTRACKING_INTERPOLATION
const Word16 subframe_idx /* i : Subframe index to 5 ms subframe */
#else
const Word16 subframe_idx, /* i : Subframe index to 5 ms subframe */
const Word16 ism_md_subframe_update /* i : Number of subframes to delay ism metadata to sync with audio */
#endif
)
{
Word16 i;
......@@ -515,14 +524,18 @@ ivas_error TDREND_GetMix_fx(
Word32 hrf_left_delta[SFX_SPAT_BIN_MAX_FILTER_LENGTH];
Word32 hrf_right_delta[SFX_SPAT_BIN_MAX_FILTER_LENGTH];
Word16 intp_count;
#ifndef NONBE_FIX_1196_TD_HEADTRACKING_INTERPOLATION
Word16 subframe_update_flag;
#endif
Word16 hrf_left_delta_e = 0, hrf_right_delta_e = 0;
move16();
move16();
#ifndef NONBE_FIX_1196_TD_HEADTRACKING_INTERPOLATION
subframe_update_flag = (Word16) EQ_16( subframe_idx, ism_md_subframe_update );
move16();
#endif
error = IVAS_ERR_OK;
move32();
/* Clear the output buffer to accumulate rendered sources */
......@@ -548,12 +561,21 @@ ivas_error TDREND_GetMix_fx(
test();
IF( EQ_16( SrcRend_p->PlayStatus, TDREND_PLAYSTATUS_PLAYING ) && ( hBinRendererTd->Listener_p->PoseUpdated || SrcSpatial_p->Updated ) )
{
#ifdef NONBE_FIX_1196_TD_HEADTRACKING_INTERPOLATION
TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx( hBinRendererTd, SrcRend_p, SrcSpatial_p,
Src_p->hrf_left_prev_fx, &Src_p->hrf_left_prev_e, Src_p->hrf_right_prev_fx, &Src_p->hrf_right_prev_e,
hrf_left_delta, &hrf_left_delta_e, hrf_right_delta, &hrf_right_delta_e,
&intp_count, &Src_p->filterlength, &Src_p->itd,
&Src_p->Gain_fx,
Src_p );
#else
TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx( hBinRendererTd, SrcRend_p, SrcSpatial_p,
Src_p->hrf_left_prev_fx, &Src_p->hrf_left_prev_e, Src_p->hrf_right_prev_fx, &Src_p->hrf_right_prev_e,
hrf_left_delta, &hrf_left_delta_e, hrf_right_delta, &hrf_right_delta_e,
&intp_count, &Src_p->filterlength, &Src_p->itd,
&Src_p->Gain_fx,
Src_p, subframe_update_flag );
#endif
}
/* Render source if needed */
......