diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 93fed0737baa77b936c7341c5287629fa42f3d76..f43642d8da48b69453e98557c02bba26ab6acf0a 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -692,4 +692,19 @@ Word16 ivas_jbm_dec_get_render_granularity( const MC_MODE mc_mode, /* i : MC mode */ const Word32 output_Fs /* i : sampling rate */ ); + +// ivas_stereo_dft_com.c +void stereo_dft_config_fx( + STEREO_DFT_CONFIG_DATA_HANDLE hConfig, /* o : DFT stereo configuration */ + const Word32 brate, /* i : IVAS/CPE/nominal total bitrate */ + Word16 *bits_frame_nominal, /* o : primary channel nominal bits per frame */ + Word16 *bits_frame_nominal_2 /* o : secondary channel nominal bits per frame*/ +); + +Word16 stereo_dft_band_config_fx( + Word16 *band_limits, /* o : DFT band limits */ + const Word16 band_res, /* i : DFT band resolution */ + const Word16 NFFT, /* i : analysis/synthesis window length */ + const Word16 enc_dec /* i : flag to indicate enc vs dec */ +); #endif \ No newline at end of file diff --git a/lib_com/ivas_stereo_dft_com.c b/lib_com/ivas_stereo_dft_com.c index 541f90a120484b76fec7bc29abc3b6ebf704000d..44cf0d606d282a7c77e1b25b665ce7abb40fc68e 100644 --- a/lib_com/ivas_stereo_dft_com.c +++ b/lib_com/ivas_stereo_dft_com.c @@ -39,6 +39,229 @@ #include "prot.h" #include "cnst.h" #include "wmc_auto.h" +#ifdef IVAS_FLOAT_FIXED +#include "ivas_prot_fx.h" +#endif + +#ifdef IVAS_FLOAT_FIXED +/*------------------------------------------------------------------------- + * stereo_dft_config() + * + * DFT Stereo Configuration function + *------------------------------------------------------------------------*/ + +void stereo_dft_config_fx( + STEREO_DFT_CONFIG_DATA_HANDLE hConfig, /* o : DFT stereo configuration */ + const Word32 brate, /* i : IVAS/CPE/nominal total bitrate */ + Word16 *bits_frame_nominal, /* o : primary channel nominal bits per frame */ + Word16 *bits_frame_nominal_2 /* o : secondary channel nominal bits per frame*/ +) +{ + IF( hConfig != NULL ) + { + hConfig->band_res = STEREO_DFT_BAND_RES_HIGH; + move16(); + hConfig->prm_res = 2; + move16(); + hConfig->dmx_active = STEREO_DFT_DMX_ACTIVE; + move16(); + hConfig->ada_wb_res_cod_mode = 0; + move16(); + } + + *bits_frame_nominal_2 = 5000 / FRAMES_PER_SEC; + move16(); + + /* ITD, IPD and residual coding is not used in SID/No data */ + IF( EQ_32( brate, FRAME_NO_DATA ) ) + { + *bits_frame_nominal = FRAME_NO_DATA; + move16(); + IF( hConfig != NULL ) + { + hConfig->res_pred_mode = STEREO_DFT_RESPRED_OFF; + move16(); + hConfig->band_res = STEREO_DFT_BAND_RES_LOW; + move16(); + hConfig->res_cod_mode = STEREO_DFT_RES_COD_OFF; + move16(); + } + } + ELSE IF( EQ_32( brate, IVAS_SID_5k2 ) ) + { + *bits_frame_nominal = SID_2k40 / FRAMES_PER_SEC; + move16(); + IF( hConfig != NULL ) + { + hConfig->res_pred_mode = STEREO_DFT_RESPRED_OFF; + move16(); + hConfig->band_res = STEREO_DFT_BAND_RES_LOW; + move16(); + hConfig->res_cod_mode = STEREO_DFT_RES_COD_OFF; + move16(); + } + } + ELSE IF( LE_32( brate, IVAS_13k2 ) ) + { + *bits_frame_nominal = ACELP_9k60 / FRAMES_PER_SEC; + move16(); + IF( hConfig != NULL ) + { + hConfig->res_pred_mode = STEREO_DFT_RESPRED_ESF; + move16(); + hConfig->band_res = STEREO_DFT_BAND_RES_LOW; + move16(); + hConfig->res_cod_mode = STEREO_DFT_RES_COD_OFF; + move16(); + } + } + ELSE IF( LE_32( brate, IVAS_16k4 ) ) + { + *bits_frame_nominal = ACELP_13k20 / FRAMES_PER_SEC; + move16(); + IF( hConfig != NULL ) + { + hConfig->res_pred_mode = STEREO_DFT_RESPRED_ESF; + move16(); + hConfig->band_res = STEREO_DFT_BAND_RES_LOW; + move16(); + hConfig->res_cod_mode = STEREO_DFT_RES_COD_OFF; + move16(); + } + } + ELSE IF( LE_32( brate, IVAS_24k4 ) ) + { + *bits_frame_nominal = ACELP_16k40 / FRAMES_PER_SEC; + move16(); + IF( hConfig != NULL ) + { + hConfig->res_pred_mode = STEREO_DFT_RESPRED_ESF; + move16(); + hConfig->res_cod_mode = STEREO_DFT_RES_COD_OFF; + move16(); + } + } + ELSE IF( LE_32( brate, IVAS_32k ) ) + { + *bits_frame_nominal = ACELP_24k40 / FRAMES_PER_SEC; + move16(); + IF( hConfig != NULL ) + { + hConfig->ada_wb_res_cod_mode = 1; + move16(); + hConfig->res_pred_mode = STEREO_DFT_RESPRED_STEFI; + move16(); + hConfig->res_cod_mode = STEREO_DFT_RES_COD_1kHz; + move16(); + } + } + ELSE IF( LE_32( brate, IVAS_48k ) ) + { + *bits_frame_nominal = ACELP_32k / FRAMES_PER_SEC; + move16(); + IF( hConfig != NULL ) + { + hConfig->res_pred_mode = STEREO_DFT_RESPRED_STEFI; + move16(); + hConfig->res_cod_mode = STEREO_DFT_RES_COD_1_6kHz; + move16(); + } + } + ELSE + { + assert( 0 && "Bit-rate not supported by DFT stereo." ); + } + + test(); + IF( hConfig != NULL && hConfig->force_mono_transmission ) + { + hConfig->res_pred_mode = STEREO_DFT_RESPRED_OFF; + move16(); + hConfig->band_res = STEREO_DFT_BAND_RES_LOW; + move16(); + hConfig->res_cod_mode = STEREO_DFT_RES_COD_OFF; + move16(); + hConfig->ada_wb_res_cod_mode = 0; + move16(); + } + + /*sanity check*/ + IF( hConfig != NULL ) + { + assert( LE_16( hConfig->prm_res, STEREO_DFT_NBDIV ) ); + /* make sure residual switching and ESF are not active at the same time */ + assert( !( EQ_16( hConfig->ada_wb_res_cod_mode, 1 ) && EQ_16( hConfig->res_pred_mode, STEREO_DFT_RESPRED_ESF ) ) ); + } + + return; +} + +/*------------------------------------------------------------------------- + * stereo_dft_band_config() + * + * Stereo DFT bands condfiguration + *------------------------------------------------------------------------*/ + +Word16 stereo_dft_band_config_fx( + Word16 *band_limits, /* o : DFT band limits */ + const Word16 band_res, /* i : DFT band resolution */ + const Word16 NFFT, /* i : analysis/synthesis window length */ + const Word16 enc_dec /* i : flag to indicate enc vs dec */ +) +{ + Word16 nbands; + + /*sanity check*/ + assert( ( EQ_16( band_res, 1 ) || EQ_16( band_res, 0 ) || EQ_16( band_res, 2 ) ) && "stereo DFT: Parameter band resolution not supported!\n" ); + + band_limits[0] = 1; + move16(); + nbands = 0; + move16(); + WHILE( LT_16( band_limits[nbands++], shr( NFFT, 1 ) ) ) + { + IF( EQ_16( band_res, 0 ) ) + { + assert( 0 && "stereo DFT: band config failed!\n" ); + } + ELSE IF( EQ_16( band_res, 1 ) ) + { + IF( EQ_16( enc_dec, ENC ) ) + { + band_limits[nbands] = round_fx( L_mult0( shl( dft_band_limits_erb4[nbands], 2 ), 26214 /* 1.60000002 in Q14 */ ) ); + move16(); + } + ELSE + { + band_limits[nbands] = round_fx( L_mult0( shl( dft_band_limits_erb4[nbands], 1 ), 26214 /* 0.800000012 in Q14 */ ) ); + move16(); + } + + assert( ( LT_16( nbands, STEREO_DFT_ERB4_BANDS ) ) && "stereo DFT: band config failed!\n" ); + } + ELSE + { + IF( EQ_16( enc_dec, ENC ) ) + { + band_limits[nbands] = round_fx( L_mult0( shl( dft_band_limits_erb8[nbands], 2 ), 26214 /* 1.60000002 in Q14 */ ) ); + move16(); + } + ELSE + { + band_limits[nbands] = round_fx( L_mult0( shl( dft_band_limits_erb8[nbands], 1 ), 26214 /* 0.800000012 in Q14 */ ) ); + move16(); + } + + assert( ( LT_16( nbands, STEREO_DFT_ERB8_BANDS ) ) && "stereo DFT: band config failed!\n" ); + } + } + nbands = sub( nbands, 1 ); + band_limits[nbands] = shr( NFFT, 1 ); /*Nyquist Freq*/ + move16(); + + return ( nbands ); +} +#endif /*------------------------------------------------------------------------- * stereo_dft_config() diff --git a/lib_dec/ivas_cpe_dec.c b/lib_dec/ivas_cpe_dec.c index df3dcced85fe56c5dd7e212bd7f6aabed0c1f8b6..5218f7f03bbab3cf5c2bcecac470d0dc46f7c596 100644 --- a/lib_dec/ivas_cpe_dec.c +++ b/lib_dec/ivas_cpe_dec.c @@ -42,6 +42,9 @@ #include "ivas_rom_com.h" #include "wmc_auto.h" #include +#ifdef IVAS_FLOAT_FIXED +#include "ivas_prot_fx.h" +#endif /*--------------------------------------------------------------------------* @@ -165,6 +168,16 @@ ivas_error ivas_cpe_dec( { if ( st_ivas->hQMetaData != NULL && ivas_total_brate > IVAS_SID_5k2 ) { +#ifdef IVAS_FLOAT_FIXED + if ( st_ivas->ivas_format == MASA_ISM_FORMAT ) + { + stereo_dft_config_fx( hCPE->hStereoDft == NULL ? NULL : hCPE->hStereoDft->hConfig, Mpy_32_32(1503238554 /* 0.7f in Q31 */, L_mult0(st_ivas->hQMetaData->bits_frame_nominal, FRAMES_PER_SEC) ), &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal ); + } + else + { + stereo_dft_config_fx( hCPE->hStereoDft == NULL ? NULL : hCPE->hStereoDft->hConfig, L_mult0(st_ivas->hQMetaData->bits_frame_nominal, FRAMES_PER_SEC), &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal ); + } +#else if ( st_ivas->ivas_format == MASA_ISM_FORMAT ) { stereo_dft_config( hCPE->hStereoDft == NULL ? NULL : hCPE->hStereoDft->hConfig, (int32_t) ( 0.7f * st_ivas->hQMetaData->bits_frame_nominal * FRAMES_PER_SEC ), &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal ); @@ -173,10 +186,21 @@ ivas_error ivas_cpe_dec( { stereo_dft_config( hCPE->hStereoDft == NULL ? NULL : hCPE->hStereoDft->hConfig, st_ivas->hQMetaData->bits_frame_nominal * FRAMES_PER_SEC, &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal ); } +#endif } else { /* Note: This only works for stereo operation. If DTX would be applied for multiple CPEs a different bitrate signaling is needed */ +#ifdef IVAS_FLOAT_FIXED + if ( ivas_total_brate <= IVAS_SID_5k2 ) + { + stereo_dft_config_fx( hCPE->hStereoDft == NULL ? NULL : hCPE->hStereoDft->hConfig, ivas_total_brate, &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal ); + } + else + { + stereo_dft_config_fx( hCPE->hStereoDft == NULL ? NULL : hCPE->hStereoDft->hConfig, hCPE->element_brate, &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal ); + } +#else if ( ivas_total_brate <= IVAS_SID_5k2 ) { stereo_dft_config( hCPE->hStereoDft == NULL ? NULL : hCPE->hStereoDft->hConfig, ivas_total_brate, &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal ); @@ -185,6 +209,7 @@ ivas_error ivas_cpe_dec( { stereo_dft_config( hCPE->hStereoDft == NULL ? NULL : hCPE->hStereoDft->hConfig, hCPE->element_brate, &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal ); } +#endif } } @@ -197,7 +222,11 @@ ivas_error ivas_cpe_dec( } else { +#ifdef IVAS_FLOAT_FIXED + stereo_dft_config_fx( NULL, hCPE->element_brate, &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal ); +#else stereo_dft_config( NULL, hCPE->element_brate, &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal ); +#endif } } @@ -670,13 +699,13 @@ ivas_error create_cpe_dec( set_zero( hCPE->input_mem_LB[i], STEREO_DFT32MS_OVL_16k ); #ifdef IVAS_FLOAT_FIXED - IF ( ( hCPE->input_mem_fx[i] = (Word32 *) malloc( sizeof( Word32 ) * NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ) ) == NULL ) + IF( ( hCPE->input_mem_fx[i] = (Word32 *) malloc( sizeof( Word32 ) * NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DFT stereo memory\n" ) ); } set32_fx( hCPE->input_mem_fx[i], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); - IF ( ( hCPE->input_mem_LB_fx[i] = (Word32 *) malloc( sizeof( Word32 ) * STEREO_DFT32MS_OVL_16k ) ) == NULL ) + IF( ( hCPE->input_mem_LB_fx[i] = (Word32 *) malloc( sizeof( Word32 ) * STEREO_DFT32MS_OVL_16k ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DFT stereo memory\n" ) ); } diff --git a/lib_dec/ivas_stereo_dft_dec.c b/lib_dec/ivas_stereo_dft_dec.c index c6ee4cd02cf6f017a6c796cd3b0fbf97c4f599fb..f5cf35c98c0d80b6f14f19b7e943bc8dbe97252c 100644 --- a/lib_dec/ivas_stereo_dft_dec.c +++ b/lib_dec/ivas_stereo_dft_dec.c @@ -292,7 +292,11 @@ ivas_error stereo_dft_dec_create( } else { +#ifdef IVAS_FLOAT_FIXED + stereo_dft_config_fx( hStereoDft_loc->hConfig, element_brate, &tmpS, &tmpS ); +#else stereo_dft_config( hStereoDft_loc->hConfig, element_brate, &tmpS, &tmpS ); +#endif } stereo_dft_dec_open( hStereoDft_loc, output_Fs, nchan_transport ); @@ -399,7 +403,11 @@ static void stereo_dft_dec_open( /*Bands: find the number of bands, Nyquist freq. is not taken into account*/ set_s( hStereoDft->band_res, hStereoDft->hConfig->band_res, STEREO_DFT_DEC_DFT_NB ); +#ifdef IVAS_FLOAT_FIXED + hStereoDft->nbands = stereo_dft_band_config_fx( hStereoDft->band_limits, hStereoDft->band_res[0], hStereoDft->NFFT, DEC ); +#else hStereoDft->nbands = stereo_dft_band_config( hStereoDft->band_limits, hStereoDft->band_res[0], hStereoDft->NFFT, DEC ); +#endif hStereoDft->hb_stefi_delay = NS2SA( output_Fs, STEREO_DFT_TD_STEFI_DELAY_NS ); if ( nchan_transport > 2 ) @@ -1855,7 +1863,11 @@ void stereo_dft_dec( /* make sure number of bands corresponds to output bwidth in case it is lower than parameter bwidth */ if ( output_frame < inner_frame_tbl[st0->bwidth] && !sba_dirac_stereo_flag ) { +#ifdef IVAS_FLOAT_FIXED + hStereoDft->nbands = stereo_dft_band_config_fx( hStereoDft->band_limits, hStereoDft->band_res[k_offset], hStereoDft->NFFT, DEC ); +#else hStereoDft->nbands = stereo_dft_band_config( hStereoDft->band_limits, hStereoDft->band_res[k_offset], hStereoDft->NFFT, DEC ); +#endif } if ( !st0->bfi ) @@ -1924,7 +1936,11 @@ void stereo_dft_dec( if ( hStereoDft->frame_sid_nodata && !sba_dirac_stereo_flag ) { NFFT_inner = STEREO_DFT32MS_N_MAX * inner_frame_tbl[st0->bwidth] / L_FRAME48k; +#ifdef IVAS_FLOAT_FIXED + hStereoDft->nbands = stereo_dft_band_config_fx( hStereoDft->band_limits, 2, NFFT_inner, DEC ); +#else hStereoDft->nbands = stereo_dft_band_config( hStereoDft->band_limits, 2, NFFT_inner, DEC ); +#endif } @@ -2358,9 +2374,9 @@ void stereo_dft_dec( *-------------------------------------------------------------------------*/ void stereo_dft_dec_res( - CPE_DEC_HANDLE hCPE, /* i/o: decoder CPE handle */ + CPE_DEC_HANDLE hCPE, /* i/o: decoder CPE handle */ float res_buf[STEREO_DFT_N_8k], /* i : residual buffer */ - float *output /* o : output */ + float *output /* o : output */ ) { int16_t i; @@ -2474,10 +2490,10 @@ void stereo_dft_dec_read_BS( STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder stereo handle */ const int16_t bwidth, /* i : bandwidth */ const int16_t output_frame, /* i : output frame length */ - float res_buf[STEREO_DFT_N_8k], /* o : residual buffer */ - int16_t *nb_bits, /* o : number of bits read */ - float *coh, /* i/o: Coherence */ - const int16_t ivas_format /* i : ivas format */ + float res_buf[STEREO_DFT_N_8k], /* o : residual buffer */ + int16_t *nb_bits, /* o : number of bits read */ + float *coh, /* i/o: Coherence */ + const int16_t ivas_format /* i : ivas format */ ) { int16_t b, N_div, nbands; @@ -2601,7 +2617,11 @@ void stereo_dft_dec_read_BS( { hStereoDft->band_res[k_offset] = STEREO_DFT_BAND_RES_LOW; hStereoDft->res_cod_mode[k_offset] = STEREO_DFT_RES_COD_OFF; +#ifdef IVAS_FLOAT_FIXED + hStereoDft->nbands = stereo_dft_band_config_fx( hStereoDft->band_limits, hStereoDft->band_res[k_offset], min( STEREO_DFT32MS_N_MAX, NFFT_inner ), DEC ); +#else hStereoDft->nbands = stereo_dft_band_config( hStereoDft->band_limits, hStereoDft->band_res[k_offset], min( STEREO_DFT32MS_N_MAX, NFFT_inner ), DEC ); +#endif if ( hStereoDft->nbands > STEREO_DFT_COH_MAXBAND ) { @@ -2611,7 +2631,11 @@ void stereo_dft_dec_read_BS( } else { +#ifdef IVAS_FLOAT_FIXED + hStereoDft->nbands = stereo_dft_band_config_fx( hStereoDft->band_limits, hStereoDft->band_res[k_offset], NFFT_inner, DEC ); +#else hStereoDft->nbands = stereo_dft_band_config( hStereoDft->band_limits, hStereoDft->band_res[k_offset], NFFT_inner, DEC ); +#endif } hStereoDft->res_cod_band_max = dft_band_res_cod[hStereoDft->band_res[k_offset]][hStereoDft->res_cod_mode[k_offset]]; diff --git a/lib_dec/ivas_stereo_dft_dec_dmx.c b/lib_dec/ivas_stereo_dft_dec_dmx.c index 120a060b2a00e1b159d5545a3ef6454f9d38a932..0d3053e1d50b32233e1a7a714a0c5a756e9e0755 100644 --- a/lib_dec/ivas_stereo_dft_dec_dmx.c +++ b/lib_dec/ivas_stereo_dft_dec_dmx.c @@ -42,6 +42,9 @@ #include "ivas_rom_dec.h" #include "rom_com.h" #include "wmc_auto.h" +#ifdef IVAS_FLOAT_FIXED +#include "ivas_prot_fx.h" +#endif /*------------------------------------------------------------------------- @@ -112,7 +115,11 @@ void stereo_dft_unify_dmx( /* make sure number of bands corresponds to output bwidth in case it is lower than parameter bwidth */ if ( output_frame < inner_frame_tbl[st0->bwidth] ) { +#ifdef IVAS_FLOAT_FIXED + hStereoDft->nbands = stereo_dft_band_config_fx( hStereoDft->band_limits, hStereoDft->band_res[k_offset], hStereoDft->NFFT, DEC ); +#else hStereoDft->nbands = stereo_dft_band_config( hStereoDft->band_limits, hStereoDft->band_res[k_offset], hStereoDft->NFFT, DEC ); +#endif } if ( prev_bfi ) {