Skip to content
......@@ -287,17 +287,15 @@ void swb_pre_proc(
FD_BWE_ENC_HANDLE hBWE_FD;
int32_t inner_Fs, input_Fs;
float old_input[NS2SA( 48000, DELAY_FD_BWE_ENC_NS + DELAY_FIR_RESAMPL_NS ) + L_FRAME48k];
float spchTmp[640];
int16_t i, j;
float spchTmp[L_FRAME32k], spchTmp2[L_FRAME32k];
int16_t i, j, L_resamp;
int16_t startB, endB;
float *realBufferFlipped[CLDFB_NO_COL_MAX];
float *imagBufferFlipped[CLDFB_NO_COL_MAX];
float realBufferTmp[CLDFB_NO_COL_MAX][20];
float imagBufferTmp[CLDFB_NO_COL_MAX][20];
int16_t ts, nB, uB;
float sign;
float lbEner, v, t;
float regression;
float sign, lbEner, v, t, regression;
const float *thr, *regV;
int16_t Sample_Delay_SWB_BWE32k, lMemRecalc32k, dft_ovl32k;
......@@ -677,7 +675,7 @@ void swb_pre_proc(
}
else
{
if ( st->bwidth == FB || st->core == ACELP_CORE || ( st->element_mode == IVAS_CPE_DFT && input_Fs == 48000 ) )
if ( ( st->bwidth == FB || st->core == ACELP_CORE ) && ( st->element_mode == EVS_MONO ) )
{
set_f( hBWE_TD->old_speech_shb, 0, L_LOOK_16k + L_SUBFR16k );
set_f( shb_speech, 0, L_FRAME16k ); /* shb_speech for FB/SWB BWE_HIGHRATE is not used at 64kbps */
......@@ -689,23 +687,47 @@ void swb_pre_proc(
st->hBWE_TD->prev_pow_exc16kWhtnd = 1.0f;
st->hBWE_TD->prev_mix_factor = 1.0f;
st->hBWE_TD->prev_Env_error = 0.0f;
}
else
{
if ( st->element_mode == IVAS_CPE_DFT )
{
set_f( hCPE->hStereoDft->output_mem_dmx_16k_shb, 0, STEREO_DFT_OVL_16k );
if ( st->L_frame == L_FRAME )
{
L_resamp = 560; /* 6.4 kHz core -> 6 - 14 kHz SHB target. 20 ms is 560 samples in 28 kHz sample rate */
}
else
{
L_resamp = 620; /* 8 kHz core -> 7.5 - 15.5 kHz SHB target. 20 ms is 620 samples in 31 kHz sample rate */
}
/* Dirty downsampling to match Nyquist to upper frequency limit of target */
lerp( st->input, new_swb_speech, L_resamp, (int16_t) ( input_Fs / 50 ) );
/* flip the spectrum */
mvr2r( new_swb_speech, spchTmp, L_resamp );
for ( i = 0; i < L_resamp; i = i + 2 )
{
spchTmp[i] = -spchTmp[i];
}
/* Dirty upsampling to match Nyquist/2 to lower frequency limit of target (reversed spectrum)*/
lerp( spchTmp, spchTmp2, L_FRAME32k, L_resamp );
mvr2r( spchTmp2, spchTmp, L_FRAME32k );
}
else
{
/* flip the spectrm */
/* flip the spectrum */
mvr2r( new_swb_speech, spchTmp, L_FRAME32k );
for ( i = 0; i < L_FRAME32k; i = i + 2 )
{
spchTmp[i] = -spchTmp[i];
}
}
Decimate_allpass_steep( spchTmp, hBWE_TD->state_ana_filt_shb, L_FRAME32k, shb_speech );
mvr2r( shb_speech + L_FRAME16k - ( L_LOOK_16k + L_SUBFR16k ), hBWE_TD->old_speech_shb, L_LOOK_16k + L_SUBFR16k );
/*Compute the past overlap for potential next iDFTs SHB*/
......@@ -723,13 +745,16 @@ void swb_pre_proc(
/* Reset CLDFB synthesis buffer */
set_f( st->cldfbSynTd->cldfb_state, 0.0f, st->cldfbSynTd->p_filter_length );
}
else
{
hCPE->hStereoDft->flip_sign = -hCPE->hStereoDft->flip_sign; /* Make sure sign is updated even if DFT SHB target is not generated */
}
}
/* Memory reset to compensate for 0.9375 ms offset when transitioning from IO to SWB */
/* When switching from n >1 to n = 1, we keep the enc/dec delay as 8.75/3.25 and below code not needed;
only when n = 1 start, it will be 9.6875/2.3125 in that case this reset is needed for IO->BWE.*/
/* IVAS_fmToDo: revisit for IVAS (the condition is currently entered for both TD and DFT stereo - is it desirable?) */
if ( st->last_extl == -1 )
if ( st->last_extl == -1 && st->element_mode == EVS_MONO )
{
delay = NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS );
for ( i = 0; i < delay; i++ )
......
......@@ -1509,7 +1509,7 @@ void ProcessStereoIGF(
Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */
int16_t ms_mask[2][MAX_SFB], /* i : bandwise MS mask */
float *pITFMDCTSpectrum[CPE_CHANNELS][2], /* i : MDCT spectrum fir ITF */
float pPowerSpectrum[CPE_CHANNELS][N_MAX], /* i : MDCT^2 + MDST^2 spectrum, or estimate */
float *pPowerSpectrum[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */
float *pPowerSpectrumMsInv[CPE_CHANNELS][2], /* i : inverse power spectrum */
float *inv_spectrum[CPE_CHANNELS][2], /* i : inverse spectrum */
const int16_t frameno, /* i : flag indicating index of current subfr. */
......
......@@ -39,7 +39,7 @@
#include "prot.h"
#include "ivas_prot.h"
#include "ivas_stat_dec.h"
#include "ivas_rom_dec.h"
#include "ivas_rom_rend.h"
#ifdef DEBUGGING
#include "debug.h"
#endif
......@@ -108,7 +108,7 @@ ivas_error ivas_sba_get_hoa_dec_matrix(
/* Allocate memory */
assert( *hoa_dec_mtx == NULL && "hoa_dec_mtx != NULL" );
if ( ( *hoa_dec_mtx = (float *) count_malloc( SBA_NHARM_HOA3 * MAX_OUTPUT_CHANNELS * sizeof( float ) ) ) == NULL )
if ( ( *hoa_dec_mtx = (float *) count_malloc( SBA_NHARM_HOA3 * ( hOutSetup.nchan_out_woLFE ) * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "ALLRAD: Cannot allocate memory!" ) );
}
......
......@@ -37,7 +37,7 @@
#include "prot.h"
#include "cnst.h"
#include "ivas_cnst.h"
#include "ivas_rom_dec.h"
#include "ivas_rom_rend.h"
#include "ivas_rom_com.h"
#include "ivas_rom_binauralRenderer.h"
#ifdef DEBUGGING
......@@ -186,6 +186,87 @@ static ivas_error ivas_binRenderer_convModuleOpen(
}
}
/* allocate memory for filter states */
if ( ( hBinRenConvModule->filterTapsLeftReal = (float ***) count_malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
}
if ( ( hBinRenConvModule->filterTapsLeftImag = (float ***) count_malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
}
if ( ( hBinRenConvModule->filterTapsRightReal = (float ***) count_malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
}
if ( ( hBinRenConvModule->filterTapsRightImag = (float ***) count_malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
}
for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
{
if ( ( hBinRenConvModule->filterTapsLeftReal[bandIdx] = (float **) count_malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
}
if ( ( hBinRenConvModule->filterTapsLeftImag[bandIdx] = (float **) count_malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
}
if ( ( hBinRenConvModule->filterTapsRightReal[bandIdx] = (float **) count_malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
}
if ( ( hBinRenConvModule->filterTapsRightImag[bandIdx] = (float **) count_malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
}
}
if ( ( hBinRenConvModule->filterStatesLeftReal = (float ***) count_malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
}
if ( ( hBinRenConvModule->filterStatesLeftImag = (float ***) count_malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
}
for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
{
if ( ( hBinRenConvModule->filterStatesLeftReal[bandIdx] = (float **) count_malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
}
if ( ( hBinRenConvModule->filterStatesLeftImag[bandIdx] = (float **) count_malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
}
for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
{
if ( ( hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx] = (float *) count_malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
}
if ( ( hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx] = (float *) count_malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
}
}
}
/* set memories */
for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
{
for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
......@@ -225,8 +306,8 @@ static ivas_error ivas_binRenderer_convModuleOpen(
if ( renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM && hRenderConfig->roomAcoustics.use_brir )
{
/* set the memories to zero */
set_zero( hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx], hBinRenConvModule->numTaps );
set_zero( hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx], hBinRenConvModule->numTaps );
set_zero( hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx], hBinRenConvModule->numTapsArray[bandIdx] );
set_zero( hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx], hBinRenConvModule->numTapsArray[bandIdx] );
if ( isLoudspeaker )
{
......@@ -290,6 +371,7 @@ static void ivas_binaural_obtain_DMX(
{
int16_t chIdx, bandIdx, k;
// ToDo: hBinRenderer->ivas_format is never set to ISM_FORMAT -> TBV
if ( hBinRenderer->ivas_format == MC_FORMAT || hBinRenderer->ivas_format == ISM_FORMAT )
{
/* Obtain the downmix */
......@@ -405,8 +487,6 @@ ivas_error ivas_binRenderer_open(
{
BINAURAL_RENDERER_HANDLE hBinRenderer;
int16_t convBand, chIdx, k;
float t60[CLDFB_NO_CHANNELS_MAX];
float ene[CLDFB_NO_CHANNELS_MAX];
ivas_error error;
error = IVAS_ERR_OK;
......@@ -500,23 +580,11 @@ ivas_error ivas_binRenderer_open(
/* Allocate memories needed for reverb module */
if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM && st_ivas->hRenderConfig->roomAcoustics.late_reverb_on )
{
if ( ( error = ivas_binaural_reverb_open( &( hBinRenderer->hReverb ), hBinRenderer->conv_band, hBinRenderer->timeSlots ) ) != IVAS_ERR_OK )
if ( ( error = ivas_binaural_reverb_open( &( hBinRenderer->hReverb ), hBinRenderer->conv_band, hBinRenderer->timeSlots, &( st_ivas->hRenderConfig->roomAcoustics ), st_ivas->hIntSetup.output_config, st_ivas->hDecoderConfig->output_Fs, RENDERER_BINAURAL_FASTCONV_ROOM ) ) != IVAS_ERR_OK )
{
return error;
}
if ( !st_ivas->hRenderConfig->roomAcoustics.override )
{
ivas_binaural_reverb_setReverbTimes( hBinRenderer->hReverb, st_ivas->hDecoderConfig->output_Fs, fastconvReverberationTimes, fastconvReverberationEneCorrections );
ivas_binaural_reverb_setPreDelay( hBinRenderer->hReverb, 10 );
}
else
{
ivas_reverb_prepare_cldfb_params( &st_ivas->hRenderConfig->roomAcoustics, st_ivas->hIntSetup.output_config, st_ivas->hRenderConfig->roomAcoustics.use_brir, st_ivas->hDecoderConfig->output_Fs, t60, ene );
ivas_binaural_reverb_setReverbTimes( hBinRenderer->hReverb, st_ivas->hDecoderConfig->output_Fs, t60, ene );
ivas_binaural_reverb_setPreDelay( hBinRenderer->hReverb, (int16_t) roundf( 48000.0f * st_ivas->hRenderConfig->roomAcoustics.acousticPreDelay / CLDFB_NO_CHANNELS_MAX ) );
}
hBinRenderer->hReverb->useBinauralCoherence = 1;
/* initialize the dmx matrix */
for ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ )
{
......@@ -561,6 +629,86 @@ ivas_error ivas_binRenderer_open(
}
/*-------------------------------------------------------------------------
* ivas_binRenderer_convModuleClose()
*
* Close convolution module handle of fastconv binaural renderer
*------------------------------------------------------------------------*/
static void ivas_binRenderer_convModuleClose(
BINAURAL_RENDERER_HANDLE *hBinRenderer /* i/o: fastconv binaural renderer handle */
)
{
int16_t bandIdx, chIdx;
BINRENDERER_CONV_MODULE_HANDLE hBinRenConvModule;
hBinRenConvModule = ( *hBinRenderer )->hBinRenConvModule;
if ( hBinRenConvModule == NULL )
{
return;
}
for ( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ )
{
count_free( hBinRenConvModule->filterTapsLeftReal[bandIdx] );
hBinRenConvModule->filterTapsLeftReal[bandIdx] = NULL;
count_free( hBinRenConvModule->filterTapsLeftImag[bandIdx] );
hBinRenConvModule->filterTapsLeftImag[bandIdx] = NULL;
count_free( hBinRenConvModule->filterTapsRightReal[bandIdx] );
hBinRenConvModule->filterTapsRightReal[bandIdx] = NULL;
count_free( hBinRenConvModule->filterTapsRightImag[bandIdx] );
hBinRenConvModule->filterTapsRightImag[bandIdx] = NULL;
}
count_free( hBinRenConvModule->filterTapsLeftReal );
hBinRenConvModule->filterTapsLeftReal = NULL;
count_free( hBinRenConvModule->filterTapsLeftImag );
hBinRenConvModule->filterTapsLeftImag = NULL;
count_free( hBinRenConvModule->filterTapsRightReal );
hBinRenConvModule->filterTapsRightReal = NULL;
count_free( hBinRenConvModule->filterTapsRightImag );
hBinRenConvModule->filterTapsRightImag = NULL;
for ( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ )
{
for ( chIdx = 0; chIdx < ( *hBinRenderer )->nInChannels; chIdx++ )
{
count_free( hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx] );
hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx] = NULL;
count_free( hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx] );
hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx] = NULL;
}
count_free( hBinRenConvModule->filterStatesLeftReal[bandIdx] );
hBinRenConvModule->filterStatesLeftReal[bandIdx] = NULL;
count_free( hBinRenConvModule->filterStatesLeftImag[bandIdx] );
hBinRenConvModule->filterStatesLeftImag[bandIdx] = NULL;
}
count_free( hBinRenConvModule->filterStatesLeftReal );
hBinRenConvModule->filterStatesLeftReal = NULL;
count_free( hBinRenConvModule->filterStatesLeftImag );
hBinRenConvModule->filterStatesLeftImag = NULL;
count_free( ( *hBinRenderer )->hBinRenConvModule );
( *hBinRenderer )->hBinRenConvModule = NULL;
return;
}
/*-------------------------------------------------------------------------
* ivas_binRenderer_close()
*
......@@ -578,8 +726,7 @@ void ivas_binRenderer_close(
if ( ( *hBinRenderer )->hBinRenConvModule != NULL )
{
count_free( ( *hBinRenderer )->hBinRenConvModule );
( *hBinRenderer )->hBinRenConvModule = NULL;
ivas_binRenderer_convModuleClose( hBinRenderer );
}
if ( ( *hBinRenderer )->hReverb != NULL )
......@@ -775,10 +922,10 @@ void ivas_binRenderer(
/* Obtain the binaural dmx and compute the reverb */
if ( hBinRenderer->hReverb != NULL )
{
float reverbRe[2][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
float reverbIm[2][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
float inRe[2][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
float inIm[2][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
float reverbRe[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
float reverbIm[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
float inRe[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
float inIm[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
ivas_binaural_obtain_DMX( numTimeSlots, hBinRenderer, RealBuffer, ImagBuffer, inRe, inIm );
......@@ -791,7 +938,7 @@ void ivas_binRenderer(
}
}
ivas_binaural_reverb_processFrame( hBinRenderer->hReverb, 2, inRe, inIm, reverbRe, reverbIm, 0u );
ivas_binaural_reverb_processFrame( hBinRenderer->hReverb, BINAURAL_CHANNELS, inRe, inIm, reverbRe, reverbIm, 0u );
/* Add the conv module and reverb module output */
for ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ )
......
......@@ -36,6 +36,7 @@
#include "ivas_prot.h"
#include "prot.h"
#include "ivas_rom_com.h"
#include "ivas_rom_binauralRenderer.h"
#ifdef DEBUGGING
#include "debug.h"
#endif
......@@ -312,12 +313,6 @@ void ivas_binaural_reverb_setReverbTimes(
}
hReverb->binauralCoherenceDirectGains[bin] = sqrtf( 1.0f - fabsf( tmpVal ) );
/* Determine loop buffer length. The following formula is manually tuned to generate sufficiently long
* but not excessively long loops to generate reverberation. */
/* Note: the resulted length is very sensitive to the precision of the constants below (e.g. 1.45 vs. 1.45f) */
hReverb->loopBufLength[bin] = (int16_t) ( 1.45 * (int16_t) ( revTimes[bin] * 150.0 ) + 1 );
hReverb->loopBufLength[bin] = min( hReverb->loopBufLength[bin], hReverb->loopBufLengthMax[bin] );
/* Determine attenuation factor that generates the appropriate energy decay according to reverberation time */
attenuationFactorPerSample = powf( 10.0f, -3.0f * ( 1.0f / ( (float) CLDFB_SLOTS_PER_SECOND * revTimes[bin] ) ) );
hReverb->loopAttenuationFactor[bin] = powf( attenuationFactorPerSample, hReverb->loopBufLength[bin] );
......@@ -337,8 +332,10 @@ void ivas_binaural_reverb_setReverbTimes(
for ( sample = 0; sample < hReverb->loopBufLength[bin]; sample++ )
{
intendedEnergy += currentEnergy;
/* The randomization at the energy build up affects where the sparse taps are located */
energyBuildup += currentEnergy + 0.1f * ( (float) binRend_rand( hReverb ) / PCM16_TO_FLT_FAC - 0.5f );
if ( energyBuildup >= 1.0f ) /* A new filter tap is added at this condition */
{
/* Four efficient phase operations: n*pi/2, n=0,1,2,3 */
......@@ -374,11 +371,18 @@ void ivas_binaural_reverb_setReverbTimes(
ivas_error ivas_binaural_reverb_open(
REVERB_STRUCT_HANDLE *hReverbPr, /* i/o: binaural reverb handle */
const int16_t numBins, /* i : number of CLDFB bins */
const int16_t numCldfbSlotsPerFrame /* i : number of CLDFB slots per frame, i.e., reverberator block size */
const int16_t numCldfbSlotsPerFrame, /* i : number of CLDFB slots per frame */
ivas_roomAcoustics_t *roomAcoustics, /* i/o: room acoustics parameters */
const AUDIO_CONFIG output_config, /* i : output audio configuration */
const int32_t sampling_rate, /* i : sampling rate */
const RENDERER_TYPE renderer_type /* i : renderer type */
)
{
int16_t bin, chIdx, k, tmp;
int16_t bin, chIdx, k, len;
REVERB_STRUCT_HANDLE hReverb;
const float *revTimes;
float t60[CLDFB_NO_CHANNELS_MAX];
float ene[CLDFB_NO_CHANNELS_MAX];
if ( ( *hReverbPr = (REVERB_STRUCT_HANDLE) count_malloc( sizeof( REVERB_STRUCT ) ) ) == NULL )
{
......@@ -387,7 +391,7 @@ ivas_error ivas_binaural_reverb_open(
hReverb = *hReverbPr;
hReverb->useBinauralCoherence = 0;
hReverb->useBinauralCoherence = 1;
hReverb->preDelayBufferLength = 1;
hReverb->preDelayBufferIndex = 0;
......@@ -400,61 +404,102 @@ ivas_error ivas_binaural_reverb_open(
set_f( hReverb->preDelayBufferImag[k], 0.0f, hReverb->numBins );
}
if ( renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM )
{
if ( !roomAcoustics->override )
{
revTimes = fastconvReverberationTimes;
}
else
{
revTimes = t60;
}
}
else
{
revTimes = parametricReverberationTimes;
}
for ( bin = 0; bin < hReverb->numBins; bin++ )
{
/* Loop Buffer */
hReverb->loopBufLengthMax[bin] = (int16_t) ( 500 / ( 1 + bin ) + ( CLDFB_NO_CHANNELS_MAX - bin ) );
tmp = hReverb->loopBufLengthMax[bin] + hReverb->blockSize;
if ( ( hReverb->loopBufReal[bin] = (float *) count_malloc( tmp * sizeof( float ) ) ) == NULL )
len = hReverb->loopBufLengthMax[bin] + hReverb->blockSize;
if ( ( hReverb->loopBufReal[bin] = (float *) count_malloc( len * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Reverberator\n" ) );
}
if ( ( hReverb->loopBufImag[bin] = (float *) count_malloc( tmp * sizeof( float ) ) ) == NULL )
if ( ( hReverb->loopBufImag[bin] = (float *) count_malloc( len * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Reverberator\n" ) );
}
set_f( hReverb->loopBufReal[bin], 0.0f, tmp );
set_f( hReverb->loopBufImag[bin], 0.0f, tmp );
set_f( hReverb->loopBufReal[bin], 0.0f, len );
set_f( hReverb->loopBufImag[bin], 0.0f, len );
/* Determine loop buffer length. The following formula is manually tuned to generate sufficiently long
* but not excessively long loops to generate reverberation. */
/* Note: the resulted length is very sensitive to the precision of the constants below (e.g. 1.45 vs. 1.45f) */
hReverb->loopBufLength[bin] = (int16_t) ( 1.45 * (int16_t) ( revTimes[bin] * 150.0 ) + 1 );
hReverb->loopBufLength[bin] = min( hReverb->loopBufLength[bin], hReverb->loopBufLengthMax[bin] );
/* Sparse Filter Tap Locations */
for ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ )
{
tmp = hReverb->loopBufLengthMax[bin];
len = hReverb->loopBufLength[bin];
if ( ( hReverb->tapPhaseShiftType[bin][chIdx] = (int16_t *) count_malloc( tmp * sizeof( int16_t ) ) ) == NULL )
if ( ( hReverb->tapPhaseShiftType[bin][chIdx] = (int16_t *) count_malloc( len * sizeof( int16_t ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Reverberator\n" ) );
}
set_s( hReverb->tapPhaseShiftType[bin][chIdx], 0, len );
if ( ( hReverb->tapPointersReal[bin][chIdx] = (float **) count_malloc( tmp * sizeof( float * ) ) ) == NULL )
if ( ( hReverb->tapPointersReal[bin][chIdx] = (float **) count_malloc( len * sizeof( float * ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Reverberator\n" ) );
}
if ( ( hReverb->tapPointersImag[bin][chIdx] = (float **) count_malloc( tmp * sizeof( float * ) ) ) == NULL )
if ( ( hReverb->tapPointersImag[bin][chIdx] = (float **) count_malloc( len * sizeof( float * ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Reverberator\n" ) );
}
set_s( hReverb->tapPhaseShiftType[bin][chIdx], 0, tmp );
tmp = hReverb->blockSize;
if ( ( hReverb->outputBufferReal[bin][chIdx] = (float *) count_malloc( tmp * sizeof( float ) ) ) == NULL )
len = hReverb->blockSize;
if ( ( hReverb->outputBufferReal[bin][chIdx] = (float *) count_malloc( len * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Reverberator\n" ) );
}
if ( ( hReverb->outputBufferImag[bin][chIdx] = (float *) count_malloc( tmp * sizeof( float ) ) ) == NULL )
if ( ( hReverb->outputBufferImag[bin][chIdx] = (float *) count_malloc( len * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Reverberator\n" ) );
}
set_f( hReverb->outputBufferReal[bin][chIdx], 0.0f, tmp );
set_f( hReverb->outputBufferImag[bin][chIdx], 0.0f, tmp );
set_f( hReverb->outputBufferReal[bin][chIdx], 0.0f, len );
set_f( hReverb->outputBufferImag[bin][chIdx], 0.0f, len );
}
}
if ( renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM )
{
if ( !roomAcoustics->override )
{
ivas_binaural_reverb_setReverbTimes( hReverb, sampling_rate, fastconvReverberationTimes, fastconvReverberationEneCorrections );
ivas_binaural_reverb_setPreDelay( hReverb, 10 );
}
else
{
ivas_reverb_prepare_cldfb_params( roomAcoustics, output_config, roomAcoustics->use_brir, sampling_rate, t60, ene );
ivas_binaural_reverb_setReverbTimes( hReverb, sampling_rate, t60, ene );
ivas_binaural_reverb_setPreDelay( hReverb, (int16_t) roundf( 48000.0f * roomAcoustics->acousticPreDelay / CLDFB_NO_CHANNELS_MAX ) );
}
}
else
{
ivas_binaural_reverb_setReverbTimes( hReverb, sampling_rate, parametricReverberationTimes, parametricReverberationEneCorrections );
ivas_binaural_reverb_setPreDelay( hReverb, 10 );
}
return IVAS_ERR_OK;
......
......@@ -35,10 +35,14 @@
#include "prot.h"
#include "ivas_prot.h"
#include "ivas_cnst.h"
#include "ivas_rom_dec.h"
#include "ivas_rom_rend.h"
#include "ivas_stat_dec.h"
#include <math.h>
#include "ivas_rom_binaural_crend_head.h"
#ifdef EXT_RENDERER
#include "lib_rend.h"
#include "ivas_lib_rend_internal.h"
#endif
#ifdef DEBUGGING
#include "debug.h"
#endif
......@@ -68,7 +72,7 @@ static ivas_error ivas_hrtf_init(
hHrtf->gain_lfe = 0;
hHrtf->index_frequency_max_diffuse = 0;
for ( i = 0; i < IVAS_MAX_NUM_CH; i++ )
for ( i = 0; i < MAX_INTERN_CHANNELS; i++ )
{
hHrtf->inv_diffuse_weight[i] = 0;
for ( j = 0; j < BINAURAL_CHANNELS; j++ )
......@@ -673,7 +677,7 @@ ivas_error ivas_crend_open(
hCrend->lfe_delay_line = NULL;
for ( i = 0; i < IVAS_MAX_NUM_CH; i++ )
for ( i = 0; i < MAX_INTERN_CHANNELS; i++ )
{
hCrend->freq_buffer_re[i] = NULL;
hCrend->freq_buffer_im[i] = NULL;
......@@ -824,7 +828,7 @@ ivas_error ivas_crend_close(
{
if ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD )
{
for ( i = 0; i < IVAS_MAX_NUM_CH; i++ )
for ( i = 0; i < MAX_INTERN_CHANNELS; i++ )
{
if ( st_ivas->hCrend->freq_buffer_re[i] != NULL )
{
......@@ -1033,7 +1037,11 @@ ivas_error ivas_crend_process(
{
int16_t i, nchan_out, output_frame;
int16_t subframe_len, subframe_idx;
#ifdef EXT_RENDERER
float pcm_tmp[BINAURAL_CHANNELS][L_FRAME48k];
#else
float pcm_tmp[MAX_TRANSPORT_CHANNELS][L_FRAME48k];
#endif
AUDIO_CONFIG intern_config;
ivas_error error;
......@@ -1073,12 +1081,20 @@ ivas_error ivas_crend_process(
*/
if ( intern_config == AUDIO_CONFIG_FOA || intern_config == AUDIO_CONFIG_HOA2 || intern_config == AUDIO_CONFIG_HOA3 )
{
#ifdef EXT_RENDERER
rotateFrame_shd( st_ivas->hHeadTrackData, output, subframe_len, st_ivas->hIntSetup, subframe_idx );
#else
rotateFrame_shd( st_ivas->hHeadTrackData, output, st_ivas->hDecoderConfig->output_Fs, subframe_len, st_ivas->hIntSetup, subframe_idx );
#endif
}
/* Rotation in SD for MC -> BINAURAL_ROOM */
else if ( st_ivas->ivas_format != ISM_FORMAT && st_ivas->hIntSetup.is_loudspeaker_setup )
{
#ifdef EXT_RENDERER
rotateFrame_sd( st_ivas->hHeadTrackData, output, subframe_len, st_ivas->hIntSetup, st_ivas->hEFAPdata, subframe_idx );
#else
rotateFrame_sd( st_ivas->hHeadTrackData, output, st_ivas->hDecoderConfig->output_Fs, subframe_len, st_ivas->hIntSetup, st_ivas->hEFAPdata, subframe_idx );
#endif
}
}
......@@ -1119,3 +1135,845 @@ ivas_error ivas_crend_process(
return IVAS_ERR_OK;
}
#ifdef EXT_RENDERER
/*-------------------------------------------------------------------------
* ivas_rend_openCrend()
*
* Allocate and initialize crend renderer handle
*------------------------------------------------------------------------*/
ivas_error ivas_rend_openCrend(
CREND_WRAPPER *pCrend,
const IVAS_REND_AudioConfig inConfig,
const IVAS_REND_AudioConfig outConfig,
RENDER_CONFIG_DATA *hRendCfg,
const int32_t output_Fs )
{
/* TODO tmu : Based on ivas_crend_open() - could be harmonized / refactored */
int16_t i, subframe_length;
int16_t max_total_ir_len;
HRTFS_HANDLE hHrtf;
CREND_HANDLE hCrend;
ivas_error error;
error = IVAS_ERR_OK;
subframe_length = (int16_t) ( output_Fs / FRAMES_PER_SEC ) / MAX_PARAM_SPATIAL_SUBFRAMES;
if ( pCrend->hHrtfCrend == NULL )
{
if ( ( error = ivas_rend_initCrend( pCrend, inConfig, outConfig, hRendCfg, output_Fs ) ) != IVAS_ERR_OK )
{
return error;
}
}
if ( ( hCrend = (CREND_HANDLE) count_malloc( sizeof( CREND_DATA ) ) ) == NULL )
{
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for renderer handle" );
}
hCrend->lfe_delay_line = NULL;
for ( i = 0; i < MAX_INTERN_CHANNELS; i++ )
{
hCrend->freq_buffer_re[i] = NULL;
hCrend->freq_buffer_im[i] = NULL;
}
for ( i = 0; i < BINAURAL_CHANNELS; i++ )
{
hCrend->prev_out_buffer[i] = NULL;
}
hCrend->freq_buffer_re_diffuse = NULL;
hCrend->freq_buffer_im_diffuse = NULL;
hCrend->hReverb = NULL;
hCrend->delay_line_rw_index = 0;
hCrend->diffuse_delay_line_rw_index = 0;
hCrend->hTrack = NULL;
hCrend->m_fYaw = 0;
hCrend->m_fPitch = 0;
hCrend->m_fRoll = 0;
hHrtf = pCrend->hHrtfCrend;
if ( hHrtf != NULL )
{
max_total_ir_len = hHrtf->max_num_iterations * subframe_length;
for ( i = 0; i < hHrtf->max_num_ir; i++ )
{
if ( ( hCrend->freq_buffer_re[i] = (float *) count_malloc( sizeof( float ) * max_total_ir_len ) ) == NULL )
{
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" );
}
set_zero( hCrend->freq_buffer_re[i], max_total_ir_len );
if ( ( hCrend->freq_buffer_im[i] = (float *) count_malloc( sizeof( float ) * max_total_ir_len ) ) == NULL )
{
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" );
}
set_zero( hCrend->freq_buffer_im[i], max_total_ir_len );
}
for ( i = 0; i < BINAURAL_CHANNELS; i++ )
{
if ( ( hCrend->prev_out_buffer[i] = (float *) count_malloc( sizeof( float ) * subframe_length ) ) == NULL )
{
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" );
}
set_zero( hCrend->prev_out_buffer[i], subframe_length );
}
max_total_ir_len = hHrtf->num_iterations_diffuse[0] * subframe_length;
if ( max_total_ir_len > 0 )
{
if ( ( hCrend->freq_buffer_re_diffuse = (float *) count_malloc( sizeof( float ) * max_total_ir_len ) ) == NULL )
{
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" );
}
set_zero( hCrend->freq_buffer_re_diffuse, max_total_ir_len );
if ( ( hCrend->freq_buffer_im_diffuse = (float *) count_malloc( sizeof( float ) * max_total_ir_len ) ) == NULL )
{
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" );
}
set_zero( hCrend->freq_buffer_im_diffuse, max_total_ir_len );
}
else
{
hCrend->freq_buffer_re_diffuse = NULL;
hCrend->freq_buffer_im_diffuse = NULL;
}
max_total_ir_len = (int16_t) ( hHrtf->latency_s * output_Fs + 0.5f ) + subframe_length;
if ( max_total_ir_len > 0 )
{
if ( ( hCrend->lfe_delay_line = (float *) count_malloc( sizeof( float ) * max_total_ir_len ) ) == NULL )
{
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" );
}
set_zero( hCrend->lfe_delay_line, max_total_ir_len );
}
else
{
hCrend->lfe_delay_line = NULL;
}
if ( false ) /* TODO tmu : check renderer headrotation flag */
{
if ( ( hCrend->hTrack = (ivas_orient_trk_state_t *) count_malloc( sizeof( ivas_orient_trk_state_t ) ) ) == NULL )
{
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Orientation tracking" );
}
ivas_orient_trk_Init( hCrend->hTrack );
}
else
{
hCrend->hTrack = NULL;
}
if ( ( hRendCfg != NULL ) && ( hRendCfg->roomAcoustics.late_reverb_on ) )
{
if ( ( error = ivas_reverb_open( &( hCrend->hReverb ),
getIvasAudioConfigFromRendAudioConfig( inConfig ),
pCrend->hHrtfCrend,
hRendCfg,
output_Fs ) ) != IVAS_ERR_OK )
{
return error;
}
}
else
{
hCrend->hReverb = NULL;
}
pCrend->binaural_latency_ns = (int32_t) ( pCrend->hHrtfCrend->latency_s * 1000000000.f );
}
pCrend->hCrend = hCrend;
return IVAS_ERR_OK;
}
/*-------------------------------------------------------------------------
* initCrend_from_rom()
*
* Allocate and initialize crend renderer handle
*------------------------------------------------------------------------*/
ivas_error ivas_rend_initCrend(
CREND_WRAPPER *pCrend,
const IVAS_REND_AudioConfig inConfig,
const IVAS_REND_AudioConfig outConfig,
RENDER_CONFIG_DATA *hRendCfg,
const int32_t output_Fs )
{
int16_t i, j, tmp;
int16_t nchan_in;
bool use_brir;
IVAS_REND_AudioConfigType inConfigType;
HRTFS_HANDLE hHrtf;
ivas_error error;
inConfigType = getAudioConfigType( inConfig );
hHrtf = pCrend->hHrtfCrend;
/* Do all error checks up front so that the nested if later is easier */
if ( inConfigType != IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED && inConfigType != IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS )
{
return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Encountered unsupported input config in Crend" );
}
if ( outConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL && outConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM )
{
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Encountered unsupported output type in Crend" );
}
if ( hHrtf == NULL )
{
if ( ivas_hrtf_open( &hHrtf ) != IVAS_ERR_OK )
{
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate memory for HRTF handle" );
}
}
/* set BRIR flag */
use_brir = false;
if ( ( hRendCfg != NULL && hRendCfg->roomAcoustics.use_brir ) || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM )
{
use_brir = true;
}
if ( ( error = getAudioConfigNumChannels( inConfig, &nchan_in ) ) != IVAS_ERR_OK )
{
return error;
}
hHrtf->max_num_ir = nchan_in;
if ( hHrtf->max_num_ir <= 0 )
{
return IVAS_ERR_INTERNAL_FATAL;
}
if ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED )
{
hHrtf->max_num_ir -= 1; /* subtract LFE */
hHrtf->gain_lfe = GAIN_LFE;
if ( output_Fs == 48000 )
{
if ( use_brir )
{
hHrtf->latency_s = CRendBin_Combined_BRIR_latency_s_48kHz;
hHrtf->max_num_iterations = CRendBin_Combined_BRIR_max_num_iterations_48kHz;
hHrtf->index_frequency_max_diffuse = CRendBin_Combined_BRIR_index_frequency_max_diffuse_48kHz;
}
else
{
hHrtf->latency_s = CRendBin_Combined_HRIR_latency_s_48kHz;
hHrtf->max_num_iterations = CRendBin_Combined_HRIR_max_num_iterations_48kHz;
hHrtf->index_frequency_max_diffuse = CRendBin_Combined_HRIR_index_frequency_max_diffuse_48kHz;
}
for ( j = 0; j < BINAURAL_CHANNELS; j++ )
{
if ( use_brir )
{
hHrtf->num_iterations_diffuse[j] = CRendBin_Combined_BRIR_num_iterations_diffuse_48kHz[j];
hHrtf->pIndex_frequency_max_diffuse[j] = CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_48kHz[j];
hHrtf->pOut_to_bin_diffuse_re[j] = CRendBin_Combined_BRIR_coeff_diffuse_re_48kHz[j];
hHrtf->pOut_to_bin_diffuse_im[j] = CRendBin_Combined_BRIR_coeff_diffuse_im_48kHz[j];
}
else
{
hHrtf->num_iterations_diffuse[j] = CRendBin_Combined_HRIR_num_iterations_diffuse_48kHz[j];
hHrtf->pIndex_frequency_max_diffuse[j] = CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_48kHz[j];
hHrtf->pOut_to_bin_diffuse_re[j] = CRendBin_Combined_HRIR_coeff_diffuse_re_48kHz[j];
hHrtf->pOut_to_bin_diffuse_im[j] = CRendBin_Combined_HRIR_coeff_diffuse_im_48kHz[j];
}
}
}
else if ( output_Fs == 32000 )
{
if ( use_brir )
{
hHrtf->latency_s = CRendBin_Combined_BRIR_latency_s_32kHz;
hHrtf->max_num_iterations = CRendBin_Combined_BRIR_max_num_iterations_32kHz;
hHrtf->index_frequency_max_diffuse = CRendBin_Combined_BRIR_index_frequency_max_diffuse_32kHz;
}
else
{
hHrtf->latency_s = CRendBin_Combined_HRIR_latency_s_32kHz;
hHrtf->max_num_iterations = CRendBin_Combined_HRIR_max_num_iterations_32kHz;
hHrtf->index_frequency_max_diffuse = CRendBin_Combined_HRIR_index_frequency_max_diffuse_32kHz;
}
for ( j = 0; j < BINAURAL_CHANNELS; j++ )
{
if ( use_brir )
{
hHrtf->num_iterations_diffuse[j] = CRendBin_Combined_BRIR_num_iterations_diffuse_32kHz[j];
hHrtf->pIndex_frequency_max_diffuse[j] = CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_32kHz[j];
hHrtf->pOut_to_bin_diffuse_re[j] = CRendBin_Combined_BRIR_coeff_diffuse_re_32kHz[j];
hHrtf->pOut_to_bin_diffuse_im[j] = CRendBin_Combined_BRIR_coeff_diffuse_im_32kHz[j];
}
else
{
hHrtf->num_iterations_diffuse[j] = CRendBin_Combined_HRIR_num_iterations_diffuse_32kHz[j];
hHrtf->pIndex_frequency_max_diffuse[j] = CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_32kHz[j];
hHrtf->pOut_to_bin_diffuse_re[j] = CRendBin_Combined_HRIR_coeff_diffuse_re_32kHz[j];
hHrtf->pOut_to_bin_diffuse_im[j] = CRendBin_Combined_HRIR_coeff_diffuse_im_32kHz[j];
}
}
}
else if ( output_Fs == 16000 )
{
if ( use_brir )
{
hHrtf->latency_s = CRendBin_Combined_BRIR_latency_s_16kHz;
hHrtf->max_num_iterations = CRendBin_Combined_BRIR_max_num_iterations_16kHz;
hHrtf->index_frequency_max_diffuse = CRendBin_Combined_BRIR_index_frequency_max_diffuse_16kHz;
}
else
{
hHrtf->latency_s = CRendBin_Combined_HRIR_latency_s_16kHz;
hHrtf->max_num_iterations = CRendBin_Combined_HRIR_max_num_iterations_16kHz;
hHrtf->index_frequency_max_diffuse = CRendBin_Combined_HRIR_index_frequency_max_diffuse_16kHz;
}
for ( j = 0; j < BINAURAL_CHANNELS; j++ )
{
if ( use_brir )
{
hHrtf->num_iterations_diffuse[j] = CRendBin_Combined_BRIR_num_iterations_diffuse_16kHz[j];
hHrtf->pIndex_frequency_max_diffuse[j] = CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_16kHz[j];
hHrtf->pOut_to_bin_diffuse_re[j] = CRendBin_Combined_BRIR_coeff_diffuse_re_16kHz[j];
hHrtf->pOut_to_bin_diffuse_im[j] = CRendBin_Combined_BRIR_coeff_diffuse_im_16kHz[j];
}
else
{
hHrtf->num_iterations_diffuse[j] = CRendBin_Combined_HRIR_num_iterations_diffuse_16kHz[j];
hHrtf->pIndex_frequency_max_diffuse[j] = CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_16kHz[j];
hHrtf->pOut_to_bin_diffuse_re[j] = CRendBin_Combined_HRIR_coeff_diffuse_re_16kHz[j];
hHrtf->pOut_to_bin_diffuse_im[j] = CRendBin_Combined_HRIR_coeff_diffuse_im_16kHz[j];
}
}
}
else
{
return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "Encountered Unsupported sampling rate in Crend" );
}
for ( i = 0; i < hHrtf->max_num_ir; i++ )
{
if ( inConfig == IVAS_REND_AUDIO_CONFIG_5_1 )
{
tmp = channelIndex_CICP6[i];
}
else if ( inConfig == IVAS_REND_AUDIO_CONFIG_7_1 )
{
tmp = channelIndex_CICP12[i];
}
else if ( inConfig == IVAS_REND_AUDIO_CONFIG_5_1_2 )
{
tmp = channelIndex_CICP14[i];
}
else if ( inConfig == IVAS_REND_AUDIO_CONFIG_5_1_4 )
{
tmp = channelIndex_CICP16[i];
}
else if ( inConfig == IVAS_REND_AUDIO_CONFIG_7_1_4 )
{
tmp = channelIndex_CICP19[i];
}
else
{
return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: Channel configuration not specified!\n\n" );
}
if ( output_Fs == 48000 )
{
if ( use_brir )
{
hHrtf->inv_diffuse_weight[i] = CRendBin_Combined_BRIR_inv_diffuse_weight_48kHz[tmp];
}
else
{
hHrtf->inv_diffuse_weight[i] = CRendBin_Combined_HRIR_inv_diffuse_weight_48kHz[tmp];
}
for ( j = 0; j < BINAURAL_CHANNELS; j++ )
{
if ( use_brir )
{
hHrtf->num_iterations[i][j] = CRendBin_Combined_BRIR_num_iterations_48kHz[tmp][j];
hHrtf->pIndex_frequency_max[i][j] = CRendBin_Combined_BRIR_pIndex_frequency_max_48kHz[tmp][j];
hHrtf->pOut_to_bin_re[i][j] = CRendBin_Combined_BRIR_coeff_re_48kHz[tmp][j];
hHrtf->pOut_to_bin_im[i][j] = CRendBin_Combined_BRIR_coeff_im_48kHz[tmp][j];
}
else
{
hHrtf->num_iterations[i][j] = CRendBin_Combined_HRIR_num_iterations_48kHz[tmp][j];
hHrtf->pIndex_frequency_max[i][j] = CRendBin_Combined_HRIR_pIndex_frequency_max_48kHz[tmp][j];
hHrtf->pOut_to_bin_re[i][j] = CRendBin_Combined_HRIR_coeff_re_48kHz[tmp][j];
hHrtf->pOut_to_bin_im[i][j] = CRendBin_Combined_HRIR_coeff_im_48kHz[tmp][j];
}
}
}
else if ( output_Fs == 32000 )
{
if ( use_brir )
{
hHrtf->inv_diffuse_weight[i] = CRendBin_Combined_BRIR_inv_diffuse_weight_32kHz[tmp];
}
else
{
hHrtf->inv_diffuse_weight[i] = CRendBin_Combined_HRIR_inv_diffuse_weight_32kHz[tmp];
}
for ( j = 0; j < BINAURAL_CHANNELS; j++ )
{
if ( use_brir )
{
hHrtf->num_iterations[i][j] = CRendBin_Combined_BRIR_num_iterations_32kHz[tmp][j];
hHrtf->pIndex_frequency_max[i][j] = CRendBin_Combined_BRIR_pIndex_frequency_max_32kHz[tmp][j];
hHrtf->pOut_to_bin_re[i][j] = CRendBin_Combined_BRIR_coeff_re_32kHz[tmp][j];
hHrtf->pOut_to_bin_im[i][j] = CRendBin_Combined_BRIR_coeff_im_32kHz[tmp][j];
}
else
{
hHrtf->num_iterations[i][j] = CRendBin_Combined_HRIR_num_iterations_32kHz[tmp][j];
hHrtf->pIndex_frequency_max[i][j] = CRendBin_Combined_HRIR_pIndex_frequency_max_32kHz[tmp][j];
hHrtf->pOut_to_bin_re[i][j] = CRendBin_Combined_HRIR_coeff_re_32kHz[tmp][j];
hHrtf->pOut_to_bin_im[i][j] = CRendBin_Combined_HRIR_coeff_im_32kHz[tmp][j];
}
}
}
else if ( output_Fs == 16000 )
{
if ( use_brir )
{
hHrtf->inv_diffuse_weight[i] = CRendBin_Combined_BRIR_inv_diffuse_weight_16kHz[tmp];
}
else
{
hHrtf->inv_diffuse_weight[i] = CRendBin_Combined_HRIR_inv_diffuse_weight_16kHz[tmp];
}
for ( j = 0; j < BINAURAL_CHANNELS; j++ )
{
if ( use_brir )
{
hHrtf->num_iterations[i][j] = CRendBin_Combined_BRIR_num_iterations_16kHz[tmp][j];
hHrtf->pIndex_frequency_max[i][j] = CRendBin_Combined_BRIR_pIndex_frequency_max_16kHz[tmp][j];
hHrtf->pOut_to_bin_re[i][j] = CRendBin_Combined_BRIR_coeff_re_16kHz[tmp][j];
hHrtf->pOut_to_bin_im[i][j] = CRendBin_Combined_BRIR_coeff_im_16kHz[tmp][j];
}
else
{
hHrtf->num_iterations[i][j] = CRendBin_Combined_HRIR_num_iterations_16kHz[tmp][j];
hHrtf->pIndex_frequency_max[i][j] = CRendBin_Combined_HRIR_pIndex_frequency_max_16kHz[tmp][j];
hHrtf->pOut_to_bin_re[i][j] = CRendBin_Combined_HRIR_coeff_re_16kHz[tmp][j];
hHrtf->pOut_to_bin_im[i][j] = CRendBin_Combined_HRIR_coeff_im_16kHz[tmp][j];
}
}
}
else
{
return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "Encountered Unsupported sampling rate in Crend" );
}
}
}
else if ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS )
{
if ( output_Fs == 48000 )
{
hHrtf->latency_s = CRendBin_HOA3_HRIR_latency_s_48kHz;
hHrtf->max_num_iterations = CRendBin_HOA3_HRIR_max_num_iterations_48kHz;
hHrtf->index_frequency_max_diffuse = CRendBin_HOA3_HRIR_index_frequency_max_diffuse_48kHz;
for ( i = 0; i < hHrtf->max_num_ir; i++ )
{
hHrtf->inv_diffuse_weight[i] = CRendBin_HOA3_HRIR_inv_diffuse_weight_48kHz[i];
for ( j = 0; j < BINAURAL_CHANNELS; j++ )
{
hHrtf->num_iterations[i][j] = CRendBin_HOA3_HRIR_num_iterations_48kHz[i][j];
hHrtf->pIndex_frequency_max[i][j] = CRendBin_HOA3_HRIR_pIndex_frequency_max_48kHz[i][j];
hHrtf->pOut_to_bin_re[i][j] = CRendBin_HOA3_HRIR_coeff_re_48kHz[i][j];
hHrtf->pOut_to_bin_im[i][j] = CRendBin_HOA3_HRIR_coeff_im_48kHz[i][j];
}
}
for ( j = 0; j < BINAURAL_CHANNELS; j++ )
{
hHrtf->num_iterations_diffuse[j] = CRendBin_HOA3_HRIR_num_iterations_diffuse_48kHz[j];
hHrtf->pIndex_frequency_max_diffuse[j] = CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_48kHz[j];
hHrtf->pOut_to_bin_diffuse_re[j] = CRendBin_HOA3_HRIR_coeff_diffuse_re_48kHz[j];
hHrtf->pOut_to_bin_diffuse_im[j] = CRendBin_HOA3_HRIR_coeff_diffuse_im_48kHz[j];
}
}
else if ( output_Fs == 32000 )
{
hHrtf->latency_s = CRendBin_HOA3_HRIR_latency_s_32kHz;
hHrtf->max_num_iterations = CRendBin_HOA3_HRIR_max_num_iterations_32kHz;
hHrtf->index_frequency_max_diffuse = CRendBin_HOA3_HRIR_index_frequency_max_diffuse_32kHz;
for ( i = 0; i < hHrtf->max_num_ir; i++ )
{
hHrtf->inv_diffuse_weight[i] = CRendBin_HOA3_HRIR_inv_diffuse_weight_32kHz[i];
for ( j = 0; j < BINAURAL_CHANNELS; j++ )
{
hHrtf->num_iterations[i][j] = CRendBin_HOA3_HRIR_num_iterations_32kHz[i][j];
hHrtf->pIndex_frequency_max[i][j] = CRendBin_HOA3_HRIR_pIndex_frequency_max_32kHz[i][j];
hHrtf->pOut_to_bin_re[i][j] = CRendBin_HOA3_HRIR_coeff_re_32kHz[i][j];
hHrtf->pOut_to_bin_im[i][j] = CRendBin_HOA3_HRIR_coeff_im_32kHz[i][j];
}
}
for ( j = 0; j < BINAURAL_CHANNELS; j++ )
{
hHrtf->num_iterations_diffuse[j] = CRendBin_HOA3_HRIR_num_iterations_diffuse_32kHz[j];
hHrtf->pIndex_frequency_max_diffuse[j] = CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_32kHz[j];
hHrtf->pOut_to_bin_diffuse_re[j] = CRendBin_HOA3_HRIR_coeff_diffuse_re_32kHz[j];
hHrtf->pOut_to_bin_diffuse_im[j] = CRendBin_HOA3_HRIR_coeff_diffuse_im_32kHz[j];
}
}
else if ( output_Fs == 16000 )
{
hHrtf->latency_s = CRendBin_HOA3_HRIR_latency_s_16kHz;
hHrtf->max_num_iterations = CRendBin_HOA3_HRIR_max_num_iterations_16kHz;
hHrtf->index_frequency_max_diffuse = CRendBin_HOA3_HRIR_index_frequency_max_diffuse_16kHz;
for ( i = 0; i < hHrtf->max_num_ir; i++ )
{
hHrtf->inv_diffuse_weight[i] = CRendBin_HOA3_HRIR_inv_diffuse_weight_16kHz[i];
for ( j = 0; j < BINAURAL_CHANNELS; j++ )
{
hHrtf->num_iterations[i][j] = CRendBin_HOA3_HRIR_num_iterations_16kHz[i][j];
hHrtf->pIndex_frequency_max[i][j] = CRendBin_HOA3_HRIR_pIndex_frequency_max_16kHz[i][j];
hHrtf->pOut_to_bin_re[i][j] = CRendBin_HOA3_HRIR_coeff_re_16kHz[i][j];
hHrtf->pOut_to_bin_im[i][j] = CRendBin_HOA3_HRIR_coeff_im_16kHz[i][j];
}
}
for ( j = 0; j < BINAURAL_CHANNELS; j++ )
{
hHrtf->num_iterations_diffuse[j] = CRendBin_HOA3_HRIR_num_iterations_diffuse_16kHz[j];
hHrtf->pIndex_frequency_max_diffuse[j] = CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_16kHz[j];
hHrtf->pOut_to_bin_diffuse_re[j] = CRendBin_HOA3_HRIR_coeff_diffuse_re_16kHz[j];
hHrtf->pOut_to_bin_diffuse_im[j] = CRendBin_HOA3_HRIR_coeff_diffuse_im_16kHz[j];
}
}
else
{
return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "Encountered Unsupported sampling rate in Crend" );
}
}
else
{
return IVAS_ERROR( IVAS_ERR_INTERNAL, "Unsupported renderer type in Crend" );
}
pCrend->hHrtfCrend = hHrtf;
return IVAS_ERR_OK;
}
/*-------------------------------------------------------------------------
* ivas_crend_close()
*
* Deallocate Crend renderer handle
*------------------------------------------------------------------------*/
ivas_error ivas_rend_closeCrend(
CREND_WRAPPER *pCrend )
{
int16_t i;
if ( pCrend->hHrtfCrend != NULL )
{
ivas_hrtf_close( &pCrend->hHrtfCrend );
}
if ( pCrend->hCrend != NULL )
{
for ( i = 0; i < MAX_INTERN_CHANNELS; i++ )
{
if ( pCrend->hCrend->freq_buffer_re[i] != NULL )
{
count_free( pCrend->hCrend->freq_buffer_re[i] );
pCrend->hCrend->freq_buffer_re[i] = NULL;
}
if ( pCrend->hCrend->freq_buffer_im[i] != NULL )
{
count_free( pCrend->hCrend->freq_buffer_im[i] );
pCrend->hCrend->freq_buffer_im[i] = NULL;
}
}
for ( i = 0; i < BINAURAL_CHANNELS; i++ )
{
if ( pCrend->hCrend->prev_out_buffer[i] != NULL )
{
count_free( pCrend->hCrend->prev_out_buffer[i] );
pCrend->hCrend->prev_out_buffer[i] = NULL;
}
}
if ( pCrend->hCrend->lfe_delay_line != NULL )
{
count_free( pCrend->hCrend->lfe_delay_line );
pCrend->hCrend->lfe_delay_line = NULL;
}
if ( pCrend->hCrend->freq_buffer_re_diffuse != NULL )
{
count_free( pCrend->hCrend->freq_buffer_re_diffuse );
pCrend->hCrend->freq_buffer_re_diffuse = NULL;
}
if ( pCrend->hCrend->freq_buffer_im_diffuse != NULL )
{
count_free( pCrend->hCrend->freq_buffer_im_diffuse );
pCrend->hCrend->freq_buffer_im_diffuse = NULL;
}
if ( pCrend->hCrend->hTrack != NULL )
{
count_free( pCrend->hCrend->hTrack );
pCrend->hCrend->hTrack = NULL;
}
ivas_reverb_close( &pCrend->hCrend->hReverb );
count_free( pCrend->hCrend );
pCrend->hCrend = NULL;
}
return IVAS_ERR_OK;
}
/*-----------------------------------------------------------------------------------------*
* Function ivas_rend_crend_Process()
*
* Process call for IVAS Crend renderer
*-----------------------------------------------------------------------------------------*/
ivas_error ivas_rend_crendProcess(
const CREND_WRAPPER *pCrend,
const IVAS_REND_AudioConfig inConfig,
const IVAS_REND_AudioConfig outConfig,
float output[][L_FRAME48k], /* i/o: input/output audio channels */
const int32_t output_Fs )
{
int16_t i, subframe_idx, output_frame;
int16_t nchan_out;
float pcm_tmp[BINAURAL_CHANNELS][L_FRAME48k];
AUDIO_CONFIG in_config;
IVAS_REND_AudioConfigType inConfigType;
ivas_error error;
wmops_sub_start( "ivas_rend_crendProcess" );
in_config = getIvasAudioConfigFromRendAudioConfig( inConfig );
inConfigType = getAudioConfigType( inConfig );
getAudioConfigNumChannels( outConfig, &nchan_out );
output_frame = (int16_t) ( output_Fs / FRAMES_PER_SEC );
for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ )
{
if ( ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) || ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) )
{
if ( ( error = ivas_rend_crendConvolver( pCrend, inConfig, outConfig, output, pcm_tmp, output_Fs, subframe_idx ) ) != IVAS_ERR_OK )
{
return error;
}
if ( pCrend->hCrend->hReverb != NULL )
{
if ( ( error = ivas_reverb_process( pCrend->hCrend->hReverb, in_config, 1, output, pcm_tmp, subframe_idx ) ) != IVAS_ERR_OK )
{
return error;
}
}
}
else
{
return IVAS_ERR_INVALID_INPUT_FORMAT;
}
}
/* move to output */
for ( i = 0; i < nchan_out; i++ )
{
mvr2r( pcm_tmp[i], output[i], output_frame );
}
wmops_sub_end();
return IVAS_ERR_OK;
}
/*-----------------------------------------------------------------------------------------*
* Function ivas_crend_convolver()
*
* Convolver block
*-----------------------------------------------------------------------------------------*/
ivas_error ivas_rend_crendConvolver(
const CREND_WRAPPER *pCrend,
IVAS_REND_AudioConfig inConfig,
IVAS_REND_AudioConfig outConfig,
float pcm_in[][L_FRAME48k],
float pcm_out[][L_FRAME48k],
const int32_t output_Fs,
const int16_t i_ts )
{
int16_t i, j, k, m;
int16_t subframe_length, idx_in;
int16_t lfe_idx_in;
int16_t offset, offset_in, offset_diffuse;
int16_t nchan_in, nchan_out;
float *pIn;
float *pFreq_buf_re, *pFreq_buf_im;
float *pFreq_filt_re, *pFreq_filt_im;
float pOut[L_FRAME48k * 2];
float tmp_out_re[L_FRAME48k], tmp_out_im[L_FRAME48k];
getAudioConfigNumChannels( inConfig, &nchan_in );
getAudioConfigNumChannels( outConfig, &nchan_out );
subframe_length = (int16_t) ( output_Fs / FRAMES_PER_SEC ) / MAX_PARAM_SPATIAL_SUBFRAMES;
lfe_idx_in = -1;
if ( getAudioConfigType( inConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED )
{
if ( inConfig != IVAS_REND_AUDIO_CONFIG_LS_CUSTOM )
{
lfe_idx_in = LFE_CHANNEL;
}
else
{
assert( 0 && "Custom LS not supported in CRend" );
}
}
offset = pCrend->hCrend->delay_line_rw_index * subframe_length; /* subframe_length * ( pCrend->hHrtfCrend->max_num_iterations - 1 ); */
offset_diffuse = pCrend->hCrend->diffuse_delay_line_rw_index * subframe_length; /* subframe_length *( pCrend->hHrtfCrend->num_iterations_diffuse[0] - 1 ); */
if ( pCrend->hHrtfCrend->num_iterations_diffuse[0] > 0 )
{
set_zero( &pCrend->hCrend->freq_buffer_re_diffuse[offset_diffuse], subframe_length );
set_zero( &pCrend->hCrend->freq_buffer_im_diffuse[offset_diffuse], subframe_length );
}
i = 0;
for ( idx_in = 0; idx_in < nchan_in; idx_in++ )
{
pIn = &pcm_in[idx_in][i_ts * subframe_length];
if ( idx_in != lfe_idx_in )
{
if ( pCrend->hHrtfCrend->num_iterations_diffuse[0] > 0 )
{
pFreq_buf_re = &pCrend->hCrend->freq_buffer_re_diffuse[offset_diffuse];
pFreq_buf_im = &pCrend->hCrend->freq_buffer_im_diffuse[offset_diffuse];
pFreq_filt_re = &pCrend->hCrend->freq_buffer_re[i][offset];
pFreq_filt_im = &pCrend->hCrend->freq_buffer_im[i][offset];
for ( k = 0; k < pCrend->hHrtfCrend->index_frequency_max_diffuse; k++ )
{
pFreq_buf_re[k] += pFreq_filt_re[k] * pCrend->hHrtfCrend->inv_diffuse_weight[i];
pFreq_buf_im[k] += pFreq_filt_im[k] * pCrend->hHrtfCrend->inv_diffuse_weight[i];
}
}
pFreq_buf_re = &pCrend->hCrend->freq_buffer_re[i][offset];
pFreq_buf_im = &pCrend->hCrend->freq_buffer_im[i][offset];
ivas_mdft( pIn, pFreq_buf_re, pFreq_buf_im, subframe_length, subframe_length );
i++;
}
}
for ( j = 0; j < nchan_out; j++ )
{
set_zero( tmp_out_re, subframe_length );
set_zero( tmp_out_im, subframe_length );
i = 0;
for ( idx_in = 0; idx_in < nchan_in; idx_in++ )
{
if ( idx_in != lfe_idx_in )
{
offset = 0;
for ( m = 0; m < pCrend->hHrtfCrend->num_iterations[i][j]; m++ )
{
offset_in = ( pCrend->hCrend->delay_line_rw_index + pCrend->hHrtfCrend->max_num_iterations - pCrend->hHrtfCrend->num_iterations[i][j] + m + 1 );
offset_in = offset_in % ( pCrend->hHrtfCrend->max_num_iterations );
offset_in = offset_in * subframe_length;
pFreq_buf_re = &pCrend->hCrend->freq_buffer_re[i][offset_in];
pFreq_buf_im = &pCrend->hCrend->freq_buffer_im[i][offset_in];
pFreq_filt_re = &pCrend->hHrtfCrend->pOut_to_bin_re[i][j][offset];
pFreq_filt_im = &pCrend->hHrtfCrend->pOut_to_bin_im[i][j][offset];
for ( k = 0; k < pCrend->hHrtfCrend->pIndex_frequency_max[i][j][m]; k++ )
{
tmp_out_re[k] += pFreq_buf_re[k] * pFreq_filt_re[k] - pFreq_buf_im[k] * pFreq_filt_im[k];
tmp_out_im[k] += pFreq_buf_re[k] * pFreq_filt_im[k] + pFreq_buf_im[k] * pFreq_filt_re[k];
}
offset = offset + k;
}
i++;
}
}
offset = 0;
for ( m = 0; m < pCrend->hHrtfCrend->num_iterations_diffuse[j]; m++ )
{
offset_diffuse = ( pCrend->hCrend->diffuse_delay_line_rw_index + m + 1 );
offset_diffuse = offset_diffuse % pCrend->hHrtfCrend->num_iterations_diffuse[0];
offset_diffuse = offset_diffuse * subframe_length;
pFreq_buf_re = &pCrend->hCrend->freq_buffer_re_diffuse[offset_diffuse];
pFreq_buf_im = &pCrend->hCrend->freq_buffer_im_diffuse[offset_diffuse];
pFreq_filt_re = &pCrend->hHrtfCrend->pOut_to_bin_diffuse_re[j][offset];
pFreq_filt_im = &pCrend->hHrtfCrend->pOut_to_bin_diffuse_im[j][offset];
for ( k = 0; k < pCrend->hHrtfCrend->pIndex_frequency_max_diffuse[j][m]; k++ )
{
tmp_out_re[k] += pFreq_buf_re[k] * pFreq_filt_re[k] - pFreq_buf_im[k] * pFreq_filt_im[k];
tmp_out_im[k] += pFreq_buf_re[k] * pFreq_filt_im[k] + pFreq_buf_im[k] * pFreq_filt_re[k];
}
offset = offset + k;
}
ivas_imdft( tmp_out_re, tmp_out_im, pOut, subframe_length );
pFreq_buf_re = &pcm_out[j][i_ts * subframe_length];
for ( k = 0; k < subframe_length; k++ )
{
pFreq_buf_re[k] = pOut[k] + pCrend->hCrend->prev_out_buffer[j][k];
pCrend->hCrend->prev_out_buffer[j][k] = pOut[k + subframe_length];
}
}
pCrend->hCrend->delay_line_rw_index++;
pCrend->hCrend->delay_line_rw_index = pCrend->hCrend->delay_line_rw_index % ( pCrend->hHrtfCrend->max_num_iterations );
if ( pCrend->hHrtfCrend->num_iterations_diffuse[0] > 0 )
{
pCrend->hCrend->diffuse_delay_line_rw_index++;
pCrend->hCrend->diffuse_delay_line_rw_index = pCrend->hCrend->diffuse_delay_line_rw_index % ( pCrend->hHrtfCrend->num_iterations_diffuse[0] );
}
return IVAS_ERR_OK;
}
#endif
......@@ -83,7 +83,7 @@ static void get_poly_gains( const float azi, const float ele, const float aziPol
static float get_tri_gain( const float A[2], const float B[2], const float C[2], const float P_minus_A[2] );
#if defined( DEBUG_EFAP_POLY_TOFILE )
#ifdef DEBUG_EFAP_POLY_TOFILE
static void get_poly_select( EFAP_POLYSET_DATA *polyData );
#endif
......@@ -96,11 +96,11 @@ static void add_vertex( EFAP_VERTEX *vtxArray, const float azi, const float ele,
static void efap_sort_s( int16_t *x, int16_t *idx, const int16_t len );
static float vertex_distance( const EFAP_VERTEX *vtxArray, const EFAP_LS_TRIANGLE tri, const int16_t vtxIdx );
static float point_plane_distance( const float P1[3], const float P2[3], const float P3[3], const float X[3] );
static float point_poly_distance( const EFAP_POLYSET poly, const float X[3] );
static void efap_crossp( const float *v1, const float *v2, float *v );
static int16_t find_int_in_tri( const EFAP_LS_TRIANGLE *tri, const int16_t n, const int16_t r, int16_t *pos );
......@@ -125,6 +125,7 @@ static int16_t in_poly( const float P[2], const EFAP_POLYSET poly );
static int16_t in_tri( float A[2], float B[2], float C[2], float P_minus_A[2] );
static void sph2cart( const float azi, const float ele, float *pos );
/*-----------------------------------------------------------------------*
* Global function definitions
......@@ -154,8 +155,12 @@ ivas_error efap_init_data(
if ( !speaker_node_azi_deg || !speaker_node_ele_deg )
{
hEFAPdata = NULL;
#ifdef EXT_RENDERER
return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "EFAP requires arrays of speaker azimuths and elevations" );
#else
/* TODO: is this path correct behaviour or and error ? */
return IVAS_ERR_OK;
#endif
}
/*-----------------------------------------------------------------*
......@@ -266,7 +271,7 @@ void efap_determine_gains(
}
normBuffer = normBuffer + hEFAPdata->bufferShort[j] * hEFAPdata->bufferShort[j];
}
normBuffer = 1.f / sqrtf( normBuffer );
normBuffer = inv_sqrt( normBuffer );
for ( j = 0; j < hEFAPdata->numSpk; ++j )
{
......@@ -462,14 +467,14 @@ static ivas_error poly_init(
efap->polyData.numPoly = finalLength;
#if defined( DEBUG_EFAP_POLY_TOFILE )
#ifdef DEBUG_EFAP_POLY_TOFILE
get_poly_select( &efap->polyData );
#endif
return error;
}
#if defined( DEBUG_EFAP_POLY_TOFILE )
#ifdef DEBUG_EFAP_POLY_TOFILE
static void get_poly_select(
EFAP_POLYSET_DATA *polyData /* o : Polygon data structure */
)
......@@ -1324,17 +1329,21 @@ static void efap_panning(
float tmpBuff[EFAP_MAX_CHAN_NUM];
float normTmpBuff;
float P[2];
#ifndef FIX_EFAP_MATH
float P_tmp[2];
#endif
P[0] = azi;
P[1] = ele;
/* Finding in which polygon the point is */
#ifndef FIX_EFAP_MATH
P_tmp[0] = roundf( P[0] / PANNING_AZI_RESOLUTION );
P_tmp[1] = roundf( P[1] / PANNING_ELE_RESOLUTION );
P[0] = P_tmp[0] * PANNING_AZI_RESOLUTION;
P[1] = P_tmp[1] * PANNING_ELE_RESOLUTION;
#endif
polyIdx = get_poly_num( P, polyData );
......@@ -1497,9 +1506,7 @@ static void add_vertex(
vtxArray[pos].ele = ( ( -180.0f > tmp ) ? -180.0f : tmp );
/* Converting spherical coordinates to cartesians, assuming radius = 1 */
vtxArray[pos].pos[0] = cosf( vtxArray[pos].azi * PI_OVER_180 ) * cosf( vtxArray[pos].ele * PI_OVER_180 );
vtxArray[pos].pos[1] = sinf( vtxArray[pos].azi * PI_OVER_180 ) * cosf( vtxArray[pos].ele * PI_OVER_180 );
vtxArray[pos].pos[2] = sinf( vtxArray[pos].ele * PI_OVER_180 );
sph2cart( vtxArray[pos].azi, vtxArray[pos].ele, &vtxArray[pos].pos[0] );
/* Computing the index defined by idx = idxAziTmp + 181 * idxEleTmp */
......@@ -1591,11 +1598,30 @@ static float vertex_distance(
return point_plane_distance( A, B, C, P );
}
/*-------------------------------------------------------------------------*
* point_poly_distance()
*
* Compute the signed distance between a point and polygon
*-------------------------------------------------------------------------*/
static float point_poly_distance(
const EFAP_POLYSET poly, /* i : The polygon which forms a plane */
const float X[3] /* i : Cartesian coordinates of the point of interest */
)
{
float P1[3], P2[3], P3[3];
sph2cart( poly.polyAzi[0], poly.polyEle[0], &P1[0] );
sph2cart( poly.polyAzi[1], poly.polyEle[1], &P2[0] );
sph2cart( poly.polyAzi[2], poly.polyEle[2], &P3[0] );
return point_plane_distance( P1, P2, P3, X );
}
/*-------------------------------------------------------------------------*
* point_plane_distance()
*
* Compute the signed distance between a point a given plane
* Compute the signed distance between a point and a given plane
*-------------------------------------------------------------------------*/
static float point_plane_distance(
......@@ -1628,7 +1654,7 @@ static float point_plane_distance(
/* Dot Product */
tmpNorm = dotp( resultCross, resultCross, 3 );
tmpNorm = 1.f / sqrtf( tmpNorm );
tmpNorm = inv_sqrt( tmpNorm );
v_sub( X, P1, tmpDot1, 3 );
v_multc( resultCross, tmpNorm, tmpDot2, 3 );
dist = dotp( tmpDot1, tmpDot2, 3 );
......@@ -2082,18 +2108,56 @@ static int16_t get_poly_num(
)
{
int16_t i;
int16_t num_poly, found_poly;
int16_t poly_tmp[EFAP_MAX_CHAN_NUM];
float poly_dist[EFAP_MAX_CHAN_NUM];
float dist_tmp;
float pos[3];
num_poly = 0;
sph2cart( P[0], P[1], &pos[0] );
/* Filter the polygon list with a fast 2d check */
for ( i = 0; i < polyData->numPoly; ++i )
{
if ( in_poly( P, polyData->polysetArray[i] ) )
{
/* select only polygons which are visible from the point */
dist_tmp = point_poly_distance( polyData->polysetArray[i], pos );
if ( dist_tmp == 0 )
{
return i;
}
else if ( dist_tmp > 0 )
{
poly_tmp[num_poly] = i;
poly_dist[num_poly] = dist_tmp;
num_poly++;
}
}
}
if ( num_poly == 0 )
{
return -1;
}
/* select the polygon with the smallest distance */
found_poly = poly_tmp[0];
dist_tmp = poly_dist[0];
for ( i = 1; i < num_poly; i++ )
{
if ( poly_dist[i] < dist_tmp )
{
found_poly = poly_tmp[i];
dist_tmp = poly_dist[i];
}
}
return found_poly;
}
/*-------------------------------------------------------------------------*
* in_poly()
......@@ -2201,7 +2265,11 @@ static int16_t in_tri(
/* Verification of the non-colinearity */
invFactor = tmpDot1[0] * tmpDot2[1] - tmpDot1[1] * tmpDot2[0];
#ifdef FIX_EFAP_MATH
if ( fabsf( invFactor ) < thresh )
#else
if ( invFactor < thresh )
#endif
{
return 0;
}
......@@ -2226,3 +2294,20 @@ static int16_t in_tri(
return 1;
}
}
/*-------------------------------------------------------------------------*
* sph2cart()
*
* Converts a vertex position to cartesian coordinates
*-------------------------------------------------------------------------*/
static void sph2cart(
const float azi, /* i : Azimuth in degrees */
const float ele, /* i : Elevation in degrees */
float *pos /* o : Cartesian coordinates vector (x, y, z) */
)
{
pos[0] = cosf( azi * PI_OVER_180 ) * cosf( ele * PI_OVER_180 );
pos[1] = sinf( azi * PI_OVER_180 ) * cosf( ele * PI_OVER_180 );
pos[2] = sinf( ele * PI_OVER_180 );
}
......@@ -32,7 +32,6 @@
#include <stdint.h>
#include "options.h"
#include "hrtf_file_reader.h"
#include "prot.h"
#include "ivas_prot.h"
#include "lib_dec.h"
......
"""
/******************************************************************************************************
(C) 2022 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,
......@@ -26,36 +27,97 @@
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.
"""
import os
def il2mm(file_in, num_ch, b_delete=True):
"""
Convert interleaved input file to multiple mono output files.
"""
num_bytes_per_sample = 2
num_bytes_per_frame = num_bytes_per_sample * num_ch
num_bytes_per_channel = os.path.getsize(file_in) / num_ch
with open(file_in, "rb") as fid_in:
out_path = os.path.splitext(file_in)[0]
for chan in range(num_ch):
file_out = out_path + str(chan + 1) + "ch.raw"
with open(file_out, "wb") as fid_out:
bytes_written = 0
offset = chan * num_bytes_per_sample
fid_in.seek(offset, 0)
while bytes_written < num_bytes_per_channel:
data = fid_in.read(num_bytes_per_sample)
fid_in.seek(num_bytes_per_frame - num_bytes_per_sample, 1)
written = fid_out.write(bytes(data))
assert (
written == num_bytes_per_sample
), f"Error writing data: {written} != {num_bytes_per_sample}"
bytes_written += num_bytes_per_sample
# delete interleaved input file
if b_delete:
os.remove(file_in)
*******************************************************************************************************/
#include "ivas_error.h"
#include "lib_rend.h"
#include "ivas_stat_dec.h"
#ifndef IVAS_LIB_REND_INTERNALS_H
#define IVAS_LIB_REND_INTERNALS_H
#ifdef EXT_RENDERER
typedef struct
{
int8_t headRotEnabled;
IVAS_QUATERNION headPositions[RENDERER_HEAD_POSITIONS_PER_FRAME];
float crossfade[L_FRAME48k / RENDERER_HEAD_POSITIONS_PER_FRAME];
} IVAS_REND_HeadRotData;
typedef struct
{
int32_t binaural_latency_ns;
BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd;
TDREND_HRFILT_FiltSet_t *hHrtfTD;
} TDREND_WRAPPER;
typedef struct
{
int32_t binaural_latency_ns;
CREND_HANDLE hCrend;
HRTFS_HANDLE hHrtfCrend;
} CREND_WRAPPER;
IVAS_REND_AudioConfigType getAudioConfigType(
const IVAS_REND_AudioConfig config );
ivas_error getAudioConfigNumChannels(
const IVAS_REND_AudioConfig config,
int16_t *numChannels );
AUDIO_CONFIG getIvasAudioConfigFromRendAudioConfig(
IVAS_REND_AudioConfig config );
ivas_error ivas_rend_openCrend(
CREND_WRAPPER *pCrend,
const IVAS_REND_AudioConfig inConfig,
const IVAS_REND_AudioConfig outConfig,
RENDER_CONFIG_DATA *hRendCfg,
const int32_t output_Fs );
ivas_error ivas_rend_initCrend(
CREND_WRAPPER *pCrend,
const IVAS_REND_AudioConfig inConfig,
const IVAS_REND_AudioConfig outConfig,
RENDER_CONFIG_DATA *hRendCfg,
const int32_t output_Fs );
ivas_error ivas_rend_closeCrend(
CREND_WRAPPER *pCrend );
ivas_error ivas_rend_crendProcess(
const CREND_WRAPPER *pCrend,
const IVAS_REND_AudioConfig inConfig,
const IVAS_REND_AudioConfig outConfig,
float output[][L_FRAME48k], /* i/o: input/output audio channels */
const int32_t output_Fs );
ivas_error ivas_rend_crendConvolver(
const CREND_WRAPPER *pCrend,
const IVAS_REND_AudioConfig inConfig,
const IVAS_REND_AudioConfig outConfig,
float pcm_in[][L_FRAME48k],
float pcm_out[][L_FRAME48k],
const int32_t output_Fs,
const int16_t i_ts );
ivas_error ivas_rend_TDObjRenderFrame(
const TDREND_WRAPPER *pTDRend, /* i : TD Renderer wrapper structure */
const IVAS_REND_AudioConfig inConfig, /* i : Input audio configuration */
const LSSETUP_CUSTOM_STRUCT *customLsInput, /* i : Input custom loudspeaker layout */
const IVAS_REND_HeadRotData *headRotData, /* i : Input head positions */
const IVAS_REND_AudioObjectPosition *currentPos, /* i : Object position */
const int16_t output_frame, /* i : output frame length */
const int32_t output_Fs, /* i : output sampling rate */
float output[][L_FRAME48k] /* i/o: SCE channels / Binaural synthesis */
);
ivas_error ivas_rend_TDObjRendOpen(
TDREND_WRAPPER *pTDRend,
const IVAS_REND_AudioConfig inConfig,
LSSETUP_CUSTOM_STRUCT *customLsInput,
const int32_t output_Fs );
#endif
#endif
......@@ -29,7 +29,7 @@
the United Nations Convention on Contracts on the International Sales of Goods.
*******************************************************************************************************/
// VE2AT: keep in lib_rend or move to lib_dec ?
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
......@@ -39,6 +39,7 @@
#include "wmops.h"
#include <assert.h>
#ifndef EXT_RENDERER
/*----------------------------------------------------------------------------------*
* Local constants
*----------------------------------------------------------------------------------*/
......@@ -46,6 +47,7 @@
#define LIMITER_THRESHOLD 32729 /* -0.01 dBFS */
#define LIMITER_ATTACK_SECONDS 0.005f
#endif
/*-------------------------------------------------------------------*
* detect_strong_saturations()
......@@ -71,11 +73,19 @@ static int16_t detect_strong_saturations(
*strong_saturation_cnt = 50;
apply_strong_limiting = 1;
}
#ifdef EXT_RENDERER
else if ( max_val > 3 * IVAS_LIMITER_THRESHOLD && *strong_saturation_cnt > 0 )
#else
else if ( max_val > 3 * LIMITER_THRESHOLD && *strong_saturation_cnt > 0 )
#endif
{
apply_strong_limiting = 1;
}
#ifdef EXT_RENDERER
else if ( max_val > 10 * IVAS_LIMITER_THRESHOLD )
#else
else if ( max_val > 10 * LIMITER_THRESHOLD )
#endif
{
*strong_saturation_cnt += 20;
*strong_saturation_cnt = min( *strong_saturation_cnt, 50 );
......@@ -130,7 +140,11 @@ IVAS_LIMITER_HANDLE ivas_limiter_open(
hLimiter->sampling_rate = sampling_rate;
hLimiter->gain = 1.f;
hLimiter->release_heuristic = 0.f;
#ifdef EXT_RENDERER
hLimiter->attack_constant = powf( 0.01f, 1.0f / ( IVAS_LIMITER_ATTACK_SECONDS * sampling_rate ) );
#else
hLimiter->attack_constant = powf( 0.01f, 1.0f / ( LIMITER_ATTACK_SECONDS * sampling_rate ) );
#endif
hLimiter->strong_saturation_count = 0;
#ifdef DEBUGGING
hLimiter->cnt_frames_limited = 0;
......@@ -202,7 +216,11 @@ void ivas_limiter_dec(
channels[c] = output[c];
}
#ifdef EXT_RENDERER
limiter_process( hLimiter, output_frame, IVAS_LIMITER_THRESHOLD, BER_detect, &hLimiter->strong_saturation_count );
#else
limiter_process( hLimiter, output_frame, LIMITER_THRESHOLD, BER_detect, &hLimiter->strong_saturation_count );
#endif
return;
}
......
......@@ -79,8 +79,13 @@ ivas_error ivas_ls_custom_open(
*-------------------------------------------------------------------------*/
void ivas_ls_custom_setup(
#ifdef EXT_RENDERER
IVAS_OUTPUT_SETUP_HANDLE hOutSetup, /* o : IVAS output setup handle */
const LSSETUP_CUSTOM_STRUCT *hLsSetupCustom /* i : Custom loudspeaker setup handle */
#else
IVAS_OUTPUT_SETUP_HANDLE hOutSetup, /* o : IVAS output setup handle */
const LSSETUP_CUSTOM_HANDLE hLsSetupCustom /* i : Custom loudspeaker setup handle */
#endif
)
{
hOutSetup->output_config = AUDIO_CONFIG_LS_CUSTOM;
......
......@@ -37,6 +37,10 @@
#include <math.h>
#include "wmops.h"
#include "ivas_rom_com.h"
#ifdef EXT_RENDERER
#include "lib_rend.h"
#include "ivas_lib_rend_internal.h"
#endif
#ifdef DEBUGGING
#include "debug.h"
#endif
......@@ -46,9 +50,26 @@
* Local function prototypes
*---------------------------------------------------------------------*/
static ivas_error TDREND_GetMix( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, float output[][L_FRAME48k], const int16_t output_frame, const int32_t output_Fs );
static ivas_error TDREND_GetMix( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, float output[][L_FRAME48k], const int16_t subframe_length, const int32_t output_Fs, const int16_t subframe_idx );
static void TDREND_Clear_Update_flags( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd );
static void TDREND_Update_listener_orientation( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd,
const int16_t headRotEnabled,
#ifdef EXT_RENDERER
const IVAS_QUATERNION *headPosition
#else
const Quaternion *headPosition
#endif
);
static void TDREND_Update_object_positions( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd,
const int16_t numSources,
#ifdef EXT_RENDERER
const int16_t lfe_idx,
#endif
const IVAS_FORMAT in_format,
const ISM_METADATA_HANDLE *hIsmMetaData,
float output[][L_FRAME48k] );
/*---------------------------------------------------------------------*
* ivas_td_binaural_open()
......@@ -143,6 +164,12 @@ ivas_error ivas_td_binaural_open(
ls_azimuth = ls_azimuth_CICP19;
ls_elevation = ls_elevation_CICP19;
break;
#ifdef EXT_RENDERER
case AUDIO_CONFIG_LS_CUSTOM:
ls_azimuth = st_ivas->hTransSetup.ls_azimuth;
ls_elevation = st_ivas->hTransSetup.ls_elevation;
break;
#endif
default:
ls_azimuth = NULL;
ls_elevation = NULL;
......@@ -220,105 +247,43 @@ void ObjRenderIVASFrame(
const int16_t output_frame /* i : output frame length */
)
{
TDREND_DirAtten_t *DirAtten_p;
int16_t nS;
float Pos[3];
float Dir[3];
float FrontVec[3];
float UpVec[3];
float Rmat[3][3];
int16_t c_indx;
int16_t subframe_length;
int16_t subframe_idx;
float reverb_signal[BINAURAL_CHANNELS][L_FRAME48k];
DirAtten_p = st_ivas->hBinRendererTd->DirAtten_p;
/* Update the listener's location/orientation */
/* Listener at the origin */
Pos[0] = 0.0f;
Pos[1] = 0.0f;
Pos[2] = 0.0f;
subframe_length = output_frame / MAX_PARAM_SPATIAL_SUBFRAMES;
if ( st_ivas->hRenderConfig != NULL ) /* Renderer Configuration not enabled in TD standalone renderer */
{
if ( st_ivas->hHeadTrackData != NULL )
if ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on && ( st_ivas->ini_frame == 0 ) )
{
/* Obtain head rotation matrix */
QuatToRotMat( st_ivas->hHeadTrackData->Quaternions[0], Rmat );
/* Apply rotation matrix to looking vector [1;0;0] */
FrontVec[0] = Rmat[0][0];
FrontVec[1] = Rmat[0][1];
FrontVec[2] = Rmat[0][2];
/* Apply rotation matrix to up vector [0;0;1] */
UpVec[0] = Rmat[2][0];
UpVec[1] = Rmat[2][1];
UpVec[2] = Rmat[2][2];
ivas_reverb_open( &st_ivas->hCrend->hReverb, st_ivas->transport_config, NULL, st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_Fs );
}
else
{
/* Oriented with looking vector along the x axis */
FrontVec[0] = 1.0f;
FrontVec[1] = 0.0f;
FrontVec[2] = 0.0f;
/* Oriented with up vector along the z axis */
UpVec[0] = 0.0f;
UpVec[1] = 0.0f;
UpVec[2] = 1.0f;
}
/* Set the listener position and orientation:*/
TDREND_MIX_LIST_SetPos( st_ivas->hBinRendererTd, Pos );
TDREND_MIX_LIST_SetOrient( st_ivas->hBinRendererTd, FrontVec, UpVec );
/* For each source, write the frame data to the source object*/
c_indx = 0;
for ( nS = 0; nS < st_ivas->nchan_transport; nS++ )
{
if ( !( st_ivas->ivas_format == MC_FORMAT && nS == LFE_CHANNEL ) ) /* Skip LFE for MC */
{
st_ivas->hBinRendererTd->Sources[c_indx]->InputFrame_p = output[nS];
st_ivas->hBinRendererTd->Sources[c_indx]->SrcRend_p->InputAvailable = TRUE;
c_indx++;
}
/* Update object position(s) */
#ifdef EXT_RENDERER
TDREND_Update_object_positions( st_ivas->hBinRendererTd, st_ivas->nchan_transport, LFE_CHANNEL, st_ivas->ivas_format, st_ivas->hIsmMetaData, output );
#else
TDREND_Update_object_positions( st_ivas->hBinRendererTd, st_ivas->nchan_transport, st_ivas->ivas_format, st_ivas->hIsmMetaData, output );
#endif
if ( st_ivas->ivas_format == ISM_FORMAT )
for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ )
{
/* Update the listener's location/orientation */
TDREND_Update_listener_orientation( st_ivas->hBinRendererTd,
st_ivas->hDecoderConfig->Opt_Headrotation,
( st_ivas->hHeadTrackData != NULL ) ? &st_ivas->hHeadTrackData->Quaternions[subframe_idx] : NULL );
/* Update the source positions */
/* Source position and direction */
Pos[0] = cosf( st_ivas->hIsmMetaData[nS]->elevation * PI_OVER_180 ) * cosf( st_ivas->hIsmMetaData[nS]->azimuth * PI_OVER_180 );
Pos[1] = cosf( st_ivas->hIsmMetaData[nS]->elevation * PI_OVER_180 ) * sinf( st_ivas->hIsmMetaData[nS]->azimuth * PI_OVER_180 );
Pos[2] = sinf( st_ivas->hIsmMetaData[nS]->elevation * PI_OVER_180 );
Dir[0] = 1.0f;
Dir[1] = 0.0f;
Dir[2] = 0.0f;
/* Source directivity info */
DirAtten_p->ConeInnerAngle = 360.0f;
DirAtten_p->ConeOuterAngle = 360.0f;
DirAtten_p->ConeOuterGain = 1.0f;
TDREND_MIX_SRC_SetPos( st_ivas->hBinRendererTd, nS, Pos );
TDREND_MIX_SRC_SetDir( st_ivas->hBinRendererTd, nS, Dir );
TDREND_MIX_SRC_SetDirAtten( st_ivas->hBinRendererTd, nS, DirAtten_p );
TDREND_MIX_SRC_SetPlayState( st_ivas->hBinRendererTd, nS, TDREND_PLAYSTATUS_PLAYING );
}
}
if ( st_ivas->hRenderConfig != NULL ) /* Renderer Configuration not enabled in TD standalone renderer */
{
if ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on )
{
if ( st_ivas->ini_frame == 0 )
{
ivas_reverb_open( &st_ivas->hCrend->hReverb, st_ivas->transport_config, NULL, st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_Fs );
}
for ( subframe_idx = 0; subframe_idx < 4; subframe_idx++ )
if ( ( st_ivas->hRenderConfig != NULL ) && ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) )
{
ivas_reverb_process( st_ivas->hCrend->hReverb, st_ivas->transport_config, 0, output, reverb_signal, subframe_idx );
}
}
/* Render subframe */
TDREND_GetMix( st_ivas->hBinRendererTd, output, subframe_length, st_ivas->hDecoderConfig->output_Fs, subframe_idx );
}
/* Call the renderer */
TDREND_GetMix( st_ivas->hBinRendererTd, output, output_frame, st_ivas->hDecoderConfig->output_Fs );
if ( st_ivas->hRenderConfig != NULL ) /* Renderer Configuration not enabled in TD standalone renderer */
{
if ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on )
......@@ -336,14 +301,14 @@ void ObjRenderIVASFrame(
/*---------------------------------------------------------------------*
* TDREND_GetMix()
*
* Render one output frame from the mixer
* Render one 5 ms subframe from the mixer
*---------------------------------------------------------------------*/
static ivas_error TDREND_GetMix(
BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */
float output[][L_FRAME48k], /* i/o: ISm object synth / rendered output in 0,1 */
const int16_t output_frame, /* i/o: Output frame length */
const int32_t output_Fs /* i : Output sampling rate */
const int16_t subframe_length, /* i/o: subframe length */
const int32_t output_Fs, /* i : Output sampling rate */
const int16_t subframe_idx /* i : Subframe index to 5 ms subframe */
)
{
int16_t i;
......@@ -351,13 +316,12 @@ static ivas_error TDREND_GetMix(
TDREND_SRC_SPATIAL_t *SrcSpatial_p;
TDREND_SRC_REND_t *SrcRend_p;
ivas_error error;
float output_buf[2][L_FRAME48k]; /* Temp buffer for left/right rendered signal */
float output_buf[2][L_SPATIAL_SUBFR_48k]; /* Temp buffer for left/right rendered signal */
error = IVAS_ERR_OK;
/* Zero out the output buffer since objects are accumulated. */
set_f( output_buf[0], 0.0f, output_frame );
set_f( output_buf[1], 0.0f, output_frame );
/* Clear the output buffer to accumulate rendered sources */
set_f( output_buf[0], 0.0f, subframe_length );
set_f( output_buf[1], 0.0f, subframe_length );
/* Create the mix */
/* Loop through the source list and render each source */
......@@ -377,19 +341,18 @@ static ivas_error TDREND_GetMix(
if ( ( SrcRend_p->InputAvailable == TRUE ) && ( SrcRend_p->PlayStatus == TDREND_PLAYSTATUS_PLAYING ) )
{
#ifdef TDREND_HRTF_TABLE_METHODS
error = TDREND_REND_RenderSourceHRFilt( Src_p, hBinRendererTd, output_buf, output_frame, output_Fs );
error = TDREND_REND_RenderSourceHRFilt( Src_p, hBinRendererTd, output_buf, subframe_length, output_Fs );
#else
error = TDREND_REND_RenderSourceHRFilt( Src_p, output_buf, output_frame, output_Fs );
error = TDREND_REND_RenderSourceHRFilt( Src_p, output_buf, subframe_length, output_Fs );
#endif
}
SrcRend_p->InputAvailable = FALSE;
}
/* Populate output variable */
mvr2r( output_buf[0], output[0], output_frame ); /* Left */
mvr2r( output_buf[1], output[1], output_frame ); /* Right */
mvr2r( output_buf[0], output[0] + subframe_idx * subframe_length, subframe_length ); /* Left */
mvr2r( output_buf[1], output[1] + subframe_idx * subframe_length, subframe_length ); /* Right */
/* Clear the mixer update flags */
/* Clear the PoseUpdated and Source position update flags */
TDREND_Clear_Update_flags( hBinRendererTd );
return error;
......@@ -417,3 +380,379 @@ static void TDREND_Clear_Update_flags(
return;
}
/*---------------------------------------------------------------------*
* TDREND_Update_object_positions()
*
* Update object position(s)
*---------------------------------------------------------------------*/
static void TDREND_Update_object_positions(
BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o : TD Renderer handle */
const int16_t numSources, /* i : Number of sources to render */
#ifdef EXT_RENDERER
const int16_t lfe_idx, /* i : Input LFE index */
#endif
const IVAS_FORMAT in_format, /* i : Format of input sources */
const ISM_METADATA_HANDLE *hIsmMetaData, /* i : Input metadata for ISM objects */
float output[][L_FRAME48k] /* i/o: SCE/MC channels */
)
{
TDREND_DirAtten_t *DirAtten_p;
int16_t nS;
float Pos[3];
float Dir[3];
int16_t c_indx;
DirAtten_p = hBinRendererTd->DirAtten_p;
/* For each source, write the frame data to the source object*/
c_indx = 0;
for ( nS = 0; nS < numSources; nS++ )
{
#ifdef EXT_RENDERER
if ( !( in_format == MC_FORMAT && nS == lfe_idx ) ) /* Skip LFE for MC */
#else
if ( !( in_format == MC_FORMAT && nS == LFE_CHANNEL ) ) /* Skip LFE for MC */
#endif
{
hBinRendererTd->Sources[c_indx]->InputFrame_p = output[nS];
hBinRendererTd->Sources[c_indx]->SrcRend_p->InputAvailable = TRUE;
c_indx++;
}
if ( in_format == ISM_FORMAT )
{
/* Update the source positions */
/* Source position and direction */
Pos[0] = cosf( hIsmMetaData[nS]->elevation * PI_OVER_180 ) * cosf( hIsmMetaData[nS]->azimuth * PI_OVER_180 );
Pos[1] = cosf( hIsmMetaData[nS]->elevation * PI_OVER_180 ) * sinf( hIsmMetaData[nS]->azimuth * PI_OVER_180 );
Pos[2] = sinf( hIsmMetaData[nS]->elevation * PI_OVER_180 );
Dir[0] = 1.0f;
Dir[1] = 0.0f;
Dir[2] = 0.0f;
/* Source directivity info */
DirAtten_p->ConeInnerAngle = 360.0f;
DirAtten_p->ConeOuterAngle = 360.0f;
DirAtten_p->ConeOuterGain = 1.0f;
TDREND_MIX_SRC_SetPos( hBinRendererTd, nS, Pos );
TDREND_MIX_SRC_SetDirAtten( hBinRendererTd, nS, DirAtten_p );
TDREND_MIX_SRC_SetPlayState( hBinRendererTd, nS, TDREND_PLAYSTATUS_PLAYING );
TDREND_MIX_SRC_SetDir( hBinRendererTd, nS, Dir );
}
}
return;
}
/*---------------------------------------------------------------------*
* TDREND_Update_listener_orientation()
*
* Update listener orientation (s)
*---------------------------------------------------------------------*/
static void TDREND_Update_listener_orientation(
BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD Renderer handle */
const int16_t headRotEnabled, /* i : Headrotation flag */
#ifdef EXT_RENDERER
const IVAS_QUATERNION *headPosition /* i : Head Position */
#else
const Quaternion *headPosition /* i : Head Position */
#endif
)
{
float Pos[3];
float FrontVec[3];
float UpVec[3];
float Rmat[3][3];
/* Update the listener's location/orientation */
/* Listener at the origin */
Pos[0] = 0.0f;
Pos[1] = 0.0f;
Pos[2] = 0.0f;
if ( headRotEnabled )
{
/* Obtain head rotation matrix */
QuatToRotMat( *headPosition, Rmat );
/* Apply rotation matrix to looking vector [1;0;0] */
FrontVec[0] = Rmat[0][0];
FrontVec[1] = Rmat[0][1];
FrontVec[2] = Rmat[0][2];
/* Apply rotation matrix to up vector [0;0;1] */
UpVec[0] = Rmat[2][0];
UpVec[1] = Rmat[2][1];
UpVec[2] = Rmat[2][2];
}
else
{
/* Oriented with looking vector along the x axis */
FrontVec[0] = 1.0f;
FrontVec[1] = 0.0f;
FrontVec[2] = 0.0f;
/* Oriented with up vector along the z axis */
UpVec[0] = 0.0f;
UpVec[1] = 0.0f;
UpVec[2] = 1.0f;
}
/* Set the listener position and orientation:*/
TDREND_MIX_LIST_SetPos( hBinRendererTd, Pos );
TDREND_MIX_LIST_SetOrient( hBinRendererTd, FrontVec, UpVec );
return;
}
#ifdef EXT_RENDERER
ivas_error ivas_rend_TDObjRendOpen(
TDREND_WRAPPER *pTDRend,
IVAS_REND_AudioConfig inConfig,
LSSETUP_CUSTOM_STRUCT *customLsInput,
const int32_t outFs )
{
/* TODO tmu : Based on ivas_td_binaural_open() - could be harmonized / refactored
- review error handling
- review hHrtfTD init
*/
BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd;
TDREND_PosType_t PosType;
int16_t nS;
int16_t SrcInd[MAX_NUM_TDREND_CHANNELS];
const float *ls_azimuth, *ls_elevation;
float Pos[3];
float Dir[3];
TDREND_DirAtten_t *DirAtten_p;
int16_t nchan_rend;
ivas_error error;
error = IVAS_ERR_OK;
if ( ( hBinRendererTd = count_malloc( sizeof( BINAURAL_TD_OBJECT_RENDERER ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD renderer\n" ) );
}
if ( ( hBinRendererTd->TdRend_MixSpatSpec_p = count_malloc( sizeof( TDREND_MixSpatSpec_t ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD renderer\n" ) );
}
if ( ( hBinRendererTd->DirAtten_p = count_malloc( sizeof( TDREND_DirAtten_t ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD renderer\n" ) );
}
if ( ( hBinRendererTd->Listener_p = count_malloc( sizeof( TDREND_MIX_Listener_t ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD renderer\n" ) );
}
if ( inConfig != IVAS_REND_AUDIO_CONFIG_LS_CUSTOM )
{
getAudioConfigNumChannels( inConfig, &nchan_rend );
if ( getAudioConfigType( inConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED )
{
nchan_rend--; /* Skip LFE channel -- added to the others */
}
}
else
{
nchan_rend = customLsInput->num_spk;
}
hBinRendererTd->NumOfSrcs = 0;
hBinRendererTd->MaxSrcInd = -1;
/* Mixer spatial setup */
hBinRendererTd->TdRend_MixSpatSpec_p->UseCommonDistAttenModel = TRUE;
hBinRendererTd->TdRend_MixSpatSpec_p->DistAttenModel = 0; /* 0=Turned off, else use TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED */
TDREND_MIX_Init( hBinRendererTd, &pTDRend->hHrtfTD, hBinRendererTd->TdRend_MixSpatSpec_p, outFs );
/* Set the attenuation (or can set MixSpatSpec.DistAttenModel above) */
TDREND_MIX_SetDistAttenModel( hBinRendererTd, TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED );
/* Add sources to module and mixer, headphones */
PosType = TDREND_POSTYPE_ABSOLUTE; /* or TDREND_POSTYPE_RELATIVE_TO_LISTENER */
for ( nS = 0; nS < nchan_rend; nS++ )
{
if ( ( error = TDREND_MIX_AddSrc( hBinRendererTd, &SrcInd[nS], PosType, outFs ) ) != IVAS_ERR_OK )
{
return error;
}
}
if ( getAudioConfigType( inConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED )
{
switch ( inConfig )
{
case IVAS_REND_AUDIO_CONFIG_5_1:
ls_azimuth = ls_azimuth_CICP6;
ls_elevation = ls_elevation_CICP6;
break;
case IVAS_REND_AUDIO_CONFIG_7_1:
ls_azimuth = ls_azimuth_CICP12;
ls_elevation = ls_elevation_CICP12;
break;
case IVAS_REND_AUDIO_CONFIG_5_1_2:
ls_azimuth = ls_azimuth_CICP14;
ls_elevation = ls_elevation_CICP14;
break;
case IVAS_REND_AUDIO_CONFIG_5_1_4:
ls_azimuth = ls_azimuth_CICP16;
ls_elevation = ls_elevation_CICP16;
break;
case IVAS_REND_AUDIO_CONFIG_7_1_4:
ls_azimuth = ls_azimuth_CICP19;
ls_elevation = ls_elevation_CICP19;
break;
case IVAS_REND_AUDIO_CONFIG_LS_CUSTOM:
ls_azimuth = customLsInput->ls_azimuth;
ls_elevation = customLsInput->ls_elevation;
break;
default:
ls_azimuth = NULL;
ls_elevation = NULL;
}
DirAtten_p = hBinRendererTd->DirAtten_p;
for ( nS = 0; nS < nchan_rend; nS++ )
{
/* Set source positions according to loudspeaker layout */
Pos[0] = cosf( ls_elevation[nS] * PI_OVER_180 ) * cosf( ls_azimuth[nS] * PI_OVER_180 );
Pos[1] = cosf( ls_elevation[nS] * PI_OVER_180 ) * sinf( ls_azimuth[nS] * PI_OVER_180 );
Pos[2] = sinf( ls_elevation[nS] * PI_OVER_180 );
Dir[0] = 1.0f;
Dir[1] = 0.0f;
Dir[2] = 0.0f;
/* Source directivity info */
DirAtten_p->ConeInnerAngle = 360.0f;
DirAtten_p->ConeOuterAngle = 360.0f;
DirAtten_p->ConeOuterGain = 1.0f;
TDREND_MIX_SRC_SetPos( hBinRendererTd, nS, Pos );
TDREND_MIX_SRC_SetDir( hBinRendererTd, nS, Dir );
TDREND_MIX_SRC_SetPlayState( hBinRendererTd, nS, TDREND_PLAYSTATUS_PLAYING );
TDREND_MIX_SRC_SetDirAtten( hBinRendererTd, nS, DirAtten_p );
}
}
pTDRend->hBinRendererTd = hBinRendererTd;
pTDRend->binaural_latency_ns = (int32_t) ( BINAURAL_TD_LATENCY_S * 1000000000.f );
return IVAS_ERR_OK;
}
/*---------------------------------------------------------------------*
* ObjRenderIVASFrame()
*
* Receives the current frames for the object streams, updates metadata
* and renders the current frame.
*---------------------------------------------------------------------*/
/*! r: TD Renderer result code. */
ivas_error ivas_rend_TDObjRenderFrame(
const TDREND_WRAPPER *pTDRend, /* i : TD Renderer wrapper structure */
const IVAS_REND_AudioConfig inConfig, /* i : Input audio configuration */
const LSSETUP_CUSTOM_STRUCT *customLsInput, /* i : Input custom loudspeaker layout */
const IVAS_REND_HeadRotData *headRotData, /* i : Input head positions */
const IVAS_REND_AudioObjectPosition *currentPos, /* i : Object position */
const int16_t output_frame, /* i : output frame length */
const int32_t output_Fs, /* i : output sampling rate */
float output[][L_FRAME48k] /* i/o: SCE channels / Binaural synthesis */
)
{
int16_t subframe_length;
int16_t subframe_idx;
ISM_METADATA_HANDLE hIsmMetaData[1];
int16_t lfe_idx;
int16_t num_src;
/* TODO tmu : pass down renderer config struct */
// float reverb_signal[BINAURAL_CHANNELS][L_FRAME48k];
IVAS_FORMAT ivas_format;
IVAS_REND_AudioConfigType inConfigType;
wmops_sub_start( "ivas_rend_TDObjRenderFrame" );
inConfigType = getAudioConfigType( inConfig );
lfe_idx = LFE_CHANNEL;
if ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED )
{
ivas_format = MC_FORMAT;
if ( inConfig != IVAS_REND_AUDIO_CONFIG_LS_CUSTOM )
{
getAudioConfigNumChannels( inConfig, &num_src );
}
else
{
lfe_idx = ( customLsInput->num_lfe > 0 ) ? customLsInput->lfe_idx[0] : -1;
num_src = customLsInput->num_spk + customLsInput->num_lfe;
}
}
else
{
ivas_format = ISM_FORMAT;
num_src = 1;
hIsmMetaData[0] = count_malloc( sizeof( ISM_METADATA_FRAME ) );
hIsmMetaData[0]->azimuth = currentPos->azimuth;
hIsmMetaData[0]->elevation = currentPos->elevation;
}
subframe_length = output_frame / MAX_PARAM_SPATIAL_SUBFRAMES;
/* TODO tmu : pass down renderer config struct and decide what to do about ini_frame ? */
// if ( hRenderConfig != NULL ) /* Renderer Configuration not enabled in TD standalone renderer */
// {
// if ( hRenderConfig->roomAcoustics.late_reverb_on && ( st_ivas->ini_frame == 0 ) )
// {
// ivas_reverb_open( &pTDRend->hCrend->hReverb, pTDRend->transport_config, NULL, pTDRend->hRenderConfig, pTDRend->hDecoderConfig->output_Fs );
// }
// }
/* Update object position(s) */
TDREND_Update_object_positions( pTDRend->hBinRendererTd, num_src, lfe_idx, ivas_format, hIsmMetaData, output );
/* TODO tmu : needs a refactor / better approach */
if ( ivas_format == ISM_FORMAT )
{
count_free( hIsmMetaData[0] );
}
for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ )
{
/* Update the listener's location/orientation */
TDREND_Update_listener_orientation( pTDRend->hBinRendererTd, headRotData->headRotEnabled, ( headRotData != NULL ) ? &headRotData->headPositions[subframe_idx] : NULL );
/* TODO tmu : pass down renderer config struct */
// if ( ( hRenderConfig != NULL ) && ( hRenderConfig->roomAcoustics.late_reverb_on ) )
// {
// ivas_reverb_process( hCrend->hReverb, transport_config, 0, output, reverb_signal, subframe_idx );
// }
/* Render subframe */
TDREND_GetMix( pTDRend->hBinRendererTd, output, subframe_length, output_Fs, subframe_idx );
}
/* TODO tmu : pass down renderer config struct */
// if ( pTDRend->hRenderConfig != NULL ) /* Renderer Configuration not enabled in TD standalone renderer */
// {
// if ( pTDRend->hRenderConfig->roomAcoustics.late_reverb_on )
// {
// /* add reverb to rendered signals */
// v_add( reverb_signal[0], output[0], output[0], output_frame );
// v_add( reverb_signal[1], output[1], output[1], output_frame );
// }
// }
wmops_sub_end();
return IVAS_ERR_OK;
}
#endif
......@@ -36,7 +36,7 @@
#include "prot.h"
#include <math.h>
#include "ivas_prot.h"
#include "ivas_rom_dec.h"
#include "ivas_rom_rend.h"
#include "ivas_cnst.h"
#include "ivas_rom_TdBinauralRenderer.h"
#include "wmops.h"
......@@ -343,23 +343,21 @@ void TDREND_HRFILT_SetFiltSet(
--------------------------------------------------------------------*/
ivas_error TDREND_REND_RenderSourceHRFilt(
const TDREND_SRC_t *Src_p, /* i/o: The source to be rendered */
TDREND_SRC_t *Src_p, /* i/o: The source to be rendered */
#ifdef TDREND_HRTF_TABLE_METHODS
BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */
#endif
float output_buf[][L_FRAME48k], /* o : Output buffer */
const int16_t output_frame, /* i : Output frame length in use */
float output_buf[][L_SPATIAL_SUBFR_48k], /* o : Output buffer */
const int16_t subframe_length, /* i : Subframe length in use */
const int32_t output_Fs /* i : Output sample rate */
)
{
TDREND_SRC_REND_t *SrcRend_p;
int16_t nS;
float *InFrame_nIC_p;
const float *InFrame_nIC_p;
int16_t NoOfUsedInputSamples, NoOfDeliveredOutputSamples;
float LeftOutputFrame[L_FRAME48k];
float RightOutputFrame[L_FRAME48k];
float *LeftOutputFrame_p, *RightOutputFrame_p;
float *LeftAccOutputFrame_p, *RightAccOutputFrame_p;
float LeftOutputFrame[L_SPATIAL_SUBFR_48k];
float RightOutputFrame[L_SPATIAL_SUBFR_48k];
/* Input channel rendering loop */
InFrame_nIC_p = Src_p->InputFrame_p;
......@@ -369,7 +367,7 @@ ivas_error TDREND_REND_RenderSourceHRFilt(
/* SrcGain = Mix_p->Gain * ( *SrcRend_p->SrcGain_p ); */
/* SrcGain *= ( *SrcRend_p->DirGain_p ) * ( *SrcRend_p->DistGain_p ); */
TDREND_SFX_SpatBin_Execute_Main( SrcRend_p->SfxSpatBin_p, InFrame_nIC_p, output_frame, LeftOutputFrame, RightOutputFrame, &NoOfUsedInputSamples, &NoOfDeliveredOutputSamples, output_Fs );
TDREND_SFX_SpatBin_Execute_Main( SrcRend_p->SfxSpatBin_p, InFrame_nIC_p, subframe_length, LeftOutputFrame, RightOutputFrame, &NoOfUsedInputSamples, &NoOfDeliveredOutputSamples, output_Fs );
#ifdef TDREND_HRTF_TABLE_METHODS
if ( hBinRendererTd->HrFiltSet_p->FilterMethod != TDREND_HRFILT_Method_BSplineModel )
......@@ -379,15 +377,11 @@ ivas_error TDREND_REND_RenderSourceHRFilt(
#endif
/* Copy to accumulative output frame */
LeftOutputFrame_p = LeftOutputFrame;
RightOutputFrame_p = RightOutputFrame;
LeftAccOutputFrame_p = output_buf[0];
RightAccOutputFrame_p = output_buf[1];
for ( nS = 0; nS < output_frame; nS++ )
{
*LeftAccOutputFrame_p++ += *LeftOutputFrame_p++;
*RightAccOutputFrame_p++ += *RightOutputFrame_p++;
}
v_add( LeftOutputFrame, output_buf[0], output_buf[0], subframe_length );
v_add( RightOutputFrame, output_buf[1], output_buf[1], subframe_length );
Src_p->InputFrame_p += subframe_length; /* Increment input pointer -- todo: should we remove this and input the current subframe instead? */
return IVAS_ERR_OK;
}
......
......@@ -34,7 +34,7 @@
#include "options.h"
#include <math.h>
#include "ivas_prot.h"
#include "ivas_rom_dec.h"
#include "ivas_rom_rend.h"
#include "prot.h"
#include "wmops.h"
......@@ -930,7 +930,7 @@ static void TDREND_SFX_SpatBin_UpdateParams(
void TDREND_SFX_SpatBin_Execute_Main(
SFX_SpatBin_t *SfxSpatBin_p, /* i/o: Spatial parameters struct */
const float *InBuffer_p, /* i : Input buffer */
const int16_t output_frame, /* i : frame length */
const int16_t subframe_length, /* i : subframe length */
float *LeftOutBuffer_p, /* o : Rendered left channel */
float *RightOutBuffer_p, /* o : Rendered right channel */
int16_t *NoOfUsedInputSamples_p, /* o : Number of input samples actually used */
......@@ -948,7 +948,7 @@ void TDREND_SFX_SpatBin_Execute_Main(
/* Make sure the blocks are not longer than 6 msec. */
NoOfBlocks = 1;
TempNoOfRequestedOutputSamples = output_frame;
TempNoOfRequestedOutputSamples = subframe_length;
while ( TempNoOfRequestedOutputSamples > SfxSpatBin_p->MaxBlockLength )
{
NoOfBlocks = NoOfBlocks << 1;
......@@ -962,7 +962,7 @@ void TDREND_SFX_SpatBin_Execute_Main(
RightOutBufferPointer_p = RightOutBuffer_p;
*NoOfUsedInputSamples_p = 0;
*NoOfDeliveredOutputSamples_p = 0;
TempNoOfInputSamples = output_frame;
TempNoOfInputSamples = subframe_length;
for ( i = 0; i < NoOfBlocks; i++ )
{
......@@ -991,7 +991,7 @@ void TDREND_SFX_SpatBin_Execute_Main(
if ( i == NoOfBlocks - 2 )
{
/* The last block should produce the remaining number of samples */
TempNoOfRequestedOutputSamples = output_frame - *NoOfDeliveredOutputSamples_p;
TempNoOfRequestedOutputSamples = subframe_length - *NoOfDeliveredOutputSamples_p;
}
*NoOfUsedInputSamples_p = *NoOfUsedInputSamples_p + TempNoOfUsedInputSamples;
TempNoOfInputSamples = TempNoOfInputSamples - TempNoOfUsedInputSamples;
......@@ -1205,6 +1205,12 @@ ivas_error TDREND_SFX_SpatBin_Initialize(
SfxSpatBin_p->TurningOnEffect = FALSE;
/* Init during next SetParams-call */
SfxSpatBin_p->InitializeParams = TRUE;
#ifdef FIX_I81
SfxSpatBin_p->LeftFilter_p = NULL;
SfxSpatBin_p->LeftFilterIncr_p = NULL;
SfxSpatBin_p->RightFilter_p = NULL;
SfxSpatBin_p->RightFilterIncr_p = NULL;
#endif
/* Init MaxTargetTime and MaxBlockLength */
switch ( output_Fs )
......
......@@ -89,7 +89,7 @@ void TDREND_SPATIAL_VecNormalize(
{
float scaler;
scaler = 1.0f / sqrtf( Vec_p[0] * Vec_p[0] + Vec_p[1] * Vec_p[1] + Vec_p[2] * Vec_p[2] );
scaler = inv_sqrt( Vec_p[0] * Vec_p[0] + Vec_p[1] * Vec_p[1] + Vec_p[2] * Vec_p[2] );
VecNorm_p[0] = scaler * Vec_p[0];
VecNorm_p[1] = scaler * Vec_p[1];
VecNorm_p[2] = scaler * Vec_p[2];
......
......@@ -29,7 +29,7 @@
the United Nations Convention on Contracts on the International Sales of Goods.
*******************************************************************************************************/
// VE2AT: keep in lib_rend or move to lib_dec ?
#include <assert.h>
#include <stdint.h>
#include "options.h"
......@@ -171,13 +171,13 @@ void ivas_output_init(
hOutSetup->ls_elevation = ls_elevation_CICP2;
break;
case AUDIO_CONFIG_FOA:
hOutSetup->ambisonics_order = 1;
hOutSetup->ambisonics_order = SBA_FOA_ORDER;
break;
case AUDIO_CONFIG_HOA2:
hOutSetup->ambisonics_order = 2;
hOutSetup->ambisonics_order = SBA_HOA2_ORDER;
break;
case AUDIO_CONFIG_HOA3:
hOutSetup->ambisonics_order = 3;
hOutSetup->ambisonics_order = SBA_HOA3_ORDER;
break;
case AUDIO_CONFIG_5_1:
hOutSetup->num_lfe = 1;
......@@ -511,18 +511,18 @@ void ivas_renderer_select(
if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->sba_mode == SBA_MODE_SPAR &&
( output_config != AUDIO_CONFIG_5_1 && output_config != AUDIO_CONFIG_5_1_2 && output_config != AUDIO_CONFIG_5_1_4 && output_config != AUDIO_CONFIG_7_1 && output_config != AUDIO_CONFIG_7_1_4 && output_config != AUDIO_CONFIG_LS_CUSTOM ) )
{
#ifdef SBA_INTERN_CONFIG_FIX_HOA2
if ( output_config == AUDIO_CONFIG_HOA2 || output_config == AUDIO_CONFIG_FOA )
{
*internal_config = output_config;
}
else if ( output_config == AUDIO_CONFIG_MONO || output_config == AUDIO_CONFIG_STEREO )
{
*internal_config = AUDIO_CONFIG_FOA;
}
else
{
*internal_config = AUDIO_CONFIG_HOA3;
}
#else
*internal_config = AUDIO_CONFIG_HOA3;
#endif
st_ivas->renderer_type = RENDERER_SBA_LINEAR_DEC;
}
else if ( ( st_ivas->ivas_format == MASA_FORMAT && output_config == AUDIO_CONFIG_MONO && st_ivas->nchan_transport == 1 ) ||
......@@ -530,7 +530,7 @@ void ivas_renderer_select(
{
*renderer_type = RENDERER_DISABLE;
}
else if ( ( st_ivas->ivas_format == MASA_FORMAT && output_config == AUDIO_CONFIG_MONO && st_ivas->hDecoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_SID_4k4 ) )
else if ( ( st_ivas->ivas_format == MASA_FORMAT && output_config == AUDIO_CONFIG_MONO && st_ivas->hDecoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_SID_5k2 ) )
{
*renderer_type = RENDERER_DISABLE;
}
......
......@@ -34,7 +34,7 @@
#include "options.h"
#include "prot.h"
#include "ivas_prot.h"
#include "ivas_rom_dec.h"
#include "ivas_rom_rend.h"
#include "ivas_rom_TdBinauralRenderer.h"
#ifdef DEBUGGING
#include "debug.h"
......