From 96598c476f92a408311dad4b77f5e62660c8a644 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Wed, 21 Sep 2022 10:54:42 +0200 Subject: [PATCH] 5 ms update rate for headrotation under define FIX_I106_TDREND_5MS --- lib_com/ivas_cnst.h | 3 + lib_com/ivas_prot.h | 13 ++ lib_com/options.h | 2 +- lib_dec/ivas_objectRenderer.c | 208 ++++++++++++++++++++++++++- lib_dec/ivas_objectRenderer_hrFilt.c | 33 +++++ lib_dec/ivas_objectRenderer_sfx.c | 28 +++- 6 files changed, 275 insertions(+), 12 deletions(-) diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 29416d2c50..dbb04643bd 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -823,6 +823,9 @@ typedef enum { *----------------------------------------------------------------------------------*/ // VE: this should be renamed to e.g. N_SPATIAL_SUBFRAMES #define MAX_PARAM_SPATIAL_SUBFRAMES 4 /* Maximum number of subframes for parameteric spatial coding */ +#ifdef FIX_I106_TDREND_5MS +#define L_SPATIAL_SUBFR_48k (L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES) +#endif /*----------------------------------------------------------------------------------* diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index c4e93a9545..13012128ae 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -4936,12 +4936,21 @@ void TDREND_HRFILT_SetFiltSet( #endif ivas_error TDREND_REND_RenderSourceHRFilt( +#ifdef FIX_I106_TDREND_5MS + TDREND_SRC_t *Src_p, /* i/o: The source to be rendered */ +#else const TDREND_SRC_t *Src_p, /* i/o: The source to be rendered */ +#endif #ifdef TDREND_HRTF_TABLE_METHODS BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ #endif +#ifdef FIX_I106_TDREND_5MS + float output_buf[][L_SPATIAL_SUBFR_48k], /* o : Output buffer */ + const int16_t subframe_length, /* i : Subframe length in use */ +#else float output_buf[][L_FRAME48k], /* o : Output buffer */ const int16_t output_frame, /* i : Output frame length in use */ +#endif const int32_t output_Fs /* i : Output sample rate */ ); @@ -5081,7 +5090,11 @@ void TDREND_SFX_SpatBin_SetParams( void TDREND_SFX_SpatBin_Execute_Main( SFX_SpatBin_t *SfxSpatBin_p, /* i/o: Spatial parameters handle */ const float *InBuffer_p, /* i : Input buffer */ +#ifdef FIX_I106_TDREND_5MS + const int16_t subframe_length, /* i : subframe length */ +#else const int16_t output_frame, /* i : frame length */ +#endif 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 */ diff --git a/lib_com/options.h b/lib_com/options.h index 54d2700014..93c29607ad 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -149,7 +149,7 @@ #define SPAR_SCALING_HARMONIZATION /* Issue 80: Changes to harmonize scaling in spar */ #define SBA_INTERN_CONFIG_FIX_HOA2 /* Issue 99 : Fix for incorrect internal_config when output format is HOA2 or FOA*/ #define FIX_I98_HANDLES_TO_NULL /* Issue 98: do the setting of all handles to NULL in one place */ - +#define FIX_I106_TDREND_5MS /* Issue 106: 5 ms update rate in TD object renderer */ /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_dec/ivas_objectRenderer.c b/lib_dec/ivas_objectRenderer.c index fe33031ad6..f4b024b38a 100644 --- a/lib_dec/ivas_objectRenderer.c +++ b/lib_dec/ivas_objectRenderer.c @@ -46,9 +46,16 @@ * Local function prototypes *---------------------------------------------------------------------*/ +#ifdef FIX_I106_TDREND_5MS +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 ); +#else 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 ); +#endif static void TDREND_Clear_Update_flags( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd ); - +#ifdef FIX_I106_TDREND_5MS +static void TDREND_Update_listener_orientation( Decoder_Struct *st_ivas, const int16_t subframe_idx ); +static void TDREND_Update_object_positions( Decoder_Struct *st_ivas, float output[][L_FRAME48k] ); +#endif /*---------------------------------------------------------------------* * ivas_td_binaural_open() @@ -220,6 +227,7 @@ void ObjRenderIVASFrame( const int16_t output_frame /* i : output frame length */ ) { +#ifndef FIX_I106_TDREND_5MS TDREND_DirAtten_t *DirAtten_p; int16_t nS; float Pos[3]; @@ -228,9 +236,15 @@ void ObjRenderIVASFrame( float UpVec[3]; float Rmat[3][3]; int16_t c_indx; +#else + int16_t subframe_length; +#endif int16_t subframe_idx; float reverb_signal[BINAURAL_CHANNELS][L_FRAME48k]; +#ifdef FIX_I106_TDREND_5MS + subframe_length = output_frame / MAX_PARAM_SPATIAL_SUBFRAMES; +#else DirAtten_p = st_ivas->hBinRendererTd->DirAtten_p; /* Update the listener's location/orientation */ @@ -302,8 +316,16 @@ void ObjRenderIVASFrame( TDREND_MIX_SRC_SetPlayState( st_ivas->hBinRendererTd, nS, TDREND_PLAYSTATUS_PLAYING ); } } +#endif if ( st_ivas->hRenderConfig != NULL ) /* Renderer Configuration not enabled in TD standalone renderer */ { + +#ifdef FIX_I106_TDREND_5MS + if ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on && ( 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 ); + } +#else if ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) { if ( st_ivas->ini_frame == 0 ) @@ -315,10 +337,31 @@ void ObjRenderIVASFrame( ivas_reverb_process( st_ivas->hCrend->hReverb, st_ivas->transport_config, 0, output, reverb_signal, subframe_idx ); } } +#endif } +#ifdef FIX_I106_TDREND_5MS + /* Update object position(s) */ + TDREND_Update_object_positions( st_ivas, output ); + + for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) + { + /* Update the listener's location/orientation */ + TDREND_Update_listener_orientation( st_ivas, 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 ); + } +#else /* Call the renderer */ TDREND_GetMix( st_ivas->hBinRendererTd, output, output_frame, st_ivas->hDecoderConfig->output_Fs ); +#endif + if ( st_ivas->hRenderConfig != NULL ) /* Renderer Configuration not enabled in TD standalone renderer */ { if ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) @@ -333,17 +376,30 @@ void ObjRenderIVASFrame( } +#ifdef FIX_I106_TDREND_5MS +/*---------------------------------------------------------------------* + * TDREND_GetMix() + * + * Render one 5 ms subframe from the mixer + *---------------------------------------------------------------------*/ +#else /*---------------------------------------------------------------------* * TDREND_GetMix() * * Render one output frame from the mixer *---------------------------------------------------------------------*/ - +#endif 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 */ +#ifdef FIX_I106_TDREND_5MS + 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 */ +#else + const int16_t output_frame, /* i/o: Output frame length */ + const int32_t output_Fs /* i : Output sampling rate */ +#endif ) { int16_t i; @@ -351,13 +407,22 @@ static ivas_error TDREND_GetMix( TDREND_SRC_SPATIAL_t *SrcSpatial_p; TDREND_SRC_REND_t *SrcRend_p; ivas_error error; +#ifdef FIX_I106_TDREND_5MS + float output_buf[2][L_SPATIAL_SUBFR_48k]; /* Temp buffer for left/right rendered signal */ +#else float output_buf[2][L_FRAME48k]; /* Temp buffer for left/right rendered signal */ - +#endif error = IVAS_ERR_OK; +#ifdef FIX_I106_TDREND_5MS + /* 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 ); +#else /* 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 ); +#endif /* Create the mix */ /* Loop through the source list and render each source */ @@ -376,20 +441,39 @@ static ivas_error TDREND_GetMix( /* Render source if needed */ if ( ( SrcRend_p->InputAvailable == TRUE ) && ( SrcRend_p->PlayStatus == TDREND_PLAYSTATUS_PLAYING ) ) { +#ifdef FIX_I106_TDREND_5MS +#ifdef TDREND_HRTF_TABLE_METHODS + error = TDREND_REND_RenderSourceHRFilt( Src_p, hBinRendererTd, output_buf, subframe_length, output_Fs ); +#else + error = TDREND_REND_RenderSourceHRFilt( Src_p, output_buf, subframe_length, output_Fs ); +#endif +#else #ifdef TDREND_HRTF_TABLE_METHODS error = TDREND_REND_RenderSourceHRFilt( Src_p, hBinRendererTd, output_buf, output_frame, output_Fs ); #else error = TDREND_REND_RenderSourceHRFilt( Src_p, output_buf, output_frame, output_Fs ); +#endif #endif } +#ifndef FIX_I106_TDREND_5MS SrcRend_p->InputAvailable = FALSE; +#endif } /* Populate output variable */ +#ifdef FIX_I106_TDREND_5MS + 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 */ +#else mvr2r( output_buf[0], output[0], output_frame ); /* Left */ mvr2r( output_buf[1], output[1], output_frame ); /* Right */ +#endif +#ifdef FIX_I106_TDREND_5MS + /* Clear the PoseUpdated and Source position update flags */ +#else /* Clear the mixer update flags */ +#endif TDREND_Clear_Update_flags( hBinRendererTd ); return error; @@ -417,3 +501,117 @@ static void TDREND_Clear_Update_flags( return; } + +#ifdef FIX_I106_TDREND_5MS +/*---------------------------------------------------------------------* + * TDREND_Update_object_positions() + * + * Update object position(s) + *---------------------------------------------------------------------*/ + +static void TDREND_Update_object_positions( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + 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 = st_ivas->hBinRendererTd->DirAtten_p; + + /* 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++; + } + + if ( st_ivas->ivas_format == ISM_FORMAT ) + { + + /* 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_SetDirAtten( st_ivas->hBinRendererTd, nS, DirAtten_p ); + TDREND_MIX_SRC_SetPlayState( st_ivas->hBinRendererTd, nS, TDREND_PLAYSTATUS_PLAYING ); + + TDREND_MIX_SRC_SetDir( st_ivas->hBinRendererTd, nS, Dir ); + } + } + + return; +} + +/*---------------------------------------------------------------------* + * TDREND_Update_listener_orientation() + * + * Update listener orientation (s) + *---------------------------------------------------------------------*/ + +static void TDREND_Update_listener_orientation( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const int16_t subframe_idx /* i: subframe index*/ +) +{ + 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 ( st_ivas->hHeadTrackData != NULL ) + { + /* Obtain head rotation matrix */ + QuatToRotMat( st_ivas->hHeadTrackData->Quaternions[subframe_idx], 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( st_ivas->hBinRendererTd, Pos ); + TDREND_MIX_LIST_SetOrient( st_ivas->hBinRendererTd, FrontVec, UpVec ); + + return; +} +#endif diff --git a/lib_dec/ivas_objectRenderer_hrFilt.c b/lib_dec/ivas_objectRenderer_hrFilt.c index b665f409ae..1c0afd9eda 100644 --- a/lib_dec/ivas_objectRenderer_hrFilt.c +++ b/lib_dec/ivas_objectRenderer_hrFilt.c @@ -343,23 +343,42 @@ void TDREND_HRFILT_SetFiltSet( --------------------------------------------------------------------*/ ivas_error TDREND_REND_RenderSourceHRFilt( +#ifdef FIX_I106_TDREND_5MS + TDREND_SRC_t *Src_p, /* i/o: The source to be rendered */ +#else const TDREND_SRC_t *Src_p, /* i/o: The source to be rendered */ +#endif #ifdef TDREND_HRTF_TABLE_METHODS BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ #endif +#ifdef FIX_I106_TDREND_5MS + float output_buf[][L_SPATIAL_SUBFR_48k], /* o : Output buffer */ + const int16_t subframe_length, /* i : Subframe length in use */ +#else float output_buf[][L_FRAME48k], /* o : Output buffer */ const int16_t output_frame, /* i : Output frame length in use */ +#endif + const int32_t output_Fs /* i : Output sample rate */ ) { TDREND_SRC_REND_t *SrcRend_p; +#ifdef FIX_I106_TDREND_5MS + const float *InFrame_nIC_p; +#else int16_t nS; float *InFrame_nIC_p; +#endif int16_t NoOfUsedInputSamples, NoOfDeliveredOutputSamples; +#ifdef FIX_I106_TDREND_5MS + float LeftOutputFrame[L_SPATIAL_SUBFR_48k]; + float RightOutputFrame[L_SPATIAL_SUBFR_48k]; +#else float LeftOutputFrame[L_FRAME48k]; float RightOutputFrame[L_FRAME48k]; float *LeftOutputFrame_p, *RightOutputFrame_p; float *LeftAccOutputFrame_p, *RightAccOutputFrame_p; +#endif /* Input channel rendering loop */ InFrame_nIC_p = Src_p->InputFrame_p; @@ -369,7 +388,11 @@ ivas_error TDREND_REND_RenderSourceHRFilt( /* SrcGain = Mix_p->Gain * ( *SrcRend_p->SrcGain_p ); */ /* SrcGain *= ( *SrcRend_p->DirGain_p ) * ( *SrcRend_p->DistGain_p ); */ +#ifdef FIX_I106_TDREND_5MS + TDREND_SFX_SpatBin_Execute_Main( SrcRend_p->SfxSpatBin_p, InFrame_nIC_p, subframe_length, LeftOutputFrame, RightOutputFrame, &NoOfUsedInputSamples, &NoOfDeliveredOutputSamples, output_Fs ); +#else TDREND_SFX_SpatBin_Execute_Main( SrcRend_p->SfxSpatBin_p, InFrame_nIC_p, output_frame, LeftOutputFrame, RightOutputFrame, &NoOfUsedInputSamples, &NoOfDeliveredOutputSamples, output_Fs ); +#endif #ifdef TDREND_HRTF_TABLE_METHODS if ( hBinRendererTd->HrFiltSet_p->FilterMethod != TDREND_HRFILT_Method_BSplineModel ) @@ -379,15 +402,25 @@ ivas_error TDREND_REND_RenderSourceHRFilt( #endif /* Copy to accumulative output frame */ +#ifdef FIX_I106_TDREND_5MS + 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? */ + +#else 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++; } +#endif + return IVAS_ERR_OK; } diff --git a/lib_dec/ivas_objectRenderer_sfx.c b/lib_dec/ivas_objectRenderer_sfx.c index 381506e249..b8d2befc37 100644 --- a/lib_dec/ivas_objectRenderer_sfx.c +++ b/lib_dec/ivas_objectRenderer_sfx.c @@ -928,9 +928,13 @@ 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 */ + SFX_SpatBin_t *SfxSpatBin_p, /* i/o: Spatial parameters struct */ + const float *InBuffer_p, /* i : Input buffer */ +#ifdef FIX_I106_TDREND_5MS + const int16_t subframe_length, /* i : subframe length */ +#else + const int16_t output_frame, /* i : frame length */ +#endif 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 +952,11 @@ void TDREND_SFX_SpatBin_Execute_Main( /* Make sure the blocks are not longer than 6 msec. */ NoOfBlocks = 1; +#ifdef FIX_I106_TDREND_5MS + TempNoOfRequestedOutputSamples = subframe_length; +#else TempNoOfRequestedOutputSamples = output_frame; +#endif while ( TempNoOfRequestedOutputSamples > SfxSpatBin_p->MaxBlockLength ) { NoOfBlocks = NoOfBlocks << 1; @@ -962,7 +970,11 @@ void TDREND_SFX_SpatBin_Execute_Main( RightOutBufferPointer_p = RightOutBuffer_p; *NoOfUsedInputSamples_p = 0; *NoOfDeliveredOutputSamples_p = 0; +#ifdef FIX_I106_TDREND_5MS + TempNoOfInputSamples = subframe_length; +#else TempNoOfInputSamples = output_frame; +#endif for ( i = 0; i < NoOfBlocks; i++ ) { @@ -991,7 +1003,11 @@ void TDREND_SFX_SpatBin_Execute_Main( if ( i == NoOfBlocks - 2 ) { /* The last block should produce the remaining number of samples */ +#ifdef FIX_I106_TDREND_5MS + TempNoOfRequestedOutputSamples = subframe_length - *NoOfDeliveredOutputSamples_p; +#else TempNoOfRequestedOutputSamples = output_frame - *NoOfDeliveredOutputSamples_p; +#endif } *NoOfUsedInputSamples_p = *NoOfUsedInputSamples_p + TempNoOfUsedInputSamples; TempNoOfInputSamples = TempNoOfInputSamples - TempNoOfUsedInputSamples; @@ -1009,10 +1025,10 @@ void TDREND_SFX_SpatBin_Execute_Main( --------------------------------------------------------------------*/ static void TDREND_SFX_SpatBin_Execute( - SFX_SpatBin_t *SfxSpatBin_p, /* i/o: Spatial parameters struct */ - const float *InBuffer_p, /* i : Input buffer */ + SFX_SpatBin_t *SfxSpatBin_p, /* i/o: Spatial parameters struct */ + const float *InBuffer_p, /* i : Input buffer */ #ifdef DEBUGGING - const int16_t NoOfInputSamples, /* i : Length of input buffer */ + const int16_t NoOfInputSamples, /* i : Length of input buffer */ #endif const int16_t NoOfRequestedOutputSamples, /* i : Length of output */ float *LeftOutBuffer_p, /* o : Rendered left channel */ -- GitLab