diff --git a/apps/renderer.c b/apps/renderer.c index 6b30c44402c812c290c41d34cb02f7c954f8394b..3cdb5f73ada542f57e47234f464e7dc504302d9c 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -839,7 +839,7 @@ int main( exit( -1 ); } #else - IF( ( error = IVAS_REND_Open( &hIvasRend, args.sampleRate, args.outConfig.audioConfig, args.nonDiegeticPan, args.nonDiegeticPanGain, (int16_t) args.render_framesize ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_REND_Open( &hIvasRend, args.sampleRate, args.outConfig.audioConfig, args.nonDiegeticPan, args.nonDiegeticPanGain, (int16_t) args.render_framesize ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error opening renderer handle: %s\n", ivas_error_to_string( error ) ); exit( -1 ); diff --git a/lib_com/fd_cng_com_fx.c b/lib_com/fd_cng_com_fx.c index 16a5ae86940982922c8681a1b6097c0fbd1b1ea3..3acd8991af523003c09505515e38465f5d52e855 100644 --- a/lib_com/fd_cng_com_fx.c +++ b/lib_com/fd_cng_com_fx.c @@ -2599,6 +2599,138 @@ void SynthesisSTFT( Residu3_fx( hFdCngCom->A_cng, buf + 1 + M, hFdCngCom->exc_cng, hFdCngCom->frameSize, 1 ); } } + +#ifdef IVAS_FLOAT_FIXED +void SynthesisSTFT_ivas_fx( + Word32 *fftBuffer, /* i : pointer to FFT bins */ + Word16 fftBufferExp, /* i : exponent of FFT bins */ + Word16 *timeDomainOutput, /* o : pointer to time domain signal */ + Word16 *olapBuffer, /* i/o : pointer to overlap buffer */ + const PWord16 *olapWin, /* i : pointer to overlap window */ + Word16 tcx_transition, + HANDLE_FD_CNG_COM hFdCngCom, /* i/o : pointer to FD_CNG structure containing all buffers and variables */ + Word16 gen_exc, + Word16 *Q_new, + const Word16 element_mode, /* i : element mode */ + const Word16 nchan_out /* i : number of output channels */ +) +{ + Word16 i, len, scale, tmp; + Word16 len2, len3, len4; + Word16 buf[M + 1 + L_FRAME16k]; + + + /* Perform IFFT */ + scale = 0; + move16(); + BASOP_rfft( fftBuffer, hFdCngCom->fftlen, &scale, 1 ); + fftBufferExp = add( fftBufferExp, scale ); + hFdCngCom->fftBuffer_exp = fftBufferExp; + move16(); + + fftBufferExp = add( fftBufferExp, hFdCngCom->fftlenShift ); + + /* Perform overlap-add */ + /* Handle overlap in P/S domain for stereo */ + IF( ( EQ_16( element_mode, IVAS_CPE_TD ) || EQ_16( element_mode, IVAS_CPE_DFT ) ) && EQ_16( nchan_out, 2 ) ) + { + Copy( olapBuffer + 3 * hFdCngCom->frameSize / 4 - ( M + 1 ), buf, hFdCngCom->frameSize + M + 1 ); + set16_fx( olapBuffer, 0, hFdCngCom->fftlen ); + } + ELSE + { + Copy( olapBuffer + hFdCngCom->frameSize, olapBuffer, hFdCngCom->frameSize ); + set16_fx( olapBuffer + hFdCngCom->frameSize, 0, hFdCngCom->frameSize ); + } + len2 = shr( hFdCngCom->fftlen, 2 ); + len4 = shr( hFdCngCom->fftlen, 3 ); + len3 = add( len2, len4 ); + len = add( hFdCngCom->frameSize, len4 ); + IF( tcx_transition ) + { + FOR( i = 0; i < len; i++ ) + { + olapBuffer[i] = round_fx_sat( L_shl_sat( fftBuffer[i], fftBufferExp - 15 ) ); + move16(); + } + } + ELSE + { + FOR( i = 0; i < len4; i++ ) + { + olapBuffer[i + 1 * len4] = add_sat( olapBuffer[i + 1 * len4], mult_r( round_fx_sat( L_shl_sat( fftBuffer[i + 1 * len4], fftBufferExp - 15 ) ), olapWin[i].v.im ) ); + move16(); + olapBuffer[i + 2 * len4] = add_sat( olapBuffer[i + 2 * len4], mult_r( round_fx_sat( L_shl_sat( fftBuffer[i + 2 * len4], fftBufferExp - 15 ) ), olapWin[len4 - 1 - i].v.re ) ); + move16(); + } + FOR( i = len3; i < len; i++ ) + { + olapBuffer[i] = round_fx_sat( L_shl_sat( fftBuffer[i], fftBufferExp - 15 ) ); + } + } + + FOR( i = 0; i < len4; i++ ) + { + olapBuffer[i + 5 * len4] = mult_r( round_fx_sat( L_shl_sat( fftBuffer[i + 5 * len4], fftBufferExp - 15 ) ), olapWin[i].v.re ); + move16(); + olapBuffer[i + 6 * len4] = mult_r( round_fx_sat( L_shl_sat( fftBuffer[i + 6 * len4], fftBufferExp - 15 ) ), olapWin[len4 - 1 - i].v.im ); + move16(); + } + + len = add( len, len2 ); + FOR( i = len; i < hFdCngCom->fftlen; i++ ) + { + olapBuffer[i] = 0; + move16(); + } + + /* Get time-domain signal */ + FOR( i = 0; i < hFdCngCom->frameSize; i++ ) + { + timeDomainOutput[i] = mult_r( olapBuffer[i + len4], hFdCngCom->fftlenFac ); + move16(); + } + /* Generate excitation */ +#ifdef IVAS_CODE_CNG_COM + PME() + if ( ( element_mode == IVAS_CPE_TD || element_mode == IVAS_CPE_DFT ) && nchan_out == 2 ) + { + for ( i = 0; i < hFdCngCom->frameSize / 2; i++ ) + { + buf[i + ( M + 1 )] += olapBuffer[i + hFdCngCom->frameSize / 4]; + } + v_multc( buf, (float) ( hFdCngCom->fftlen / 2 ), buf, M + 1 + hFdCngCom->frameSize ); + } + else +#endif + { + FOR( i = 0; i < M + 1 + hFdCngCom->frameSize; i++ ) + { + buf[i] = mult_r( olapBuffer[i + len4 - M - 1], hFdCngCom->fftlenFac ); + move16(); + } + tmp = buf[0]; + } + IF( EQ_16( gen_exc, 1 ) ) + { + Word16 s = getScaleFactor16( buf + 1, M + hFdCngCom->frameSize ); + if ( GT_16( *Q_new, s ) ) + { + *Q_new = s; + move16(); + } + + E_UTIL_f_preemph2( *Q_new - 1, buf + 1, PREEMPH_FAC, M + hFdCngCom->frameSize, &tmp ); + Residu3_fx( hFdCngCom->A_cng, buf + 1 + M, hFdCngCom->exc_cng, hFdCngCom->frameSize, 1 ); + } + IF( EQ_16( gen_exc, 2 ) ) + { + *Q_new = E_UTIL_f_preemph3( buf + 1, PREEMPH_FAC, M + hFdCngCom->frameSize, &tmp, 1 ); + Residu3_fx( hFdCngCom->A_cng, buf + 1 + M, hFdCngCom->exc_cng, hFdCngCom->frameSize, 1 ); + } +} +#endif + #ifdef IVAS_CODE_CNG_COM /*------------------------------------------------------------------- * SynthesisSTFT_dirac() diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 96d4354bd66c6b3eaee30170d01a7e2e5f46c9ed..c65baf0807f0fd9955f35de2232002fb3c5cbd69 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -4861,6 +4861,20 @@ void SynthesisSTFT( const Word16 nchan_out /* i : number of output channels */ ); +void SynthesisSTFT_ivas_fx( + Word32 *fftBuffer, /* i : pointer to FFT bins */ + Word16 fftBufferExp, /* i : exponent of FFT bins */ + Word16 *timeDomainOutput, /* o : pointer to time domain signal */ + Word16 *olapBuffer, /* i/o : pointer to overlap buffer */ + const PWord16 *olapWin, /* i : pointer to overlap window */ + Word16 tcx_transition, + HANDLE_FD_CNG_COM hFdCngCom, /* i/o : pointer to FD_CNG structure containing all buffers and variables */ + Word16 gen_exc, + Word16 *Q_new, + const Word16 element_mode, /* i : element mode */ + const Word16 nchan_out /* i : number of output channels */ +); + void mhvals( const Word16 d, Word16 *m /*, float * h*/ diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index 54c251e2123eca4d588309433868ddacb0e2dac4..ae13e69c8cc42a9075b4cf7f9088b46f8f08f0fd 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -4032,8 +4032,8 @@ void generate_comfort_noise_dec_ivas_fx( } /* Perform STFT synthesis */ - SynthesisSTFT( fftBuffer, fftBuffer_exp, timeDomainOutput, hFdCngCom->olapBufferSynth, hFdCngCom->olapWinSyn, - tcx_transition, hFdCngCom, gen_exc, Q_new, st->element_mode, nchan_out ); + SynthesisSTFT_ivas_fx( fftBuffer, fftBuffer_exp, timeDomainOutput, hFdCngCom->olapBufferSynth, hFdCngCom->olapWinSyn, + tcx_transition, hFdCngCom, gen_exc, Q_new, st->element_mode, nchan_out ); scale_sig32( fftBuffer + hFdCngCom->fftlen, sub( FFTLEN, hFdCngCom->fftlen ), sub( fftBuffer_exp, hFdCngCom->fftBuffer_exp ) ); { diff --git a/lib_dec/ivas_dirac_output_synthesis_cov.c b/lib_dec/ivas_dirac_output_synthesis_cov.c index 30d982aaaa8d411e1126a55ba355f0b5d4971ec4..cde4a83b8a3c54cb09a154c68ccf11304f84a08b 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov.c @@ -1887,7 +1887,7 @@ Word16 computeMixingMatrices_fx( Cr_p_fx = Cr_fx; Cy_p_fx = Cy_fx; Cy_tilde_p_fx = mat_mult_buffer2_fx; - exp = s_max( Cy_fx_e, mat_mult_buffer2_e ); + exp = add( s_max( Cy_fx_e, mat_mult_buffer2_e ), 1 ); /* Guard bit */ FOR( i = 0; i < lengthCy * lengthCy; i++ ) { Cy_fx[i] = L_shr( Cy_p_fx[i], exp - Cy_fx_e ); diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 1b0a1d9f63c773e6723a4c546fd54f8437665200..34039bb53f41bab04a63e77a302cf3bdee1ebb8b 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -1485,7 +1485,7 @@ ivas_error ivas_jbm_dec_tc_fx( } FOR( Word16 ii = 0; ii < CPE_CHANNELS; ii++ ) { - scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); + scale_sig32( hCPE->output_mem_fx[ii], NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, hCPE->q_output_mem_fx[ii] ) ); hCPE->q_output_mem_fx[ii] = hCPE->hStereoDft->q_dft; move16(); } diff --git a/lib_dec/ivas_out_setup_conversion.c b/lib_dec/ivas_out_setup_conversion.c index 2764b640b3a9af0f5a8132585ac15530026567cc..b9a28ae63041e4d08660304b56276f0f44c4c891 100644 --- a/lib_dec/ivas_out_setup_conversion.c +++ b/lib_dec/ivas_out_setup_conversion.c @@ -75,13 +75,13 @@ static void ivas_lssetupconversion_computeEQFactor_fx( Word32 *EQ ) { - IF( GT_32( L_shr( *outputEnergy, 3 ), Mpy_32_32( LS_OUT_CONV_CLIP_FACTOR_MAX_SQ_Q28, *inputEnergy ) ) ) + IF( GE_32( L_shr( *outputEnergy, 3 ), Mpy_32_32( LS_OUT_CONV_CLIP_FACTOR_MAX_SQ_Q28, *inputEnergy ) ) ) { *EQ = L_shl_sat( LS_OUT_CONV_CLIP_FACTOR_MAX_Q29, 1 ); move32(); return; } - IF( LT_32( L_shr( *outputEnergy, 3 ), Mpy_32_32( LS_OUT_CONV_CLIP_FACTOR_MIN_SQ_Q28, *inputEnergy ) ) ) + IF( LE_32( L_shr( *outputEnergy, 3 ), Mpy_32_32( LS_OUT_CONV_CLIP_FACTOR_MIN_SQ_Q28, *inputEnergy ) ) ) { *EQ = L_shl_sat( LS_OUT_CONV_CLIP_FACTOR_MIN_Q29, 1 ); move32();