diff --git a/apps/decoder.c b/apps/decoder.c index 09f9339db9069328f7bf2e4881ff387267c69109..af9a847aab28d08844bc1860e1b4a3460206c226 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -1297,15 +1297,24 @@ static ivas_error initOnFirstGoodFrame( /* If outputting MASA, open output file and write metadata for initial bad frames */ else if ( *pBsFormat == IVAS_DEC_BS_MASA ) { +#ifdef FIX_350_MASA_DELAY_COMP + if ( ( error = MasaFileWriter_open( arg.outputWavFilename, arg.delayCompensationEnabled, ppMasaWriter ) ) != IVAS_ERR_OK ) +#else if ( ( error = MasaFileWriter_open( arg.outputWavFilename, ppMasaWriter ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nError: Error opening MASA decoded metadata file %s\n", MasaFileWriter_getFilePath( *ppMasaWriter ) ); return error; } /* Duplicate good first frame metadata to fill the beginning of stream. */ +#ifdef FIX_350_MASA_DELAY_COMP + MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta = NULL; + if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta ) ) != IVAS_ERR_OK ) +#else IVAS_MASA_QMETADATA_HANDLE qMetadata = NULL; if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &qMetadata ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nError in IVAS_DEC_GetMasaMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) ); return error; @@ -1313,7 +1322,11 @@ static ivas_error initOnFirstGoodFrame( for ( int16_t j = 0; j < numInitialBadFrames; ++j ) { +#ifdef FIX_350_MASA_DELAY_COMP + if ( ( error = MasaFileWriter_writeFrame( *ppMasaWriter, hMasaExtOutMeta ) ) != IVAS_ERR_OK ) +#else if ( ( error = MasaFileWriter_writeFrame( *ppMasaWriter, qMetadata ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nError writing MASA metadata to file: %s\n", MasaFileWriter_getFilePath( *ppMasaWriter ) ); return error; @@ -1546,14 +1559,23 @@ static ivas_error decodeG192( } else if ( bsFormat == IVAS_DEC_BS_MASA ) { +#ifdef FIX_350_MASA_DELAY_COMP + MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta; + if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta ) ) != IVAS_ERR_OK ) +#else IVAS_MASA_QMETADATA_HANDLE qMetadata; if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &qMetadata ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nError in IVAS_DEC_GetMasaMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } +#ifdef FIX_350_MASA_DELAY_COMP + if ( ( error = MasaFileWriter_writeFrame( masaWriter, hMasaExtOutMeta ) ) != IVAS_ERR_OK ) +#else if ( ( error = MasaFileWriter_writeFrame( masaWriter, qMetadata ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nError writing MASA metadata to file: %s\n", MasaFileWriter_getFilePath( masaWriter ) ); goto cleanup; diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index 893bf6b265b141435359c3ea71ff93c773cff49b..8c1e1837f56eda1c02bd16bea4a7bcbaaba8d75e 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -87,7 +87,11 @@ typedef struct } IVAS_QUATERNION; typedef struct ivas_masa_metadata_frame_struct *IVAS_MASA_METADATA_HANDLE; +#ifdef FIX_350_MASA_DELAY_COMP +typedef struct ivas_masa_decoder_ext_out_meta_struct *MASA_DECODER_EXT_OUT_META_HANDLE; +#else typedef struct ivas_masa_qmetadata_frame_struct *IVAS_MASA_QMETADATA_HANDLE; +#endif typedef struct TDREND_HRFILT_FiltSet_struct *IVAS_DEC_HRTF_HANDLE; typedef struct ivas_hrtfs_crend_structure *IVAS_DEC_HRTF_CREND_HANDLE; diff --git a/lib_com/delay_comp.c b/lib_com/delay_comp.c index 09a642bbaa4c558048ce79077430ac8de01ea25b..9f8c1c7b9b1530716d207462b021b5b2a5e4bdfe 100644 --- a/lib_com/delay_comp.c +++ b/lib_com/delay_comp.c @@ -72,6 +72,13 @@ int32_t get_delay( else /* IVAS */ { delay = IVAS_ENC_DELAY_NS; + +#ifdef FIX_350_MASA_DELAY_COMP + if ( ivas_format == MASA_FORMAT ) + { + delay = 0; /* All delay is compensated in the decoder with MASA */ + } +#endif } if ( ivas_format == SBA_FORMAT ) @@ -107,6 +114,13 @@ int32_t get_delay( /* compensate for binauralization delay */ delay += binaural_latency_ns; #endif + +#ifdef FIX_350_MASA_DELAY_COMP + if ( ivas_format == MASA_FORMAT ) + { + delay += IVAS_ENC_DELAY_NS; /* Compensate also the encoder delay in the decoder with MASA */ + } +#endif } } diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 0db65bcf44575681c4f03c691b880bdfea0e2e18..04e11c465660414e70f44006ffa74c8a617ee029 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -931,6 +931,10 @@ typedef enum #define DELAY_DIRAC_SPAR_ENC_CMP_NS 500000L /* here we may set the 24 samples (at 48 kHz) additional delay to something else, leave as is for now*/ #define DELAY_DIRAC_PARAM_DEC_SFR 2 /* Delay to be compensation for DirAC parameters in the decoder (subframes) */ +#ifdef FIX_350_MASA_DELAY_COMP +#define DELAY_MASA_PARAM_DEC_SFR 2 /* Delay to be compensation for MASA parameters in the decoder (subframes) */ +#endif + #define DIRAC_SLOT_NS 1250000L /* time duration of a time slot, 1.25ms (==DELAY_RENERER_NS/MAX_PARAM_SPATIAL_SUBFRAMES) */ #define DIRAC_SLOT_ENC_NS 5000000L @@ -1100,7 +1104,11 @@ enum #define MASA_MAXIMUM_CODING_SUBBANDS 24 #define MASA_MAXIMUM_DIRECTIONS 2 #define MASA_MAX_TRANSPORT_CHANNELS 2 + +#ifndef FIX_350_MASA_DELAY_COMP #define MASA_ENC_DELAY_SLOTS 7 +#endif + #define MASA_NUM_DEFINED_SUR_SPR_COH_ENE_BINS 5 #define MASA_DELTA_AZI_DCT0 30 diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 9d58810857a44c8f3266483b5b354a336a173acf..3ea6e6bbae22fe5713c892fac89dfd3d46cdc68d 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -4436,9 +4436,12 @@ ivas_error ivas_masa_enc_open( ); void ivas_masa_enc_close( - MASA_ENCODER_HANDLE hMasa, /* i/o: MASA metadata structure */ + MASA_ENCODER_HANDLE hMasa /* i/o: MASA metadata structure */ + #ifndef FIX_350_MASA_DELAY_COMP + , const int16_t nchan_transport, /* i : Number of transport channels */ const IVAS_FORMAT ivas_format /* i : IVAS format */ + #endif ); void ivas_masa_enc_reconfigure( diff --git a/lib_com/options.h b/lib_com/options.h index 26bdb5e55ec424021854cfb53a2a59ba3f85d575..5fd4b3d2a6723053649c06f5ce171ecd02e29503 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -143,7 +143,7 @@ /*#define FIX_I4_OL_PITCH*/ /* fix open-loop pitch used for EVS core switching */ #define SBA_BR_SWITCHING_CLEAN_UP /*Issue 114: Clean up changes for the SBA reconfiguation functions*/ #define LOW_RATE_TRANS_CORE_CODER /* Eri: Activate low-rate-encoding-of-transients contribution for core coder, affects MC, MASA and SBA */ -#define FIX_197_CREND_INTERFACE +#define FIX_197_CREND_INTERFACE #define FIX_329_ENABLE_TD_RENDERER_REVERB_MC /* Eri: Enable reverb for TD renderer for 5.1 and 7.1 with headtracking enabled for IVAS_dec */ #define FIX_330_ENABLE_TD_RENDERER_REVERB_REND /* Eri: Enable reverb for TD renderer for ISM, 5.1 and 7.1 with headtracking enabled for IVAS_rend */ @@ -167,7 +167,7 @@ #define FIX_94_VERIFY_WAV_NUM_CHANNELS /* FhG: Issue 94 - Check if number of channels in input wav file matches encoder/renderer configuration */ #define ISM_HIGHEST_BITRATE /* VA: Issue 284: Update highest bitrate limit in ISM format */ #define TUNE_360_OBJECT_WITH_NOISE /* VA: issue 360: consider objects being speech+noise for active speech coding */ - +#define FIX_350_MASA_DELAY_COMP /* Nokia: Issue 350: MASA audio/meta delay compensation */ /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 17718e86a345d45ed4e01cebcebe3bb46889d254..14b8d91affd23b657996cce64e8b4155c1cceba2 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -762,10 +762,22 @@ ivas_error ivas_dirac_dec_config( hDirAC->dirac_read_idx = 0; hDirAC->spar_to_dirac_write_idx = 0; +#ifdef FIX_350_MASA_DELAY_COMP + if ( st_ivas->mc_mode == MC_MODE_MCMASA ) + { + hDirAC->dirac_md_buffer_length = MAX_PARAM_SPATIAL_SUBFRAMES; + } + else if ( st_ivas->ivas_format == MASA_FORMAT ) + { + hDirAC->dirac_md_buffer_length = MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR; + hDirAC->dirac_bs_md_write_idx = DELAY_MASA_PARAM_DEC_SFR; + } +#else if ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->mc_mode == MC_MODE_MCMASA ) { hDirAC->dirac_md_buffer_length = MAX_PARAM_SPATIAL_SUBFRAMES; } +#endif else { int16_t num_slots_in_subfr; @@ -1498,8 +1510,45 @@ void ivas_qmetadata_to_dirac( if ( hMasa != NULL && ivas_total_brate > IVAS_SID_5k2 ) { +#ifdef FIX_350_MASA_DELAY_COMP + int16_t meta_write_index; band_mapping = hMasa->data.band_mapping; + for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; ++block ) + { + meta_write_index = ( hDirAC->dirac_bs_md_write_idx + block ) % hDirAC->dirac_md_buffer_length; + + for ( band = 0; band < hMasa->config.numCodingBands; ++band ) + { + for ( b = MASA_band_grouping_24[band_mapping[band]]; b < MASA_band_grouping_24[band_mapping[band + 1]]; ++b ) + { + hDirAC->azimuth[meta_write_index][b] = (int16_t) q_direction->band_data[band].azimuth[block]; + hDirAC->elevation[meta_write_index][b] = (int16_t) q_direction->band_data[band].elevation[block]; + hDirAC->energy_ratio1[meta_write_index][b] = q_direction->band_data[band].energy_ratio[block]; + hDirAC->diffuseness_vector[meta_write_index][b] = 1.0f - q_direction->band_data[band].energy_ratio[block]; + + if ( q_direction->coherence_band_data != NULL ) + { + hDirAC->spreadCoherence[meta_write_index][b] = q_direction->coherence_band_data[band].spread_coherence[block] / 255.0f; + } + else + { + hDirAC->spreadCoherence[meta_write_index][b] = 0.0f; + } + + if ( hQMetaData->surcoh_band_data != NULL ) + { + hDirAC->surroundingCoherence[meta_write_index][b] = hQMetaData->surcoh_band_data[band].surround_coherence[block] / 255.0f; + } + else + { + hDirAC->surroundingCoherence[meta_write_index][b] = 0.0f; + } + } + } + } +#else + band_mapping = hMasa->data.band_mapping; for ( band = 0; band < hMasa->config.numCodingBands; ++band ) { for ( b = MASA_band_grouping_24[band_mapping[band]]; b < MASA_band_grouping_24[band_mapping[band + 1]]; ++b ) @@ -1531,10 +1580,37 @@ void ivas_qmetadata_to_dirac( } } } +#endif if ( hQMetaData->no_directions == 2 ) { q_direction = &( hQMetaData->q_direction[1] ); +#ifdef FIX_350_MASA_DELAY_COMP + for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; ++block ) + { + meta_write_index = ( hDirAC->dirac_bs_md_write_idx + block ) % hDirAC->dirac_md_buffer_length; + + for ( band = 0; band < hMasa->config.numCodingBands; ++band ) + { + for ( b = MASA_band_grouping_24[band_mapping[band]]; b < MASA_band_grouping_24[band_mapping[band + 1]]; ++b ) + { + hDirAC->azimuth2[meta_write_index][b] = (int16_t) q_direction->band_data[band].azimuth[block]; + hDirAC->elevation2[meta_write_index][b] = (int16_t) q_direction->band_data[band].elevation[block]; + hDirAC->energy_ratio2[meta_write_index][b] = q_direction->band_data[band].energy_ratio[block]; + hDirAC->diffuseness_vector[meta_write_index][b] -= q_direction->band_data[band].energy_ratio[block]; + + if ( q_direction->coherence_band_data != NULL ) + { + hDirAC->spreadCoherence2[meta_write_index][b] = q_direction->coherence_band_data[band].spread_coherence[block] / 255.0f; + } + else + { + hDirAC->spreadCoherence2[meta_write_index][b] = 0.0f; + } + } + } + } +#else for ( band = 0; band < hMasa->config.numCodingBands; ++band ) { for ( b = MASA_band_grouping_24[band_mapping[band]]; b < MASA_band_grouping_24[band_mapping[band + 1]]; ++b ) @@ -1557,7 +1633,22 @@ void ivas_qmetadata_to_dirac( } } } +#endif + } +#ifdef FIX_350_MASA_DELAY_COMP + else if ( hDirAC->azimuth2 != NULL && hDirAC->elevation2 != NULL && hDirAC->energy_ratio2 != NULL && hDirAC->spreadCoherence2 != NULL ) + { + /* zero out old dir2 data */ + for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; ++block ) + { + meta_write_index = ( hDirAC->dirac_bs_md_write_idx + block ) % hDirAC->dirac_md_buffer_length; + set_s( hDirAC->azimuth2[meta_write_index], 0, hDirAC->num_freq_bands ); + set_s( hDirAC->elevation2[meta_write_index], 0, hDirAC->num_freq_bands ); + set_zero( hDirAC->energy_ratio2[meta_write_index], hDirAC->num_freq_bands ); + set_zero( hDirAC->spreadCoherence2[meta_write_index], hDirAC->num_freq_bands ); + } } +#endif } else /* SBA mode/SID/Zero frame*/ { diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index cefade119f8f28966dfa96675105096137b55651..28c25de4a3e382716035e205bd691618da133b7c 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -48,6 +48,9 @@ * Local constants *-----------------------------------------------------------------------*/ #define SPAR_META_DELAY_SUBFRAMES 2 /* Number of subframes to delay the SPAR metadata */ +#ifdef FIX_350_MASA_DELAY_COMP +#define SPH_IDX_FRONT ( MASA_NO_POINTS_EQUATOR / 2 ) /* Spherical index corresponding to front direction for setting as default value */ +#endif /*-----------------------------------------------------------------------* * Local function prototypes @@ -57,6 +60,9 @@ static int16_t quantize_theta( float x, int16_t no_cb, float *xhat ); static uint16_t index_theta_phi_16( float theta, float phi, SPHERICAL_GRID_DATA *Sph_Grid16 ); static int16_t quantize_phi_masa( float phi, int16_t flag_delta, float *phi_hat, const int16_t n ); static void index_16bits( IVAS_QMETADATA_HANDLE hQMetaData, SPHERICAL_GRID_DATA *Sph_Grid16 ); +#ifdef FIX_350_MASA_DELAY_COMP +static void create_masa_ext_out_meta( MASA_DECODER *hMasa, IVAS_QMETADATA_HANDLE hQMetaData, const int16_t nchan_transport ); +#endif static void replicate_subframes( IVAS_QMETADATA_HANDLE hQMetaData ); @@ -302,6 +308,12 @@ ivas_error ivas_masa_decode( } } +#ifdef FIX_350_MASA_DELAY_COMP + if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_EXTERNAL ) + { + create_masa_ext_out_meta( hMasa, hQMetaData, st_ivas->nchan_transport ); + } +#endif return error /* *nb_bits_read*/; } @@ -335,10 +347,16 @@ ivas_error ivas_masa_dec_open( { hMasa->data.sph_grid16 = (SPHERICAL_GRID_DATA *) malloc( sizeof( SPHERICAL_GRID_DATA ) ); generate_gridEq( hMasa->data.sph_grid16 ); +#ifdef FIX_350_MASA_DELAY_COMP + hMasa->data.extOutMeta = (MASA_DECODER_EXT_OUT_META *) malloc( sizeof( MASA_DECODER_EXT_OUT_META ) ); +#endif } else { hMasa->data.sph_grid16 = NULL; +#ifdef FIX_350_MASA_DELAY_COMP + hMasa->data.extOutMeta = NULL; +#endif } if ( st_ivas->mc_mode == MC_MODE_MCMASA ) @@ -373,6 +391,13 @@ void ivas_masa_dec_close( hMasa->data.sph_grid16 = NULL; } +#ifdef FIX_350_MASA_DELAY_COMP + if ( hMasa->data.extOutMeta != NULL ) + { + free( hMasa->data.extOutMeta ); + hMasa->data.extOutMeta = NULL; + } +#endif if ( hMasa->hMasaLfeSynth != NULL ) { if ( hMasa->hMasaLfeSynth->lfeSynthRingBuffer != NULL ) @@ -1351,3 +1376,134 @@ static void compute_foa_cov_matrix( return; } + +#ifdef FIX_350_MASA_DELAY_COMP +static void create_masa_ext_out_meta( MASA_DECODER *hMasa, IVAS_QMETADATA_HANDLE hQMetaData, const int16_t nchan_transport ) +{ + const uint8_t ivasmasaFormatDescriptor[8] = { 0x49, 0x56, 0x41, 0x53, 0x4D, 0x41, 0x53, 0x41 }; /* "IVASMASA" */ + int16_t i, sf, b_old, b_new, dir; + MASA_DECRIPTIVE_META *descMeta; + int16_t *bandMap; + uint8_t numCodingBands; + uint8_t 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 = (uint8_t) ( 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]; + } + } + + /* 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++ ) + { + extOutMeta->directToTotalRatio[dir][sf][b_new] = (uint8_t) floorf( hQMetaData->q_direction[dir].band_data[b_old].energy_ratio[sf] * UINT8_MAX ); + } + } + + /* 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; + } + + 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++ ) + { + extOutMeta->diffuseToTotalRatio[sf][b_new] -= (uint8_t) floorf( hQMetaData->q_direction[dir].band_data[b_old].energy_ratio[sf] * UINT8_MAX ); + } + } + } + + /* 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 diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 81eec94a2774af923709e808d56f46ce3b01b1d5..4157438f80a1ea635c01b984a77422c03c24ba2f 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -1096,11 +1096,29 @@ typedef struct ivas_mcmasa_lfe_synth_struct } MCMASA_LFE_SYNTH_DATA, *MCMASA_LFE_SYNTH_DATA_HANDLE; +#ifdef FIX_350_MASA_DELAY_COMP +typedef struct ivas_masa_decoder_ext_out_meta_struct +{ + MASA_DECRIPTIVE_META descriptiveMeta; + + uint16_t directionIndex[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + uint8_t directToTotalRatio[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + uint8_t spreadCoherence[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + + uint8_t surroundCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + uint8_t diffuseToTotalRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + +} MASA_DECODER_EXT_OUT_META; +#endif + typedef struct ivas_masa_decoder_data_struct { int16_t band_mapping[MASA_FREQUENCY_BANDS + 1]; SPHERICAL_GRID_DATA *sph_grid16; +#ifdef FIX_350_MASA_DELAY_COMP + MASA_DECODER_EXT_OUT_META *extOutMeta; +#endif float dir_decode_quality; } MASA_DECODER_DATA; diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index fb2bd7e4d1cbcc114ca17ce3f6f391c11d2c6515..237fc0c0caa74598c34f4e783372078f8638fcd6 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -873,8 +873,12 @@ ivas_error IVAS_DEC_GetObjectMetadata( *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_GetMasaMetadata( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ +#ifdef FIX_350_MASA_DELAY_COMP + MASA_DECODER_EXT_OUT_META_HANDLE *hMasaExtOutMeta /* o : pointer to handle, which will be set to point to metadata from the most recently decoded frame */ +#else IVAS_MASA_QMETADATA_HANDLE *hMasaMetadata /* o : pointer to handle, which will be set to point to metadata from the most recently decoded frame */ +#endif ) { if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) @@ -887,7 +891,11 @@ ivas_error IVAS_DEC_GetMasaMetadata( return IVAS_ERR_WRONG_MODE; } +#ifdef FIX_350_MASA_DELAY_COMP + *hMasaExtOutMeta = hIvasDec->st_ivas->hMasa->data.extOutMeta; +#else *hMasaMetadata = hIvasDec->st_ivas->hQMetaData; +#endif return IVAS_ERR_OK; } diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index 10a9fdc49f81780f19d530ea93c4eaccc1f15636..36dab5c1f9cd11f6423b9107aa994d7fe24e7144 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -174,8 +174,12 @@ ivas_error IVAS_DEC_GetObjectMetadata( /*! r: error code */ ivas_error IVAS_DEC_GetMasaMetadata( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_MASA_QMETADATA_HANDLE *hMasaMetadata /* o : pointer to handle, which will be set to point to metadata from the most recently decoded frame */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ +#ifdef FIX_350_MASA_DELAY_COMP + MASA_DECODER_EXT_OUT_META_HANDLE *hMasaExtOutMeta /* o : pointer to handle, which will be set to point to metadata from the most recently decoded frame */ +#else + IVAS_MASA_QMETADATA_HANDLE *hMasaMetadata /* o : pointer to handle, which will be set to point to metadata from the most recently decoded frame */ +#endif ); /*! r: error code */ diff --git a/lib_enc/ivas_init_enc.c b/lib_enc/ivas_init_enc.c index bce42bba9237bba7ac7e48588fcdaa3140b68bb4..60f3a230a589b97ce0e390957645d26e1eaba551 100644 --- a/lib_enc/ivas_init_enc.c +++ b/lib_enc/ivas_init_enc.c @@ -977,7 +977,11 @@ void ivas_destroy_enc( /* MASA handle */ if ( st_ivas->hMasa != NULL ) { +#ifdef FIX_350_MASA_DELAY_COMP + ivas_masa_enc_close( st_ivas->hMasa ); +#else ivas_masa_enc_close( st_ivas->hMasa, st_ivas->nchan_transport, ivas_format ); +#endif st_ivas->hMasa = NULL; } diff --git a/lib_enc/ivas_masa_enc.c b/lib_enc/ivas_masa_enc.c index 3a7ac61038f339a07776a1ffcb1452252fa2915a..c2b6b5423b154cccaed8df8aa3b9aa49b81a164b 100644 --- a/lib_enc/ivas_masa_enc.c +++ b/lib_enc/ivas_masa_enc.c @@ -119,6 +119,7 @@ ivas_error ivas_masa_enc_open( mvs2s( DirAC_block_grouping, hMasa->config.block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 ); mvs2s( MASA_band_grouping_24, hMasa->config.band_grouping, MASA_FREQUENCY_BANDS + 1 ); +#ifndef FIX_350_MASA_DELAY_COMP if ( hEncoderConfig->ivas_format == MASA_FORMAT ) { for ( i = 0; i < st_ivas->nchan_transport; i++ ) @@ -127,6 +128,7 @@ ivas_error ivas_masa_enc_open( set_f( hMasa->data.delay_buffer[i], 0.0f, MASA_ENC_DELAY_SLOTS * CLDFB_NO_CHANNELS_MAX ); } } +#endif hMasa->data.onset_detector_1 = 0.0f; hMasa->data.onset_detector_2 = 0.0f; @@ -147,9 +149,12 @@ ivas_error ivas_masa_enc_open( *-----------------------------------------------------------------------*/ void ivas_masa_enc_close( - MASA_ENCODER_HANDLE hMasa, /* i/o: MASA metadata structure */ + MASA_ENCODER_HANDLE hMasa /* i/o: MASA metadata structure */ +#ifndef FIX_350_MASA_DELAY_COMP + , const int16_t nchan_transport, /* i : Number of transport channels */ const IVAS_FORMAT ivas_format /* i : IVAS format */ +#endif ) { int16_t i; @@ -159,6 +164,7 @@ void ivas_masa_enc_close( deleteCldfb( &( hMasa->data.cldfbAnaEnc[i] ) ); } +#ifndef FIX_350_MASA_DELAY_COMP if ( ivas_format == MASA_FORMAT ) { for ( i = 0; i < nchan_transport; i++ ) @@ -167,6 +173,7 @@ void ivas_masa_enc_close( hMasa->data.delay_buffer[i] = NULL; } } +#endif free( hMasa ); @@ -397,6 +404,12 @@ void ivas_masa_estimate_energy( for ( ts = mrange[0]; ts < mrange[1]; ts++ ) { +#ifdef FIX_350_MASA_DELAY_COMP + for ( i = 0; i < nchan_transport; i++ ) + { + cldfbAnalysis_ts( &( data_f[i][l_ts * ts] ), Input_RealBuffer[i], Input_ImagBuffer[i], l_ts, hMasa->data.cldfbAnaEnc[i] ); + } +#else if ( ts < MASA_ENC_DELAY_SLOTS ) { for ( i = 0; i < nchan_transport; i++ ) @@ -411,6 +424,7 @@ void ivas_masa_estimate_energy( cldfbAnalysis_ts( &( data_f[i][l_ts * ( ts - MASA_ENC_DELAY_SLOTS )] ), Input_RealBuffer[i], Input_ImagBuffer[i], l_ts, hMasa->data.cldfbAnaEnc[i] ); } } +#endif for ( band_m_idx = 0; band_m_idx < MASA_FREQUENCY_BANDS; band_m_idx++ ) { @@ -438,10 +452,12 @@ void ivas_masa_estimate_energy( } } +#ifndef FIX_350_MASA_DELAY_COMP for ( i = 0; i < nchan_transport; i++ ) { mvr2r( &data_f[i][input_frame - MASA_ENC_DELAY_SLOTS * maxBin], &( hMasa->data.delay_buffer[i][0] ), MASA_ENC_DELAY_SLOTS * maxBin ); } +#endif return; } diff --git a/lib_enc/ivas_mcmasa_enc.c b/lib_enc/ivas_mcmasa_enc.c index 7cae277f9a5cb2b7c63bcdf8020dc51b928143be..6ac686b01e4c149759ab2b2f82987da9d93d7ccb 100644 --- a/lib_enc/ivas_mcmasa_enc.c +++ b/lib_enc/ivas_mcmasa_enc.c @@ -425,7 +425,11 @@ ivas_error ivas_mcmasa_enc_reconfig( /* bitrate changed, may need to do something */ /* brute-force solution: close McMASA and re-instantiate with new settings */ +#ifdef FIX_350_MASA_DELAY_COMP + ivas_masa_enc_close( st_ivas->hMasa ); +#else ivas_masa_enc_close( st_ivas->hMasa, st_ivas->nchan_transport, st_ivas->hEncoderConfig->ivas_format ); +#endif ivas_mcmasa_enc_close( st_ivas->hMcMasa, st_ivas->hEncoderConfig->input_Fs ); /* Determine if to separate some channels from the analysis */ diff --git a/lib_enc/ivas_mct_enc.c b/lib_enc/ivas_mct_enc.c index eb7975c1c1110daeb8d8699d8375fd135d4bb661..1482cf3e2075628e6603f98abf2e6b6ab81540b4 100644 --- a/lib_enc/ivas_mct_enc.c +++ b/lib_enc/ivas_mct_enc.c @@ -623,7 +623,11 @@ static ivas_error ivas_mc_enc_reconfig( if ( st_ivas->hMasa != NULL ) { +#ifdef FIX_350_MASA_DELAY_COMP + ivas_masa_enc_close( st_ivas->hMasa ); +#else ivas_masa_enc_close( st_ivas->hMasa, nchan_transport_old, MC_FORMAT ); +#endif st_ivas->hMasa = NULL; } @@ -656,7 +660,11 @@ static ivas_error ivas_mc_enc_reconfig( } if ( st_ivas->hMasa != NULL ) { +#ifdef FIX_350_MASA_DELAY_COMP + ivas_masa_enc_close( st_ivas->hMasa ); +#else ivas_masa_enc_close( st_ivas->hMasa, nchan_transport_old, MC_FORMAT ); +#endif st_ivas->hMasa = NULL; } diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 5792800c179084d8420bccfaeda232afc5a79660..e4509902548f2d07141b3da9debcecad759605a3 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -743,7 +743,9 @@ typedef struct ivas_masa_encoder_data_struct float energy[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; int16_t num_Cldfb_instances; HANDLE_CLDFB_FILTER_BANK cldfbAnaEnc[MAX_NUM_ENC_CLDFB_INSTANCES]; +#ifndef FIX_350_MASA_DELAY_COMP float *delay_buffer[MASA_MAX_TRANSPORT_CHANNELS]; +#endif int16_t band_mapping[MASA_FREQUENCY_BANDS + 1]; uint8_t twoDirBands[MASA_FREQUENCY_BANDS]; float importanceWeight[MASA_FREQUENCY_BANDS]; diff --git a/lib_util/masa_file_writer.c b/lib_util/masa_file_writer.c index 0ccd8b2ae0ae6592e2c295df84e4b79dda609b1f..6daa2d2092cc9e8a51b8aba077d90e353920e2e9 100644 --- a/lib_util/masa_file_writer.c +++ b/lib_util/masa_file_writer.c @@ -32,24 +32,43 @@ #include "masa_file_writer.h" #include "ivas_stat_com.h" +#ifdef FIX_350_MASA_DELAY_COMP +#include "ivas_stat_dec.h" +#endif #include "ivas_cnst.h" #include #include #include +#ifdef FIX_350_MASA_DELAY_COMP +typedef struct masaMetaDelayStorage +{ + MASA_DECRIPTIVE_META descriptiveMeta; + uint16_t directionIndex[MASA_MAXIMUM_DIRECTIONS][DELAY_MASA_PARAM_DEC_SFR][MASA_FREQUENCY_BANDS]; + uint8_t directToTotalRatio[MASA_MAXIMUM_DIRECTIONS][DELAY_MASA_PARAM_DEC_SFR][MASA_FREQUENCY_BANDS]; + uint8_t spreadCoherence[MASA_MAXIMUM_DIRECTIONS][DELAY_MASA_PARAM_DEC_SFR][MASA_FREQUENCY_BANDS]; + uint8_t surroundCoherence[DELAY_MASA_PARAM_DEC_SFR][MASA_FREQUENCY_BANDS]; + uint8_t diffuseToTotalRatio[DELAY_MASA_PARAM_DEC_SFR][MASA_FREQUENCY_BANDS]; + +} MASA_META_DELAY_STORAGE; +#endif struct MasaFileWriter { FILE *file; char *file_path; +#ifdef FIX_350_MASA_DELAY_COMP + MASA_META_DELAY_STORAGE *delayStorage; +#endif }; /*-----------------------------------------------------------------------* * Local constants *-----------------------------------------------------------------------*/ +#ifndef FIX_350_MASA_DELAY_COMP #define SPH_IDX_FRONT ( MASA_NO_POINTS_EQUATOR / 2 ) /* Spherical index corresponding to front direction for setting as default value */ - +#endif /*-----------------------------------------------------------------------* * Local functions @@ -74,16 +93,76 @@ static void getExtMasaMetadataFileName( return; } +#ifdef FIX_350_MASA_DELAY_COMP +static void delayMasaMetadata( + MASA_DECODER_EXT_OUT_META_HANDLE extOutMeta, /* i/o : New input metadata which is inplace replaced with delayed metadata frame */ + MASA_META_DELAY_STORAGE *delayStorage /* i/o : Storage for 10 ms of metadata and related descriptive metadata */ +) +{ + int16_t dir, sf, band; + uint16_t temp; + uint8_t currentNumberOfDirections; + + /* Move meta to delay and output. Always use two directions as the metadata is prepared to contain zero energy second direction + * if there is 1dir meta. */ + for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES - DELAY_MASA_PARAM_DEC_SFR; sf++ ) + { + for ( band = 0; band < MASA_FREQUENCY_BANDS; band++ ) + { + for ( dir = 0; dir < MASA_MAXIMUM_DIRECTIONS; dir++ ) + { + temp = delayStorage->directionIndex[dir][sf][band]; + delayStorage->directionIndex[dir][sf][band] = extOutMeta->directionIndex[dir][sf + DELAY_MASA_PARAM_DEC_SFR][band]; + extOutMeta->directionIndex[dir][sf + DELAY_MASA_PARAM_DEC_SFR][band] = extOutMeta->directionIndex[dir][sf][band]; + extOutMeta->directionIndex[dir][sf][band] = temp; + + temp = delayStorage->directToTotalRatio[dir][sf][band]; + delayStorage->directToTotalRatio[dir][sf][band] = extOutMeta->directToTotalRatio[dir][sf + DELAY_MASA_PARAM_DEC_SFR][band]; + extOutMeta->directToTotalRatio[dir][sf + DELAY_MASA_PARAM_DEC_SFR][band] = extOutMeta->directToTotalRatio[dir][sf][band]; + extOutMeta->directToTotalRatio[dir][sf][band] = temp; + + temp = delayStorage->spreadCoherence[dir][sf][band]; + delayStorage->spreadCoherence[dir][sf][band] = extOutMeta->spreadCoherence[dir][sf + DELAY_MASA_PARAM_DEC_SFR][band]; + extOutMeta->spreadCoherence[dir][sf + DELAY_MASA_PARAM_DEC_SFR][band] = extOutMeta->spreadCoherence[dir][sf][band]; + extOutMeta->spreadCoherence[dir][sf][band] = temp; + } + + temp = delayStorage->surroundCoherence[sf][band]; + delayStorage->surroundCoherence[sf][band] = extOutMeta->surroundCoherence[sf + DELAY_MASA_PARAM_DEC_SFR][band]; + extOutMeta->surroundCoherence[sf + DELAY_MASA_PARAM_DEC_SFR][band] = extOutMeta->surroundCoherence[sf][band]; + extOutMeta->surroundCoherence[sf][band] = temp; + + temp = delayStorage->diffuseToTotalRatio[sf][band]; + delayStorage->diffuseToTotalRatio[sf][band] = extOutMeta->diffuseToTotalRatio[sf + DELAY_MASA_PARAM_DEC_SFR][band]; + extOutMeta->diffuseToTotalRatio[sf + DELAY_MASA_PARAM_DEC_SFR][band] = extOutMeta->diffuseToTotalRatio[sf][band]; + extOutMeta->diffuseToTotalRatio[sf][band] = temp; + } + } + + /* Finalize descriptive meta by using new frame except for number of directions which is the larger of the two */ + currentNumberOfDirections = extOutMeta->descriptiveMeta.numberOfDirections; + if ( delayStorage->descriptiveMeta.numberOfDirections > extOutMeta->descriptiveMeta.numberOfDirections ) + { + extOutMeta->descriptiveMeta.numberOfDirections = delayStorage->descriptiveMeta.numberOfDirections; + } + delayStorage->descriptiveMeta.numberOfDirections = currentNumberOfDirections; + + return; +} +#endif /*---------------------------------------------------------------------* - * MasaFileWriter_writeFrame() + * MasaFileWriter_open() * * *---------------------------------------------------------------------*/ ivas_error MasaFileWriter_open( const char *outputWavFilename, /* i : name of the output audio file */ - MasaFileWriter **masaWriter /* o : MasaFileWriter handle */ +#ifdef FIX_350_MASA_DELAY_COMP + const bool delayCompensationEnabled, /* i : is delay compensation enabled */ +#endif + MasaFileWriter **masaWriter /* o : MasaFileWriter handle */ ) { MasaFileWriter *self; @@ -109,6 +188,13 @@ ivas_error MasaFileWriter_open( self->file_path = calloc( sizeof( char ), strlen( filePath ) + 1 ); strcpy( self->file_path, filePath ); +#ifdef FIX_350_MASA_DELAY_COMP + if ( !delayCompensationEnabled ) + { + self->delayStorage = calloc( sizeof( MASA_META_DELAY_STORAGE ), 1 ); + } +#endif + *masaWriter = self; return IVAS_ERR_OK; @@ -122,8 +208,12 @@ ivas_error MasaFileWriter_open( *---------------------------------------------------------------------*/ ivas_error MasaFileWriter_writeFrame( - MasaFileWriter *self, /* i/o: MasaFileWriter handle */ - IVAS_MASA_QMETADATA_HANDLE hMasaQMetadata /* i/o: MASA qMetadata handle to be written */ + MasaFileWriter *self, /* i/o: MasaFileWriter handle */ +#ifdef FIX_350_MASA_DELAY_COMP + MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta /* i/o: MASA ext out meta handle to be written */ +#else + IVAS_MASA_QMETADATA_HANDLE hMasaQMetadata /* i/o: MASA qMetadata handle to be written */ +#endif ) { if ( self == NULL ) @@ -131,6 +221,11 @@ ivas_error MasaFileWriter_writeFrame( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } +#ifdef FIX_350_MASA_DELAY_COMP + uint16_t descMetaTemp = 0; + int16_t i, sf, dir, numDirections; + uint8_t writeTempOther[MASA_FREQUENCY_BANDS]; +#else const uint8_t ivasmasaFormatDescriptor[8] = { 0x49, 0x56, 0x41, 0x53, 0x4D, 0x41, 0x53, 0x41 }; /* "IVASMASA" */ uint16_t descMetaTemp = 0; int16_t i, sf, b_old, b_new, dir; @@ -146,7 +241,45 @@ ivas_error MasaFileWriter_writeFrame( numCodingBands = hMasaQMetadata->numCodingBands; bandMap = hMasaQMetadata->bandMap; nchan_transport = hMasaQMetadata->nchan_transport; +#endif + +#ifdef FIX_350_MASA_DELAY_COMP + /* If delay storage has been reserved, then we are in the normal mode for the decoder + * (i.e., no delay compensation for PCM) which means that metadata should be delayed + * by two subframes (10 ms). Descriptive metadata is a combined result. */ + if ( self->delayStorage ) + { + delayMasaMetadata( hMasaExtOutMeta, self->delayStorage ); + } + numDirections = hMasaExtOutMeta->descriptiveMeta.numberOfDirections + 1; + + if ( fwrite( &( hMasaExtOutMeta->descriptiveMeta.formatDescriptor ), sizeof( uint8_t ), 8, self->file ) != 8 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + + descMetaTemp += hMasaExtOutMeta->descriptiveMeta.numberOfDirections << 15u; + descMetaTemp += hMasaExtOutMeta->descriptiveMeta.numberOfChannels << 14u; + descMetaTemp += hMasaExtOutMeta->descriptiveMeta.sourceFormat << 12u; + if ( hMasaExtOutMeta->descriptiveMeta.sourceFormat == 0x0 || hMasaExtOutMeta->descriptiveMeta.sourceFormat == 0x1 ) + { + descMetaTemp += hMasaExtOutMeta->descriptiveMeta.transportDefinition << 9u; + descMetaTemp += hMasaExtOutMeta->descriptiveMeta.channelAngle << 6u; + descMetaTemp += hMasaExtOutMeta->descriptiveMeta.channelDistance; + } + else if ( hMasaExtOutMeta->descriptiveMeta.sourceFormat == 0x2 ) + { + descMetaTemp += hMasaExtOutMeta->descriptiveMeta.channelLayout << 9u; + /* 9 LSB remain at zero */ + } + else if ( hMasaExtOutMeta->descriptiveMeta.sourceFormat == 0x3 ) + { + descMetaTemp += hMasaExtOutMeta->descriptiveMeta.transportDefinition << 9u; + descMetaTemp += hMasaExtOutMeta->descriptiveMeta.channelAngle << 6u; + /* 6 LSB remain at zero */ + } +#else /* Construct descriptive meta */ for ( i = 0; i < 8; i++ ) { @@ -186,6 +319,7 @@ ivas_error MasaFileWriter_writeFrame( descMetaTemp += descMeta.channelAngle << 6u; /* 6 LSB remain at zero */ } +#endif if ( fwrite( &( descMetaTemp ), sizeof( uint16_t ), 1, self->file ) != 1 ) { @@ -197,6 +331,9 @@ ivas_error MasaFileWriter_writeFrame( for ( dir = 0; dir < numDirections; dir++ ) { /* Spherical index */ +#ifdef FIX_350_MASA_DELAY_COMP + if ( fwrite( hMasaExtOutMeta->directionIndex[dir][sf], sizeof( uint16_t ), MASA_FREQUENCY_BANDS, self->file ) != MASA_FREQUENCY_BANDS ) +#else for ( i = 0; i < MASA_FREQUENCY_BANDS; i++ ) { writeTempIndex[i] = SPH_IDX_FRONT; @@ -211,11 +348,15 @@ ivas_error MasaFileWriter_writeFrame( } if ( fwrite( writeTempIndex, sizeof( uint16_t ), MASA_FREQUENCY_BANDS, self->file ) != MASA_FREQUENCY_BANDS ) +#endif { return IVAS_ERR_FAILED_FILE_WRITE; } /* Direct-to-total ratio */ +#ifdef FIX_350_MASA_DELAY_COMP + if ( fwrite( hMasaExtOutMeta->directToTotalRatio[dir][sf], sizeof( uint8_t ), MASA_FREQUENCY_BANDS, self->file ) != MASA_FREQUENCY_BANDS ) +#else for ( i = 0; i < MASA_FREQUENCY_BANDS; i++ ) { writeTempOther[i] = 0; @@ -230,11 +371,15 @@ ivas_error MasaFileWriter_writeFrame( } if ( fwrite( writeTempOther, sizeof( uint8_t ), MASA_FREQUENCY_BANDS, self->file ) != MASA_FREQUENCY_BANDS ) +#endif { return IVAS_ERR_FAILED_FILE_WRITE; } /* Spread coherence */ +#ifdef FIX_350_MASA_DELAY_COMP + if ( fwrite( hMasaExtOutMeta->spreadCoherence[dir][sf], sizeof( uint8_t ), MASA_FREQUENCY_BANDS, self->file ) != MASA_FREQUENCY_BANDS ) +#else for ( i = 0; i < MASA_FREQUENCY_BANDS; i++ ) { writeTempOther[i] = 0; @@ -252,6 +397,7 @@ ivas_error MasaFileWriter_writeFrame( } if ( fwrite( writeTempOther, sizeof( uint8_t ), MASA_FREQUENCY_BANDS, self->file ) != MASA_FREQUENCY_BANDS ) +#endif { return IVAS_ERR_FAILED_FILE_WRITE; } @@ -259,6 +405,9 @@ ivas_error MasaFileWriter_writeFrame( /* Common spatial meta */ /* Diffuse-to-total ratio = 1 - sum(direct-to-total ratios) */ +#ifdef FIX_350_MASA_DELAY_COMP + if ( fwrite( hMasaExtOutMeta->diffuseToTotalRatio[sf], sizeof( uint8_t ), MASA_FREQUENCY_BANDS, self->file ) != MASA_FREQUENCY_BANDS ) +#else for ( b_new = 0; b_new < MASA_FREQUENCY_BANDS; b_new++ ) { writeTempOther[b_new] = UINT8_MAX; @@ -277,11 +426,16 @@ ivas_error MasaFileWriter_writeFrame( } if ( fwrite( writeTempOther, sizeof( uint8_t ), MASA_FREQUENCY_BANDS, self->file ) != MASA_FREQUENCY_BANDS ) +#endif { return IVAS_ERR_FAILED_FILE_WRITE; } /* Surround coherence */ +#ifdef FIX_350_MASA_DELAY_COMP + if ( fwrite( hMasaExtOutMeta->surroundCoherence[sf], sizeof( uint8_t ), MASA_FREQUENCY_BANDS, self->file ) != MASA_FREQUENCY_BANDS ) +#else + /* Surround coherence */ for ( i = 0; i < MASA_FREQUENCY_BANDS; i++ ) { writeTempOther[i] = 0; @@ -299,16 +453,24 @@ ivas_error MasaFileWriter_writeFrame( } if ( fwrite( writeTempOther, sizeof( uint8_t ), MASA_FREQUENCY_BANDS, self->file ) != MASA_FREQUENCY_BANDS ) +#endif { return IVAS_ERR_FAILED_FILE_WRITE; } /* Remainder-to-total ratio */ /* This is zero after codec */ +#ifdef FIX_350_MASA_DELAY_COMP + for ( i = 0; i < MASA_FREQUENCY_BANDS; i++ ) + { + writeTempOther[i] = 0u; + } +#else for ( b_new = 0; b_new < MASA_FREQUENCY_BANDS; b_new++ ) { writeTempOther[b_new] = 0u; } +#endif if ( fwrite( writeTempOther, sizeof( uint8_t ), MASA_FREQUENCY_BANDS, self->file ) != MASA_FREQUENCY_BANDS ) { @@ -337,6 +499,9 @@ void MasaFileWriter_close( fclose( ( *selfPtr )->file ); free( ( *selfPtr )->file_path ); +#ifdef FIX_350_MASA_DELAY_COMP + free( ( *selfPtr )->delayStorage ); +#endif free( *selfPtr ); *selfPtr = NULL; diff --git a/lib_util/masa_file_writer.h b/lib_util/masa_file_writer.h index a01b90e7ee412a082d7034c43db9bf102b1957f8..cb7d8f3d1efdb608e5e880be8a18a49bd43bffec 100644 --- a/lib_util/masa_file_writer.h +++ b/lib_util/masa_file_writer.h @@ -33,6 +33,11 @@ #ifndef IVAS_MASA_FILE_WRITER_H #define IVAS_MASA_FILE_WRITER_H +#include +#include "options.h" +#ifdef FIX_350_MASA_DELAY_COMP +#include +#endif #include "common_api_types.h" @@ -41,12 +46,19 @@ typedef struct MasaFileWriter MasaFileWriter; ivas_error MasaFileWriter_open( const char *outputWavFilename, /* i : name of the output audio file */ - MasaFileWriter **masaWriter /* o : MasaFileWriter handle */ +#ifdef FIX_350_MASA_DELAY_COMP + const bool delayCompensationEnabled, /* i : is delay compensation enabled */ +#endif + MasaFileWriter **masaWriter /* o : MasaFileWriter handle */ ); ivas_error MasaFileWriter_writeFrame( - MasaFileWriter *self, /* i/o: MasaFileWriter handle */ + MasaFileWriter *self, /* i/o: MasaFileWriter handle */ +#ifdef FIX_350_MASA_DELAY_COMP + MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta /* i/o: MASA ext out meta handle to be written */ +#else IVAS_MASA_QMETADATA_HANDLE hMasaQMetadata /* i/o: MASA qMetadata handle to be written */ +#endif ); void MasaFileWriter_close(