diff --git a/apps/decoder.c b/apps/decoder.c index 8bc31fdea6470d63585ce762dfbba755cd85493f..1b6b7e5d57614343574b70e43718c0ba3877eb19 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -128,11 +128,7 @@ typedef struct bool customLsOutputEnabled; char *customLsSetupFilename; int16_t orientation_tracking; -#ifdef FIX_745_FIX_DATA_TYPE_CONVERSION bool non_diegetic_pan_enabled; -#else - int16_t Opt_non_diegetic_pan; -#endif float non_diegetic_pan_gain; bool renderConfigEnabled; char *renderConfigFilename; @@ -152,11 +148,7 @@ typedef struct #endif #endif AcousticEnvironmentSequence aeSequence; -#ifdef FIX_745_FIX_DATA_TYPE_CONVERSION bool dpidEnabled; -#else - int16_t Opt_dpid_on; -#endif uint16_t directivityPatternId[IVAS_MAX_NUM_OBJECTS]; } DecArguments; @@ -415,12 +407,7 @@ int main( if ( arg.renderConfigEnabled ) { /* sanity check */ -#ifdef FIX_745_FIX_DATA_TYPE_CONVERSION if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM && arg.non_diegetic_pan_enabled == false ) -#else - if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM && - arg.Opt_non_diegetic_pan == 0 ) -#endif { fprintf( stderr, "\nError: Renderer configuration file cannot be used in this output configuration.\n\n" ); goto cleanup; @@ -440,13 +427,8 @@ int main( asked_frame_size = arg.renderFramesize; uint16_t aeID = arg.aeSequence.count > 0 ? arg.aeSequence.pID[0] : 65535; -#ifdef FIX_745_FIX_DATA_TYPE_CONVERSION if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputConfig, arg.tsmEnabled, arg.renderFramesize, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation, arg.enableExternalOrientation, arg.orientation_tracking, arg.renderConfigEnabled, arg.non_diegetic_pan_enabled, arg.non_diegetic_pan_gain, arg.dpidEnabled, aeID, arg.delayCompensationEnabled ) ) != IVAS_ERR_OK ) -#else - if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputConfig, arg.tsmEnabled, arg.renderFramesize, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation, arg.enableExternalOrientation, arg.orientation_tracking, arg.renderConfigEnabled, arg.Opt_non_diegetic_pan, arg.non_diegetic_pan_gain, - arg.Opt_dpid_on, aeID, arg.delayCompensationEnabled ) ) != IVAS_ERR_OK ) -#endif { fprintf( stderr, "\nConfigure failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -612,12 +594,7 @@ int main( /* sanity check */ if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB && -#ifdef FIX_745_FIX_DATA_TYPE_CONVERSION arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM && arg.non_diegetic_pan_enabled == false ) -#else - arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM && - arg.Opt_non_diegetic_pan == 0 ) -#endif { fprintf( stderr, "\nExternal Renderer Config is supported only when binaural output configurations is used as output OR when Split rendering mode is enabled. Exiting. \n" ); goto cleanup; @@ -1088,20 +1065,12 @@ static bool parseCmdlIVAS_dec( arg->renderConfigEnabled = false; arg->renderConfigFilename = NULL; -#ifdef FIX_745_FIX_DATA_TYPE_CONVERSION arg->dpidEnabled = false; -#else - arg->Opt_dpid_on = 0; -#endif arg->outputMdFilename = NULL; arg->inputFormat = IVAS_DEC_INPUT_FORMAT_G192; -#ifdef FIX_745_FIX_DATA_TYPE_CONVERSION arg->non_diegetic_pan_enabled = false; -#else - arg->Opt_non_diegetic_pan = 0; -#endif arg->non_diegetic_pan_gain = 0.f; arg->tsmEnabled = false; arg->renderFramesize = IVAS_RENDER_FRAMESIZE_20MS; @@ -1440,11 +1409,7 @@ static bool parseCmdlIVAS_dec( else if ( strcmp( argv_to_upper, "-NON_DIEGETIC_PAN" ) == 0 ) { i++; -#ifdef FIX_745_FIX_DATA_TYPE_CONVERSION arg->non_diegetic_pan_enabled = true; -#else - arg->Opt_non_diegetic_pan = 1; -#endif strncpy( argv_to_upper, argv[i], sizeof( argv_to_upper ) - 1 ); argv_to_upper[sizeof( argv_to_upper ) - 1] = '\0'; to_upper( argv_to_upper ); @@ -1541,11 +1506,7 @@ static bool parseCmdlIVAS_dec( { int16_t id, tmp; -#ifdef FIX_745_FIX_DATA_TYPE_CONVERSION arg->dpidEnabled = true; -#else - arg->Opt_dpid_on = 1; -#endif ++i; tmp = 0; while ( is_number( argv[i + tmp] ) && tmp < IVAS_MAX_NUM_OBJECTS ) @@ -1626,11 +1587,7 @@ static bool parseCmdlIVAS_dec( } i++; -#ifdef FIX_745_FIX_DATA_TYPE_CONVERSION if ( arg->non_diegetic_pan_enabled && arg->outputConfig != IVAS_AUDIO_CONFIG_STEREO ) -#else - if ( ( arg->Opt_non_diegetic_pan ) && ( arg->outputConfig != IVAS_AUDIO_CONFIG_STEREO ) ) -#endif { fprintf( stderr, "Error: non-diegetic panning is supported in stereo only\n\n" ); usage_dec(); @@ -1649,11 +1606,7 @@ static bool parseCmdlIVAS_dec( arg->outputConfig = IVAS_AUDIO_CONFIG_MONO; arg->decMode = IVAS_DEC_MODE_EVS; -#ifdef FIX_745_FIX_DATA_TYPE_CONVERSION if ( arg->non_diegetic_pan_enabled ) -#else - if ( ( arg->Opt_non_diegetic_pan ) ) -#endif { arg->outputConfig = IVAS_AUDIO_CONFIG_STEREO; } diff --git a/ci/basop-pages/create_report_pages.py b/ci/basop-pages/create_report_pages.py index 25dfaf5f2db6f2cff992003d8478c6521ec006f1..af937355ef4054fbf24561bf0aee9aa0285ee776 100644 --- a/ci/basop-pages/create_report_pages.py +++ b/ci/basop-pages/create_report_pages.py @@ -105,6 +105,7 @@ COLUMNS = [ "MLD", "MAXIMUM ABS DIFF", "MIN_SSNR", + "MIN_ODG", ] COLUMNS_GLOBAL = COLUMNS[:1] COLUMNS_DIFFERENTIAL = COLUMNS[3:] diff --git a/lib_com/gs_bitallocation.c b/lib_com/gs_bitallocation.c index 7dd4535b1b21af9c2d300a5dd03824fca8a9efcf..b1e8dbf4abc2c2f6e38a924f4f934bd88a99a4c1 100644 --- a/lib_com/gs_bitallocation.c +++ b/lib_com/gs_bitallocation.c @@ -53,7 +53,29 @@ static float Find_bit_frac( const int16_t nb_band, const int16_t remaining_bits ); static void reajust_bits( float *bits_per_bands, const int16_t st_band, const int16_t end_band, const int16_t sum_bit_in, const int16_t bit_bdgt_in ); - +#ifdef NON_BE_FIX_1137_GSC_IVAS_FXFLT_DECODING +#define Q15_0_33 10922 /* 0.33 */ +#define Q18_0_1 26214 /* 0.1 */ +#define Q18_0_50 131072 /* 0.50 */ +#define Q18_0_75 196608 /* 0.75 */ +#define Q18_0_76 199229 /* 76/100 */ +#define Q18_1_0 262144 /* 1.0 */ +#define Q18_1_2 314573 /* 1.2 */ +#define Q18_112 29360128 /* 112 */ +#define Q18_DSR_NB_PULSE 1179648 /* 4.5 */ +#define Q18_1_5xDSR_NB_PULSE 1769472 /* 1.5x4.5 */ +#define Q18_2_0xDSR_NB_PULSE ( Q18_DSR_NB_PULSE << 1 ) /* 2.0x4.5 */ + +#define Q31_0_00125 2684355 /* 0.125/100 */ +#define Q31_0_0125 26843546 /* 0.0125 */ +#define Q31_0_015 32212255 /* 0.0125 */ +#define Q31_0_02 42949673 /* 0.02 */ +#define Q31_0_17 365072220 /* 0.17 */ +#define Q31_0_23 493921239 /* 0.23 */ +static Word16 Find_norm_inv( const Word32 ToDivide, Word16 *e_div ); +static Word16 Find_bit_alloc_IVAS_int( const Word32 core_brate, const Word16 GSC_IVAS_mode, const Word16 Diff_len, const Word16 nb_tot_bands, const Word16 L_frame, Word16 *bit, Word16 *max_ener_band, float *ener_vec, float *bits_per_bands ); +static Word16 maximum_fx( const Word16 *vec_fx, const Word16 lvec_fx, Word16 *max_fx ); +#endif /*-------------------------------------------------------------------* * bands_and_bit_alloc() @@ -92,9 +114,12 @@ void bands_and_bit_alloc( int16_t pos, band; float SWB_bit_budget; float bits_per_bands[MBANDS_GN_BITALLOC16k]; +#ifndef NON_BE_FIX_1137_GSC_IVAS_FXFLT_DECODING float fzero_val, mp, mb, nb_bands_adj, bit_adj; int16_t nb_pulse_per_band[MBANDS_GN_BITALLOC16k]; - +#else + float fzero_val; +#endif /* initializations */ nb_tot_bands = 16; set_f( bits_per_bands, 0.0f, MBANDS_GN_BITALLOC16k ); @@ -193,6 +218,7 @@ void bands_and_bit_alloc( { if ( GSC_IVAS_mode > 0 ) { +#ifndef NON_BE_FIX_1137_GSC_IVAS_FXFLT_DECODING SWB_bit_budget = *bit; st_band = 5; @@ -371,6 +397,10 @@ void bands_and_bit_alloc( bits_per_bands[i] += sum_bit; } } +#else + nb_tot_bands = Find_bit_alloc_IVAS_int( core_brate, GSC_IVAS_mode, Diff_len, nb_tot_bands, L_frame, bit, max_ener_band, ener_vec, bits_per_bands ); + nb_bands = nb_tot_bands; +#endif } else if ( GSC_noisy_speech ) { @@ -824,7 +854,6 @@ void bands_and_bit_alloc( *nb_subbands = 0; *pvq_len = 0; } - return; } @@ -933,3 +962,293 @@ static float Find_bit_frac( return ( var_out ); } +#ifdef NON_BE_FIX_1137_GSC_IVAS_FXFLT_DECODING + +static Word16 Find_bit_alloc_IVAS_int( /*o: Number of band to encode */ + const Word32 core_brate, /* i : core bit rate */ + const Word16 GSC_IVAS_mode, /* i : GSC IVAS mode */ + const Word16 Diff_len, /* i : Length of the difference signal (before pure spectral)*/ + const Word16 nb_tot_bands_in, /* i : total number of band */ + const Word16 L_frame, /* i : frame length */ + Word16 *bit, /* i/o: Number of bit allowed for frequency quantization */ + Word16 *max_ener_band, /* i/o: Energy based sorted order */ + float *ener_vec_io, /* i/o: Energy per band order */ + float *bits_per_bands_o /* o : Number of bit allowed per allowed sub-band Q3 */ +) +{ + Word32 mp, mb, nb_bands_adj, bit_adj; + Word16 nb_pulse_per_band[MBANDS_GN_BITALLOC16k]; + Word32 SWB_bit_budget; // Q0 -> Q18 + Word16 i, j, nb_bands_max, st_band, nb_tot_bands_loc, etmp; + Word32 sum_bit /*Q18*/, bit_fracf /*Q18*/; + Word16 d_tmp, e_div, tmp16, ener_vec[MBANDS_GN_BITALLOC16k]; + Word32 Ltmp, etmp_32fx, bits_per_bands[MBANDS_GN_BITALLOC16k]; + + + SWB_bit_budget = *bit; // Q0 + st_band = 5; + nb_bands_max = nb_tot_bands_in; + + + for ( i = 0; i < MBANDS_GN; i++ ) + { + ener_vec[i] = (short) ( ener_vec_io[i] ); /* Q12 -> Q12 */ + } + if ( L_frame == L_FRAME16k ) + { + for ( i = MBANDS_GN; i < MBANDS_GN_BITALLOC16k; i++ ) + { + ener_vec[i] = (short) ( ener_vec_io[i] * 4096.0 + 0.5f ); /* Q0 -> Q12 */ + } + } + + set_l( bits_per_bands, 0, MBANDS_GN_BITALLOC16k ); + + /* Decide the pourcentage of bits allocated to LF (between 50-75%) depending of the temporal contribution in GSC */ + /* bit_fracf = ( -0.125f * Diff_len + 76.0f ) / 100; */ + bit_fracf = L_add( Mpy_32_32( -Q31_0_00125, L_shl( Diff_len, 18 ) ), Q18_0_76 ); /* Q18 */ + + /* bit_fracf = check_bounds(bit_fracf, 0.50f, 0.75f); */ + bit_fracf = min( max( bit_fracf, Q18_0_50 ), Q18_0_75 ); + + /* Adjusment of the bitrate between LF and HF base on the content type */ + /* 1 = new GSC bit alloc + 2 = GSC bit alloc for tc frame + 3 = more music like (should not happen often given music is coded with dft) */ + + if ( GSC_IVAS_mode <= 3 ) + { + nb_bands_max -= 6; + } + if ( GSC_IVAS_mode == 2 ) + { + /* bit_fracf += 0.1f; */ + bit_fracf += Q18_0_1; /* Q18*/ + nb_bands_max -= 1; + } + if ( GSC_IVAS_mode == 3 ) + { + /* bit_fracf -= 0.1f; */ + bit_fracf -= Q18_0_1; /* Q18*/ + nb_bands_max += 3; + } + + /* First find how much we want to share between LF and HF, at low bitrate, a miminum of bits is needed in LF by limitating the number of bands*/ + /* Adjust the number of band based on the content type and bitrate */ + + /* nb_bands_adj = 1.0f; */ + nb_bands_adj = Q18_1_0; + if ( GSC_IVAS_mode == 1 && core_brate < GSC_L_RATE_STG ) + { + /* nb_bands_adj = 0.0125f * SWB_bit_budget - 0.75f;*/ + nb_bands_adj = L_sub( Mpy_32_32( Q31_0_0125, L_shl( SWB_bit_budget, 18 ) ), Q18_0_75 ); // Q18 + } + else if ( GSC_IVAS_mode != 2 && core_brate > GSC_H_RATE_STG ) + { + /*nb_bands_adj = 0.02f * SWB_bit_budget - 1.2f;*/ + nb_bands_adj = L_sub( Mpy_32_32( Q31_0_02, L_shl( SWB_bit_budget, 18 ) ), Q18_1_2 ); // Q18 + } + /*nb_bands_max = (int16_t)(nb_bands_max * nb_bands_adj + 0.5f);*/ + + nb_bands_max = round_fx( Mpy_32_16_1( L_shl( nb_bands_adj, 5 ), shl( nb_bands_max, 10 - 2 ) ) ); /* Q0 */ + nb_bands_max = check_bounds_s( nb_bands_max, 5, nb_tot_bands_in ); + + /* bit_fracf *= SWB_bit_budget;*/ + /* At this point bit_fracf has a value below 1.0 */ + bit_fracf = Mpy_32_16_1( L_shl( bit_fracf, 10 ), extract_l( L_shl( SWB_bit_budget, 5 ) ) ); /* (Q(18+10)*Q(0+5) + 1 - 16 = Q18 */ + + /* Estimation of the number of bit used in HF */ + /* with only the first weighting The number of bits in max_ener_band[st_band-1] = 17% of bit_fracf */ + /* mb = .17f * bit_fracf;*/ + mb = Mpy_32_32( Q31_0_17, bit_fracf ); /* Q18 */ + + /* mp = 2 * DSR_NB_PULSE;*/ + mp = Q18_2_0xDSR_NB_PULSE; + if ( core_brate < GSC_L_RATE_STG && GSC_IVAS_mode == 3 ) + { + /* mp = 1.5f * DSR_NB_PULSE;*/ + mp = Q18_1_5xDSR_NB_PULSE; + } + else if ( core_brate < GSC_L_RATE_STG ) + { + /* mp = DSR_NB_PULSE;*/ + mp = Q18_DSR_NB_PULSE; + } + + /* We want max_ener_band[st_band] <= max_ener_band[st_band-1] and max_ener_band[nb_bands_max-1] <= max_ener_band[st_band]*/ + /* We will estimate the number of bits to allocate of HF and put the remaining bits, if any, back on LF */ + /* compute the total possible number of band to be coded */ + + /* nb_tot_bands = (int16_t)((SWB_bit_budget - bit_fracf) / (mp + (mb - mp) / 2.0f)); */ + d_tmp = Find_norm_inv( L_add( mp, mb ), &e_div ); + Ltmp = Mpy_32_16_1( L_sub( L_shl( SWB_bit_budget, 18 ), bit_fracf ), d_tmp ); /* Perform mult by 1/den */ + nb_tot_bands_loc = extract_h( L_shl( Ltmp, sub( 1, e_div ) ) ); /* adjust exponent: 1 is to take into account the / 2.0f, and e_div for the num and den of the division*/ + + mp = min( mp, mb ); + tmp16 = sub( add( nb_tot_bands_loc, st_band ), nb_bands_max ); + if ( tmp16 > 0 ) + { + /* bit_adj = ( ( mb + mp ) / 2 ) * ( nb_tot_bands_loc + st_band - nb_bands_max ); */ + bit_adj = Mpy_32_16_1( L_shl( L_add( mb, mp ), 5 ), shl( tmp16, 10 - 1 ) ); /* Q18+5 * Q0+10 + 1 -1 - 16 = Q18 (-1 is to cover for the /2 in the equation) */ + bit_adj = L_max( 0, bit_adj ); + nb_tot_bands_loc = nb_bands_max - st_band; + bit_fracf += bit_adj; /* Q18 */ + } + nb_tot_bands_loc += st_band; + + /* Allocate bits to LF */ + /* etmp = 0.23f; */ + etmp_32fx = Q31_0_23; + for ( j = 0; j < st_band; j++ ) + { + i = j; + max_ener_band[j] = i; + ener_vec[i] = MIN16B; + /* bits_per_bands[j] = etmp * bit_fracf; */ + bits_per_bands[j] = Mpy_32_32( bit_fracf, etmp_32fx ); /* 18 + 31 + 1 - 32 = Q18 */ + /* etmp -= 0.015f; */ + etmp_32fx -= Q31_0_015; /* Q18 */ + } + + /* SWB_bit_budget -= bit_fracf; */ + SWB_bit_budget = L_sub( L_shl( SWB_bit_budget, 18 ), bit_fracf ); /* Q0->Q18 */ + + /* Find low energy band in HF */ + set_s( nb_pulse_per_band, 2, MBANDS_GN_BITALLOC16k ); + for ( i = st_band + 2; i < nb_tot_bands_loc - 1; i++ ) + { + if ( ener_vec[i] < ener_vec[i - 1] && ener_vec[i] < ener_vec[i + 1] ) /* i +1 and i -1 can be considered as 2 ptrs */ + { + nb_pulse_per_band[i] = 1; + } + } + for ( j = st_band; j < nb_tot_bands_loc; j++ ) + { + if ( j > 6 ) + { + i = maximum_fx( ener_vec, nb_tot_bands_loc, &etmp ); + } + else + { + i = j; + } + max_ener_band[j] = i; + ener_vec[i] = MIN16B; + } + /* Recompute the final bit distribution for HF */ + IF( nb_tot_bands_loc > st_band ) + { + /* This is not bit exact because of the precision lost */ + /* mb = ( SWB_bit_budget * 2 / ( nb_tot_bands_loc - st_band ) ) - mp; */ + d_tmp = Find_norm_inv( L_deposit_h( sub( nb_tot_bands_loc, st_band ) ), &e_div ); + mb = L_sub( L_shr( Mpy_32_16_1( L_shl( SWB_bit_budget, 1 ), d_tmp ), e_div ), mp ); /* Q18 */ + /* bit_fracf = ( mb - mp ) / ( nb_tot_bands_loc - st_band ); */ + bit_fracf = L_shr( Mpy_32_16_1( L_sub( mb, mp ), d_tmp ), e_div ); /* Q18 */ + + mb -= bit_fracf; + /* Do the distribution */ + for ( j = st_band; j < nb_tot_bands_loc; j++ ) + { + bits_per_bands[max_ener_band[j]] = Q18_DSR_NB_PULSE; + if ( nb_pulse_per_band[max_ener_band[j]] > 1 ) + { + bits_per_bands[max_ener_band[j]] = mb; + } + mb -= bit_fracf; + SWB_bit_budget -= bits_per_bands[max_ener_band[j]]; // Q18 + } + } + /* Series of verification in case bit allocated != the budget */ + if ( SWB_bit_budget > 0 ) + { + i = st_band - 1; + while ( SWB_bit_budget > 0 ) + { + /* bits_per_bands[i]++; */ + bits_per_bands[i] += Q18_1_0; + /* SWB_bit_budget--; */ + SWB_bit_budget -= Q18_1_0; + i--; + if ( i == -1 ) + { + i = st_band - 1; + } + } + } + + /*nb_bands = nb_tot_bands_loc;*/ + + sum_bit = 0; + j = 0; + for ( i = 0; i < nb_tot_bands_loc; i++ ) + { + /* if (bits_per_bands[i] > 112) */ + if ( bits_per_bands[i] > Q18_112 ) + { + /* sum_bit += bits_per_bands[i] - 112; */ + sum_bit = L_add( sum_bit, L_sub( bits_per_bands[i], Q18_112 ) ); + /* bits_per_bands[i] = 112; */ + bits_per_bands[i] = Q18_112; + j = add( j, add( i, 1 ) ); + } + + /* safety check for overage bit reallocation */ + /* else if (bits_per_bands[i] + sum_bit / 3 > 112) */ + else if ( L_add( bits_per_bands[i], Mpy_32_16_1( sum_bit, Q15_0_33 ) ) > Q18_112 ) + { + j = add( j, add( i, 1 ) ); + } + } + + if ( sum_bit != 0 ) + { + /* sum_bit /= (nb_bands - j); */ + d_tmp = Find_norm_inv( L_deposit_h( sub( nb_tot_bands_loc, j ) ), &e_div ); + sum_bit = L_shr( Mpy_32_16_1( sum_bit, d_tmp ), e_div ); /* Q18 */ + for ( i = j; i < nb_tot_bands_loc; i++ ) + { + bits_per_bands[i] = L_add( bits_per_bands[i], sum_bit ); + } + } + for ( i = 0; i < MBANDS_GN_BITALLOC16k; i++ ) + { + bits_per_bands_o[i] = (float) bits_per_bands[i] / 262144.0f; /* Q18 -> float */ + } + return nb_tot_bands_loc; +} + +static Word16 Find_norm_inv( const Word32 ToDivide, Word16 *e_div ) /* Find normalized 1 / ToDivide */ +{ + Word16 d_tmp, e_tmp; + e_tmp = norm_l( ToDivide ); + d_tmp = round_fx( L_shl( ToDivide, e_tmp ) ); + d_tmp = div_s( 16384, d_tmp ); /* 1.0 in Q14, dividend is normalize so >= 16384 as required for the division */ + *e_div = sub( 14, e_tmp ); + move16(); + return d_tmp; +} +static Word16 maximum_fx( /* o : index of the maximum value in the input vector */ + const Word16 *vec_fx, /* i : input vector */ + const Word16 lvec_fx, /* i : length of input vector */ + Word16 *max_fx /* o : maximum value in the input vector */ +) +{ + Word16 j, ind; + Word16 tmp; + ind = 0; + + tmp = vec_fx[0]; + + for ( j = 1; j < lvec_fx; j++ ) + { + if ( vec_fx[j] > tmp ) + { + ind = j; + } + tmp = s_max( tmp, vec_fx[j] ); + } + *max_fx = tmp; + + return ind; +} +#endif diff --git a/lib_com/options.h b/lib_com/options.h index 6b1a8d303a1d8b298c767eb030478f3b9e5cfaad..8d9fa9a11f4664cfc6a94e8c276b15b419c75922 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -162,7 +162,6 @@ //#define FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT /* Orange issue 1031 : new fix point hrtf binary file format */ //#define FIX_CREND_SIMPLIFY_CODE /* Ora : simplify line code in crend */ #define FLOAT_FIX_POINT_HRTF_FILE_FORMAT /* allows reading floation or fix point hrtf binary file format */ -#define FIX_745_FIX_DATA_TYPE_CONVERSION /* VA: issue 745: implicit data type conversion when calling IVAS_DEC_Configure() */ /* #################### End BE switches ################################## */ @@ -170,10 +169,8 @@ /* any switch which is non-be wrt selection floating point code */ /* all switches in this category should start with "NONBE_" */ -#define NONBE_MDCT_ST_DTX_SKIP_DEWHITENING_OF_NOISE_SHAPES_ON_SID_FRAMES /* FhG: issue 1133: skip de-whitening of bg noise shape after frameloss period if the first good frame is an SID */ -#define NONBE_MDCT_ST_PLC_DO_NOT_SCALE_OLD_OUT_IF_FIRST_GOOD_IS_SID /* FhG: issue 1133: in TCX PLC, don't scale hHQ_core->old_out after applying fade to noise in burst frame error */ -#define NONBE_FIX_1130_DIV_ZERO_LEV_DUR /* VA: issue 1130: avoid div by zero in L-D by thresholding R[0] to a min value of 100.0 */ - +#define NON_BE_FIX_1137_GSC_IVAS_FXFLT_DECODING /* VA: Add fix point bit allocation for special GSC mode such that float and fixed point have the same final bit allocation */ + /* ##################### End NON-BE switches ########################### */ /* ################## End DEVELOPMENT switches ######################### */ diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index 47e6bf25b47d456969239e4457f10c3d9afb6d38..26b1ef7047972a45b9cd5b56fd537b74dc5d2c39 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -189,11 +189,7 @@ ivas_error ivas_core_dec( st->flagGuidedAcelp = 0; } -#ifdef NONBE_MDCT_ST_PLC_DO_NOT_SCALE_OLD_OUT_IF_FIRST_GOOD_IS_SID if ( !st->bfi && st->prev_bfi && st->total_brate > SID_2k40 && ( st->last_core_bfi == TCX_20_CORE || st->last_core_bfi == TCX_10_CORE ) && st->hTcxDec != NULL ) -#else - if ( !st->bfi && st->prev_bfi && ( st->last_core_bfi == TCX_20_CORE || st->last_core_bfi == TCX_10_CORE ) && st->hTcxDec != NULL ) -#endif { v_multc( st->hHQ_core->old_out, st->hTcxDec->conceal_eof_gain * st->last_concealed_gain_syn_deemph, st->hHQ_core->old_out, st->hTcxDec->L_frameTCX ); v_multc( st->hHQ_core->old_outLB, st->hTcxDec->conceal_eof_gain * st->last_concealed_gain_syn_deemph, st->hHQ_core->old_outLB, st->L_frame ); @@ -406,16 +402,10 @@ ivas_error ivas_core_dec( { updateBuffersForDmxMdctStereo( hCPE, output_frame, output, synth ); } -#ifdef NONBE_MDCT_ST_DTX_SKIP_DEWHITENING_OF_NOISE_SHAPES_ON_SID_FRAMES /* On first good active frame after frameloss undo the whitening of the bg noise shape */ if ( sts[0]->core_brate > SID_2k40 && sts[0]->bfi == 0 && sts[0]->prev_bfi == 1 ) { -#else - if ( sts[0]->bfi == 0 && sts[0]->prev_bfi == 1 ) - { - /* On first good frame after frameloss undo the whitening of the bg noise shape */ -#endif for ( n = 0; n < n_channels; ++n ) { if ( sts[n]->last_core_bfi != ACELP_CORE ) diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 7cca9fc39b317b819750db8980a77979f7474ffe..c5654bd8ad534816f60105363b51cee90fc80796 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -401,46 +401,22 @@ static IVAS_DEC_BS_FORMAT mapIvasFormat( *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_Configure( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const uint32_t sampleRate, /* i : output sampling frequency */ - const AUDIO_CONFIG outputConfig, /* i : output configuration */ -#ifdef FIX_745_FIX_DATA_TYPE_CONVERSION - const bool tsmEnabled, /* i : enable TSM */ -#else - const int16_t tsmEnabled, /* i : enable time scale modification */ -#endif - const IVAS_RENDER_FRAMESIZE renderFramesize, /* i : rendering frame size */ -#ifdef FIX_745_FIX_DATA_TYPE_CONVERSION - const bool customLsOutputEnabled, /* i : enable custom loudspeaker setup handle */ - const bool hrtfReaderEnabled, /* i : enable HRTF binary file input */ - const bool enableHeadRotation, /* i : enable head rotation for binaural output */ - const bool enableExternalOrientation, /* i : enable external orientations */ -#else - const int16_t customLsOutputEnabled, /* i : enable custom loudspeaker setup handle */ - const int16_t hrtfReaderEnabled, /* i : enable HRTF binary file input */ - const int16_t enableHeadRotation, /* i : enable head rotation for binaural output */ - const int16_t enableExternalOrientation, /* i : enable external orientations */ -#endif + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const uint32_t sampleRate, /* i : output sampling frequency */ + const AUDIO_CONFIG outputConfig, /* i : output configuration */ + const bool tsmEnabled, /* i : enable TSM */ + const IVAS_RENDER_FRAMESIZE renderFramesize, /* i : rendering frame size */ + const bool customLsOutputEnabled, /* i : enable custom loudspeaker setup handle */ + const bool hrtfReaderEnabled, /* i : enable HRTF binary file input */ + const bool enableHeadRotation, /* i : enable head rotation for binaural output */ + const bool enableExternalOrientation, /* i : enable external orientations */ const IVAS_HEAD_ORIENT_TRK_T orientation_tracking, /* i : head orientation tracking type */ -#ifdef FIX_745_FIX_DATA_TYPE_CONVERSION - const bool renderConfigEnabled, /* i : enable Renderer config. file for binaural output */ - const bool non_diegetic_pan_enabled, /* i : enabled diegetic panning */ -#else - const int16_t renderConfigEnabled, /* i : enable Renderer config. file for binaural output */ - const int16_t Opt_non_diegetic_pan, /* i : diegetic or not */ -#endif - const float non_diegetic_pan_gain, /* i : non diegetic panning gain */ -#ifdef FIX_745_FIX_DATA_TYPE_CONVERSION - const bool dpidEnabled, /* i : enable directivity pattern option */ -#else - const int16_t Opt_dpid_on, /* i : enable directivity pattern option */ -#endif - const uint16_t acousticEnvironmentId, /* i : Acoustic environment ID */ -#ifdef FIX_745_FIX_DATA_TYPE_CONVERSION - const bool delayCompensationEnabled /* i : enable delay compensation */ -#else - const int16_t delayCompensationEnabled /* i : enable delay compensation */ -#endif + const bool renderConfigEnabled, /* i : enable Renderer config. file for binaural output */ + const bool non_diegetic_pan_enabled, /* i : enabled diegetic panning */ + const float non_diegetic_pan_gain, /* i : non diegetic panning gain */ + const bool dpidEnabled, /* i : enable directivity pattern option */ + const uint16_t acousticEnvironmentId, /* i : Acoustic environment ID */ + const bool delayCompensationEnabled /* i : enable delay compensation */ ) { Decoder_Struct *st_ivas; @@ -458,13 +434,8 @@ ivas_error IVAS_DEC_Configure( return IVAS_ERR_WRONG_PARAMS; } -#ifdef FIX_745_FIX_DATA_TYPE_CONVERSION if ( hIvasDec->mode == IVAS_DEC_MODE_EVS && !( ( outputConfig == IVAS_AUDIO_CONFIG_MONO && !non_diegetic_pan_enabled ) || ( outputConfig == IVAS_AUDIO_CONFIG_STEREO && non_diegetic_pan_enabled ) ) ) -#else - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS && !( ( outputConfig == IVAS_AUDIO_CONFIG_MONO && Opt_non_diegetic_pan == 0 ) || - ( outputConfig == IVAS_AUDIO_CONFIG_STEREO && Opt_non_diegetic_pan == 1 ) ) ) -#endif { return IVAS_ERR_WRONG_MODE; } @@ -492,37 +463,17 @@ ivas_error IVAS_DEC_Configure( hDecoderConfig->nchan_out = audioCfg2channels( hDecoderConfig->output_config ); } -#ifdef FIX_745_FIX_DATA_TYPE_CONVERSION hDecoderConfig->Opt_tsm = (int16_t) tsmEnabled; hDecoderConfig->Opt_LsCustom = (int16_t) customLsOutputEnabled; hDecoderConfig->Opt_Headrotation = (int16_t) enableHeadRotation; -#else - hDecoderConfig->Opt_tsm = tsmEnabled; - hDecoderConfig->Opt_LsCustom = customLsOutputEnabled; - hDecoderConfig->Opt_Headrotation = enableHeadRotation; -#endif hDecoderConfig->orientation_tracking = orientation_tracking; -#ifdef FIX_745_FIX_DATA_TYPE_CONVERSION hDecoderConfig->Opt_HRTF_binary = (int16_t) hrtfReaderEnabled; hDecoderConfig->Opt_RendConfigCustom = (int16_t) renderConfigEnabled; hDecoderConfig->Opt_non_diegetic_pan = (int16_t) non_diegetic_pan_enabled; -#else - hDecoderConfig->Opt_HRTF_binary = hrtfReaderEnabled; - hDecoderConfig->Opt_RendConfigCustom = renderConfigEnabled; - hDecoderConfig->Opt_non_diegetic_pan = Opt_non_diegetic_pan; -#endif hDecoderConfig->non_diegetic_pan_gain = non_diegetic_pan_gain; -#ifdef FIX_745_FIX_DATA_TYPE_CONVERSION hDecoderConfig->Opt_delay_comp = (int16_t) delayCompensationEnabled; -#else - hDecoderConfig->Opt_delay_comp = delayCompensationEnabled; -#endif hDecoderConfig->Opt_ExternalOrientation = enableExternalOrientation; -#ifdef FIX_745_FIX_DATA_TYPE_CONVERSION hDecoderConfig->Opt_dpid_on = (int16_t) dpidEnabled; -#else - hDecoderConfig->Opt_dpid_on = Opt_dpid_on; -#endif hDecoderConfig->Opt_aeid_on = acousticEnvironmentId != 65535 ? TRUE : FALSE; if ( renderFramesize == IVAS_RENDER_FRAMESIZE_UNKNOWN ) diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index 85f5d60566cf7e502757d19aa73171774fcb2ac4..3d20bee0962fb476b0fe9d38cde1ed3d84f76a11 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -122,43 +122,19 @@ ivas_error IVAS_DEC_Configure( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ const uint32_t sampleRate, /* i : output sampling frequency */ const IVAS_AUDIO_CONFIG outputConfig, /* i : audio configuration */ -#ifdef FIX_745_FIX_DATA_TYPE_CONVERSION const bool tsmEnabled, /* i : enable TSM */ -#else - const int16_t tsmEnabled, /* i : enable TSM */ -#endif const IVAS_RENDER_FRAMESIZE renderFramesize, /* i : rendering frame size */ -#ifdef FIX_745_FIX_DATA_TYPE_CONVERSION const bool customLsOutputEnabled, /* i : enable custom loudspeaker setup handle */ const bool hrtfReaderEnabled, /* i : enable HRTF binary file input */ const bool enableHeadRotation, /* i : enable head rotation for binaural output */ const bool enableExternalOrientation, /* i : enable external orientations */ -#else - const int16_t customLsOutputEnabled, /* i : enable custom loudspeaker setup handle */ - const int16_t hrtfReaderEnabled, /* i : enable HRTF binary file input */ - const int16_t enableHeadRotation, /* i : enable head rotation for binaural output */ - const int16_t enableExternalOrientation, /* i : enable external orientations */ -#endif const IVAS_HEAD_ORIENT_TRK_T orientation_tracking, /* i : head orientation tracking type */ -#ifdef FIX_745_FIX_DATA_TYPE_CONVERSION const bool renderConfigEnabled, /* i : enable Renderer config. file for binaural output */ const bool non_diegetic_pan_enabled, /* i : enabled diegetic panning */ -#else - const int16_t renderConfigEnabled, /* i : enable Renderer config. file for binaural output */ - const int16_t Opt_non_diegetic_pan, /* i : diegetic or not */ -#endif const float non_diegetic_pan_gain, /* i : non diegetic panning gain */ -#ifdef FIX_745_FIX_DATA_TYPE_CONVERSION const bool dpidEnabled, /* i : enable directivity pattern option */ -#else - const int16_t Opt_dpid_on, /* i : enable directivity pattern option */ -#endif const uint16_t acousticEnvironmentId, /* i : Acoustic environment ID */ -#ifdef FIX_745_FIX_DATA_TYPE_CONVERSION const bool delayCompensationEnabled /* i : enable delay compensation */ -#else - const int16_t delayCompensationEnabled /* i : enable delay compensation */ -#endif ); void IVAS_DEC_Close( diff --git a/lib_enc/swb_tbe_enc.c b/lib_enc/swb_tbe_enc.c index 1cf69fab8a13ddd7bf40a262ed9675a233485526..89d31b2be86ae8766709b6812a67656329cdbdcb 100644 --- a/lib_enc/swb_tbe_enc.c +++ b/lib_enc/swb_tbe_enc.c @@ -281,13 +281,11 @@ void wb_tbe_enc( autocorr( hb_old_speech, R, LPC_SHB_ORDER_WB + 1, ( NS2SA( INT_FS_12k8, 5000000L ) + L_SUBFR + L_FRAME ) * 5 / 16, win_lpc_hb_wb, 0, 1, 1 ); -#ifdef NONBE_FIX_1130_DIV_ZERO_LEV_DUR if ( st->element_mode > EVS_MONO ) { /* Ensure R[0] isn't zero when entering Levinson-Durbin */ R[0] = max( R[0], 1.0e-8f ); } -#endif lev_dur( lpc_wb_temp, R, LPC_SHB_ORDER_WB, ervec_temp ); a2lsp( lsp_wb_temp, lpc_wb_temp, LPC_SHB_ORDER_WB ); diff --git a/scripts/parse_xml_report.py b/scripts/parse_xml_report.py index 3bc0b619ab19b9f9e97be55f0289797035c22ab5..366e02aba5ae14fc2ca203c5bda1db1699a751f2 100644 --- a/scripts/parse_xml_report.py +++ b/scripts/parse_xml_report.py @@ -10,7 +10,7 @@ from xml.etree import ElementTree Parse a junit report and create a summary report. """ -PROPERTIES = ["MLD", "MAXIMUM ABS DIFF", "MIN_SSNR"] +PROPERTIES = ["MLD", "MAXIMUM ABS DIFF", "MIN_SSNR", "MIN_ODG"] FORMATS = { "Stereo": r"stereo", diff --git a/tests/cmp_pcm.py b/tests/cmp_pcm.py index 1d225b90ecac9292e78c5fd41ea2dbfdc7e2bde3..e299047492f8a3d5922d2c1d750253556f07616c 100755 --- a/tests/cmp_pcm.py +++ b/tests/cmp_pcm.py @@ -3,6 +3,11 @@ import argparse import os import sys +import tempfile +import re +import subprocess +from pathlib import Path +from typing import Optional THIS_PATH = os.path.join(os.getcwd(), __file__) sys.path.append(os.path.join(os.path.dirname(THIS_PATH), "../scripts")) @@ -10,6 +15,7 @@ sys.path.append(os.path.join(os.path.dirname(THIS_PATH), "../scripts")) import numpy as np import pyaudio3dtools import pyivastest +from .constants import ODG_PATTERN_PQEVALAUDIO def cmp_pcm( @@ -22,6 +28,7 @@ def cmp_pcm( mld_lim=0, abs_tol=0, get_ssnr=False, + get_odg=False, ) -> (int, str): """ Compare 2 PCM files for bitexactness @@ -106,11 +113,46 @@ def cmp_pcm( for i, s in enumerate(cmp_result["SSNR"], start=1): msg = f"Channel {i} SSNR: {s}" reason += msg + " - " + + if get_odg: + for n in range(nchannels): + pqeval_output = pqevalaudio_wrapper(s1[:, n], s2[:, n], fs) + + match_odg = re.search(ODG_PATTERN_PQEVALAUDIO, pqeval_output) + odg = float(match_odg.groups()[0]) + msg = f"Channel {n} ODG: {odg}" + reason += " - " + msg print(msg) return output_differs, reason +def pqevalaudio_wrapper( + ref_sig: np.ndarray, + eval_sig: np.ndarray, + fs: int, + ) -> str: + with tempfile.TemporaryDirectory() as tmp_dir: + tmp_dir = Path(tmp_dir) + tmp_file_ref = str(tmp_dir.joinpath("ref.wav")) + tmp_file_eval = str(tmp_dir.joinpath("eval.wav")) + + # PQevalAudio neeeds 48 kHz sampling rate + r48 = np.clip( pyaudio3dtools.audioarray.resample(ref_sig.astype(float), fs, 48000), -32768, 32767 ).astype(np.int16) + t48 = np.clip( pyaudio3dtools.audioarray.resample(eval_sig.astype(float), fs, 48000), -32768, 32767 ).astype(np.int16) + + pyaudio3dtools.audiofile.writefile(tmp_file_ref, r48, 48000) + pyaudio3dtools.audiofile.writefile(tmp_file_eval, t48, 48000) + + cmd = ["PQevalAudio", tmp_file_ref, tmp_file_eval] + + result = subprocess.run(cmd, capture_output=True) + if result.returncode != 0: + raise RuntimeError(f"Error running PQevalaudio: {result.stderr}") + + return result.stdout.decode("utf8") + + if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("ref_file", type=str) diff --git a/tests/codec_be_on_mr_nonselection/test_param_file.py b/tests/codec_be_on_mr_nonselection/test_param_file.py index 814a6441df7a74d55f8344b10962758ebafc395f..61f40072cd3913d007c4dbb677f8f8c931f36498 100644 --- a/tests/codec_be_on_mr_nonselection/test_param_file.py +++ b/tests/codec_be_on_mr_nonselection/test_param_file.py @@ -45,7 +45,6 @@ from tests.cmp_pcm import cmp_pcm from tests.conftest import DecoderFrontend, EncoderFrontend, parse_properties from tests.testconfig import PARAM_FILE - VALID_DEC_OUTPUT_CONF = [ "MONO", "STEREO", @@ -153,6 +152,7 @@ def test_param_file_tests( get_mld_lim, abs_tol, get_ssnr, + get_odg, ): enc_opts, dec_opts, sim_opts, eid_opts = param_file_test_dict[test_tag] @@ -351,6 +351,7 @@ def test_param_file_tests( abs_tol=abs_tol, allow_differing_lengths=allow_differing_lengths, get_ssnr=get_ssnr, + get_odg=get_odg, ) md_out_files = get_expected_md_files(ref_output_file, enc_split, output_config) diff --git a/tests/codec_be_on_mr_nonselection/test_sba_bs_dec_plc.py b/tests/codec_be_on_mr_nonselection/test_sba_bs_dec_plc.py index e188d4a11454ff08769f4477a2dcec76ff63af59..d191f87e10da9ef0d835d1045366410f70c545a2 100644 --- a/tests/codec_be_on_mr_nonselection/test_sba_bs_dec_plc.py +++ b/tests/codec_be_on_mr_nonselection/test_sba_bs_dec_plc.py @@ -94,6 +94,7 @@ def test_sba_plc_system( get_mld_lim, abs_tol, get_ssnr, + get_odg ): SID = 0 if dtx == "1" and ivas_br not in ["13200", "16400", "24400", "32000", "64000"]: @@ -135,6 +136,7 @@ def test_sba_plc_system( get_mld_lim=get_mld_lim, abs_tol=abs_tol, get_ssnr=get_ssnr, + get_odg=get_odg, ) @@ -161,6 +163,7 @@ def sba_dec_plc( get_mld_lim=0, abs_tol=0, get_ssnr=False, + get_odg=False, ): # ------------ run cmd ------------ @@ -219,6 +222,7 @@ def sba_dec_plc( mld_lim=get_mld_lim, abs_tol=abs_tol, get_ssnr=get_ssnr, + get_odg=get_odg, ) props = parse_properties(reason, cmp_result!=0, props_to_record) diff --git a/tests/codec_be_on_mr_nonselection/test_sba_bs_enc.py b/tests/codec_be_on_mr_nonselection/test_sba_bs_enc.py index ce99c55a272c9fa69459d34bea7903e126586965..3dd7e6dc6714c9d876735cff5273a9d52f726ed7 100644 --- a/tests/codec_be_on_mr_nonselection/test_sba_bs_enc.py +++ b/tests/codec_be_on_mr_nonselection/test_sba_bs_enc.py @@ -108,6 +108,7 @@ def test_pca_enc( decoder_only, abs_tol, get_ssnr, + get_odg, ): pca = True tag = tag + fs + "c" @@ -165,6 +166,7 @@ def test_pca_enc( pca=pca, abs_tol=abs_tol, get_ssnr=get_ssnr, + get_odg=get_odg, ) @@ -199,6 +201,7 @@ def test_sba_enc_system( decoder_only, abs_tol, get_ssnr, + get_odg, ): if dtx == "1" and ivas_br not in ["13200", "16400", "24400", "32000", "64000"]: # skip high bitrates for DTX until DTX issue is resolved @@ -276,6 +279,7 @@ def test_sba_enc_system( get_mld_lim=get_mld_lim, abs_tol=abs_tol, get_ssnr=get_ssnr, + get_odg=get_odg, ) @@ -301,6 +305,7 @@ def test_spar_hoa2_enc_system( decoder_only, abs_tol, get_ssnr, + get_odg, ): fs = "48" dtx = "0" @@ -355,6 +360,7 @@ def test_spar_hoa2_enc_system( get_mld_lim=get_mld_lim, abs_tol=abs_tol, get_ssnr=get_ssnr, + get_odg=get_odg, ) @@ -380,6 +386,7 @@ def test_spar_hoa3_enc_system( decoder_only, abs_tol, get_ssnr, + get_odg, ): fs = "48" dtx = "0" @@ -434,6 +441,7 @@ def test_spar_hoa3_enc_system( get_mld_lim=get_mld_lim, abs_tol=abs_tol, get_ssnr=get_ssnr, + get_odg=get_odg, ) @@ -463,6 +471,7 @@ def test_sba_enc_BWforce_system( decoder_only, abs_tol, get_ssnr, + get_odg, ): if dtx == "1" and ivas_br not in ["32000", "64000"]: # skip high bitrates for DTX until DTX issue is resolved @@ -523,6 +532,7 @@ def test_sba_enc_BWforce_system( get_mld_lim=get_mld_lim, abs_tol=abs_tol, get_ssnr=get_ssnr, + get_odg=get_odg, ) @@ -686,6 +696,7 @@ def sba_dec( pca=False, abs_tol=0, get_ssnr=False, + get_odg=False, ): # -------- run cmd ------------ # sampling rate to BW mapping @@ -751,6 +762,7 @@ def sba_dec( mld_lim=get_mld_lim, abs_tol=abs_tol, get_ssnr=get_ssnr, + get_odg=get_odg, ) props = parse_properties(reason, cmp_result!=0, props_to_record) diff --git a/tests/conftest.py b/tests/conftest.py index 24446c9678fa25d0475979f71ccd65aa21ea2e49..b75b3ba9979b4bafc1646d70e8e91b446fc0f374 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -42,7 +42,7 @@ import textwrap from pathlib import Path from subprocess import TimeoutExpired, run from typing import Optional, Union -from .constants import MLD_PATTERN, MAX_DIFF_PATTERN, SSNR_PATTERN +from .constants import MLD_PATTERN, MAX_DIFF_PATTERN, SSNR_PATTERN, ODG_PATTERN logger = logging.getLogger(__name__) USE_LOGGER_FOR_DBG = False # current tests do not make use of the logger feature @@ -180,6 +180,12 @@ def pytest_addoption(parser): help="Compute Segmental SNR (SSNR) between ref and dut output instead of just comparing for bitexactness", ) + parser.addoption( + "--odg", + action="store_true", + help="Get Objective Difference Grade for both conditions during comparison and report difference", + ) + parser.addoption( "--create_ref", action="store_true", @@ -259,6 +265,14 @@ def get_ssnr(request): return request.config.option.ssnr +@pytest.fixture(scope="session", autouse=True) +def get_odg(request): + """ + Return indication to compute ssnr during ref/dut comparison. + """ + return request.config.option.odg + + @pytest.fixture(scope="session") def abs_tol(request) -> int: """ @@ -566,11 +580,20 @@ class DecoderFrontend: raise ValueError(f'Wrong system "{system}"!') if not os.path.isfile(netsim_path): - raise FileNotFoundError(f"network simulator binary {netsim_path} not found!\n") + raise FileNotFoundError( + f"network simulator binary {netsim_path} not found!\n" + ) netsim_bitstream_path = input_bitstream_path.with_suffix(".netsimout") tracefile_path = input_bitstream_path.with_suffix(".netsimtrace") # TODO: need to check if the "1" works with every profile - netsim_command = [netsim_path, netsim_profile, input_bitstream_path, netsim_bitstream_path, tracefile_path, "1"] + netsim_command = [ + netsim_path, + netsim_profile, + input_bitstream_path, + netsim_bitstream_path, + tracefile_path, + "1", + ] print(netsim_command) try: run(netsim_command, check=True, cwd=run_dir) @@ -810,12 +833,14 @@ def pytest_configure(config): @pytest.fixture(scope="session") -def props_to_record(request, get_mld, get_ssnr) -> str: +def props_to_record(request, get_mld, get_ssnr, get_odg) -> str: props = ["MAXIMUM ABS DIFF"] if get_mld: props.append("MLD") if get_ssnr: props.append("SSNR") + if get_odg: + props.append("ODG") return props @@ -845,6 +870,12 @@ def parse_properties(text_to_parse: str, output_differs: bool, props_to_record: min_ssnr_channel = ssnrs.index(min_ssnr) props["MIN_SSNR"] = min_ssnr props["MIN_SSNR_CHANNEL"] = min_ssnr_channel + elif prop == "ODG": + odgs = re.findall(ODG_PATTERN, text_to_parse) + min_odg = min(odgs) + min_odg_channel = odgs.index(min_odg) + props["MIN_ODG"] = min_odg + props["MIN_ODG_CHANNEL"] = min_odg_channel return props diff --git a/tests/constants.py b/tests/constants.py index 0f985d0b567057b5ad7cd074fd4c7ebb1502ddf5..e6ea1c1589fbfb9e16d71776737599ac0bfa25e5 100644 --- a/tests/constants.py +++ b/tests/constants.py @@ -7,4 +7,6 @@ TESTV_DIR = SCRIPTS_DIR.joinpath("testv") # regex patterns for parsing the output from cmp_pcm -> mainly for BASOP ci MLD_PATTERN = r"MLD: ([\d\.]*)" MAX_DIFF_PATTERN = r"MAXIMUM ABS DIFF: (\d*)" +ODG_PATTERN_PQEVALAUDIO = r"Objective Difference Grade: (-*\d*\.\d*)" +ODG_PATTERN = r"ODG: (-*\d*\.\d*)" SSNR_PATTERN = r"Channel \d* SSNR: (nan|[+-]*inf|[\d\.]*)"