Loading lib_com/options.h +1 −1 Original line number Diff line number Diff line Loading @@ -115,7 +115,7 @@ #define FIX_FLOAT_1533_BLEND_SUBFR2 /* FhG: float issue 1533: correct blending in blend_subfr2() */ #define FIX_2436_CLDFBANAHANDLE_ADRESS /*FhG: cldfb handle pointer were handed over in faulty manner*/ //#define FIX_BASOP_2436_REUSED_CLDFB_IN_OMASA_SR /*FhG: basop issue 2436 (related to basop 2283): fix garbage output for >1 object OMASA with extrend as ISAR prerenderer */ #define FIX_BASOP_2436_REUSED_CLDFB_IN_OMASA_SR /*FhG: basop issue 2436 (related to basop 2283): fix garbage output for >1 object OMASA with extrend as ISAR prerenderer */ /* ##################### End NON-BE switches ########################### */ Loading lib_rend/lib_rend_fx.c +94 −47 Original line number Diff line number Diff line Loading @@ -568,7 +568,7 @@ static void accumulate2dArrayToBuffer_fx( #ifdef FIX_BASOP_2436_REUSED_CLDFB_IN_OMASA_SR /*-------------------------------------------------------------------* * audio_buffer_td_to_cldfb() * audio_buffer_td_to_cldfb_fx() * * Performs CLDFB analysis on contents of td_buffer and mixes the result into cldfb_buffer. * Loading @@ -577,48 +577,83 @@ static void accumulate2dArrayToBuffer_fx( * The number of valid CLDFB handles in cldfbAna must be a least equal to the number of channels * in the audio buffers. *-------------------------------------------------------------------*/ static void audio_buffer_td_to_cldfb( static void audio_buffer_td_to_cldfb_fx( IVAS_REND_AudioBuffer td_buffer, IVAS_REND_AudioBuffer cldfb_buffer, int32_t fs, Word32 fs, HANDLE_CLDFB_FILTER_BANK *cldfbAna ) { int16_t ch, slot_idx; float *td_read_ptr; float *cldfb_write_ptr; int16_t num_bands, num_slots; Word16 ch, slot_idx; Word32 *td_read_ptr; Word32 *cldfb_write_ptr; Word16 num_bands, num_slots; const Word32 inv48000_Q15r = 0x57619F10 /*1/48000 in Q15, rounded*/; assert( !td_buffer.config.is_cldfb ); assert( cldfb_buffer.config.is_cldfb ); assert( td_buffer.config.numChannels == cldfb_buffer.config.numChannels ); assert( td_buffer.config.numSamplesPerChannel * 2 == cldfb_buffer.config.numSamplesPerChannel ); assert( EQ_16(td_buffer.config.numChannels, cldfb_buffer.config.numChannels) ); assert( EQ_16(shl(td_buffer.config.numSamplesPerChannel, 1), cldfb_buffer.config.numSamplesPerChannel) ); td_read_ptr = td_buffer.data; cldfb_write_ptr = cldfb_buffer.data; num_bands = (int16_t) ( ( CLDFB_NO_CHANNELS_MAX * fs ) / 48000 ); td_read_ptr = td_buffer.data_fx; cldfb_write_ptr = cldfb_buffer.data_fx; num_bands = shl( extract_h( Mpy_32_32( imult3216( fs, CLDFB_NO_CHANNELS_MAX ), inv48000_Q15r ) ), 1 ) /*CLDFB*fs/48000 in Q0*/; assert( td_buffer.config.numSamplesPerChannel % num_bands == 0 ); num_slots = td_buffer.config.numSamplesPerChannel / num_bands; num_slots = idiv1616( td_buffer.config.numSamplesPerChannel, num_bands ); for ( ch = 0; ch < cldfb_buffer.config.numChannels; ++ch ) FOR ( ch = 0; ch < cldfb_buffer.config.numChannels; ++ch ) { for ( slot_idx = 0; slot_idx < num_slots; ++slot_idx ) FOR ( slot_idx = 0; slot_idx < num_slots; ++slot_idx ) { float re[CLDFB_NO_CHANNELS_MAX]; float im[CLDFB_NO_CHANNELS_MAX]; Word32 re[CLDFB_NO_CHANNELS_MAX]; Word32 im[CLDFB_NO_CHANNELS_MAX]; Word16 q_cldfb = *( cldfb_buffer.pq_fact ); cldfbAnalysis_ts( td_read_ptr, cldfbAnalysis_ts_fx( td_read_ptr, re, im, num_bands, cldfbAna[ch] ); cldfbAna[ch], &q_cldfb ); td_read_ptr += num_bands; v_add( re, cldfb_write_ptr, cldfb_write_ptr, num_bands ); cldfb_write_ptr += num_bands; v_add( im, cldfb_write_ptr, cldfb_write_ptr, num_bands ); cldfb_write_ptr += num_bands; #ifdef FIX_2283_Q_CLDFB /* scale re and im according to exp-q_cldfb */ { Word16 exp = *( cldfb_buffer.pq_fact ); Word16 noChannels = cldfbAna[ch]->no_channels; #ifdef FIX_2283_ACCU_CLDFB Word16 scale = sub( exp, q_cldfb ); FOR( Word16 j = 0; j < noChannels; j++ ) { re[j] = L_shl( re[j], scale ); /*Q(exp)*/ im[j] = L_shl( im[j], scale ); /*Q(exp)*/ } #else Word16 scale = sub( sub( exp, q_cldfb ), 1 ); FOR( Word16 j = 0; j < noChannels; j++ ) { re[j] = L_shl( re[j], scale ); /*Q(exp)*/ im[j] = L_shl( im[j], scale ); /*Q(exp)*/ } #endif } #endif //v_add( re, cldfb_write_ptr, cldfb_write_ptr, num_bands ); // cldfb_write_ptr += num_bands; FOR( int smplIdx = 0; smplIdx < num_bands; smplIdx++ ) { *cldfb_write_ptr++ += re[smplIdx]; } //v_add( im, cldfb_write_ptr, cldfb_write_ptr, num_bands ); //cldfb_write_ptr += num_bands; FOR( int smplIdx = 0; smplIdx < num_bands; smplIdx++ ) { *cldfb_write_ptr++ += im[smplIdx]; } } } } Loading Loading @@ -7166,9 +7201,9 @@ static ivas_error renderIsmToSplitBinaural( IVAS_QUATERNION originalHeadRot[MAX_PARAM_SPATIAL_SUBFRAMES]; IVAS_QUATERNION localHeadRot[MAX_PARAM_SPATIAL_SUBFRAMES]; Word16 i; Word32 tmpBinaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][L_FRAME48k]; #ifndef FIX_BASOP_2436_REUSED_CLDFB_IN_OMASA_SR Word16 ch, slot_idx, num_bands; Word32 tmpBinaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][L_FRAME48k]; Word32 tmpBinaural_CldfbRe[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; Word32 tmpBinaural_CldfbIm[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; #endif Loading Loading @@ -7507,20 +7542,24 @@ static ivas_error renderActiveInputsIsm( move16(); #ifdef FIX_BASOP_2436_REUSED_CLDFB_IN_OMASA_SR int16_t num_active_inputs; Word16 num_active_inputs; IVAS_REND_AudioBuffer work_buffer; float tmp_td_binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS * L_FRAME48k]; Word32 tmp_td_binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS * L_FRAME48k]; // Early return in case there are no active ISM inputs num_active_inputs = 0; for ( i = 0, pCurrentInput = hIvasRend->inputsIsm; i < RENDERER_MAX_ISM_INPUTS; ++i, ++pCurrentInput ) move16(); pCurrentInput = hIvasRend->inputsIsm; FOR( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) { if ( pCurrentInput->base.inConfig != IVAS_AUDIO_CONFIG_INVALID ) if ( NE_32(pCurrentInput->base.inConfig, IVAS_AUDIO_CONFIG_INVALID) ) { ++num_active_inputs; num_active_inputs = add( num_active_inputs, 1 ); } ++pCurrentInput; } if ( num_active_inputs == 0 ) IF ( num_active_inputs == 0 ) { return IVAS_ERR_OK; } Loading @@ -7531,15 +7570,23 @@ static ivas_error renderActiveInputsIsm( // without initialization in code below, as well as some WMC tool instrumentation problems. work_buffer = outAudio; /*This loop is instrumentation-only and has no effect on operational result*/ for ( int i_instr = 0; i_instr < sizeof( outAudio ) / 4; i_instr++ ) { move32(); } // ISM rendering only supports TD output. If CLDFB output was requested, we first render // to TD in a temporary buffer and then convert to CLDFB. We do this by swapping out the // underlying memory of work_buffer and modifying its config to TD. if ( outAudio.config.is_cldfb ) IF ( outAudio.config.is_cldfb ) { work_buffer.config.numSamplesPerChannel /= 2; work_buffer.config.numSamplesPerChannel = shr( work_buffer.config.numSamplesPerChannel, 1 ); work_buffer.config.is_cldfb = false; work_buffer.data = tmp_td_binaural; set_zero( tmp_td_binaural, MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS * L_FRAME48k ); move16(); work_buffer.data_fx = tmp_td_binaural; set32_fx( tmp_td_binaural, 0, MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS * L_FRAME48k ); } #endif Loading @@ -7562,16 +7609,6 @@ static ivas_error renderActiveInputsIsm( return error; } #ifdef FIX_BASOP_2436_REUSED_CLDFB_IN_OMASA_SR if ( outAudio.config.is_cldfb ) { audio_buffer_td_to_cldfb( work_buffer, outAudio, hIvasRend->sampleRateOut, hIvasRend->splitRendWrapper->hCldfbHandles->cldfbAna ); } #endif FOR( Word16 j = 0; j < outAudio.config.numSamplesPerChannel * outAudio.config.numChannels; ++j ) { outAudio.data_fx[j] = L_shl( outAudio.data_fx[j], sub( sub( input_q, 1 ), ( *outAudio.pq_fact ) ) ); /* Q(input_q - 1) */ Loading @@ -7581,6 +7618,16 @@ static ivas_error renderActiveInputsIsm( move16(); } #ifdef FIX_BASOP_2436_REUSED_CLDFB_IN_OMASA_SR IF( outAudio.config.is_cldfb ) { audio_buffer_td_to_cldfb_fx( work_buffer, outAudio, hIvasRend->sampleRateOut, hIvasRend->splitRendWrapper->hCldfbHandles->cldfbAna ); } #endif return IVAS_ERR_OK; } Loading Loading
lib_com/options.h +1 −1 Original line number Diff line number Diff line Loading @@ -115,7 +115,7 @@ #define FIX_FLOAT_1533_BLEND_SUBFR2 /* FhG: float issue 1533: correct blending in blend_subfr2() */ #define FIX_2436_CLDFBANAHANDLE_ADRESS /*FhG: cldfb handle pointer were handed over in faulty manner*/ //#define FIX_BASOP_2436_REUSED_CLDFB_IN_OMASA_SR /*FhG: basop issue 2436 (related to basop 2283): fix garbage output for >1 object OMASA with extrend as ISAR prerenderer */ #define FIX_BASOP_2436_REUSED_CLDFB_IN_OMASA_SR /*FhG: basop issue 2436 (related to basop 2283): fix garbage output for >1 object OMASA with extrend as ISAR prerenderer */ /* ##################### End NON-BE switches ########################### */ Loading
lib_rend/lib_rend_fx.c +94 −47 Original line number Diff line number Diff line Loading @@ -568,7 +568,7 @@ static void accumulate2dArrayToBuffer_fx( #ifdef FIX_BASOP_2436_REUSED_CLDFB_IN_OMASA_SR /*-------------------------------------------------------------------* * audio_buffer_td_to_cldfb() * audio_buffer_td_to_cldfb_fx() * * Performs CLDFB analysis on contents of td_buffer and mixes the result into cldfb_buffer. * Loading @@ -577,48 +577,83 @@ static void accumulate2dArrayToBuffer_fx( * The number of valid CLDFB handles in cldfbAna must be a least equal to the number of channels * in the audio buffers. *-------------------------------------------------------------------*/ static void audio_buffer_td_to_cldfb( static void audio_buffer_td_to_cldfb_fx( IVAS_REND_AudioBuffer td_buffer, IVAS_REND_AudioBuffer cldfb_buffer, int32_t fs, Word32 fs, HANDLE_CLDFB_FILTER_BANK *cldfbAna ) { int16_t ch, slot_idx; float *td_read_ptr; float *cldfb_write_ptr; int16_t num_bands, num_slots; Word16 ch, slot_idx; Word32 *td_read_ptr; Word32 *cldfb_write_ptr; Word16 num_bands, num_slots; const Word32 inv48000_Q15r = 0x57619F10 /*1/48000 in Q15, rounded*/; assert( !td_buffer.config.is_cldfb ); assert( cldfb_buffer.config.is_cldfb ); assert( td_buffer.config.numChannels == cldfb_buffer.config.numChannels ); assert( td_buffer.config.numSamplesPerChannel * 2 == cldfb_buffer.config.numSamplesPerChannel ); assert( EQ_16(td_buffer.config.numChannels, cldfb_buffer.config.numChannels) ); assert( EQ_16(shl(td_buffer.config.numSamplesPerChannel, 1), cldfb_buffer.config.numSamplesPerChannel) ); td_read_ptr = td_buffer.data; cldfb_write_ptr = cldfb_buffer.data; num_bands = (int16_t) ( ( CLDFB_NO_CHANNELS_MAX * fs ) / 48000 ); td_read_ptr = td_buffer.data_fx; cldfb_write_ptr = cldfb_buffer.data_fx; num_bands = shl( extract_h( Mpy_32_32( imult3216( fs, CLDFB_NO_CHANNELS_MAX ), inv48000_Q15r ) ), 1 ) /*CLDFB*fs/48000 in Q0*/; assert( td_buffer.config.numSamplesPerChannel % num_bands == 0 ); num_slots = td_buffer.config.numSamplesPerChannel / num_bands; num_slots = idiv1616( td_buffer.config.numSamplesPerChannel, num_bands ); for ( ch = 0; ch < cldfb_buffer.config.numChannels; ++ch ) FOR ( ch = 0; ch < cldfb_buffer.config.numChannels; ++ch ) { for ( slot_idx = 0; slot_idx < num_slots; ++slot_idx ) FOR ( slot_idx = 0; slot_idx < num_slots; ++slot_idx ) { float re[CLDFB_NO_CHANNELS_MAX]; float im[CLDFB_NO_CHANNELS_MAX]; Word32 re[CLDFB_NO_CHANNELS_MAX]; Word32 im[CLDFB_NO_CHANNELS_MAX]; Word16 q_cldfb = *( cldfb_buffer.pq_fact ); cldfbAnalysis_ts( td_read_ptr, cldfbAnalysis_ts_fx( td_read_ptr, re, im, num_bands, cldfbAna[ch] ); cldfbAna[ch], &q_cldfb ); td_read_ptr += num_bands; v_add( re, cldfb_write_ptr, cldfb_write_ptr, num_bands ); cldfb_write_ptr += num_bands; v_add( im, cldfb_write_ptr, cldfb_write_ptr, num_bands ); cldfb_write_ptr += num_bands; #ifdef FIX_2283_Q_CLDFB /* scale re and im according to exp-q_cldfb */ { Word16 exp = *( cldfb_buffer.pq_fact ); Word16 noChannels = cldfbAna[ch]->no_channels; #ifdef FIX_2283_ACCU_CLDFB Word16 scale = sub( exp, q_cldfb ); FOR( Word16 j = 0; j < noChannels; j++ ) { re[j] = L_shl( re[j], scale ); /*Q(exp)*/ im[j] = L_shl( im[j], scale ); /*Q(exp)*/ } #else Word16 scale = sub( sub( exp, q_cldfb ), 1 ); FOR( Word16 j = 0; j < noChannels; j++ ) { re[j] = L_shl( re[j], scale ); /*Q(exp)*/ im[j] = L_shl( im[j], scale ); /*Q(exp)*/ } #endif } #endif //v_add( re, cldfb_write_ptr, cldfb_write_ptr, num_bands ); // cldfb_write_ptr += num_bands; FOR( int smplIdx = 0; smplIdx < num_bands; smplIdx++ ) { *cldfb_write_ptr++ += re[smplIdx]; } //v_add( im, cldfb_write_ptr, cldfb_write_ptr, num_bands ); //cldfb_write_ptr += num_bands; FOR( int smplIdx = 0; smplIdx < num_bands; smplIdx++ ) { *cldfb_write_ptr++ += im[smplIdx]; } } } } Loading Loading @@ -7166,9 +7201,9 @@ static ivas_error renderIsmToSplitBinaural( IVAS_QUATERNION originalHeadRot[MAX_PARAM_SPATIAL_SUBFRAMES]; IVAS_QUATERNION localHeadRot[MAX_PARAM_SPATIAL_SUBFRAMES]; Word16 i; Word32 tmpBinaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][L_FRAME48k]; #ifndef FIX_BASOP_2436_REUSED_CLDFB_IN_OMASA_SR Word16 ch, slot_idx, num_bands; Word32 tmpBinaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][L_FRAME48k]; Word32 tmpBinaural_CldfbRe[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; Word32 tmpBinaural_CldfbIm[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; #endif Loading Loading @@ -7507,20 +7542,24 @@ static ivas_error renderActiveInputsIsm( move16(); #ifdef FIX_BASOP_2436_REUSED_CLDFB_IN_OMASA_SR int16_t num_active_inputs; Word16 num_active_inputs; IVAS_REND_AudioBuffer work_buffer; float tmp_td_binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS * L_FRAME48k]; Word32 tmp_td_binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS * L_FRAME48k]; // Early return in case there are no active ISM inputs num_active_inputs = 0; for ( i = 0, pCurrentInput = hIvasRend->inputsIsm; i < RENDERER_MAX_ISM_INPUTS; ++i, ++pCurrentInput ) move16(); pCurrentInput = hIvasRend->inputsIsm; FOR( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) { if ( pCurrentInput->base.inConfig != IVAS_AUDIO_CONFIG_INVALID ) if ( NE_32(pCurrentInput->base.inConfig, IVAS_AUDIO_CONFIG_INVALID) ) { ++num_active_inputs; num_active_inputs = add( num_active_inputs, 1 ); } ++pCurrentInput; } if ( num_active_inputs == 0 ) IF ( num_active_inputs == 0 ) { return IVAS_ERR_OK; } Loading @@ -7531,15 +7570,23 @@ static ivas_error renderActiveInputsIsm( // without initialization in code below, as well as some WMC tool instrumentation problems. work_buffer = outAudio; /*This loop is instrumentation-only and has no effect on operational result*/ for ( int i_instr = 0; i_instr < sizeof( outAudio ) / 4; i_instr++ ) { move32(); } // ISM rendering only supports TD output. If CLDFB output was requested, we first render // to TD in a temporary buffer and then convert to CLDFB. We do this by swapping out the // underlying memory of work_buffer and modifying its config to TD. if ( outAudio.config.is_cldfb ) IF ( outAudio.config.is_cldfb ) { work_buffer.config.numSamplesPerChannel /= 2; work_buffer.config.numSamplesPerChannel = shr( work_buffer.config.numSamplesPerChannel, 1 ); work_buffer.config.is_cldfb = false; work_buffer.data = tmp_td_binaural; set_zero( tmp_td_binaural, MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS * L_FRAME48k ); move16(); work_buffer.data_fx = tmp_td_binaural; set32_fx( tmp_td_binaural, 0, MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS * L_FRAME48k ); } #endif Loading @@ -7562,16 +7609,6 @@ static ivas_error renderActiveInputsIsm( return error; } #ifdef FIX_BASOP_2436_REUSED_CLDFB_IN_OMASA_SR if ( outAudio.config.is_cldfb ) { audio_buffer_td_to_cldfb( work_buffer, outAudio, hIvasRend->sampleRateOut, hIvasRend->splitRendWrapper->hCldfbHandles->cldfbAna ); } #endif FOR( Word16 j = 0; j < outAudio.config.numSamplesPerChannel * outAudio.config.numChannels; ++j ) { outAudio.data_fx[j] = L_shl( outAudio.data_fx[j], sub( sub( input_q, 1 ), ( *outAudio.pq_fact ) ) ); /* Q(input_q - 1) */ Loading @@ -7581,6 +7618,16 @@ static ivas_error renderActiveInputsIsm( move16(); } #ifdef FIX_BASOP_2436_REUSED_CLDFB_IN_OMASA_SR IF( outAudio.config.is_cldfb ) { audio_buffer_td_to_cldfb_fx( work_buffer, outAudio, hIvasRend->sampleRateOut, hIvasRend->splitRendWrapper->hCldfbHandles->cldfbAna ); } #endif return IVAS_ERR_OK; } Loading