diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h old mode 100644 new mode 100755 index 04866530c16ca77758bd39f7a6fb45e12b34314c..2aab3dd7ee7c539233ca2a06a77ff81068d70af9 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -1205,6 +1205,9 @@ void stereo_dft_dec( float *input_mem, /* i/o: mem of buffer DFT analysis */ STEREO_CNG_DEC_HANDLE hStereoCng, /* i/o: Stereo CNG data structure */ const int16_t sba_dirac_stereo_flag, /* i : signal stereo output for SBA DirAC */ +#ifdef SBA2MONO + const int16_t sba_mono_flag, /* i : signal mono output for SBA DirAC */ +#endif ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD handle for upmixing */ const int16_t cross_fade_start_offset, /* i : SPAR mixer delay compensation */ const int32_t output_Fs, /* i : Fs for delay calculation */ @@ -3301,6 +3304,12 @@ void ivas_sba_dirac_stereo_config( STEREO_DFT_CONFIG_DATA_HANDLE hConfig /* o : DFT stereo configuration */ ); +#ifdef SBA2MONO +int16_t ivas_get_sba_dirac_stereo_flag( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); +#endif + void ivas_sba_dirac_stereo_smooth_parameters( STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: encoder DFT stereo handle */ ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD handle for upmixing */ diff --git a/lib_com/options.h b/lib_com/options.h index f0f86f814d9a7f55754f04a0b9071d51b2f3a64d..6d97909f18b4173d46f2b1a00701f1fd7613292e 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -151,6 +151,8 @@ #define FIX_382_MASA_META_FRAMING_ASYNC /* Nokia: Issue 382: detect potential MASA metadata framing offset */ +#define SBA2MONO /* FhG: Issue 365: Adapt processing of SBA mono output to be in line with stereo output (less delay, lower complexity) */ + /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ #endif diff --git a/lib_dec/ivas_corecoder_dec_reconfig.c b/lib_dec/ivas_corecoder_dec_reconfig.c index a066164da4dea999bdcbdcd92f064b4e941226e5..62579d35d757ea6936aaa6c7fd295bcaba579a92 100644 --- a/lib_dec/ivas_corecoder_dec_reconfig.c +++ b/lib_dec/ivas_corecoder_dec_reconfig.c @@ -87,8 +87,13 @@ ivas_error ivas_corecoder_dec_reconfig( *-----------------------------------------------------------------*/ /* remove dummy CPE element for DFT stereo-like upmix */ +#ifdef SBA2MONO + if ( ( st_ivas->ivas_format == SBA_FORMAT && sba_dirac_stereo_flag_old && nchan_transport_old == 1 && ( !st_ivas->sba_dirac_stereo_flag || st_ivas->nchan_transport > 1 ) ) || + ( st_ivas->ivas_format == MC_FORMAT && last_mc_mode == MC_MODE_MCMASA && sba_dirac_stereo_flag_old && nchan_transport_old == 1 && ( !st_ivas->sba_dirac_stereo_flag || st_ivas->nchan_transport > 1 ) ) ) +#else if ( ( st_ivas->ivas_format == SBA_FORMAT && sba_dirac_stereo_flag_old && !st_ivas->sba_dirac_stereo_flag ) || ( st_ivas->ivas_format == MC_FORMAT && last_mc_mode == MC_MODE_MCMASA && sba_dirac_stereo_flag_old && !st_ivas->sba_dirac_stereo_flag ) ) +#endif { st_ivas->hCPE[0]->hCoreCoder[0] = NULL; st_ivas->hCPE[0]->hCoreCoder[1] = NULL; @@ -146,6 +151,23 @@ ivas_error ivas_corecoder_dec_reconfig( for ( cpe_id = st_ivas->nCPE; cpe_id < nCPE_old; cpe_id++ ) { +#ifdef SBA2MONO + /* don't deallocate first CPE in case of mono/stereo output of 1 TC SBA, only deallocate core coder */ + if ( cpe_id == 0 && st_ivas->sba_dirac_stereo_flag && sba_dirac_stereo_flag_old ) + { + for ( n = 0; n < CPE_CHANNELS; n++ ) + { + if ( st_ivas->hCPE[cpe_id]->hCoreCoder[n] != NULL ) + { + destroy_core_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] ); + + free( st_ivas->hCPE[cpe_id]->hCoreCoder[n] ); + st_ivas->hCPE[cpe_id]->hCoreCoder[n] = NULL; + } + } + continue; + } +#endif destroy_cpe_dec( st_ivas->hCPE[cpe_id] ); st_ivas->hCPE[cpe_id] = NULL; } @@ -185,6 +207,13 @@ ivas_error ivas_corecoder_dec_reconfig( return error; } } +#ifdef SBA2MONO + if ( st_ivas->sba_dirac_stereo_flag && sba_dirac_stereo_flag_old && st_ivas->nchan_transport == 1 && nSCE_old == 0 ) + { + st_ivas->hCPE[0]->hCoreCoder[0] = st_ivas->hSCE[0]->hCoreCoder[0]; /* don't allocate unnecessary core coder, simply point to core coder of SCE element */ + st_ivas->hCPE[0]->hCoreCoder[1] = NULL; + } +#endif for ( cpe_id = 0; cpe_id < nCPE_existing; cpe_id++ ) { @@ -264,10 +293,29 @@ ivas_error ivas_corecoder_dec_reconfig( if ( ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->sba_dirac_stereo_flag && !sba_dirac_stereo_flag_old ) || ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA && st_ivas->sba_dirac_stereo_flag && !sba_dirac_stereo_flag_old ) ) { +#ifdef SBA2MONO + /* if at least one CPE is already available, only allocate DFT Stereo struct */ + if ( st_ivas->nCPE > 0 ) + { + if ( ( error = stereo_dft_dec_create( &( st_ivas->hCPE[0]->hStereoDft ), st_ivas->hCPE[0]->element_brate, st_ivas->hDecoderConfig->output_Fs, st_ivas->sba_dirac_stereo_flag, st_ivas->nchan_transport ) ) != IVAS_ERR_OK ) + { + return error; + } + } + /* otherwise create extra dummy CPE */ + else + { + if ( ( error = create_cpe_dec( st_ivas, 0, ivas_total_brate / ( st_ivas->nSCE + st_ivas->nCPE ) ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#else if ( ( error = create_cpe_dec( st_ivas, 0, ivas_total_brate / ( st_ivas->nSCE + st_ivas->nCPE ) ) ) != IVAS_ERR_OK ) { return error; } +#endif set_f( st_ivas->hCPE[0]->hStereoDft->buff_LBTCX_mem, 0, NS2SA( 16000, STEREO_DFT32MS_OVL_NS ) ); @@ -508,7 +556,11 @@ ivas_error ivas_cldfb_dec_reconfig( } /* CLDFB Interpolation weights */ +#ifdef SBA2MONO + if ( st_ivas->sba_mode == SBA_MODE_SPAR && ( numCldfbAnalyses_old != numCldfbAnalyses || numCldfbSyntheses_old != numCldfbSyntheses || nchan_transport_old != st_ivas->nchan_transport ) && numCldfbAnalyses != 0 && numCldfbSyntheses != 0 ) +#else if ( st_ivas->sba_mode == SBA_MODE_SPAR && ( numCldfbAnalyses_old != numCldfbAnalyses || numCldfbSyntheses_old != numCldfbSyntheses || nchan_transport_old != st_ivas->nchan_transport ) ) +#endif { ivas_spar_get_cldfb_gains( st_ivas->hSpar, st_ivas->cldfbAnaDec[0], st_ivas->cldfbSynDec[0], hDecoderConfig ); } diff --git a/lib_dec/ivas_cpe_dec.c b/lib_dec/ivas_cpe_dec.c old mode 100644 new mode 100755 index ddd4ae363feef98107508958914daa32ca85362b..17d2efd51620d437b020f13899a8b75c16fded61 --- a/lib_dec/ivas_cpe_dec.c +++ b/lib_dec/ivas_cpe_dec.c @@ -405,7 +405,11 @@ ivas_error ivas_cpe_dec( } else { +#ifdef SBA2MONO + stereo_dft_dec( hCPE->hStereoDft, sts[0], DFT, hCPE->input_mem[1], hCPE->hStereoCng, 0, 0, 0, 0, 0, 0 ); +#else stereo_dft_dec( hCPE->hStereoDft, sts[0], DFT, hCPE->input_mem[1], hCPE->hStereoCng, 0, 0, 0, 0, 0 ); +#endif } /* synthesis iFFT */ diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c index 0983aee6cbf0864a1c8b8b458a6dd51d6d07a2a8..f89a64bf3e7792eada58a65c39903b0f25d94f8d 100644 --- a/lib_dec/ivas_dec.c +++ b/lib_dec/ivas_dec.c @@ -339,10 +339,23 @@ ivas_error ivas_dec( nchan_remapped = st_ivas->nchan_transport; if ( st_ivas->sba_dirac_stereo_flag ) { +#ifdef SBA2MONO + nchan_remapped = nchan_out; +#else nchan_remapped = CPE_CHANNELS; +#endif if ( st_ivas->sba_mode == SBA_MODE_SPAR ) { +#ifdef SBA2MONO + ivas_agc_dec_process( st_ivas->hSpar->hAgcDec, output, output, st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, output_frame ); + + if ( st_ivas->hSpar->hPCA != NULL ) + { + ivas_pca_dec( st_ivas->hSpar->hPCA, output_frame, st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->bfi, output ); + } + +#endif ivas_spar_dec_gen_umx_mat( st_ivas->hSpar->hMdDec, st_ivas->nchan_transport, IVAS_MAX_NUM_BANDS, st_ivas->bfi ); } @@ -416,7 +429,11 @@ ivas_error ivas_dec( ivas_dirac_dec( st_ivas, output, nchan_remapped, NULL, NULL, -1 ); } } +#ifdef SBA2MONO + else if ( !st_ivas->sba_dirac_stereo_flag && nchan_out != 1 ) +#else else if ( !st_ivas->sba_dirac_stereo_flag ) +#endif { ivas_sba_upmixer_renderer( st_ivas, output, output_frame ); /* Note: ivas_sba_linear_renderer() or ivas_dirac_dec() are called internally */ } diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c old mode 100644 new mode 100755 index 5c19eca256723bf9fe739ee147c2b0d03cf0cc54..e53218d3e70ff0bb9b70b5e1524d6c17ebb9635e --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -983,7 +983,11 @@ ivas_error ivas_init_decoder( ivas_dirac_config_bands( band_grouping, IVAS_MAX_NUM_BANDS, (int16_t) ( st_ivas->hDecoderConfig->output_Fs * INV_CLDFB_BANDWIDTH + 0.5f ), st_ivas->hSpar->dirac_to_spar_md_bands, st_ivas->hQMetaData->useLowerBandRes, st_ivas->hSpar->enc_param_start_band, 0 ); } +#ifdef SBA2MONO + st_ivas->sba_dirac_stereo_flag = ivas_get_sba_dirac_stereo_flag( st_ivas ); +#else st_ivas->sba_dirac_stereo_flag = ( output_config == AUDIO_CONFIG_STEREO ); +#endif } else /* SBA_MODE_DIRAC */ { @@ -992,7 +996,11 @@ ivas_error ivas_init_decoder( return error; } +#ifdef SBA2MONO + st_ivas->sba_dirac_stereo_flag = ivas_get_sba_dirac_stereo_flag( st_ivas ); +#else st_ivas->sba_dirac_stereo_flag = ( st_ivas->nchan_transport == 1 && output_config == AUDIO_CONFIG_STEREO ); +#endif } } @@ -1029,7 +1037,11 @@ ivas_error ivas_init_decoder( } /* create CPE element for DFT Stereo like upmix */ +#ifdef SBA2MONO + if ( st_ivas->sba_dirac_stereo_flag && st_ivas->nCPE == 0 ) +#else if ( st_ivas->sba_dirac_stereo_flag && st_ivas->nchan_transport == 1 ) +#endif { if ( ( error = create_cpe_dec( st_ivas, cpe_id, ivas_total_brate / ( st_ivas->nSCE + st_ivas->nCPE ) ) ) != IVAS_ERR_OK ) { @@ -1158,7 +1170,11 @@ ivas_error ivas_init_decoder( return error; } +#ifdef SBA2MONO + st_ivas->sba_dirac_stereo_flag = ivas_get_sba_dirac_stereo_flag( st_ivas ); +#else st_ivas->sba_dirac_stereo_flag = ( st_ivas->nchan_transport == 1 && output_config == AUDIO_CONFIG_STEREO ); +#endif if ( st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_MCMASA_MONO_STEREO ) { @@ -1422,7 +1438,11 @@ ivas_error ivas_init_decoder( } /* CLDFB Interpolation weights */ +#ifdef SBA2MONO + if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->sba_mode == SBA_MODE_SPAR && !st_ivas->sba_dirac_stereo_flag && st_ivas->hDecoderConfig->nchan_out != 1 ) +#else if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->sba_mode == SBA_MODE_SPAR && !st_ivas->sba_dirac_stereo_flag ) +#endif { ivas_spar_get_cldfb_gains( st_ivas->hSpar, st_ivas->cldfbAnaDec[0], st_ivas->cldfbSynDec[0], hDecoderConfig ); } diff --git a/lib_dec/ivas_mcmasa_dec.c b/lib_dec/ivas_mcmasa_dec.c old mode 100644 new mode 100755 index 3ef12f309478a30e2deec4c55970c6234dcb43cf..d075bf61da999ff97a6a1b29b2b627b72780fa3d --- a/lib_dec/ivas_mcmasa_dec.c +++ b/lib_dec/ivas_mcmasa_dec.c @@ -76,7 +76,11 @@ ivas_error ivas_mcmasa_dec_reconfig( return error; } +#ifdef SBA2MONO + st_ivas->sba_dirac_stereo_flag = ivas_get_sba_dirac_stereo_flag( st_ivas ); +#else st_ivas->sba_dirac_stereo_flag = ( st_ivas->nchan_transport == 1 && st_ivas->hOutSetup.output_config == AUDIO_CONFIG_STEREO ); +#endif if ( st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_MCMASA_MONO_STEREO ) { diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c old mode 100644 new mode 100755 index 8c53538deccfb06b314ed8a7b1bfd373e80023c6..f39951e0878b8b44fdef53a6cddc0ba6afe4d0f0 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -707,7 +707,11 @@ static ivas_error ivas_mc_dec_reconfig( { nchan_hp20_old = nchan_transport_old; } +#ifdef SBA2MONO + st_ivas->sba_dirac_stereo_flag = ivas_get_sba_dirac_stereo_flag( st_ivas ); +#else st_ivas->sba_dirac_stereo_flag = 0; /* needs to be after getNumChanSynthesis() */ +#endif /* renderer might have changed, reselect */ renderer_type_old = st_ivas->renderer_type; diff --git a/lib_dec/ivas_output_config.c b/lib_dec/ivas_output_config.c index f38e810ce3289158e5f66ac2feb42be54c22d57b..f522a3217d2e9fff9e0422e6dea667e4697ca3a9 100644 --- a/lib_dec/ivas_output_config.c +++ b/lib_dec/ivas_output_config.c @@ -303,7 +303,11 @@ void ivas_renderer_select( *renderer_type = RENDERER_DIRAC; if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->sba_mode == SBA_MODE_SPAR && +#ifdef SBA2MONO + ( 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 && output_config != AUDIO_CONFIG_MONO && output_config != AUDIO_CONFIG_STEREO ) ) +#else ( 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 ) ) +#endif { if ( output_config == AUDIO_CONFIG_HOA2 || output_config == AUDIO_CONFIG_FOA ) { @@ -320,7 +324,11 @@ void ivas_renderer_select( 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 ) || +#ifdef SBA2MONO + ( st_ivas->ivas_format == SBA_FORMAT && ( output_config == AUDIO_CONFIG_STEREO || output_config == AUDIO_CONFIG_MONO ) ) ) +#else ( st_ivas->ivas_format == SBA_FORMAT && output_config == AUDIO_CONFIG_STEREO && st_ivas->nchan_transport == 1 ) ) +#endif { *renderer_type = RENDERER_DISABLE; } diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c old mode 100644 new mode 100755 index 745ea1b9ba052106117ba064d3f3524f69570125..bf905457e02e7858120940f1a5ec3105233987fc --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -117,7 +117,11 @@ ivas_error ivas_sba_dec_reconfigure( return error; } +#ifdef SBA2MONO + st_ivas->sba_dirac_stereo_flag = ivas_get_sba_dirac_stereo_flag( st_ivas ); +#else st_ivas->sba_dirac_stereo_flag = ( st_ivas->nchan_transport == 1 && hDecoderConfig->output_config == AUDIO_CONFIG_STEREO ); +#endif } else { @@ -156,7 +160,11 @@ ivas_error ivas_sba_dec_reconfigure( } hSpar = st_ivas->hSpar; +#ifdef SBA2MONO + st_ivas->sba_dirac_stereo_flag = ivas_get_sba_dirac_stereo_flag( st_ivas ); +#else st_ivas->sba_dirac_stereo_flag = 0; +#endif } if ( st_ivas->nchan_transport == 1 ) diff --git a/lib_dec/ivas_sba_dirac_stereo_dec.c b/lib_dec/ivas_sba_dirac_stereo_dec.c index e184654eaa1d36a2c7d0c1da9b82558746a46176..82ccaceea92e266ab569af6a080a9cb4cebebf76 100644 --- a/lib_dec/ivas_sba_dirac_stereo_dec.c +++ b/lib_dec/ivas_sba_dirac_stereo_dec.c @@ -45,6 +45,46 @@ #include "wmc_auto.h" +#ifdef SBA2MONO +/*-------------------------------------------------------------------* + * ivas_get_sba_dirac_stereo_flag() + * + * Set sba_dirac_stereo_flag + *-------------------------------------------------------------------*/ + +int16_t ivas_get_sba_dirac_stereo_flag( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +) +{ + int16_t sba_dirac_stereo_flag; + AUDIO_CONFIG output_config; + + sba_dirac_stereo_flag = 0; + output_config = st_ivas->hDecoderConfig->output_config; + + if ( st_ivas->ivas_format == SBA_FORMAT || ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) ) + { + if ( st_ivas->sba_mode == SBA_MODE_SPAR ) + { + if ( output_config == AUDIO_CONFIG_STEREO || ( output_config == AUDIO_CONFIG_MONO && st_ivas->nchan_transport == 1 ) ) + { + sba_dirac_stereo_flag = 1; + } + } + else + { + if ( st_ivas->nchan_transport == 1 && output_config == AUDIO_CONFIG_STEREO ) + { + sba_dirac_stereo_flag = 1; + } + } + } + + return sba_dirac_stereo_flag; +} +#endif + + /*-------------------------------------------------------------------* * ivas_sba_dirac_stereo_config() * @@ -453,13 +493,93 @@ static void ivas_sba_dirac_stereo_upmix_hb( float hb_gain[NB_DIV], /* i : side gains for HB signal */ const int16_t output_frame, /* i : output frame length per channel */ const int16_t mcmasa, /* i : McMASA flag */ - const STEREO_DFT_DEC_DATA_HANDLE hStereoDft /* i : Stereo DFT handle for mixing matrix */ +#ifdef SBA2MONO + const int16_t sba_mono_flag, /* i : flag for mono output */ + const int16_t bwidth, /* i : bandwidth of signal */ +#endif + const STEREO_DFT_DEC_DATA_HANDLE hStereoDft /* i : Stereo DFT handle for mixing matrix */ ) { int16_t i; +#ifdef SBA2MONO + float gp, gm; + float gain_fac; +#endif if ( !mcmasa ) { +#ifdef SBA2MONO + gain_fac = ( bwidth == FB ) ? 0.25f : 0.33f; /* last matrix element not used for SWB, divide by 3 instead of 4*/ + if ( sba_mono_flag ) + { + gp = hStereoDft->mixer_mat_smooth[0][0][8] + hStereoDft->mixer_mat_smooth[0][0][9] + + hStereoDft->mixer_mat_smooth[0][0][10]; + if ( bwidth == FB ) + { + gp += hStereoDft->mixer_mat_smooth[0][0][11]; + } + for ( i = 0; i < output_frame / 2; i++ ) + { + hb_stereo_synth[0][i] = hb_synth[i] * gain_fac * gp; + } + gp = hStereoDft->mixer_mat_smooth[0][0][8 + IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[0][0][9 + IVAS_MAX_NUM_BANDS] + + hStereoDft->mixer_mat_smooth[0][0][10 + IVAS_MAX_NUM_BANDS]; + if ( bwidth == FB ) + { + gp += hStereoDft->mixer_mat_smooth[0][0][11 + IVAS_MAX_NUM_BANDS]; + } + for ( i = output_frame / 2; i < output_frame; i++ ) + { + hb_stereo_synth[0][i] = hb_synth[i] * gain_fac * gp; + } + } + else + { + gp = hStereoDft->mixer_mat_smooth[0][0][8] + hStereoDft->mixer_mat_smooth[1][0][8] + + hStereoDft->mixer_mat_smooth[0][0][9] + hStereoDft->mixer_mat_smooth[1][0][9] + + hStereoDft->mixer_mat_smooth[0][0][10] + hStereoDft->mixer_mat_smooth[1][0][10]; + if ( bwidth == FB ) + { + gp += hStereoDft->mixer_mat_smooth[0][0][11] + hStereoDft->mixer_mat_smooth[1][0][11]; + } + + gm = hStereoDft->mixer_mat_smooth[0][0][8] - hStereoDft->mixer_mat_smooth[1][0][8] + + hStereoDft->mixer_mat_smooth[0][0][9] - hStereoDft->mixer_mat_smooth[1][0][9] + + hStereoDft->mixer_mat_smooth[0][0][10] - hStereoDft->mixer_mat_smooth[1][0][10]; + if ( bwidth == FB ) + { + gm += hStereoDft->mixer_mat_smooth[0][0][11] - hStereoDft->mixer_mat_smooth[1][0][11]; + } + + for ( i = 0; i < output_frame / 2; i++ ) + { + hb_stereo_synth[0][i] = 0.5f * hb_synth[i] * gain_fac * gp; + hb_stereo_synth[1][i] = 0.5f * hb_synth[i] * gain_fac * gm; + } + + gp = hStereoDft->mixer_mat_smooth[0][0][8 + IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[1][0][8 + IVAS_MAX_NUM_BANDS] + + hStereoDft->mixer_mat_smooth[0][0][9 + IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[1][0][9 + IVAS_MAX_NUM_BANDS] + + hStereoDft->mixer_mat_smooth[0][0][10 + IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[1][0][10 + IVAS_MAX_NUM_BANDS]; + if ( bwidth == FB ) + { + gp += hStereoDft->mixer_mat_smooth[0][0][11 + IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[1][0][11 + IVAS_MAX_NUM_BANDS]; + } + + gm = hStereoDft->mixer_mat_smooth[0][0][8 + IVAS_MAX_NUM_BANDS] - hStereoDft->mixer_mat_smooth[1][0][8 + IVAS_MAX_NUM_BANDS] + + hStereoDft->mixer_mat_smooth[0][0][9 + IVAS_MAX_NUM_BANDS] - hStereoDft->mixer_mat_smooth[1][0][9 + IVAS_MAX_NUM_BANDS] + + hStereoDft->mixer_mat_smooth[0][0][10 + IVAS_MAX_NUM_BANDS] - hStereoDft->mixer_mat_smooth[1][0][10 + IVAS_MAX_NUM_BANDS]; + if ( bwidth == FB ) + { + gm += hStereoDft->mixer_mat_smooth[0][0][11 + IVAS_MAX_NUM_BANDS] - hStereoDft->mixer_mat_smooth[1][0][11 + IVAS_MAX_NUM_BANDS]; + } + + for ( i = output_frame / 2; i < output_frame; i++ ) + { + hb_stereo_synth[0][i] = 0.5f * hb_synth[i] * gain_fac * gp; + hb_stereo_synth[1][i] = 0.5f * hb_synth[i] * gain_fac * gm; + } + } +#else for ( i = 0; i < output_frame / 2; i++ ) { float gp = hStereoDft->mixer_mat_smooth[0][0][8] + hStereoDft->mixer_mat_smooth[1][0][8] + @@ -490,6 +610,7 @@ static void ivas_sba_dirac_stereo_upmix_hb( hb_stereo_synth[0][i] = 0.5f * hb_synth[i] * 0.25f * gp; hb_stereo_synth[1][i] = 0.5f * hb_synth[i] * 0.25f * gm; } +#endif } else { @@ -732,6 +853,9 @@ void ivas_sba_dirac_stereo_dec( ) { int16_t dtx_flag, fd_cng_flag; +#ifdef SBA2MONO + int16_t sba_mono_flag; +#endif int16_t memOffset; float tmp_buf[NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS )]; float tmp_synth[L_FRAME16k]; @@ -756,6 +880,9 @@ void ivas_sba_dirac_stereo_dec( dtx_flag = ( hSCE->hCoreCoder[0]->core_brate <= SID_2k40 ); fd_cng_flag = ( dtx_flag && hSCE->hCoreCoder[0]->cng_type == FD_CNG ); } +#ifdef SBA2MONO + sba_mono_flag = ( st_ivas->hDecoderConfig->nchan_out == 1 ) ? 1 : 0; +#endif memOffset = NS2SA( output_frame * FRAMES_PER_SEC, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ); @@ -794,20 +921,39 @@ void ivas_sba_dirac_stereo_dec( } /* DFT Stereo upmix */ +#ifdef SBA2MONO + stereo_dft_dec( hStereoDft, hCPE->hCoreCoder[0], DFT, NULL, NULL, 1 /*st_ivas->sba_dirac_stereo_flag*/, sba_mono_flag, +#else stereo_dft_dec( hStereoDft, hCPE->hCoreCoder[0], DFT, NULL, NULL, 1, /*st_ivas->sba_dirac_stereo_flag*/ +#endif ( st_ivas->hSpar != NULL && !mcmasa ) ? st_ivas->hSpar->hMdDec : 0, ( st_ivas->hSpar != NULL && !mcmasa ) ? st_ivas->hSpar->hFbMixer->cross_fade_start_offset : 0, st_ivas->hDecoderConfig->output_Fs, st_ivas->nchan_transport ); /* DFT synthesis */ stereo_dft_dec_synthesize( hCPE, DFT, 0, output[0], output_frame ); +#ifdef SBA2MONO + if ( !sba_mono_flag ) + { + stereo_dft_dec_synthesize( hCPE, DFT, 1, output[1], output_frame ); + } +#else stereo_dft_dec_synthesize( hCPE, DFT, 1, output[1], output_frame ); +#endif synchro_synthesis( st_ivas->hDecoderConfig->ivas_total_brate, hCPE, output, output_frame, 1 /*st_ivas->sba_dirac_stereo_flag*/ ); /* output scaling */ +#ifdef SBA2MONO + if ( !sba_mono_flag ) + { + v_multc( output[0], 0.5f, output[0], output_frame ); + v_multc( output[1], 0.5f, output[1], output_frame ); + } +#else v_multc( output[0], 0.5f, output[0], output_frame ); v_multc( output[1], 0.5f, output[1], output_frame ); +#endif /* delay HB synth */ if ( st_ivas->nchan_transport == 1 ) @@ -824,15 +970,26 @@ void ivas_sba_dirac_stereo_dec( ivas_sba_dirac_stereo_compute_hb_gain( hStereoDft, hb_gain ); ivas_sba_dirac_stereo_upmix_hb( hb_synth_stereo, hSCE->save_hb_synth, hb_gain, output_frame, +#ifdef SBA2MONO + ( st_ivas->sba_mode != SBA_MODE_SPAR || mcmasa ), sba_mono_flag, hSCE->hCoreCoder[0]->bwidth, hStereoDft ); +#else ( st_ivas->sba_mode != SBA_MODE_SPAR || mcmasa ), hStereoDft ); +#endif /* add HB to ACELP core */ v_add( output[0], hb_synth_stereo[0], output[0], output_frame ); - v_add( output[1], hb_synth_stereo[1], output[1], output_frame ); +#ifdef SBA2MONO + if ( !sba_mono_flag ) + { +#endif + v_add( output[1], hb_synth_stereo[1], output[1], output_frame ); - /* apply TD Stereo Filling as is done in ICBWE */ - ivas_sba_dirac_stereo_apply_td_stefi( hStereoDft, output, output_frame, ( st_ivas->sba_mode == SBA_MODE_SPAR && !mcmasa ) ); + /* apply TD Stereo Filling as is done in ICBWE */ + ivas_sba_dirac_stereo_apply_td_stefi( hStereoDft, output, output_frame, ( st_ivas->sba_mode == SBA_MODE_SPAR && !mcmasa ) ); +#ifdef SBA2MONO + } +#endif } return; diff --git a/lib_dec/ivas_sce_dec.c b/lib_dec/ivas_sce_dec.c old mode 100644 new mode 100755 index 5c06b4b49deb82d60934535de0006e7cfb3c03cb..064cdbb4e093afee49f03aec8b479615008039f5 --- a/lib_dec/ivas_sce_dec.c +++ b/lib_dec/ivas_sce_dec.c @@ -365,7 +365,11 @@ ivas_error create_sce_dec( return error; } +#ifdef SBA2MONO + if ( st_ivas->ivas_format == SBA_FORMAT && ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_STEREO || ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_MONO && st_ivas->nchan_transport == 1 ) ) ) +#else if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_STEREO ) +#endif { if ( ( error = openCldfb( &st->cldfbSynHB, CLDFB_SYNTHESIS, st->output_Fs, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK ) { diff --git a/lib_dec/ivas_stereo_dft_dec.c b/lib_dec/ivas_stereo_dft_dec.c index f1cbf180bd1974567688e1471629750954237adb..769f6016b487b16c2f1824ad302af50b9a6136ee 100644 --- a/lib_dec/ivas_stereo_dft_dec.c +++ b/lib_dec/ivas_stereo_dft_dec.c @@ -1126,10 +1126,13 @@ void stereo_dft_dec( float *input_mem, /* i/o: mem of buffer DFT analysis */ STEREO_CNG_DEC_HANDLE hStereoCng, /* i/o: Stereo CNG data structure */ const int16_t sba_dirac_stereo_flag, /* i : signal stereo output for SBA DirAC */ - ivas_spar_md_dec_state_t *hMdDec, /* i : SPAR MD handle for upmixing */ - const int16_t cross_fade_start_offset, /* i : SPAR mixer delay compensation */ - const int32_t output_Fs, /* i : Fs for delay calculation */ - const int16_t nchan_transport /* i : number of transpor channels */ +#ifdef SBA2MONO + const int16_t sba_mono_flag, /* i : signal mono output for SBA DirAC */ +#endif + ivas_spar_md_dec_state_t *hMdDec, /* i : SPAR MD handle for upmixing */ + const int16_t cross_fade_start_offset, /* i : SPAR mixer delay compensation */ + const int32_t output_Fs, /* i : Fs for delay calculation */ + const int16_t nchan_transport /* i : number of transpor channels */ ) { int16_t i, k, b, N_div, stop; @@ -1410,50 +1413,92 @@ void stereo_dft_dec( if ( nchan_transport == 1 ) { - if ( b == 0 ) +#ifdef SBA2MONO + if ( sba_mono_flag ) { - i = 0; + if ( b == 0 ) + { + i = 0; - DFT_W = hStereoDft->mixer_mat_smooth[0][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i]; - DFT_Y = hStereoDft->mixer_mat_smooth[1][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i]; + DFT_W = hStereoDft->mixer_mat_smooth[0][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i]; + DFT_L[2 * i] = DFT_W; + DFT_R[2 * i] = 0.f; - DFT_L[2 * i] = DFT_W + DFT_Y; - DFT_R[2 * i] = DFT_W - DFT_Y; + DFT_W = hStereoDft->mixer_mat_smooth[0][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i + 1]; + DFT_L[2 * i + 1] = DFT_W; + DFT_R[2 * i + 1] = 0.f; + } + for ( i = hStereoDft->band_limits[b]; i < min( stop, hStereoDft->band_limits[b + 1] ); i++ ) + { + DFT_W = hStereoDft->mixer_mat_smooth[0][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i] + ( hStereoDft->mixer_mat_smooth[0][1][b + k * IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[0][2][b + k * IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[0][3][b + k * IVAS_MAX_NUM_BANDS] ) * DFT_PRED_RES[2 * i]; + DFT_L[2 * i] = DFT_W; + DFT_R[2 * i] = 0.f; - DFT_W = hStereoDft->mixer_mat_smooth[0][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i + 1]; - DFT_Y = hStereoDft->mixer_mat_smooth[1][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i + 1]; + DFT_W = hStereoDft->mixer_mat_smooth[0][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i + 1] + ( hStereoDft->mixer_mat_smooth[0][1][b + k * IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[0][2][b + k * IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[0][3][b + k * IVAS_MAX_NUM_BANDS] ) * DFT_PRED_RES[2 * i + 1]; + DFT_L[2 * i + 1] = DFT_W; + DFT_R[2 * i + 1] = 0.f; + } + for ( ; i < hStereoDft->band_limits[b + 1]; i++ ) + { + DFT_W = hStereoDft->mixer_mat_smooth[0][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i]; + DFT_L[2 * i] = DFT_W; + DFT_R[2 * i] = 0.f; - DFT_L[2 * i + 1] = DFT_W + DFT_Y; - DFT_R[2 * i + 1] = DFT_W - DFT_Y; + DFT_W = hStereoDft->mixer_mat_smooth[0][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i + 1]; + DFT_L[2 * i + 1] = DFT_W; + DFT_R[2 * i + 1] = 0.f; + } } - for ( i = hStereoDft->band_limits[b]; i < min( stop, hStereoDft->band_limits[b + 1] ); i++ ) + else { - DFT_W = hStereoDft->mixer_mat_smooth[0][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i] + ( hStereoDft->mixer_mat_smooth[0][1][b + k * IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[0][2][b + k * IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[0][3][b + k * IVAS_MAX_NUM_BANDS] ) * DFT_PRED_RES[2 * i]; - DFT_Y = hStereoDft->mixer_mat_smooth[1][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i] + ( hStereoDft->mixer_mat_smooth[1][1][b + k * IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[1][2][b + k * IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[1][3][b + k * IVAS_MAX_NUM_BANDS] ) * DFT_PRED_RES[2 * i]; +#endif + if ( b == 0 ) + { + i = 0; - DFT_L[2 * i] = DFT_W + DFT_Y; - DFT_R[2 * i] = DFT_W - DFT_Y; + DFT_W = hStereoDft->mixer_mat_smooth[0][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i]; + DFT_Y = hStereoDft->mixer_mat_smooth[1][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i]; - DFT_W = hStereoDft->mixer_mat_smooth[0][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i + 1] + ( hStereoDft->mixer_mat_smooth[0][1][b + k * IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[0][2][b + k * IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[0][3][b + k * IVAS_MAX_NUM_BANDS] ) * DFT_PRED_RES[2 * i + 1]; - DFT_Y = hStereoDft->mixer_mat_smooth[1][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i + 1] + ( hStereoDft->mixer_mat_smooth[1][1][b + k * IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[1][2][b + k * IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[1][3][b + k * IVAS_MAX_NUM_BANDS] ) * DFT_PRED_RES[2 * i + 1]; + DFT_L[2 * i] = DFT_W + DFT_Y; + DFT_R[2 * i] = DFT_W - DFT_Y; - DFT_L[2 * i + 1] = DFT_W + DFT_Y; - DFT_R[2 * i + 1] = DFT_W - DFT_Y; - } - for ( ; i < hStereoDft->band_limits[b + 1]; i++ ) - { - DFT_W = hStereoDft->mixer_mat_smooth[0][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i]; - DFT_Y = hStereoDft->mixer_mat_smooth[1][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i]; + DFT_W = hStereoDft->mixer_mat_smooth[0][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i + 1]; + DFT_Y = hStereoDft->mixer_mat_smooth[1][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i + 1]; - DFT_L[2 * i] = DFT_W + DFT_Y; - DFT_R[2 * i] = DFT_W - DFT_Y; + DFT_L[2 * i + 1] = DFT_W + DFT_Y; + DFT_R[2 * i + 1] = DFT_W - DFT_Y; + } + for ( i = hStereoDft->band_limits[b]; i < min( stop, hStereoDft->band_limits[b + 1] ); i++ ) + { + DFT_W = hStereoDft->mixer_mat_smooth[0][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i] + ( hStereoDft->mixer_mat_smooth[0][1][b + k * IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[0][2][b + k * IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[0][3][b + k * IVAS_MAX_NUM_BANDS] ) * DFT_PRED_RES[2 * i]; + DFT_Y = hStereoDft->mixer_mat_smooth[1][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i] + ( hStereoDft->mixer_mat_smooth[1][1][b + k * IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[1][2][b + k * IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[1][3][b + k * IVAS_MAX_NUM_BANDS] ) * DFT_PRED_RES[2 * i]; - DFT_W = hStereoDft->mixer_mat_smooth[0][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i + 1]; - DFT_Y = hStereoDft->mixer_mat_smooth[1][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i + 1]; + DFT_L[2 * i] = DFT_W + DFT_Y; + DFT_R[2 * i] = DFT_W - DFT_Y; - DFT_L[2 * i + 1] = DFT_W + DFT_Y; - DFT_R[2 * i + 1] = DFT_W - DFT_Y; + DFT_W = hStereoDft->mixer_mat_smooth[0][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i + 1] + ( hStereoDft->mixer_mat_smooth[0][1][b + k * IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[0][2][b + k * IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[0][3][b + k * IVAS_MAX_NUM_BANDS] ) * DFT_PRED_RES[2 * i + 1]; + DFT_Y = hStereoDft->mixer_mat_smooth[1][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i + 1] + ( hStereoDft->mixer_mat_smooth[1][1][b + k * IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[1][2][b + k * IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[1][3][b + k * IVAS_MAX_NUM_BANDS] ) * DFT_PRED_RES[2 * i + 1]; + + DFT_L[2 * i + 1] = DFT_W + DFT_Y; + DFT_R[2 * i + 1] = DFT_W - DFT_Y; + } + for ( ; i < hStereoDft->band_limits[b + 1]; i++ ) + { + DFT_W = hStereoDft->mixer_mat_smooth[0][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i]; + DFT_Y = hStereoDft->mixer_mat_smooth[1][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i]; + + DFT_L[2 * i] = DFT_W + DFT_Y; + DFT_R[2 * i] = DFT_W - DFT_Y; + + DFT_W = hStereoDft->mixer_mat_smooth[0][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i + 1]; + DFT_Y = hStereoDft->mixer_mat_smooth[1][0][b + k * IVAS_MAX_NUM_BANDS] * pDFT_DMX[2 * i + 1]; + + DFT_L[2 * i + 1] = DFT_W + DFT_Y; + DFT_R[2 * i + 1] = DFT_W - DFT_Y; + } +#ifdef SBA2MONO } +#endif } else if ( nchan_transport >= 2 ) {