diff --git a/lib_com/ivas_masa_com.c b/lib_com/ivas_masa_com.c index f4659907c0ee9cc29d6a4534d2a0b81c0ceca131..c0ace55715d870f69fadf2a56db874f07c5a5f32 100644 --- a/lib_com/ivas_masa_com.c +++ b/lib_com/ivas_masa_com.c @@ -979,6 +979,113 @@ uint16_t index_theta_phi_16( return idx_sph; } +#ifdef IVAS_FLOAT_FIXED +/*------------------------------------------------------------------------- + * index_theta_phi_16_fx() + * + * + *------------------------------------------------------------------------*/ + +/*! r: output index for direction */ +UWord16 index_theta_phi_16_fx( + Word32 *p_theta, /* i/o: input elevation to be indexed */ + Word32 *p_phi, /* i/o: input azimuth to be indexed */ + const SPHERICAL_GRID_DATA *gridData /* i : generated grid data */ +) +{ + float abs_theta; + int16_t sign_th, id_phi, id_th; + uint16_t idx_sph; + uint16_t cum_n; + float theta_hat, phi_hat; + float theta, phi; + + float *p_theta_flt, *p_phi_flt; + float p_theta_flt_tmp = fix_to_float(*p_theta, Q22); + float p_phi_flt_tmp = fix_to_float(*p_phi, Q22); + p_theta_flt = &p_theta_flt_tmp; + p_phi_flt = &p_phi_flt_tmp; + + theta = *p_theta_flt; + phi = *p_phi_flt; + phi_hat = 0; + theta_hat = 0; + phi = phi + 180; + + if ( theta < 0 ) + { + abs_theta = -theta; + sign_th = -1; + } + else + { + abs_theta = theta; + sign_th = 1; + } + + id_th = quantize_theta_masa( abs_theta, gridData->no_theta, &theta_hat ); + if ( gridData->no_theta > 1 ) + { + if ( gridData->no_phi[id_th] > 1 ) + { + id_phi = quantize_phi_masa( phi, ( id_th % 2 == 1 ), &phi_hat, gridData->no_phi[id_th] ); + } + else + { + id_phi = 0; + phi_hat = 180; + } + } + else + { + id_phi = quantize_phi_masa( phi, ( id_th % 2 == 1 ), &phi_hat, gridData->no_phi[id_th] ); + } + *p_theta_flt = sign_th * theta_hat; + *p_phi_flt = phi_hat - 180; + + /* Starting from Equator, alternating positive and negative */ + if ( id_th == 0 ) + { + idx_sph = id_phi; + } + else + { + if ( id_th == gridData->no_theta - 1 ) + { + idx_sph = 65534 + ( sign_th < 0 ); + } + else + { + theta = MASA_ANGLE_AT_EQUATOR * (float) ( id_th + 0.5f ); + if ( id_th == 1 ) + { + cum_n = 2 * (uint16_t) ceilf( MASA_NTOT2_FAC * ( sinf( theta ) - MASA_ASIN_OFFSET ) ); + } + else + { + cum_n = 2 * (uint16_t) roundf( MASA_NTOT2_FAC * ( sinf( theta ) - MASA_ASIN_OFFSET ) ); + } + + cum_n += gridData->no_phi[0]; + + if ( sign_th > 0 ) + { + cum_n -= 2 * gridData->no_phi[id_th]; + } + else + { + cum_n -= gridData->no_phi[id_th]; + } + idx_sph = cum_n + id_phi; + } + } + + *p_theta = float_to_fix(*p_theta_flt, Q22); + *p_phi = float_to_fix(*p_phi_flt, Q22); + + return idx_sph; +} +#endif /*------------------------------------------------------------------------- * quantize_phi_masa() @@ -1373,8 +1480,8 @@ void deindex_sph_idx_fx( } } } - *theta_fx = theta * ( 1 << 22 ); - *phi_fx = phi * ( 1 << 22 ); + *theta_fx = (Word32)(theta * ( 1 << 22 )); + *phi_fx = (Word32)(phi * ( 1 << 22 )); return; } @@ -1584,6 +1691,50 @@ void ivas_omasa_modify_masa_energy_ratios( return; } +#ifdef IVAS_FLOAT_FIXED +/*--------------------------------------------------------------- + * ivas_omasa_modify_masa_energy_ratios_fx() + * + * Updates energy ratios by taking into account the MASA content contribution + * to the total audio scene + *---------------------------------------------------------------*/ + +void ivas_omasa_modify_masa_energy_ratios_fx( + IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */ + const Word32 masa_to_total_energy_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_MAXIMUM_CODING_SUBBANDS] /* Q30 */ ) +{ + Word16 i, m, d, b; + + FOR( m = 0; m < MAX_PARAM_SPATIAL_SUBFRAMES; m++ ) + { + IF( EQ_16( hQMetaData->q_direction[0].cfg.nblocks, 1 ) ) + { + i = 0; + move16(); + } + ELSE + { + i = m; + move16(); + } + + FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ ) + { + FOR( d = 0; d < hQMetaData->no_directions; d++ ) + { + hQMetaData->q_direction[d].band_data[b].energy_ratio_fx[m] = L_shl( + Mpy_32_32( hQMetaData->q_direction[d].band_data[b].energy_ratio_fx[m], + masa_to_total_energy_ratio_fx[i][b] ), + 1 ); // Q30 + Q30 - 31 = Q29 + 1 = Q30 + move32(); + } + } + } + + return; +} +#endif + /*--------------------------------------------------------------- * distribute_evenly_ism() @@ -1722,3 +1873,55 @@ int32_t calculate_cpe_brate_MASA_ISM( return cpe_brate; } + + +#ifdef IVAS_FLOAT_FIXED +/*--------------------------------------------------------------- + * calculate_cpe_brate_MASA_ISM_fx() + * + * Calculates bitrate for MASA_ISM mode that is not used for separated objects, + * * but for the CPE part (metadata included) + *---------------------------------------------------------------*/ + +/*! r: CPE bitrate value */ +Word32 calculate_cpe_brate_MASA_ISM_fx( + const ISM_MODE ism_mode, /* i : ism mode */ + const Word32 ivas_total_brate, /* i : IVAS total bitrate */ + const Word16 nchan_ism /* i : number of objects */ +) +{ + Word32 cpe_brate; + Word16 k, sce_id; + + k = 0; + move16(); + + WHILE ( LT_16(k, SIZE_IVAS_BRATE_TBL) && NE_32(ivas_total_brate, ivas_brate_tbl[k]) ) + { + k = add(k, 1); + } + + IF ( EQ_16(ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ) || EQ_16(ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ) ) + { + cpe_brate = L_sub(ivas_total_brate, sep_object_brate[k - 2][0]); /* take data from the first column */ + } + ELSE IF ( EQ_16(ism_mode, ISM_MASA_MODE_DISC) ) + { + cpe_brate = ivas_total_brate; + move32(); + + FOR ( sce_id = 0; sce_id < nchan_ism; sce_id++ ) + { + cpe_brate = L_sub(cpe_brate, sep_object_brate[k - 2][nchan_ism - 1]); + } + } + ELSE + { + cpe_brate = ivas_total_brate; + move32(); + } + + return cpe_brate; +} + +#endif diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 6cf225e905aac568f2a71edc10f28c994afae00f..981f5f05530bb3ced748295dd4aac475674cb6c1 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -120,6 +120,29 @@ Word16 valid_ratio_index_fx( const Word16 len /* i : vector length */ ); +UWord16 index_theta_phi_16_fx( + Word32 *p_theta, /* i/o: input elevation to be indexed */ + Word32 *p_phi, /* i/o: input azimuth to be indexed */ + const SPHERICAL_GRID_DATA *gridData /* i : generated grid data */ +); + +ivas_error ivas_masa_decode_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ + Decoder_State *st, /* i/o: decoder state structure */ + Word16 *nb_bits_read /* o : number of bits read */ +); + +void ivas_omasa_modify_masa_energy_ratios_fx( + IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */ + const Word32 masa_to_total_energy_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_MAXIMUM_CODING_SUBBANDS] // Q30 +); + +Word32 calculate_cpe_brate_MASA_ISM_fx( + const ISM_MODE ism_mode, /* i : ism mode */ + const Word32 ivas_total_brate, /* i : IVAS total bitrate */ + const Word16 nchan_ism /* i : number of objects */ +); + Word16 ivas_jbm_dec_get_num_tc_channels_fx( Decoder_Struct *st_ivas /* i : IVAS decoder handle */ ); diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index e2f8803328a032c9be66dd1819cbc73fde4e04d6..9e7e234dbe2186630bfd9ba5e0ba782c8f44f756 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -353,10 +353,117 @@ ivas_error ivas_jbm_dec_tc( { st = ( st_ivas->nSCE > 0 ) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0]; +#ifdef IVAS_FLOAT_FIXED + // Float to fix conversion starts here. + FOR( Word32 l = 0; l < st_ivas->nchan_ism; l++ ) + { + st_ivas->hMasaIsmData->q_azimuth_old_fx[l] = float_to_fix( st_ivas->hMasaIsmData->q_azimuth_old[l], Q22 ); + } + IF( st_ivas->hMasa->hMasaLfeSynth != NULL ) + { + FOR( Word32 j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + st_ivas->hMasa->hMasaLfeSynth->lfeToTotalEnergyRatio_fx[j] = float_to_fix16( st_ivas->hMasa->hMasaLfeSynth->lfeToTotalEnergyRatio[j], Q14 ); + } + } + IF( st_ivas->hSpatParamRendCom != NULL ) + { + FOR( Word16 i = 0; i < st_ivas->hSpatParamRendCom->dirac_md_buffer_length; i++ ) + { + FOR( Word16 j = 0; j < st_ivas->hSpatParamRendCom->num_freq_bands; j++ ) + { + st_ivas->hSpatParamRendCom->diffuseness_vector_fx[i][j] = float_to_fix( st_ivas->hSpatParamRendCom->diffuseness_vector[i][j], 30 ); + st_ivas->hSpatParamRendCom->energy_ratio1_fx[i][j] = float_to_fix( st_ivas->hSpatParamRendCom->energy_ratio1[i][j], 30 ); + IF( EQ_16( st_ivas->hQMetaData->no_directions, 2 ) ) + { + st_ivas->hSpatParamRendCom->energy_ratio2_fx[i][j] = float_to_fix( st_ivas->hSpatParamRendCom->energy_ratio2[i][j], 30 ); + st_ivas->hSpatParamRendCom->spreadCoherence2_fx[i][j] = float_to_fix16( st_ivas->hSpatParamRendCom->spreadCoherence2[i][j], 15 ); + } + st_ivas->hSpatParamRendCom->surroundingCoherence_fx[i][j] = float_to_fix16( st_ivas->hSpatParamRendCom->surroundingCoherence[i][j], 15 ); + st_ivas->hSpatParamRendCom->spreadCoherence_fx[i][j] = float_to_fix16( st_ivas->hSpatParamRendCom->spreadCoherence[i][j], 15 ); + } + } + } + // Float to fix conversion ends here. + + IF( ( error = ivas_masa_decode_fx( st_ivas, st, &nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + + // Fix to float conversion starts here. + IF( st_ivas->hSpatParamRendCom != NULL ) + { + FOR( Word16 i = 0; i < st_ivas->hSpatParamRendCom->dirac_md_buffer_length; i++ ) + { + FOR( Word16 j = 0; j < st_ivas->hSpatParamRendCom->num_freq_bands; j++ ) + { + st_ivas->hSpatParamRendCom->energy_ratio1[i][j] = fix_to_float( st_ivas->hSpatParamRendCom->energy_ratio1_fx[i][j], 30 ); + st_ivas->hSpatParamRendCom->diffuseness_vector[i][j] = fix_to_float( st_ivas->hSpatParamRendCom->diffuseness_vector_fx[i][j], 30 ); + IF( EQ_16( st_ivas->hQMetaData->no_directions, 2 ) ) + { + st_ivas->hSpatParamRendCom->energy_ratio2[i][j] = fix_to_float( st_ivas->hSpatParamRendCom->energy_ratio2_fx[i][j], 30 ); + st_ivas->hSpatParamRendCom->spreadCoherence2[i][j] = fix_to_float( st_ivas->hSpatParamRendCom->spreadCoherence2_fx[i][j], 15 ); + } + st_ivas->hSpatParamRendCom->surroundingCoherence[i][j] = fix_to_float( st_ivas->hSpatParamRendCom->surroundingCoherence_fx[i][j], 15 ); + st_ivas->hSpatParamRendCom->spreadCoherence[i][j] = fix_to_float( st_ivas->hSpatParamRendCom->spreadCoherence_fx[i][j], 15 ); + } + } + } + FOR( Word16 d = 0; d < max( st_ivas->hMasa->config.numberOfDirections, st_ivas->hQMetaData->no_directions ); d++ ) + { + FOR( Word16 j = 0; j < max( st_ivas->hMasa->config.numCodingBands, st_ivas->hQMetaData->q_direction[0].cfg.nbands ); j++ ) + { + FOR( Word16 k = 0; k < MAX_PARAM_SPATIAL_SUBFRAMES; k++ ) + { + st_ivas->hQMetaData->q_direction[d].band_data[j].elevation[k] = fix_to_float( st_ivas->hQMetaData->q_direction[d].band_data[j].elevation_fx[k], Q22 ); + st_ivas->hQMetaData->q_direction[d].band_data[j].azimuth[k] = fix_to_float( st_ivas->hQMetaData->q_direction[d].band_data[j].azimuth_fx[k], Q22 ); + st_ivas->hQMetaData->q_direction[d].band_data[j].energy_ratio[k] = fix_to_float( st_ivas->hQMetaData->q_direction[d].band_data[j].energy_ratio_fx[k], Q30 ); + } + } + } + FOR( Word32 l = 0; l < st_ivas->nchan_ism; l++ ) + { + st_ivas->hMasaIsmData->q_azimuth_old[l] = fix_to_float( st_ivas->hMasaIsmData->q_azimuth_old_fx[l], Q22 ); + } + IF( st_ivas->hMasaIsmData != NULL ) + { + FOR( Word32 k = 0; k < MAX_PARAM_SPATIAL_SUBFRAMES; k++ ) + { + FOR( Word32 j = 0; j < MASA_FREQUENCY_BANDS; j++ ) + { + st_ivas->hMasaIsmData->masa_to_total_energy_ratio[k][j] = fix_to_float( st_ivas->hMasaIsmData->masa_to_total_energy_ratio_fx[k][j], Q30 ); + } + } + } + st_ivas->hMasa->data.dir_decode_quality = fix16_to_float( st_ivas->hMasa->data.dir_decode_quality_fx, Q14 ); + IF( st_ivas->hMasa->hMasaLfeSynth != NULL ) + { + for ( int j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + st_ivas->hMasa->hMasaLfeSynth->lfeToTotalEnergyRatio[j] = fix16_to_float( st_ivas->hMasa->hMasaLfeSynth->lfeToTotalEnergyRatio_fx[j], Q14 ); + } + } + IF( st_ivas->hSpatParamRendCom != NULL ) + { + FOR( Word16 i = 0; i < st_ivas->hSpatParamRendCom->numIsmDirections; i++ ) + { + FOR( Word16 block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ ) + { + FOR(Word16 b = 0; b < st_ivas->hSpatParamRendCom->num_freq_bands; b++) + { + st_ivas->hMasaIsmData->energy_ratio_ism[i][block][b] = fix_to_float(st_ivas->hMasaIsmData->energy_ratio_ism_fx[i][block][b], Q30); + } + } + } + } + // Fixed to float conversion ends here. +#else if ( ( error = ivas_masa_decode( st_ivas, st, &nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) { return error; } +#endif if ( output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) { @@ -584,7 +691,11 @@ ivas_error ivas_jbm_dec_tc( } /* MASA metadata decoding */ +#ifdef IVAS_FLOAT_FIXED + IF ( ( error = ivas_masa_decode( st_ivas, st_ivas->hCPE[0]->hCoreCoder[0], &nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_masa_decode( st_ivas, st_ivas->hCPE[0]->hCoreCoder[0], &nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -1115,11 +1226,117 @@ ivas_error ivas_jbm_dec_tc( } /* read McMASA parameters from the bitstream */ - if ( ( error = ivas_masa_decode( st_ivas, st, &nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) +#ifdef IVAS_FLOAT_FIXED + // Float to fix conversion starts here. + FOR( Word32 l = 0; l < st_ivas->nchan_ism; l++ ) + { + st_ivas->hMasaIsmData->q_azimuth_old_fx[l] = float_to_fix( st_ivas->hMasaIsmData->q_azimuth_old[l], Q22 ); + } + IF( st_ivas->hMasa->hMasaLfeSynth != NULL ) + { + FOR( Word32 j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + st_ivas->hMasa->hMasaLfeSynth->lfeToTotalEnergyRatio_fx[j] = float_to_fix16( st_ivas->hMasa->hMasaLfeSynth->lfeToTotalEnergyRatio[j], Q14 ); + } + } + IF( st_ivas->hSpatParamRendCom != NULL ) + { + FOR( Word16 i = 0; i < st_ivas->hSpatParamRendCom->dirac_md_buffer_length; i++ ) + { + FOR( Word16 j = 0; j < st_ivas->hSpatParamRendCom->num_freq_bands; j++ ) + { + st_ivas->hSpatParamRendCom->diffuseness_vector_fx[i][j] = float_to_fix( st_ivas->hSpatParamRendCom->diffuseness_vector[i][j], 30 ); + st_ivas->hSpatParamRendCom->energy_ratio1_fx[i][j] = float_to_fix( st_ivas->hSpatParamRendCom->energy_ratio1[i][j], 30 ); + IF( EQ_16( st_ivas->hQMetaData->no_directions, 2 ) ) + { + st_ivas->hSpatParamRendCom->energy_ratio2_fx[i][j] = float_to_fix( st_ivas->hSpatParamRendCom->energy_ratio2[i][j], 30 ); + st_ivas->hSpatParamRendCom->spreadCoherence2_fx[i][j] = float_to_fix16( st_ivas->hSpatParamRendCom->spreadCoherence2[i][j], 15 ); + } + st_ivas->hSpatParamRendCom->surroundingCoherence_fx[i][j] = float_to_fix16( st_ivas->hSpatParamRendCom->surroundingCoherence[i][j], 15 ); + st_ivas->hSpatParamRendCom->spreadCoherence_fx[i][j] = float_to_fix16( st_ivas->hSpatParamRendCom->spreadCoherence[i][j], 15 ); + } + } + } + // Float to fix conversion ends here. + + IF( ( error = ivas_masa_decode_fx( st_ivas, st, &nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) { return error; } + // Fix to float conversion starts here. + IF( st_ivas->hSpatParamRendCom != NULL ) + { + FOR( Word16 i = 0; i < st_ivas->hSpatParamRendCom->dirac_md_buffer_length; i++ ) + { + FOR( Word16 j = 0; j < st_ivas->hSpatParamRendCom->num_freq_bands; j++ ) + { + st_ivas->hSpatParamRendCom->energy_ratio1[i][j] = fix_to_float( st_ivas->hSpatParamRendCom->energy_ratio1_fx[i][j], 30 ); + st_ivas->hSpatParamRendCom->diffuseness_vector[i][j] = fix_to_float( st_ivas->hSpatParamRendCom->diffuseness_vector_fx[i][j], 30 ); + IF( EQ_16( st_ivas->hQMetaData->no_directions, 2 ) ) + { + st_ivas->hSpatParamRendCom->energy_ratio2[i][j] = fix_to_float( st_ivas->hSpatParamRendCom->energy_ratio2_fx[i][j], 30 ); + st_ivas->hSpatParamRendCom->spreadCoherence2[i][j] = fix_to_float( st_ivas->hSpatParamRendCom->spreadCoherence2_fx[i][j], 15 ); + } + st_ivas->hSpatParamRendCom->surroundingCoherence[i][j] = fix_to_float( st_ivas->hSpatParamRendCom->surroundingCoherence_fx[i][j], 15 ); + st_ivas->hSpatParamRendCom->spreadCoherence[i][j] = fix_to_float( st_ivas->hSpatParamRendCom->spreadCoherence_fx[i][j], 15 ); + } + } + } + FOR( Word16 d = 0; d < max( st_ivas->hMasa->config.numberOfDirections, st_ivas->hQMetaData->no_directions ); d++ ) + { + FOR( Word16 j = 0; j < max( st_ivas->hMasa->config.numCodingBands, st_ivas->hQMetaData->q_direction[0].cfg.nbands ); j++ ) + { + FOR( Word16 k = 0; k < MAX_PARAM_SPATIAL_SUBFRAMES; k++ ) + { + st_ivas->hQMetaData->q_direction[d].band_data[j].elevation[k] = fix_to_float( st_ivas->hQMetaData->q_direction[d].band_data[j].elevation_fx[k], Q22 ); + st_ivas->hQMetaData->q_direction[d].band_data[j].azimuth[k] = fix_to_float( st_ivas->hQMetaData->q_direction[d].band_data[j].azimuth_fx[k], Q22 ); + st_ivas->hQMetaData->q_direction[d].band_data[j].energy_ratio[k] = fix_to_float( st_ivas->hQMetaData->q_direction[d].band_data[j].energy_ratio_fx[k], Q30 ); + } + } + } + FOR( Word32 l = 0; l < st_ivas->nchan_ism; l++ ) + { + st_ivas->hMasaIsmData->q_azimuth_old[l] = fix_to_float( st_ivas->hMasaIsmData->q_azimuth_old_fx[l], Q22 ); + } + IF( st_ivas->hMasaIsmData != NULL ) + { + FOR( Word32 k = 0; k < MAX_PARAM_SPATIAL_SUBFRAMES; k++ ) + { + FOR( Word32 j = 0; j < MASA_FREQUENCY_BANDS; j++ ) + { + st_ivas->hMasaIsmData->masa_to_total_energy_ratio[k][j] = fix_to_float( st_ivas->hMasaIsmData->masa_to_total_energy_ratio_fx[k][j], Q30 ); + } + } + } + st_ivas->hMasa->data.dir_decode_quality = fix16_to_float( st_ivas->hMasa->data.dir_decode_quality_fx, Q14 ); + IF( st_ivas->hMasa->hMasaLfeSynth != NULL ) + { + for ( int j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + st_ivas->hMasa->hMasaLfeSynth->lfeToTotalEnergyRatio[j] = fix16_to_float( st_ivas->hMasa->hMasaLfeSynth->lfeToTotalEnergyRatio_fx[j], Q14 ); + } + } + IF( st_ivas->hSpatParamRendCom != NULL ) + { + FOR( Word16 i = 0; i < st_ivas->hSpatParamRendCom->numIsmDirections; i++ ) + { + FOR( Word16 block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ ) + { + FOR( Word16 b = 0; b < st_ivas->hSpatParamRendCom->num_freq_bands; b++ ) + { + st_ivas->hMasaIsmData->energy_ratio_ism[i][block][b] = fix_to_float( st_ivas->hMasaIsmData->energy_ratio_ism_fx[i][block][b], Q30 ); + } + } + } + } + // Fixed to float conversion ends here. +#else + if ( ( error = ivas_masa_decode( st_ivas, st, &nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif if ( st_ivas->hOutSetup.separateChannelEnabled ) { /* Decode the transport audio signals */ diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index f25a28e84a147609d71ba8bb0c6c277397ca2429..fc74a9d274228fc259ad0061cac82478f1cb5e4a 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -62,12 +62,24 @@ static Word16 rint_fx( Word32 num ); static void index_16bits( IVAS_QMETADATA_HANDLE hQMetaData, SPHERICAL_GRID_DATA *Sph_Grid16 ); +#ifdef IVAS_FLOAT_FIXED +static void index_16bits_fx( IVAS_QMETADATA_HANDLE hQMetaData, SPHERICAL_GRID_DATA *Sph_Grid16 ); +#endif static void create_masa_ext_out_meta( MASA_DECODER *hMasa, IVAS_QMETADATA_HANDLE hQMetaData, const int16_t nchan_transport ); +#ifdef IVAS_FLOAT_FIXED +static void create_masa_ext_out_meta_fx( MASA_DECODER *hMasa, IVAS_QMETADATA_HANDLE hQMetaData, const Word16 nchan_transport ); +#endif static void replicate_subframes( IVAS_QMETADATA_HANDLE hQMetaData ); +#ifdef IVAS_FLOAT_FIXED +static void replicate_subframes_fx( IVAS_QMETADATA_HANDLE hQMetaData ); +#endif static void restore_lowbitrate_masa( IVAS_QMETADATA_HANDLE hQMetaData, const int16_t low_bitrate_mode, const int16_t numCodingBands ); +#ifdef IVAS_FLOAT_FIXED +static void restore_lowbitrate_masa_fx( IVAS_QMETADATA_HANDLE hQMetaData, const Word16 low_bitrate_mode, const Word16 numCodingBands ); +#endif static ivas_error init_lfe_synth_data( Decoder_Struct *st_ivas, MASA_DECODER_HANDLE hMasa ); @@ -109,6 +121,7 @@ static void read_ism_ratio_index( int16_t ratio_ism_idx[MASA_FREQUENCY_BANDS][MA static void read_ism_ratio_index_fx( Word16 ratio_ism_idx[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], const Word16 nchan_ism, const Word16 numCodingBands, const Word16 sf, Word16 ratio_ism_idx_prev_sf[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], UWord16 *bit_stream, Word16 *next_bit_pos, const Word32 *masa_to_total_energy_ratio_fx, const Word16 idx_sep_obj, Word16 *num_zeros ); #endif + /*-----------------------------------------------------------------------* * ivas_masa_decode() * @@ -508,7 +521,21 @@ ivas_error ivas_masa_decode( if ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode != ISM_MASA_MODE_DISC && st_ivas->ism_mode != ISM_MASA_MODE_MASA_ONE_OBJ ) { /* Modify spatial metadata based on the MASA-to-total energy ratios */ +#ifdef IVAS_FLOAT_FIXED + ivas_omasa_modify_masa_energy_ratios_fx( hQMetaData, st_ivas->hMasaIsmData->masa_to_total_energy_ratio_fx ); + for (int k = 0; k < hQMetaData->no_directions; k++) + { + for (int j = 0; j < hQMetaData->q_direction[0].cfg.nbands; j++) + { + for (int m = 0; m < MAX_PARAM_SPATIAL_SUBFRAMES; m++) + { + hQMetaData->q_direction[k].band_data[j].energy_ratio[m] = fix_to_float(hQMetaData->q_direction[k].band_data[j].energy_ratio_fx[m], Q30); + } + } + } +#else ivas_omasa_modify_masa_energy_ratios( hQMetaData, st_ivas->hMasaIsmData->masa_to_total_energy_ratio ); +#endif } /* Get direction decoding quality. EC 1 and 2 are handled by the default value. */ @@ -755,45 +782,680 @@ ivas_error ivas_masa_decode( if ( ivas_total_brate <= IVAS_SID_5k2 ) { - st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 0; + st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 0; + } + } + } + else + { + if ( ivas_format == MASA_FORMAT && st_ivas->nCPE == 1 && st_ivas->hCPE[0]->hStereoDft != NULL && st_ivas->hCPE[0]->hStereoDft->hConfig != NULL ) + { + st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = ivas_total_brate < MASA_STEREO_MIN_BITRATE ? 1 : 0; + + if ( ivas_total_brate <= IVAS_SID_5k2 ) + { + st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 0; + } + } + } + + if ( ivas_format == MASA_FORMAT && st_ivas->nCPE == 1 ) + { + st_ivas->hCPE[0]->hCoreCoder[0]->masa_sid_format = 0; + + if ( st_ivas->hDecoderConfig->last_ivas_total_brate <= IVAS_SID_5k2 ) + { + st_ivas->hCPE[0]->hCoreCoder[0]->masa_sid_format = 1; + + if ( ivas_total_brate >= IVAS_SID_5k2 ) + { + st_ivas->hCPE[0]->element_brate = ivas_total_brate; + } + } + } + + if ( ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) && st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) + { + create_masa_ext_out_meta( hMasa, hQMetaData, st_ivas->nchan_transport ); + } + + return error /* *nb_bits_read*/; +} + +#ifdef IVAS_FLOAT_FIXED +/*-----------------------------------------------------------------------* + * ivas_masa_decode_fx() + * + * MASA metadata decoder + *-----------------------------------------------------------------------*/ + +ivas_error ivas_masa_decode_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ + Decoder_State *st, /* i/o: decoder state structure with bitstream */ + Word16 *nb_bits_read /* o : number of bits read */ +) +{ + UWord16 byteBuffer; + Word16 next_bit_pos_orig; + Word32 masa_brate, ivas_total_brate; + MASA_DECODER_HANDLE hMasa; + IVAS_QMETADATA_HANDLE hQMetaData; + IVAS_FORMAT ivas_format; + Word16 low_bitrate_mode, tmp_elem_mode; + ivas_error error; + Word16 obj; + Word16 i, ch, ism_imp; + Word16 dirac_bs_md_write_idx; + Word32 masa_total_brate; + + dirac_bs_md_write_idx = 0; + move16(); + ism_imp = 0; + move16(); + + error = IVAS_ERR_OK; + move16(); + ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; + move32(); + + low_bitrate_mode = -1; /* This means that LBR mode is not used. */ + move16(); + + test(); + test(); + IF( st_ivas->hOutSetup.separateChannelEnabled || EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) + { + masa_brate = st_ivas->hCPE[0]->element_brate; + move32(); + } + ELSE + { + masa_brate = ivas_total_brate; + move32(); + } + + hMasa = st_ivas->hMasa; + hQMetaData = st_ivas->hQMetaData; + ivas_format = st_ivas->ivas_format; + + hMasa->data.dir_decode_quality_fx = ONE_IN_Q14; /* Set to default of max quality */ + move16(); + + hQMetaData->is_masa_ivas_format = 1; + + *nb_bits_read = 0; + move16(); + + next_bit_pos_orig = st->next_bit_pos; + move16(); + + Word16 tmp, tmp_e; + tmp = BASOP_Util_Divide3232_Scale( masa_brate, FRAMES_PER_SEC, &tmp_e ); + tmp = shr( tmp, 15 - tmp_e ); + assert( masa_brate / FRAMES_PER_SEC == tmp ); + + IF( EQ_32( masa_brate, IVAS_SID_5k2 ) ) + { + // st->next_bit_pos = (int16_t) ( ( masa_brate / FRAMES_PER_SEC ) - 1 - SID_FORMAT_NBITS ); + st->next_bit_pos = sub( sub( tmp, 1 ), SID_FORMAT_NBITS ); + } + ELSE + { + // st->next_bit_pos = (int16_t) ( ( masa_brate / FRAMES_PER_SEC ) - 1 ); + st->next_bit_pos = sub( tmp, 1 ); + } + + test(); + test(); + test(); + IF( EQ_16( st->bfi, 0 ) && GT_32( ivas_total_brate, IVAS_SID_5k2 ) ) + { + test(); + // IF ( !( ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) ) + IF( NE_16( ivas_format, MC_FORMAT ) || NE_16( st_ivas->mc_mode, MC_MODE_MCMASA ) ) + { + IF( NE_16( ivas_format, MASA_ISM_FORMAT ) ) + { + /* number of transport channels is always 2 for MASA_ISM format */ + /* the number of MASA transport channels was read in ivas_dec_setup() */ + st->next_bit_pos = sub( st->next_bit_pos, MASA_TRANSP_BITS ); + *nb_bits_read = add( *nb_bits_read, MASA_TRANSP_BITS ); + } + + IF( EQ_16( ivas_format, MASA_ISM_FORMAT ) && NE_16( st_ivas->ism_mode, ISM_MODE_NONE ) ) + { + /* the number of objects was read */ + st->next_bit_pos = sub( st->next_bit_pos, NO_BITS_MASA_ISM_NO_OBJ ); + *nb_bits_read = add( *nb_bits_read, NO_BITS_MASA_ISM_NO_OBJ ); + + IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) ) + { + /* read index of separated object */ + /* nchan_ism should be > 1*/ + byteBuffer = st->bit_stream[( st->next_bit_pos )--]; + *nb_bits_read = add( *nb_bits_read, 1 ); + st_ivas->hMasaIsmData->idx_separated_ism = 2 * byteBuffer + st->bit_stream[( st->next_bit_pos )--]; + *nb_bits_read = add( *nb_bits_read, 1 ); + } + ELSE + { + st_ivas->hMasaIsmData->idx_separated_ism = -1; + move16(); + } + + /* read ISM importance flag (one per object) */ + IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) ) + { + ism_imp = 0; + move16(); + + FOR( i = 0; i < ISM_METADATA_FLAG_BITS; i++ ) + { + byteBuffer = st->bit_stream[( st->next_bit_pos )--]; + *nb_bits_read = add( *nb_bits_read, 1 ); + ism_imp = add( shl( ism_imp, 1 ), (Word16) byteBuffer ); + } + st_ivas->hIsmMetaData[0]->ism_imp = ism_imp; + move16(); + } + + IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) ) + { + ism_imp = 0; + move16(); + FOR( i = 0; i < ISM_METADATA_FLAG_BITS; i++ ) + { + byteBuffer = st->bit_stream[( st->next_bit_pos )--]; + *nb_bits_read = add( *nb_bits_read, 1 ); + ism_imp = add( shl( ism_imp, 1 ), (Word16) byteBuffer ); + } + st_ivas->hIsmMetaData[0]->ism_imp = ism_imp; + move16(); + + /* reset */ + st_ivas->hIsmMetaData[0]->ism_md_null_flag = 0; + move16(); + st_ivas->hIsmMetaData[0]->ism_md_lowrate_flag = 0; + move16(); + IF( EQ_16( st_ivas->hIsmMetaData[0]->ism_imp, ISM_NO_META ) ) + { + /* read flags */ + st_ivas->hIsmMetaData[0]->ism_md_null_flag = st->bit_stream[( st->next_bit_pos )--]; + *nb_bits_read = add( *nb_bits_read, ISM_METADATA_MD_FLAG_BITS ); + st_ivas->hIsmMetaData[0]->ism_md_lowrate_flag = st->bit_stream[( st->next_bit_pos )--]; + *nb_bits_read = add( *nb_bits_read, ISM_METADATA_INACTIVE_FLAG_BITS ); + } + } + ELSE IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) + { + FOR( ch = 0; ch < st_ivas->nchan_ism; ch++ ) + { + ism_imp = 0; + move16(); + FOR( i = 0; i < ISM_METADATA_FLAG_BITS; i++ ) + { + byteBuffer = st->bit_stream[( st->next_bit_pos )--]; + *nb_bits_read = add( *nb_bits_read, 1 ); + ism_imp = add( shl( ism_imp, 1 ), (Word16) byteBuffer ); + } + st_ivas->hIsmMetaData[ch]->ism_imp = ism_imp; + move16(); + + /* reset */ + st_ivas->hIsmMetaData[ch]->ism_md_null_flag = 0; + move16(); + st_ivas->hIsmMetaData[ch]->ism_md_lowrate_flag = 0; + move16(); + IF( EQ_16( st_ivas->hIsmMetaData[ch]->ism_imp, ISM_NO_META ) ) + { + /* read flags */ + st_ivas->hIsmMetaData[ch]->ism_md_null_flag = st->bit_stream[( st->next_bit_pos )--]; + *nb_bits_read = add( *nb_bits_read, ISM_METADATA_MD_FLAG_BITS ); + st_ivas->hIsmMetaData[ch]->ism_md_lowrate_flag = st->bit_stream[( st->next_bit_pos )--]; + *nb_bits_read = add( *nb_bits_read, ISM_METADATA_INACTIVE_FLAG_BITS ); + } + } + st_ivas->flag_omasa_brate = 0; + move16(); + IF( GE_16( st_ivas->nchan_ism, 3 ) && EQ_32( ivas_total_brate, IVAS_128k ) ) + { + st_ivas->flag_omasa_brate = st->bit_stream[( st->next_bit_pos )--]; + move16(); + *nb_bits_read = add( *nb_bits_read, 1 ); + } + } + } + + /* read the MASA_ISM_FORMAT bit */ + byteBuffer = st->bit_stream[( st->next_bit_pos )--]; + IF( byteBuffer == 1 ) + { + hMasa->config.input_ivas_format = MASA_ISM_FORMAT; + } + ELSE + { + hMasa->config.input_ivas_format = MASA_FORMAT; + } + move16(); + + /* reserved bit */ + byteBuffer = st->bit_stream[( st->next_bit_pos )--]; + *nb_bits_read = add( *nb_bits_read, MASA_HEADER_BITS ); + + /* read number of directions */ + byteBuffer = st->bit_stream[( st->next_bit_pos )--]; + *nb_bits_read = add( *nb_bits_read, 1 ); + hMasa->config.numberOfDirections = (uint8_t) ( byteBuffer + 1 ); + } + ELSE + { + hMasa->config.numberOfDirections = 1; + } + + // IF ( !( ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) ) + IF( NE_16( ivas_format, MC_FORMAT ) || NE_16( st_ivas->mc_mode, MC_MODE_MCMASA ) ) + { + /* read subframe mode */ + byteBuffer = st->bit_stream[( st->next_bit_pos )--]; + *nb_bits_read = add( *nb_bits_read, 1 ); + hMasa->config.joinedSubframes = (uint8_t) byteBuffer; + } + ELSE + { + hMasa->config.joinedSubframes = FALSE; + } + + IF( EQ_16( st_ivas->mc_mode, MC_MODE_MCMASA ) ) + { + *nb_bits_read = add( *nb_bits_read, decode_lfe_to_total_energy_ratio_fx( hMasa->hMasaLfeSynth, st->bit_stream, &st->next_bit_pos, ivas_total_brate ) ); + } + + /* Once we know incoming configuration, we can config decoder further based on bitrate etc. */ + IF( ( error = ivas_masa_dec_config_fx( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* If we are under metadata bit budget limit and joined subframes is not signalled, then read LBR mode. */ + IF( hMasa->config.max_metadata_bits < MINIMUM_BIT_BUDGET_NORMAL_META && hMasa->config.joinedSubframes == FALSE ) + { + /* read low bitrate mode */ + byteBuffer = st->bit_stream[( st->next_bit_pos )--]; + *nb_bits_read = add( *nb_bits_read, 1 ); + low_bitrate_mode = byteBuffer; + move16(); + + IF( EQ_16( low_bitrate_mode, 1 ) ) + { + hQMetaData->q_direction[0].cfg.nblocks = 1; + move16(); + } + ELSE + { + hQMetaData->q_direction[0].cfg.nbands = 1; + move16(); + } + } + + /* Remove already read bits from the bit budget */ + hQMetaData->metadata_max_bits = sub( hQMetaData->metadata_max_bits, *nb_bits_read ); + + IF( EQ_16( st_ivas->ivas_format, MASA_ISM_FORMAT ) ) + { + IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) ) + { + IF( st_ivas->hDirAC != NULL ) + { + *nb_bits_read = add( *nb_bits_read, ivas_decode_masaism_metadata_fx( hQMetaData, st_ivas->hMasa, st_ivas->hMasaIsmData, st_ivas->nchan_ism, st->bit_stream, &st->next_bit_pos, + st_ivas->hMasaIsmData->idx_separated_ism, ism_imp, st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx, st_ivas->hSpatParamRendCom->dirac_md_buffer_length ) ); + FOR( obj = 0; obj <= st_ivas->nchan_ism; obj++ ) + { + IF( EQ_16( st_ivas->hMasaIsmData->idx_separated_ism, obj ) ) + { + Word16 sf; + Word16 meta_write_index; + + FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) + { + meta_write_index = add( st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx, sf ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length; + st_ivas->hMasaIsmData->azimuth_separated_ism[meta_write_index] = st_ivas->hMasaIsmData->azimuth_ism[obj][meta_write_index]; + move16(); + st_ivas->hMasaIsmData->elevation_separated_ism[meta_write_index] = st_ivas->hMasaIsmData->elevation_ism[obj][meta_write_index]; + move16(); + } + } + } + } + ELSE + { + *nb_bits_read = add( *nb_bits_read, ivas_decode_masaism_metadata_fx( hQMetaData, st_ivas->hMasa, st_ivas->hMasaIsmData, st_ivas->nchan_ism, st->bit_stream, &st->next_bit_pos, + st_ivas->hMasaIsmData->idx_separated_ism, ism_imp, 0, MAX_PARAM_SPATIAL_SUBFRAMES ) ); + } + } + } + + masa_total_brate = ivas_total_brate; + move32(); + IF( EQ_16( ivas_format, MASA_ISM_FORMAT ) && EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) + { + masa_total_brate = calculate_cpe_brate_MASA_ISM_fx( st_ivas->ism_mode, ivas_total_brate, st_ivas->nchan_ism ); + move32(); + } + + IF( GE_32( masa_total_brate, IVAS_384k ) ) + { + IF( GE_32( masa_total_brate, IVAS_512k ) ) + { + *nb_bits_read = add( *nb_bits_read, + ivas_qmetadata_dec_decode_hr_384_512( hQMetaData, st->bit_stream, &st->next_bit_pos, hMasa->data.sph_grid16, 16, 4, hMasa->config.numCodingBands ) ); + } + ELSE + { + *nb_bits_read = add( *nb_bits_read, + ivas_qmetadata_dec_decode_hr_384_512( hQMetaData, st->bit_stream, &st->next_bit_pos, hMasa->data.sph_grid16, 11, 3, hMasa->config.numCodingBands ) ); + } + } + ELSE + { + *nb_bits_read = add( *nb_bits_read, + ivas_qmetadata_dec_decode( hQMetaData, st->bit_stream, &st->next_bit_pos, 0 ) ); + } + + test(); + test(); + IF( EQ_16( st_ivas->ivas_format, MASA_ISM_FORMAT ) && NE_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) && NE_16( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) ) + { + /* Modify spatial metadata based on the MASA-to-total energy ratios */ + ivas_omasa_modify_masa_energy_ratios_fx( hQMetaData, st_ivas->hMasaIsmData->masa_to_total_energy_ratio_fx ); + } + + /* Get direction decoding quality. EC 1 and 2 are handled by the default value. */ + IF( EQ_16( hQMetaData->ec_flag, 2 ) ) + { + hMasa->data.dir_decode_quality_fx = shr( hQMetaData->dir_comp_ratio_fx, 1 ); // Q14 + } + + hMasa->config.coherencePresent = !hQMetaData->all_coherence_zero; + + IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) ) + { + index_16bits_fx( hQMetaData, hMasa->data.sph_grid16 ); + } + + /* If LBR mode is not disabled, then we restore metadata to 5 bands and 4 subframes based on the LBR mode. */ + IF( NE_16( low_bitrate_mode, -1 ) ) + { + restore_lowbitrate_masa_fx( hQMetaData, low_bitrate_mode, hMasa->config.numCodingBands ); + } + ELSE IF( hMasa->config.joinedSubframes == TRUE ) + { + replicate_subframes_fx( hQMetaData ); + } + } + ELSE IF( EQ_16( st->bfi, 0 ) && EQ_16( ivas_format, MASA_FORMAT ) && EQ_32( ivas_total_brate, IVAS_SID_5k2 ) ) + { + IF( hQMetaData->q_direction == NULL ) + { + /* replicate ivas_masa_dec_config() in case that first good received frame is SID frame */ + IF( ( error = ivas_masa_dec_config_fx( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + + ivas_masa_set_elements_fx( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, hQMetaData, &st_ivas->element_mode_init, &st_ivas->nSCE, &st_ivas->nCPE, st_ivas->ivas_format, st_ivas->ism_mode, 0 ); + + hQMetaData->metadata_max_bits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC; + move16(); + + IF( ( error = ivas_qmetadata_allocate_memory( hQMetaData, 5, 1, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + hQMetaData->numTwoDirBands = hMasa->config.numTwoDirBands; + hQMetaData->useLowerRes = 0; + + hQMetaData->q_direction->cfg.nbands = 5; + move16(); + hQMetaData->q_direction->cfg.nblocks = 4; + move16(); + + IF( EQ_16( ivas_format, MC_FORMAT ) && EQ_16( st_ivas->mc_mode, MC_MODE_MCMASA ) ) + { + hQMetaData->q_direction->cfg.mc_ls_setup = ivas_mc_map_output_config_to_mc_ls_setup( st_ivas->transport_config ); + } + ELSE + { + hQMetaData->q_direction->cfg.mc_ls_setup = MC_LS_SETUP_INVALID; + } + move16(); + } + + tmp_elem_mode = -1; + move16(); + + *nb_bits_read = add( *nb_bits_read, + ivas_qmetadata_dec_sid_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), st_ivas->nchan_transport, &tmp_elem_mode, ivas_format ) ); + + IF( EQ_16( st_ivas->nchan_transport, 2 ) ) + { + assert( GT_16( st_ivas->nCPE, 0 ) ); + st_ivas->hCPE[0]->element_mode = tmp_elem_mode; + move16(); + } + *nb_bits_read = add( *nb_bits_read, SID_FORMAT_NBITS ); + } + ELSE IF( EQ_16( st->bfi, 0 ) && EQ_16( ivas_format, MASA_FORMAT ) && EQ_32( ivas_total_brate, FRAME_NO_DATA ) ) + { + IF( hQMetaData->q_direction == NULL ) + { + IF( ( error = ivas_masa_dec_config_fx( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + + IF( st_ivas->hDirAC != NULL ) + { + dirac_bs_md_write_idx = st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx; /* Store the write-index for this frame */ + move16(); + + ivas_qmetadata_to_dirac_fx( hQMetaData, st_ivas->hDirAC, hMasa, st_ivas->hSpatParamRendCom, ivas_total_brate, ivas_format, 0, 0 ); + } + + IF( EQ_16( st_ivas->ivas_format, MASA_ISM_FORMAT ) ) + { + IF( hQMetaData->q_direction == NULL ) + { + IF( ( error = ivas_masa_dec_config_fx( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + IF( st_ivas->hDirAC != NULL ) + { + Word16 b; + Word16 block; + Word16 meta_write_index; + + FOR( i = 0; i < st_ivas->hSpatParamRendCom->numIsmDirections; i++ ) + { + FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ ) + { + meta_write_index = add( dirac_bs_md_write_idx, block ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length; + + FOR( b = 0; b < st_ivas->hSpatParamRendCom->num_freq_bands; b++ ) + { + st_ivas->hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b] = L_sub( st_ivas->hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b], + st_ivas->hMasaIsmData->energy_ratio_ism_fx[i][meta_write_index][b] ); + } + } + } + + FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ ) + { + meta_write_index = add( dirac_bs_md_write_idx, block ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length; + + FOR( b = 0; b < st_ivas->hSpatParamRendCom->num_freq_bands; b++ ) + { + st_ivas->hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b] = L_max( 0, st_ivas->hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b] ); + } + } + } + } + + st->next_bit_pos = next_bit_pos_orig; + move16(); + + IF( EQ_16( ivas_format, MASA_ISM_FORMAT ) ) + { + Word32 cpe_brate; + cpe_brate = calculate_cpe_brate_MASA_ISM_fx( st_ivas->ism_mode, ivas_total_brate, st_ivas->nchan_ism ); + + IF( EQ_16( st_ivas->nCPE, 1 ) && st_ivas->hCPE[0]->hStereoDft != NULL && st_ivas->hCPE[0]->hStereoDft->hConfig != NULL ) + { + IF( LT_32( cpe_brate, MASA_STEREO_MIN_BITRATE ) ) + { + st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 1; + move16(); + } + ELSE + { + st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 0; + move16(); + } + + IF( LE_32( ivas_total_brate, IVAS_SID_5k2 ) ) + { + st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 0; + move32(); + } + } + } + ELSE + { + test(); + IF( EQ_16( ivas_format, MASA_FORMAT ) && EQ_16( st_ivas->nCPE, 1 ) && st_ivas->hCPE[0]->hStereoDft != NULL && st_ivas->hCPE[0]->hStereoDft->hConfig != NULL ) + { + IF( LT_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) ) + { + st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 1; + move16(); + } + ELSE + { + st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 0; + move16(); + } + + IF( LE_32( ivas_total_brate, IVAS_SID_5k2 ) ) + { + st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 0; + move16(); + } + } + } + + IF( EQ_16( ivas_format, MASA_FORMAT ) && EQ_16( st_ivas->nCPE, 1 ) ) + { + st_ivas->hCPE[0]->hCoreCoder[0]->masa_sid_format = 0; + move16(); + + IF( LE_32( st_ivas->hDecoderConfig->last_ivas_total_brate, IVAS_SID_5k2 ) ) + { + st_ivas->hCPE[0]->hCoreCoder[0]->masa_sid_format = 1; + move16(); + + IF( GE_32( ivas_total_brate, IVAS_SID_5k2 ) ) + { + st_ivas->hCPE[0]->element_brate = ivas_total_brate; + move32(); + } + } + } + + test(); + test(); + IF( ( EQ_16( st_ivas->ivas_format, MASA_FORMAT ) || EQ_16( st_ivas->ivas_format, MASA_ISM_FORMAT ) ) && EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) ) + { + create_masa_ext_out_meta_fx( hMasa, hQMetaData, st_ivas->nchan_transport ); + } + +#if 1 /* fix to float */ + if ( st_ivas->hSpatParamRendCom != NULL ) + { + for ( i = 0; i < st_ivas->hSpatParamRendCom->dirac_md_buffer_length; i++ ) + { + for ( int j = 0; j < st_ivas->hSpatParamRendCom->num_freq_bands; j++ ) + { + st_ivas->hSpatParamRendCom->energy_ratio1[i][j] = fix_to_float( st_ivas->hSpatParamRendCom->energy_ratio1_fx[i][j], 30 ); + st_ivas->hSpatParamRendCom->diffuseness_vector[i][j] = fix_to_float( st_ivas->hSpatParamRendCom->diffuseness_vector_fx[i][j], 30 ); + IF( hQMetaData->no_directions == 2 ) + { + st_ivas->hSpatParamRendCom->energy_ratio2[i][j] = fix_to_float( st_ivas->hSpatParamRendCom->energy_ratio2_fx[i][j], 30 ); + st_ivas->hSpatParamRendCom->spreadCoherence2[i][j] = fix_to_float( st_ivas->hSpatParamRendCom->spreadCoherence2_fx[i][j], 15 ); + } + st_ivas->hSpatParamRendCom->surroundingCoherence[i][j] = fix_to_float( st_ivas->hSpatParamRendCom->surroundingCoherence_fx[i][j], 15 ); + st_ivas->hSpatParamRendCom->spreadCoherence[i][j] = fix_to_float( st_ivas->hSpatParamRendCom->spreadCoherence_fx[i][j], 15 ); } } } - else + for ( int d = 0; d < max( hMasa->config.numberOfDirections, hQMetaData->no_directions ); d++ ) { - if ( ivas_format == MASA_FORMAT && st_ivas->nCPE == 1 && st_ivas->hCPE[0]->hStereoDft != NULL && st_ivas->hCPE[0]->hStereoDft->hConfig != NULL ) + FOR( Word16 j = 0; j < max( hMasa->config.numCodingBands, hQMetaData->q_direction[0].cfg.nbands ); j++ ) { - st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = ivas_total_brate < MASA_STEREO_MIN_BITRATE ? 1 : 0; - - if ( ivas_total_brate <= IVAS_SID_5k2 ) + FOR( Word16 k = 0; k < MAX_PARAM_SPATIAL_SUBFRAMES; k++ ) { - st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 0; + + hQMetaData->q_direction[d].band_data[j].elevation[k] = fix_to_float( hQMetaData->q_direction[d].band_data[j].elevation_fx[k], Q22 ); + hQMetaData->q_direction[d].band_data[j].azimuth[k] = fix_to_float( hQMetaData->q_direction[d].band_data[j].azimuth_fx[k], Q22 ); + hQMetaData->q_direction[d].band_data[j].energy_ratio[k] = fix_to_float( hQMetaData->q_direction[d].band_data[j].energy_ratio_fx[k], Q30 ); } } } - - if ( ivas_format == MASA_FORMAT && st_ivas->nCPE == 1 ) + FOR( Word32 n = 0; n < st_ivas->nchan_ism; n++ ) { - st_ivas->hCPE[0]->hCoreCoder[0]->masa_sid_format = 0; - - if ( st_ivas->hDecoderConfig->last_ivas_total_brate <= IVAS_SID_5k2 ) + st_ivas->hMasaIsmData->q_azimuth_old[n] = fix_to_float( st_ivas->hMasaIsmData->q_azimuth_old_fx[n], Q22 ); + } + IF( st_ivas->hMasaIsmData != NULL ) + { + FOR( Word32 k = 0; k < MAX_PARAM_SPATIAL_SUBFRAMES; k++ ) { - st_ivas->hCPE[0]->hCoreCoder[0]->masa_sid_format = 1; - - if ( ivas_total_brate >= IVAS_SID_5k2 ) + FOR( Word32 j = 0; j < MASA_FREQUENCY_BANDS; j++ ) { - st_ivas->hCPE[0]->element_brate = ivas_total_brate; + st_ivas->hMasaIsmData->masa_to_total_energy_ratio[k][j] = fix_to_float( st_ivas->hMasaIsmData->masa_to_total_energy_ratio_fx[k][j], Q30 ); } } } - - if ( ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) && st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) + hMasa->data.dir_decode_quality = fix16_to_float( hMasa->data.dir_decode_quality_fx, Q14 ); + if ( hMasa->hMasaLfeSynth != NULL ) { - create_masa_ext_out_meta( hMasa, hQMetaData, st_ivas->nchan_transport ); + for ( int j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + hMasa->hMasaLfeSynth->lfeToTotalEnergyRatio[j] = fix16_to_float( hMasa->hMasaLfeSynth->lfeToTotalEnergyRatio_fx[j], Q14 ); + } + } + IF( st_ivas->hSpatParamRendCom != NULL ) + { + FOR( i = 0; i < st_ivas->hSpatParamRendCom->numIsmDirections; i++ ) + { + FOR( Word16 block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ ) + { + Word16 meta_write_index = add( dirac_bs_md_write_idx, block ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length; + FOR( Word16 b = 0; b < st_ivas->hSpatParamRendCom->num_freq_bands; b++ ) + { + st_ivas->hMasaIsmData->energy_ratio_ism[i][meta_write_index][b] = fix_to_float( st_ivas->hMasaIsmData->energy_ratio_ism_fx[i][meta_write_index][b], Q30 ); + } + } + } } +#endif return error /* *nb_bits_read*/; } +#endif /*-------------------------------------------------------------------* @@ -1499,6 +2161,30 @@ static void index_16bits( return; } +#ifdef IVAS_FLOAT_FIXED +static void index_16bits_fx( + IVAS_QMETADATA_HANDLE hQMetaData, + SPHERICAL_GRID_DATA *Sph_Grid16 ) +{ + Word16 d, band, block; + + FOR( d = 0; d < hQMetaData->no_directions; d++ ) + { + /* Note: The band information is read from the first direction as it contains the full information. */ + FOR( band = 0; band < hQMetaData->q_direction[0].cfg.nbands; band++ ) + { + FOR( block = 0; block < hQMetaData->q_direction[0].cfg.nblocks; block++ ) + { + hQMetaData->q_direction[d].band_data[band].spherical_index[block] = index_theta_phi_16_fx( &( hQMetaData->q_direction[d].band_data[band].elevation_fx[block] ), + &( hQMetaData->q_direction[d].band_data[band].azimuth_fx[block] ), Sph_Grid16 ); + } + } + } + + return; +} +#endif + /* Replicate subframe data when there is only one subframe sent */ static void replicate_subframes( @@ -1545,6 +2231,48 @@ static void replicate_subframes( return; } +#ifdef IVAS_FLOAT_FIXED +/* Replicate subframe data when there is only one subframe sent */ +static void replicate_subframes_fx( + IVAS_QMETADATA_HANDLE hQMetaData ) +{ + Word16 sf, band, dir, nbands, ndirs; + + nbands = hQMetaData->q_direction->cfg.nbands; + move16(); + ndirs = hQMetaData->no_directions; + move16(); + + FOR ( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) + { + FOR ( band = 0; band < nbands; band++ ) + { + FOR ( dir = 0; dir < ndirs; dir++ ) + { + hQMetaData->q_direction[dir].band_data[band].spherical_index[sf] = hQMetaData->q_direction[dir].band_data[band].spherical_index[0]; + hQMetaData->q_direction[dir].band_data[band].azimuth_fx[sf] = hQMetaData->q_direction[dir].band_data[band].azimuth_fx[0]; + move32(); + hQMetaData->q_direction[dir].band_data[band].elevation_fx[sf] = hQMetaData->q_direction[dir].band_data[band].elevation_fx[0]; + move32(); + hQMetaData->q_direction[dir].band_data[band].energy_ratio_fx[sf] = hQMetaData->q_direction[dir].band_data[band].energy_ratio_fx[0]; + move32(); + + IF ( hQMetaData->q_direction[dir].coherence_band_data != NULL ) + { + hQMetaData->q_direction[dir].coherence_band_data[band].spread_coherence[sf] = hQMetaData->q_direction[dir].coherence_band_data[band].spread_coherence[0]; + } + } + + IF ( hQMetaData->surcoh_band_data != NULL ) + { + hQMetaData->surcoh_band_data[band].surround_coherence[sf] = hQMetaData->surcoh_band_data[band].surround_coherence[0]; + } + } + } + + return; +} +#endif static void restore_lowbitrate_masa( IVAS_QMETADATA_HANDLE hQMetaData, @@ -1624,6 +2352,79 @@ static void restore_lowbitrate_masa( return; } +#ifdef IVAS_FLOAT_FIXED +static void restore_lowbitrate_masa_fx( + IVAS_QMETADATA_HANDLE hQMetaData, + const Word16 low_bitrate_mode, + const Word16 numCodingBands ) +{ + Word16 sf, band; + + IF ( EQ_16(low_bitrate_mode, 1) ) + { + /* With signal 1, we are in 5 frequency bands, 1 subframe mode. */ + /* Replicate data to all subframes */ + FOR ( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) + { + FOR ( band = 0; band < numCodingBands; band++ ) + { + + hQMetaData->q_direction[0].band_data[band].spherical_index[sf] = hQMetaData->q_direction[0].band_data[band].spherical_index[0]; + + hQMetaData->q_direction[0].band_data[band].azimuth_fx[sf] = hQMetaData->q_direction[0].band_data[band].azimuth_fx[0]; + move32(); + hQMetaData->q_direction[0].band_data[band].elevation_fx[sf] = hQMetaData->q_direction[0].band_data[band].elevation_fx[0]; + move32(); + hQMetaData->q_direction[0].band_data[band].energy_ratio_fx[sf] = hQMetaData->q_direction[0].band_data[band].energy_ratio_fx[0]; + move32(); + + IF ( hQMetaData->q_direction[0].coherence_band_data != NULL ) + { + hQMetaData->q_direction[0].coherence_band_data[band].spread_coherence[sf] = hQMetaData->q_direction[0].coherence_band_data[band].spread_coherence[0]; + } + IF ( hQMetaData->surcoh_band_data != NULL ) + { + hQMetaData->surcoh_band_data[band].surround_coherence[sf] = hQMetaData->surcoh_band_data[band].surround_coherence[0]; + } + } + } + hQMetaData->q_direction->cfg.nblocks = 4; + move16(); + } + ELSE + { + /* With signal 0, we are in 1 frequency bands, 4 subframes mode. */ + /* Replicate data to all bands */ + FOR ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) + { + FOR ( band = 1; band < numCodingBands; band++ ) + { + hQMetaData->q_direction[0].band_data[band].spherical_index[sf] = hQMetaData->q_direction[0].band_data[0].spherical_index[sf]; + hQMetaData->q_direction[0].band_data[band].azimuth_fx[sf] = hQMetaData->q_direction[0].band_data[0].azimuth_fx[sf]; + move32(); + hQMetaData->q_direction[0].band_data[band].elevation_fx[sf] = hQMetaData->q_direction[0].band_data[0].elevation_fx[sf]; + move32(); + hQMetaData->q_direction[0].band_data[band].energy_ratio_fx[sf] = hQMetaData->q_direction[0].band_data[0].energy_ratio_fx[sf]; + move32(); + + IF ( hQMetaData->q_direction[0].coherence_band_data != NULL ) + { + hQMetaData->q_direction[0].coherence_band_data[band].spread_coherence[sf] = hQMetaData->q_direction[0].coherence_band_data[0].spread_coherence[sf]; + } + IF ( hQMetaData->surcoh_band_data != NULL ) + { + hQMetaData->surcoh_band_data[band].surround_coherence[sf] = hQMetaData->surcoh_band_data[0].surround_coherence[sf]; + } + } + } + hQMetaData->q_direction->cfg.nbands = numCodingBands; + move16(); + } + + return; +} +#endif + static ivas_error init_lfe_synth_data( Decoder_Struct *st_ivas, /* i : IVAS decoder struct */ @@ -3222,6 +4023,144 @@ static void create_masa_ext_out_meta( return; } +#ifdef IVAS_FLOAT_FIXED +static void create_masa_ext_out_meta_fx( + MASA_DECODER *hMasa, + IVAS_QMETADATA_HANDLE hQMetaData, + const Word16 nchan_transport ) +{ + const UWord8 ivasmasaFormatDescriptor[8] = { 0x49, 0x56, 0x41, 0x53, 0x4D, 0x41, 0x53, 0x41 }; /* "IVASMASA" */ + Word16 i, sf, b_old, b_new, dir; + MASA_DECRIPTIVE_META *descMeta; + Word16 *bandMap; + UWord8 numCodingBands; + UWord8 numDirections; + MASA_DECODER_EXT_OUT_META *extOutMeta; + + numDirections = hMasa->config.numberOfDirections; + numCodingBands = hMasa->config.numCodingBands; + bandMap = hMasa->data.band_mapping; + extOutMeta = hMasa->data.extOutMeta; + descMeta = &hMasa->data.extOutMeta->descriptiveMeta; + + /* Construct descriptive meta */ + FOR ( i = 0; i < 8; i++ ) + { + descMeta->formatDescriptor[i] = ivasmasaFormatDescriptor[i]; + } + descMeta->numberOfDirections = numDirections - 1; + descMeta->numberOfChannels = (UWord8) ( sub(nchan_transport, 1) ); + /* Following correspond to "unknown" values until transmission is implemented */ + descMeta->sourceFormat = 0x0u; + descMeta->transportDefinition = 0x0u; + descMeta->channelAngle = 0x0u; + descMeta->channelDistance = 0x0u; + descMeta->channelLayout = 0x0u; + + /* Construct spatial metadata from qmetadata */ + FOR ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) + { + FOR ( dir = 0; dir < numDirections; dir++ ) + { + /* Spherical index */ + FOR ( b_old = 0; b_old < numCodingBands; b_old++ ) + { + FOR ( b_new = bandMap[b_old]; b_new < bandMap[b_old + 1]; b_new++ ) + { + extOutMeta->directionIndex[dir][sf][b_new] = hQMetaData->q_direction[dir].band_data[b_old].spherical_index[sf]; + move16(); + } + } + + /* Direct-to-total ratio */ + FOR ( b_old = 0; b_old < numCodingBands; b_old++ ) + { + FOR ( b_new = bandMap[b_old]; b_new < bandMap[b_old + 1]; b_new++ ) + { + UWord8 tmp = (UWord8)L_shr(hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf], Q30 - 8); + extOutMeta->directToTotalRatio[dir][sf][b_new] = tmp; + } + } + + /* Spread coherence */ + IF ( hQMetaData->q_direction[dir].coherence_band_data != NULL ) + { + FOR ( b_old = 0; b_old < numCodingBands; b_old++ ) + { + FOR ( b_new = bandMap[b_old]; b_new < bandMap[b_old + 1]; b_new++ ) + { + extOutMeta->spreadCoherence[dir][sf][b_new] = hQMetaData->q_direction[dir].coherence_band_data[b_old].spread_coherence[sf]; + } + } + } + ELSE + { + FOR ( i = 0; i < MASA_FREQUENCY_BANDS; i++ ) + { + extOutMeta->spreadCoherence[dir][sf][i] = 0; + } + } + } + + /* Fill second direction with zero energy data for EXT output */ + IF ( numDirections == 1 ) + { + FOR ( i = 0; i < MASA_FREQUENCY_BANDS; i++ ) + { + extOutMeta->directionIndex[1][sf][i] = SPH_IDX_FRONT; + move16(); + } + + FOR ( i = 0; i < MASA_FREQUENCY_BANDS; i++ ) + { + extOutMeta->directToTotalRatio[1][sf][i] = 0; + } + + FOR ( i = 0; i < MASA_FREQUENCY_BANDS; i++ ) + { + extOutMeta->spreadCoherence[1][sf][i] = 0; + } + } + + /* Common spatial meta */ + /* Diffuse-to-total ratio = 1 - sum(direct-to-total ratios) */ + FOR ( b_old = 0; b_old < numCodingBands; b_old++ ) + { + FOR ( b_new = bandMap[b_old]; b_new < bandMap[b_old + 1]; b_new++ ) + { + extOutMeta->diffuseToTotalRatio[sf][b_new] = UINT8_MAX; + FOR ( dir = 0; dir < numDirections; dir++ ) + { + UWord8 tmp = (UWord8)L_shr(hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf], Q30 - 8); + extOutMeta->diffuseToTotalRatio[sf][b_new] -= tmp; + } + } + } + + /* Surround coherence */ + IF ( hQMetaData->surcoh_band_data != NULL ) + { + FOR ( b_old = 0; b_old < numCodingBands; b_old++ ) + { + FOR ( b_new = bandMap[b_old]; b_new < bandMap[b_old + 1]; b_new++ ) + { + extOutMeta->surroundCoherence[sf][b_new] = hQMetaData->surcoh_band_data[b_old].surround_coherence[sf]; + } + } + } + ELSE + { + FOR ( i = 0; i < MASA_FREQUENCY_BANDS; i++ ) + { + extOutMeta->surroundCoherence[sf][i] = 0; + } + } + } + + return; +} +#endif + static void decode_index_slice( int16_t index, /* i : index to decode */ int16_t *ratio_idx_ism, /* o : decodec array of integers */ diff --git a/lib_dec/ivas_omasa_dec.c b/lib_dec/ivas_omasa_dec.c index 0c0b8e502a9fd0d108789a26bb2291dc2c42e97e..527e68f9fd7755ad12a7fefa578afc814a7bf5e1 100644 --- a/lib_dec/ivas_omasa_dec.c +++ b/lib_dec/ivas_omasa_dec.c @@ -209,7 +209,11 @@ ivas_error ivas_omasa_dec_config( old_renderer_type = st_ivas->renderer_type; /* MASA reconfig. */ +#ifdef IVAS_FLOAT_FIXED + cpe_brate = calculate_cpe_brate_MASA_ISM_fx( st_ivas->ism_mode, ivas_total_brate, st_ivas->nchan_ism ); +#else cpe_brate = calculate_cpe_brate_MASA_ISM( st_ivas->ism_mode, ivas_total_brate, st_ivas->nchan_ism ); +#endif if ( st_ivas->ini_active_frame == 0 && ivas_total_brate != FRAME_NO_DATA && ( cpe_brate < MASA_STEREO_MIN_BITRATE ) && st_ivas->nCPE == 1 ) { st_ivas->hCPE[0]->nchan_out = 1; diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index ee505ac2dc7c039c1800a93d2faa95db2978173d..5d86991b4d18fd6f4a01b91a8f23f8298f49e657 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -959,6 +959,9 @@ typedef struct ivas_masa_decoder_data_struct MASA_DECODER_EXT_OUT_META *extOutMeta; float dir_decode_quality; +#ifdef IVAS_FLOAT_FIXED + Word16 dir_decode_quality_fx; // Q14 +#endif } MASA_DECODER_DATA;