Loading lib_com/ivas_masa_com.c +205 −2 Original line number Diff line number Diff line Loading @@ -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() Loading Loading @@ -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; } Loading Loading @@ -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() Loading Loading @@ -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 lib_com/ivas_prot_fx.h +23 −0 Original line number Diff line number Diff line Loading @@ -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 */ ); Loading lib_dec/ivas_jbm_dec.c +218 −1 Original line number Diff line number Diff line Loading @@ -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 ) { Loading Loading @@ -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; } Loading Loading @@ -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 */ Loading lib_dec/ivas_masa_dec.c +958 −19 File changed.Preview size limit exceeded, changes collapsed. Show changes lib_dec/ivas_omasa_dec.c +4 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading
lib_com/ivas_masa_com.c +205 −2 Original line number Diff line number Diff line Loading @@ -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() Loading Loading @@ -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; } Loading Loading @@ -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() Loading Loading @@ -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
lib_com/ivas_prot_fx.h +23 −0 Original line number Diff line number Diff line Loading @@ -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 */ ); Loading
lib_dec/ivas_jbm_dec.c +218 −1 Original line number Diff line number Diff line Loading @@ -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 ) { Loading Loading @@ -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; } Loading Loading @@ -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 */ Loading
lib_dec/ivas_masa_dec.c +958 −19 File changed.Preview size limit exceeded, changes collapsed. Show changes
lib_dec/ivas_omasa_dec.c +4 −0 Original line number Diff line number Diff line Loading @@ -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; Loading