From e3e976b42e49f182eb18f3c6009923618e81e31d Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Wed, 13 Mar 2024 15:46:16 +0100 Subject: [PATCH 01/54] Update split rendering bitstream format --- apps/decoder.c | 24 +- apps/isar_post_rend.c | 34 +- apps/renderer.c | 37 +- lib_com/common_api_types.h | 6 + lib_com/ivas_cnst.h | 7 + lib_com/ivas_error.h | 4 + lib_com/options.h | 7 + lib_dec/lib_dec.c | 15 +- lib_dec/lib_dec.h | 4 + lib_isar/isar_lc3plus_common.c | 28 + lib_isar/isar_lc3plus_common.h | 21 +- lib_isar/isar_lc3plus_dec.c | 262 ++- lib_isar/isar_lc3plus_dec.h | 19 +- lib_isar/isar_lc3plus_enc.c | 325 ++- lib_isar/isar_lc3plus_enc.h | 32 +- lib_isar/isar_lc3plus_payload.c | 819 +++++++ lib_isar/isar_lc3plus_payload.h | 215 ++ lib_isar/isar_prot.h | 12 +- lib_isar/isar_splitRendererPre.c | 132 +- lib_isar/isar_splitRenderer_utils.c | 17 +- lib_isar/lib_isar_post_rend.c | 59 +- lib_isar/lib_isar_post_rend.h | 9 +- lib_rend/ivas_render_config.c | 3 + lib_rend/lib_rend.c | 3 + lib_rend/lib_rend.h | 3 + lib_util/render_config_reader.c | 9 + lib_util/split_render_file_read_write.c | 40 +- lib_util/split_render_file_read_write.h | 16 +- .../lc3plus/ivas_lc3plus_unit_test.c | 193 +- .../ivas_lc3plus_unit_test_payload_format.c | 451 ++++ ...vas_lc3plus_unit_test_selective_decoding.c | 1953 ----------------- 31 files changed, 2579 insertions(+), 2180 deletions(-) create mode 100644 lib_isar/isar_lc3plus_payload.c create mode 100644 lib_isar/isar_lc3plus_payload.h create mode 100644 scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test_payload_format.c delete mode 100644 scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test_selective_decoding.c diff --git a/apps/decoder.c b/apps/decoder.c index 41a3d327ee..33b1f8f9fc 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -1830,6 +1830,9 @@ static ivas_error initOnFirstGoodFrame( ISAR_SPLIT_REND_CODEC splitRendCodec; int16_t splitRendCodecFrameSizeMs; ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection; +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + int16_t lc3plusHighRes; +#endif if ( ( error = IVAS_DEC_GetDelay( hIvasDec, delayNumSamples_temp, &delayTimeScale_temp ) ) != IVAS_ERR_OK ) { @@ -1837,11 +1840,21 @@ static ivas_error initOnFirstGoodFrame( return error; } - IVAS_DEC_GetSplitRendBitstreamHeader( hIvasDec, &splitRendCodec, &poseCorrection, &splitRendCodecFrameSizeMs ); + IVAS_DEC_GetSplitRendBitstreamHeader( hIvasDec, &splitRendCodec, &poseCorrection, &splitRendCodecFrameSizeMs +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + , + &lc3plusHighRes +#endif + ); if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) { - if ( ( error = split_rend_writer_open( splitRendWriter, arg.outputWavFilename, delayNumSamples_temp[0], delayTimeScale_temp, splitRendCodec, poseCorrection, splitRendCodecFrameSizeMs ) ) != IVAS_ERR_OK ) + if ( ( error = split_rend_writer_open( splitRendWriter, arg.outputWavFilename, delayNumSamples_temp[0], delayTimeScale_temp, splitRendCodec, poseCorrection, splitRendCodecFrameSizeMs +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + , + arg.output_Fs, lc3plusHighRes +#endif + ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nUnable to open output split rendering metadata file %s\n", arg.outputWavFilename ); return error; @@ -1849,7 +1862,12 @@ static ivas_error initOnFirstGoodFrame( } else { - if ( ( error = split_rend_writer_open( splitRendWriter, arg.outputMdFilename, delayNumSamples_temp[0], delayTimeScale_temp, splitRendCodec, poseCorrection, splitRendCodecFrameSizeMs ) ) != IVAS_ERR_OK ) + if ( ( error = split_rend_writer_open( splitRendWriter, arg.outputMdFilename, delayNumSamples_temp[0], delayTimeScale_temp, splitRendCodec, poseCorrection, splitRendCodecFrameSizeMs +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + , + arg.output_Fs, lc3plusHighRes +#endif + ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nUnable to open output split rendering metadata file %s\n", arg.outputWavFilename ); return error; diff --git a/apps/isar_post_rend.c b/apps/isar_post_rend.c index 3dd7ed99a5..ecc5f36a44 100644 --- a/apps/isar_post_rend.c +++ b/apps/isar_post_rend.c @@ -895,6 +895,9 @@ int main( bitsBuffer.config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; bitsBuffer.config.poseCorrection = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; bitsBuffer.config.codec_frame_size_ms = 20; +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + bitsBuffer.config.lc3plusHighRes = 0; +#endif CmdlnArgs args = parseCmdlnArgs( argc, argv ); @@ -927,11 +930,19 @@ int main( } } +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + int32_t inFileSampleRate = 0; +#endif strncpy( audioFilePath, args.inputFilePath, FILENAME_MAX - 1 ); hSplitRendFileReadWrite = NULL; if ( ( args.inConfig.numBinBuses > 0 ) && ( args.inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) { - error = split_rend_reader_open( &hSplitRendFileReadWrite, args.inMetadataFilePaths[0], &bitsBuffer.config.codec, &bitsBuffer.config.poseCorrection, &bitsBuffer.config.codec_frame_size_ms ); + error = split_rend_reader_open( &hSplitRendFileReadWrite, args.inMetadataFilePaths[0], &bitsBuffer.config.codec, &bitsBuffer.config.poseCorrection, &bitsBuffer.config.codec_frame_size_ms +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + , + &inFileSampleRate, &bitsBuffer.config.lc3plusHighRes +#endif + ); if ( error != IVAS_ERR_OK ) { fprintf( stderr, "Could not open split rend metadata file %s\n", args.inMetadataFilePaths[0] ); @@ -948,7 +959,12 @@ int main( /*if split renderer is running in post renderer mode*/ if ( ( args.inConfig.numBinBuses > 0 ) && ( args.inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ) { - error = split_rend_reader_open( &hSplitRendFileReadWrite, args.inputFilePath, &bitsBuffer.config.codec, &bitsBuffer.config.poseCorrection, &bitsBuffer.config.codec_frame_size_ms ); + error = split_rend_reader_open( &hSplitRendFileReadWrite, args.inputFilePath, &bitsBuffer.config.codec, &bitsBuffer.config.poseCorrection, &bitsBuffer.config.codec_frame_size_ms +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + , + &inFileSampleRate, &bitsBuffer.config.lc3plusHighRes +#endif + ); if ( error != IVAS_ERR_OK ) { fprintf( stderr, "Could not open split rend metadata file %s\n", args.inputFilePath ); @@ -957,12 +973,17 @@ int main( audioReader = NULL; } +#ifndef SPLIT_REND_EXTEND_BITSTREAM_HEADER int32_t inFileSampleRate = 0; +#endif if ( audioReader != NULL ) { error = AudioFileReader_getSamplingRate( audioReader, &inFileSampleRate ); } else +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + if ( hSplitRendFileReadWrite == NULL ) +#endif { inFileSampleRate = args.sampleRate; } @@ -970,7 +991,7 @@ int main( switch ( error ) { case IVAS_ERR_OK: - /* If sampling rate not given on command line, use the one from wav file */ + /* If sampling rate not given on command line, use the one from SR file */ if ( args.sampleRate == 0 ) { args.sampleRate = inFileSampleRate; @@ -1022,7 +1043,12 @@ int main( if ( args.inConfig.numBinBuses > 0 ) { IVAS_REND_SetSplitRendBitstreamHeader( hIsarPostRend, bitsBuffer.config.codec, bitsBuffer.config.poseCorrection, - bitsBuffer.config.codec_frame_size_ms ); + bitsBuffer.config.codec_frame_size_ms +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + , + bitsBuffer.config.lc3plusHighRes +#endif + ); } diff --git a/apps/renderer.c b/apps/renderer.c index 00b9082820..81f5d11890 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -649,7 +649,15 @@ static void setupWithSingleFormatInput( if ( args.inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { ivas_error error; - error = split_rend_reader_open( hhSplitRendFileReadWrite, args.inMetadataFilePaths[0], &hBitsBuffer->config.codec, &hBitsBuffer->config.poseCorrection, &hBitsBuffer->config.codec_frame_size_ms ); +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + int32_t sr_fs = 0; +#endif + error = split_rend_reader_open( hhSplitRendFileReadWrite, args.inMetadataFilePaths[0], &hBitsBuffer->config.codec, &hBitsBuffer->config.poseCorrection, &hBitsBuffer->config.codec_frame_size_ms +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + , + &sr_fs, &hBitsBuffer->config.lc3plus_highres +#endif + ); if ( error != IVAS_ERR_OK ) { fprintf( stderr, "Could not open split rend metadata file %s\n", args.inMetadataFilePaths[0] ); @@ -811,6 +819,9 @@ int main( bitsBuffer.config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; bitsBuffer.config.poseCorrection = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; bitsBuffer.config.codec_frame_size_ms = 20; +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + bitsBuffer.config.lc3plus_highres = 0; +#endif #endif for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) { @@ -932,8 +943,16 @@ int main( /*if split renderer is running in post renderer mode*/ if ( ( args.inConfig.numBinBuses > 0 ) && ( args.inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ) { +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + int32_t sr_fs = 0; +#endif error = split_rend_reader_open( &hSplitRendFileReadWrite, args.inputFilePath, &bitsBuffer.config.codec, &bitsBuffer.config.poseCorrection, - &bitsBuffer.config.codec_frame_size_ms ); + &bitsBuffer.config.codec_frame_size_ms +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + , + &sr_fs, &bitsBuffer.config.lc3plus_highres +#endif + ); if ( error != IVAS_ERR_OK ) { fprintf( stderr, "Could not open split rend metadata file %s\n", args.inputFilePath ); @@ -1487,7 +1506,12 @@ int main( exit( -1 ); } - if ( ( error = split_rend_writer_open( &hSplitRendFileReadWrite, args.outputFilePath, delayNumSamples_temp, delayTimeScale_temp, bitsBuffer.config.codec, bitsBuffer.config.poseCorrection, bitsBuffer.config.codec_frame_size_ms ) ) != IVAS_ERR_OK ) + if ( ( error = split_rend_writer_open( &hSplitRendFileReadWrite, args.outputFilePath, delayNumSamples_temp, delayTimeScale_temp, bitsBuffer.config.codec, bitsBuffer.config.poseCorrection, bitsBuffer.config.codec_frame_size_ms +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + , + args.sampleRate, bitsBuffer.config.lc3plus_highres +#endif + ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Could not open split rend metadata file %s\n", args.outputFilePath ); exit( -1 ); @@ -1507,7 +1531,12 @@ int main( exit( -1 ); } - if ( ( error = split_rend_writer_open( &hSplitRendFileReadWrite, args.outMetadataFilePath, delayNumSamples_temp, delayTimeScale_temp, bitsBuffer.config.codec, bitsBuffer.config.poseCorrection, bitsBuffer.config.codec_frame_size_ms ) ) != IVAS_ERR_OK ) + if ( ( error = split_rend_writer_open( &hSplitRendFileReadWrite, args.outMetadataFilePath, delayNumSamples_temp, delayTimeScale_temp, bitsBuffer.config.codec, bitsBuffer.config.poseCorrection, bitsBuffer.config.codec_frame_size_ms +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + , + args.sampleRate, bitsBuffer.config.lc3plus_highres +#endif + ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Could not open split rend metadata file %s\n", args.outMetadataFilePath ); exit( -1 ); diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index 1b0bddb1c2..c8a7a38674 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -252,6 +252,9 @@ typedef struct _ISAR_SPLIT_REND_BITS_DATA int16_t codec_frame_size_ms; ISAR_SPLIT_REND_CODEC codec; ISAR_SPLIT_REND_POSE_CORRECTION_MODE pose_correction; +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + int32_t lc3plus_highres; +#endif } ISAR_SPLIT_REND_BITS_DATA, *ISAR_SPLIT_REND_BITS_HANDLE; @@ -271,6 +274,9 @@ typedef struct _ISAR_SPLIT_REND_CONFIG ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode; ISAR_SPLIT_REND_CODEC codec; ISAR_SPLIT_REND_RENDERER_SELECTION rendererSelection; +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + int16_t lc3plus_highres; +#endif } ISAR_SPLIT_REND_CONFIG_DATA, *ISAR_SPLIT_REND_CONFIG_HANDLE; #endif diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index b1d5b5c421..8395e93d56 100755 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1586,10 +1586,17 @@ typedef enum #define IVAS_SPLIT_REND_PITCH_G_1BYQ_STEP (( IVAS_SPLIT_REND_PITCH_G_QUANT_PNTS - 1 )/( IVAS_SPLIT_REND_PITCH_G_MAX_VAL - IVAS_SPLIT_REND_PITCH_G_MIN_VAL )) #define IVAS_SPLIT_REND_MAX_NUM_BYTES 4000 +#ifdef SPLIT_REND_METADATA_SECTION_SIZE +#define IVAS_SPLIT_REND_MD_SIZE_BITS 13 /* Max expected size of the MD section: 256000 kbps / 50 fps = 5120 < 2^13 = 8192 */ +#endif #define IVAS_SPLIT_REND_HEAD_POSE_BITS 9 #define IVAS_SPLIT_REND_DOF_BITS 2 #define IVAS_SPLIT_REND_HQ_MODE_BITS 1 #define ISAR_SPLIT_REND_ROT_AXIS_BITS 3 + +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT +#define IVAS_LC3PLUS_MAX_NUM_DECODERS 2 +#endif #endif diff --git a/lib_com/ivas_error.h b/lib_com/ivas_error.h index d9d6b31138..0e00437b8e 100644 --- a/lib_com/ivas_error.h +++ b/lib_com/ivas_error.h @@ -104,6 +104,10 @@ typedef enum * input data errors * *----------------------------------------*/ IVAS_ERR_INVALID_BITSTREAM = 0x2000, +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + IVAS_ERR_UNEXPECTED_LC3PLUS_BITSTREAM, + IVAS_ERR_UNEXPECTED_LC3PLUS_BITSTREAM_CONFIG, +#endif /*----------------------------------------* * hardware errors * diff --git a/lib_com/options.h b/lib_com/options.h index 6ce72f4d6d..bb323766dc 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -159,6 +159,13 @@ #define SPLIT_REBD_FIX_SBA_PRE_ROT #define LCLD_PLC_IMPROVEMENT #define LCLD_CLEAN_UPS + +#define LC3PLUS_RTP_PAYLOAD_FORMAT /* FhG: uses the official RTP payload format instead of raw frames for the LC3plus bit stream*/ +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT +#define LC3PLUS_VBR /* FhG: re-uses unused pose correction bits for coding audio with LC3plus */ +#define SPLIT_REND_EXTEND_BITSTREAM_HEADER /* FhG: adds info to split rendering bitstream header, which is required to open LC3plus decoder before decoding first frame */ +#define SPLIT_REND_METADATA_SECTION_SIZE /* FhG: prepends metadata section in the split bitstream frame with size information */ +#endif #endif #define FIX_1020_AEID_SELECTION_ERRORS /* Philips: issue #1020: fix for acoustic environment ID selection errors */ diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index c5a4d5a96f..e0ef2d0d97 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -2035,6 +2035,8 @@ static ivas_error copyRendererConfigStruct( mvr2r( hRCin->roomAcoustics.pAcoustic_dsr, hRCout->roomAcoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); mvr2r( hRCin->directivity, hRCout->directivity, 3 * MAX_NUM_OBJECTS ); #ifdef SPLIT_REND_WITH_HEAD_ROT + /* TODO: This seems wrong. Why set default instead of copying from hRCin? + * Currently seems to work because we only ever copy from a default-initialized handle anyway */ hRCout->split_rend_config.splitRendBitRate = SPLIT_REND_768k; hRCout->split_rend_config.dof = 3; hRCout->split_rend_config.hq_mode = 0; @@ -2043,6 +2045,9 @@ static ivas_error copyRendererConfigStruct( hRCout->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; hRCout->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; hRCout->split_rend_config.rendererSelection = hRCin->split_rend_config.rendererSelection; +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + hRCout->split_rend_config.lc3plus_highres = hRCin->split_rend_config.lc3plus_highres; +#endif #endif hRCout->roomAcoustics.use_er = hRCin->roomAcoustics.use_er; hRCout->roomAcoustics.lowComplexity = hRCin->roomAcoustics.lowComplexity; @@ -3659,7 +3664,12 @@ ivas_error IVAS_DEC_GetSplitRendBitstreamHeader( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ ISAR_SPLIT_REND_CODEC *pCodec, /* o: pointer to codec setting */ ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o: pointer to pose correction mode */ - int16_t *pCodec_frame_size_ms /* o: pointer to codec frame size setting */ ) + int16_t *pCodec_frame_size_ms /* o: pointer to codec frame size setting */ +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + , + int16_t *pLc3plusHighRes +#endif +) { if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { @@ -3669,6 +3679,9 @@ ivas_error IVAS_DEC_GetSplitRendBitstreamHeader( *pCodec = hIvasDec->st_ivas->hRenderConfig->split_rend_config.codec; *pCodec_frame_size_ms = hIvasDec->st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms; *poseCorrection = hIvasDec->st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode; +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + *pLc3plusHighRes = hIvasDec->st_ivas->hRenderConfig->split_rend_config.lc3plus_highres; +#endif return IVAS_ERR_OK; } diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index cda969204e..a68da6aa06 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -183,6 +183,10 @@ ivas_error IVAS_DEC_GetSplitRendBitstreamHeader( ISAR_SPLIT_REND_CODEC *pCodec, /* o: pointer to codec setting */ ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o: pointer to pose correction mode */ int16_t *pCodec_frame_size_ms /* o: pointer to codec frame size setting */ +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + , + int16_t *pLc3plusHighRes /* o: pointer to LC3plus High-Res setting */ +#endif ); /*! r: decoder error code */ diff --git a/lib_isar/isar_lc3plus_common.c b/lib_isar/isar_lc3plus_common.c index 1f16239bb4..43c5384626 100644 --- a/lib_isar/isar_lc3plus_common.c +++ b/lib_isar/isar_lc3plus_common.c @@ -57,4 +57,32 @@ ivas_error IVAS_LC3PLUS_LC3plusErrToIvasErr( return IVAS_ERR_INTERNAL; } +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT +ivas_error IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( const LC3PLUS_RTP_ERR lc3PlusRtpError ) +{ + switch ( lc3PlusRtpError ) + { + case LC3PLUS_RTP_ERR_NO_ERROR: + return IVAS_ERR_OK; + case LC3PLUS_RTP_ERR_NULL_PTR: + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + case LC3PLUS_RTP_ERR_INVALID_PARAMETERS: + return IVAS_ERR_WRONG_PARAMS; + case LC3PLUS_RTP_ERR_NOT_IMPLEMENTED: + return IVAS_ERR_NOT_IMPLEMENTED; + case LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION: + return IVAS_ERR_INTERNAL; + case LC3PLUS_RTP_ERR_INVALID_BITSTREAM: + return IVAS_ERR_UNEXPECTED_LC3PLUS_BITSTREAM; + case LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE: + return IVAS_ERR_INVALID_BUFFER_SIZE; + case LC3PLUS_RTP_ERR_NOT_ENOUGH_FTDS_ALLOCATED: + return IVAS_ERR_INTERNAL; + case LC3PLUS_RTP_ERR_GENERIC_ERROR: + return IVAS_ERR_UNKNOWN; + default: + return IVAS_ERR_UNKNOWN; + } +} +#endif #endif diff --git a/lib_isar/isar_lc3plus_common.h b/lib_isar/isar_lc3plus_common.h index c0ecec55a4..1b2899a649 100644 --- a/lib_isar/isar_lc3plus_common.h +++ b/lib_isar/isar_lc3plus_common.h @@ -35,23 +35,34 @@ #include +#include "options.h" #include "ivas_error.h" #include "lc3.h" +#include "isar_lc3plus_payload.h" /*! common configuration parameters between encoder and decoder */ typedef struct LC3PLUS_CONFIG { /*! frame duration in microseconds [10000, 5000, 2500] */ - uint32_t lc3plus_frame_duration_us; + int32_t lc3plus_frame_duration_us; /*! ivas frame duration in microseconds [20000, 5000] */ - uint32_t ivas_frame_duration_us; + int32_t ivas_frame_duration_us; /*! sampling rate*/ - uint32_t samplerate; + int32_t samplerate; /*! number of channels */ - uint16_t channels; + int16_t channels; +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + /*! high resolution mode enabled (1) or disabled (0)*/ + int16_t high_res_mode_enabled; +#endif } LC3PLUS_CONFIG; /*! utility function to convert LC3PLUS_Errors to the suitable ivas_error */ ivas_error IVAS_LC3PLUS_LC3plusErrToIvasErr( const LC3PLUS_Error lc3PlusError ); -#endif /* IVAS_LC3PLUS_COM_H */ +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT +/*! utility function to convert LC3PLUS_Errors to the suitable ivas_error */ +ivas_error IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( const LC3PLUS_RTP_ERR lc3PlusRtpError ); +#endif + +#endif /* ISAR_LC3PLUS_COM_H */ diff --git a/lib_isar/isar_lc3plus_dec.c b/lib_isar/isar_lc3plus_dec.c index 6af5549a2d..440e9d60c0 100644 --- a/lib_isar/isar_lc3plus_dec.c +++ b/lib_isar/isar_lc3plus_dec.c @@ -55,20 +55,39 @@ ivas_error IVAS_LC3PLUS_DEC_Open( { LC3PLUS_Error err; int32_t decoder_size; +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + int16_t i; + + if ( 0 == config.lc3plus_frame_duration_us ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid lc3plus_frame_duration_us (0)\n" ); + } +#else int16_t lc3plusFrameIdx; int16_t numLC3plusFramesPerIvasFrame; int16_t i; +#endif if ( ( *handle = malloc( sizeof( struct ISAR_LC3PLUS_DEC_HANDLE ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); } +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + if ( config.channels > IVAS_LC3PLUS_MAX_NUM_DECODERS ) + { + return IVAS_ERROR( IVAS_ERR_INIT_ERROR, "Maximum number of channels exceeds IVAS_LC3PLUS_MAX_NUM_DECODERS\n" ); + } +#else + if ( 0 == config.lc3plus_frame_duration_us ) { return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid lc3plus_frame_duration_us (0)\n" ); } +#endif +#ifndef LC3PLUS_RTP_PAYLOAD_FORMAT numLC3plusFramesPerIvasFrame = (int16_t) ( config.ivas_frame_duration_us / config.lc3plus_frame_duration_us ); +#endif ( *handle )->num_decs = 0; @@ -127,7 +146,11 @@ ivas_error IVAS_LC3PLUS_DEC_Open( return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); } +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + err = lc3plus_dec_init( ( *handle )->handles[iCh], config.samplerate, 1, LC3PLUS_PLC_ADVANCED, config.high_res_mode_enabled ); +#else err = lc3plus_dec_init( ( *handle )->handles[iCh], config.samplerate, 1, LC3PLUS_PLC_ADVANCED, 0 ); +#endif if ( LC3PLUS_OK != err ) { IVAS_LC3PLUS_DEC_Close( handle ); @@ -148,18 +171,24 @@ ivas_error IVAS_LC3PLUS_DEC_Open( return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); } +#ifndef LC3PLUS_RTP_PAYLOAD_FORMAT if ( ( ( *handle )->selective_decoding_states[iCh]->frame_actions = malloc( numLC3plusFramesPerIvasFrame * sizeof( SelectiveDecAction ) ) ) == NULL ) { IVAS_LC3PLUS_DEC_Close( handle ); return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); } +#endif ( *handle )->selective_decoding_states[iCh]->has_skipped_a_frame = 0; ( *handle )->selective_decoding_states[iCh]->shall_decode_cached_frame = 0; +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + ( *handle )->selective_decoding_states[iCh]->frame_action = DEC_ACTION_DECODE_AND_USE; +#else for ( lc3plusFrameIdx = 0; lc3plusFrameIdx < numLC3plusFramesPerIvasFrame; lc3plusFrameIdx++ ) { ( *handle )->selective_decoding_states[iCh]->frame_actions[lc3plusFrameIdx] = DEC_ACTION_DECODE_AND_USE; } +#endif /* allocate and configure per LC3plus decoder bitstream cache */ if ( ( ( *handle )->bitstream_caches[iCh] = malloc( sizeof( IVAS_LC3PLUS_DEC_BITSTREAM_CACHE ) ) ) == NULL ) @@ -167,7 +196,11 @@ ivas_error IVAS_LC3PLUS_DEC_Open( IVAS_LC3PLUS_DEC_Close( handle ); return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); } +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity = 400 /*LC3plus max non-HR octet count*/; +#else ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity = 400 /*LC3plus max non-HR octet count*/ * numLC3plusFramesPerIvasFrame; +#endif if ( ( ( *handle )->bitstream_caches[iCh]->bitstream_cache = malloc( ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity ) ) == NULL ) { IVAS_LC3PLUS_DEC_Close( handle ); @@ -192,7 +225,7 @@ ivas_error IVAS_LC3PLUS_DEC_Open( return IVAS_ERR_OK; } - +#ifndef LC3PLUS_RTP_PAYLOAD_FORMAT /*------------------------------------------------------------------------- * IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix() * @@ -246,121 +279,7 @@ void IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( return; } - - -/*------------------------------------------------------------------------- - * IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix() - * - * - *------------------------------------------------------------------------*/ - -ivas_error IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( - ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */ - int16_t *subframeChannelMatrix[MAX_PARAM_SPATIAL_SUBFRAMES] ) -{ - int16_t numIvasSubFramesPerLC3frame; - uint32_t decIdx; - int16_t ivasSubframeIdx; - int16_t effectiveIvasSubframeDuration; - int16_t actual_num_spatial_subframes; - - if ( NULL == handle ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "ISAR_LC3PLUS_DEC_HANDLE is NULL\n" ); - } - - if ( NULL == subframeChannelMatrix ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "subframeChannelMatrix is NULL\n" ); - } - - if ( handle->config.lc3plus_frame_duration_us == 0 || handle->config.ivas_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) - { - return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "invalid ivas_frame_duration_us/lc3plus_frame_duration_us values\n" ); - } - - effectiveIvasSubframeDuration = (int16_t) ( handle->config.ivas_frame_duration_us == 20000 ? handle->config.ivas_frame_duration_us / MAX_PARAM_SPATIAL_SUBFRAMES : handle->config.ivas_frame_duration_us ); - numIvasSubFramesPerLC3frame = (int16_t) handle->config.lc3plus_frame_duration_us / effectiveIvasSubframeDuration; - actual_num_spatial_subframes = (int16_t) handle->config.ivas_frame_duration_us / effectiveIvasSubframeDuration; - /* 0.5(0) = 10ms lc3plus, 5ms subframe */ - if ( numIvasSubFramesPerLC3frame != 1 ) - { - return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Selective decoding is only implemented for aligned IVAS-Subframes & LC3plus \n" ); - } - - /* map subframeChannelMatrix to lc3plus skip states */ - /* 1st pass: Flag the required frames */ - for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) - { - for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) - { - if ( 1 == subframeChannelMatrix[ivasSubframeIdx][decIdx] ) - { - /* subframe needed by the user, definitely decode */ - handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_DECODE_AND_USE; - } - else - { - - /* subframe not needed by the user, but might be required to re-initialize a decoder after inactivity */ - if ( - ( ivasSubframeIdx != actual_num_spatial_subframes - 1 ) && 1 == subframeChannelMatrix[ivasSubframeIdx + 1][decIdx] ) - { - /* ... but if the following subframe is required, it needs to be decoded and dropped */ - handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_DECODE_AND_DROP; - } - else - { - handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_SKIP; - } - } - } - } - - /* if a decoder was paused before, it needs to either: - * - Decode the cached frame (if available) and the first required frame OR - * - Decode the previous LC3plus subframe, even if it isn't needed by the user */ - for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) - { - if ( handle->selective_decoding_states[decIdx]->has_skipped_a_frame ) - { - /* find the first frame required by the user */ - for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) - { - if ( DEC_ACTION_DECODE_AND_USE == handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] ) - { - /* The first required frame is the first subframe. To flush the decoder, the cached frame must be decoded and dropped */ - if ( 0 == ivasSubframeIdx ) - { - handle->selective_decoding_states[decIdx]->shall_decode_cached_frame = 1; - break; - } - /* The first required frame is not the first frame, so the cache is useless. Instead we decode & drop the previous frame*/ - else - { - handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx - 1] = DEC_ACTION_DECODE_AND_DROP; - break; - } - } - } - } - } - - /* if a dec gets paused & caching is activated we need to flag the last useful LC3plus frame for caching */ - for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) - { - for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) - { - if ( handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] == DEC_ACTION_SKIP && handle->selective_decoding_states[decIdx]->frame_actions[actual_num_spatial_subframes - 1] != DEC_ACTION_DECODE_AND_USE ) - { - handle->selective_decoding_states[decIdx]->frame_actions[actual_num_spatial_subframes - 1] = DEC_ACTION_CACHE; - } - } - } - - return IVAS_ERR_OK; -} - +#endif /*------------------------------------------------------------------------- * IVAS_LC3PLUS_DEC_GetDelay() @@ -430,7 +349,9 @@ void IVAS_LC3PLUS_DEC_Close( if ( NULL != ( *handle )->selective_decoding_states && NULL != ( *handle )->selective_decoding_states[iDec] ) { +#ifndef LC3PLUS_RTP_PAYLOAD_FORMAT free( ( *handle )->selective_decoding_states[iDec]->frame_actions ); +#endif free( ( *handle )->selective_decoding_states[iDec] ); } @@ -509,13 +430,20 @@ static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( ) { uint32_t iDec; +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + int32_t config_num_media_times; + int32_t iMediaTime; + int32_t iFtd; + LC3PLUS_RTP_PAYLOAD payload; +#else int32_t iLc3plusFrame; int32_t lc3framesPerIvasFrame; + int32_t bitstreamOffsetPerCoder; + uint8_t *bitstream_in_iter = bitstream_in; +#endif int32_t ivasSampleIndex; int16_t numSamplesPerLC3plusChannel; - int32_t bitstreamOffsetPerCoder; ivas_error err; - uint8_t *bitstream_in_iter = bitstream_in; if ( NULL == handle ) { @@ -543,6 +471,45 @@ static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "ivas_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); } +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + config_num_media_times = handle->config.ivas_frame_duration_us / handle->config.lc3plus_frame_duration_us; + if ( !badFrameIndicator ) + { + if ( LC3PLUS_RTP_payload_deserialize( &payload, bitstream_in, bitstream_in_size ) != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_payload_deserialize failed\n" ); + } + if ( payload.sampling_rate_hz != handle->config.samplerate ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (samplerate) in bitstream is not supported\n" ); + } + if ( payload.num_channels != handle->config.channels ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (number of channels) in bitstream is not supported\n" ); + } + if ( payload.frame_duration_us != handle->config.lc3plus_frame_duration_us ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (frame duration) in bitstream is not supported\n" ); + } + if ( payload.high_resolution_enabled != handle->config.high_res_mode_enabled ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (high resolution mode) in bitstream is not supported\n" ); + } + if ( payload.num_media_times != config_num_media_times ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (number of media times per frame data block) in bitstream is not supported\n" ); + } + } +#endif + +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + numSamplesPerLC3plusChannel = (int16_t) ( handle->config.samplerate / ( 1000000 / handle->config.ivas_frame_duration_us ) / config_num_media_times ); + for ( iDec = 0; iDec < handle->num_decs; iDec++ ) + { + for ( iMediaTime = 0; iMediaTime < config_num_media_times; iMediaTime++ ) + { + iFtd = iDec + iMediaTime * handle->num_decs; +#else lc3framesPerIvasFrame = handle->config.ivas_frame_duration_us / handle->config.lc3plus_frame_duration_us; numSamplesPerLC3plusChannel = (int16_t) ( handle->config.samplerate / ( 1000000 / handle->config.ivas_frame_duration_us ) / lc3framesPerIvasFrame ); @@ -551,6 +518,7 @@ static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( { for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) { +#endif if ( handle->selective_decoding_states[iDec]->shall_decode_cached_frame ) { if ( 0 == handle->bitstream_caches[iDec]->bitstream_cache_size ) @@ -572,8 +540,14 @@ static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( { handle->bitstream_caches[iDec]->bitstream_cache_size = 0; } + +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + switch ( handle->selective_decoding_states[iDec]->frame_action ) +#else switch ( handle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] ) +#endif { +#ifndef LC3PLUS_RTP_PAYLOAD_FORMAT case DEC_ACTION_DECODE_AND_DROP: { err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in_iter, bitstreamOffsetPerCoder, &handle->pcm_conversion_buffer, badFrameIndicator ); @@ -584,8 +558,37 @@ static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; break; } +#endif case DEC_ACTION_DECODE_AND_USE: { +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + if ( badFrameIndicator ) + { + err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in, bitstream_in_size, &handle->pcm_conversion_buffer, badFrameIndicator ); + } + else if ( payload.ftds[iFtd].frame_data_length == LC3PLUS_RTP_FDL_SPEECH_BAD ) + { + return IVAS_ERR_NOT_IMPLEMENTED; + /* Untested therefore disabled. Would probably only need to call concealment, + * but the LC3plus API requires a non-NULL ptr for this which is not available here */ + } + else + { + err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], payload.ftds[iFtd].frame_data, payload.ftds[iFtd].frame_data_length, &handle->pcm_conversion_buffer, badFrameIndicator ); + } + if ( err != IVAS_ERR_OK ) + { + return IVAS_ERROR( err, "lc3plus decoding failed\n" ); + } + + for ( int16_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ ) + { + ivasSampleIndex = iSampleInt16 + iMediaTime * numSamplesPerLC3plusChannel; + pcm_out[iDec][ivasSampleIndex] = (float) handle->pcm_conversion_buffer[iSampleInt16]; + } + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; + break; +#else err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in_iter, bitstreamOffsetPerCoder, &handle->pcm_conversion_buffer, badFrameIndicator ); if ( err != IVAS_ERR_OK ) { @@ -599,15 +602,30 @@ static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( } handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; break; +#endif } +#ifndef LC3PLUS_RTP_PAYLOAD_FORMAT case DEC_ACTION_SKIP: { /* log that this instance has skipped a frame and must decode twice once reactivated */ handle->selective_decoding_states[iDec]->has_skipped_a_frame = 1; break; } +#endif case DEC_ACTION_CACHE: { +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + if ( handle->bitstream_caches[iDec]->bitstream_cache_capacity < (int32_t) payload.ftds[iFtd].frame_data_length ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "bitstream_cache_capacity is too low for LC3plus frame size\n" ); + } + /* store bit rate of cached frame */ + mvc2c( payload.ftds[iFtd].frame_data, handle->bitstream_caches[iDec]->bitstream_cache, (int16_t) payload.ftds[iFtd].frame_data_length ); + handle->bitstream_caches[iDec]->bitstream_cache_size = payload.ftds[iFtd].frame_data_length; + /* log that this instance has skipped a frame and must decode twice once reactivated */ + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 1; + break; +#else if ( handle->bitstream_caches[iDec]->bitstream_cache_capacity < bitstreamOffsetPerCoder ) { return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "bitstream_cache_capacity is too low for LC3plus frame size\n" ); @@ -618,11 +636,18 @@ static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( /* log that this instance has skipped a frame and must decode twice once reactivated */ handle->selective_decoding_states[iDec]->has_skipped_a_frame = 1; break; +#endif } case DEC_ACTION_NUM_ENUMS: default: return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid LC3plus decoder state\n" ); } +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + } /* for each media time */ + /* reset skipping state, must be set by the user before each decode call*/ + handle->selective_decoding_states[iDec]->frame_action = DEC_ACTION_DECODE_AND_USE; + } /* for each dec/channel */ +#else bitstream_in_iter += bitstreamOffsetPerCoder; } @@ -634,6 +659,7 @@ static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( } } +#endif return IVAS_ERR_OK; } diff --git a/lib_isar/isar_lc3plus_dec.h b/lib_isar/isar_lc3plus_dec.h index 79db0b063a..052271f3f5 100644 --- a/lib_isar/isar_lc3plus_dec.h +++ b/lib_isar/isar_lc3plus_dec.h @@ -42,9 +42,13 @@ typedef enum { +#ifndef LC3PLUS_RTP_PAYLOAD_FORMAT DEC_ACTION_DECODE_AND_DROP = 0, +#endif DEC_ACTION_DECODE_AND_USE, +#ifndef LC3PLUS_RTP_PAYLOAD_FORMAT DEC_ACTION_SKIP, +#endif DEC_ACTION_CACHE, DEC_ACTION_NUM_ENUMS } SelectiveDecAction; @@ -54,8 +58,13 @@ typedef struct IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE { /*! indicates that the decoder has skipped one or more frames. This means it must decode two frames to flush algorithmic delay when re-activated */ int16_t has_skipped_a_frame; +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + /*! action to execute for the next frame */ + SelectiveDecAction frame_action; +#else /*! if set to 1, decoder will skip decoding for the next frame */ SelectiveDecAction *frame_actions; +#endif /*! if set to 1, decoder will decode the cache before decoding any of current frames */ int16_t shall_decode_cached_frame; } IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE; @@ -92,12 +101,6 @@ void IVAS_LC3PLUS_DEC_Close( ISAR_LC3PLUS_DEC_HANDLE *handle /* i/o: pointer to decoder handle */ ); -/*! Sets a matrix[MAX_PARAM_SPATIAL_SUBFRAMES][numLC3plusDecoders] where all require subframes must be flagged with 1, frames that are not required with 0 */ -ivas_error IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( - ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ - int16_t *subframeChannelMatrix[MAX_PARAM_SPATIAL_SUBFRAMES] /* i : */ -); - ivas_error IVAS_LC3PLUS_DEC_Decode( ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ uint8_t *bitstream_in, /* i : pointer to input bitstream */ @@ -110,10 +113,12 @@ ivas_error IVAS_LC3PLUS_DEC_Conceal( float **pcm_out /* o : concealed samples */ ); +#ifndef LC3PLUS_RTP_PAYLOAD_FORMAT ivas_error IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( int16_t ***subframeChannelMatrix, const uint32_t num_decs ); void IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( int16_t **subframeChannelMatrix ); +#endif -#endif /* IVAS_LC3PLUS_DEC_H */ +#endif /* ISAR_LC3PLUS_DEC_H */ diff --git a/lib_isar/isar_lc3plus_enc.c b/lib_isar/isar_lc3plus_enc.c index ea3081be87..324d295d56 100644 --- a/lib_isar/isar_lc3plus_enc.c +++ b/lib_isar/isar_lc3plus_enc.c @@ -36,6 +36,7 @@ #include "ivas_error_utils.h" #include "prot.h" #include "wmc_auto.h" +#include "options.h" #ifdef SPLIT_REND_WITH_HEAD_ROT /*-------------------------------------------------------------------* @@ -50,6 +51,14 @@ ivas_error IVAS_LC3PLUS_ENC_Open( ISAR_LC3PLUS_ENC_HANDLE *handle /* o : encoder handle */ ) { +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + int32_t num_lc3plus_media_times_per_ivas_frame; + int32_t lc3plus_num_bytes_per_frame; + bool is_last_media_time, is_last_channel; +#ifdef LC3PLUS_VBR + ivas_error ivas_err; +#endif +#endif int32_t bitsPerSecondPerChannel; int32_t encoder_size; LC3PLUS_Error err; @@ -64,6 +73,16 @@ ivas_error IVAS_LC3PLUS_ENC_Open( } bitsPerSecondPerChannel = bitsPerSecond / config.channels; +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + if ( config.lc3plus_frame_duration_us != 2500 && config.lc3plus_frame_duration_us != 5000 && config.lc3plus_frame_duration_us != 10000 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid lc3plus_frame_duration_us\n" ); + } + if ( config.ivas_frame_duration_us != 20000 && config.ivas_frame_duration_us != 5000 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid ivas_frame_duration_us\n" ); + } +#endif encoder_size = lc3plus_enc_get_size( config.samplerate, 1 ); if ( 0 == encoder_size ) { @@ -74,6 +93,10 @@ ivas_error IVAS_LC3PLUS_ENC_Open( { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); } +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + ( *handle )->config = config; + ( *handle )->frame_type_descriptors = NULL; +#endif ( *handle )->pcm_conversion_buffer = NULL; ( *handle )->num_encs = 0; @@ -88,6 +111,17 @@ ivas_error IVAS_LC3PLUS_ENC_Open( ( *handle )->handles[i] = NULL; } ( *handle )->num_encs = config.channels; +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + num_lc3plus_media_times_per_ivas_frame = config.ivas_frame_duration_us / config.lc3plus_frame_duration_us; + ( *handle )->fdl_request = LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA; + ( *handle )->num_ftds = config.channels * num_lc3plus_media_times_per_ivas_frame; + ( *handle )->frame_type_descriptors = malloc( ( *handle )->num_ftds * sizeof( LC3PLUS_RTP_FTD ) ); + if ( NULL == ( *handle )->frame_type_descriptors ) + { + IVAS_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus frame_type_descriptors\n" ); + } +#endif for ( int32_t iCh = 0; iCh < config.channels; iCh++ ) { @@ -97,7 +131,11 @@ ivas_error IVAS_LC3PLUS_ENC_Open( return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus encoder\n" ); } +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + err = lc3plus_enc_init( ( *handle )->handles[iCh], config.samplerate, 1, config.high_res_mode_enabled, lfeChans ); +#else err = lc3plus_enc_init( ( *handle )->handles[iCh], config.samplerate, 1, 0, lfeChans ); +#endif if ( err != LC3PLUS_OK ) { IVAS_LC3PLUS_ENC_Close( handle ); @@ -125,7 +163,9 @@ ivas_error IVAS_LC3PLUS_ENC_Open( return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Current pcm_conversion_buffer sizing requires that lc3plus uses a shorter or equal frame duration than ivas\n" ); } +#ifndef LC3PLUS_RTP_PAYLOAD_FORMAT ( *handle )->config = config; +#endif ( *handle )->pcm_conversion_buffer = malloc( sizeof( int16_t ) * config.samplerate * config.lc3plus_frame_duration_us / 1000000 ); if ( NULL == ( *handle )->pcm_conversion_buffer ) { @@ -133,8 +173,186 @@ ivas_error IVAS_LC3PLUS_ENC_Open( return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus encoder wrapper pcm_conversion_buffer\n" ); } +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + /* update FDI fields */ + for ( int32_t iMediaTime = 0; iMediaTime < num_lc3plus_media_times_per_ivas_frame; ++iMediaTime ) + { + for ( uint32_t iEnc = 0; iEnc < ( *handle )->num_encs; ++iEnc ) + { + int32_t ftd_index = iEnc + iMediaTime * ( *handle )->num_encs; + lc3plus_num_bytes_per_frame = lc3plus_enc_get_num_bytes( ( *handle )->handles[iEnc] ); + if ( lc3plus_num_bytes_per_frame <= 0 ) + { + IVAS_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc_get_num_bytes reported invalid result failed\n" ); + } + ( *handle )->frame_type_descriptors[ftd_index].frame_data_length = lc3plus_num_bytes_per_frame; + if ( 0 != LC3PLUS_RTP_ftd_bwr_from_samplerate( &( *handle )->frame_type_descriptors[ftd_index].bwr, config.samplerate, config.high_res_mode_enabled ) ) + { + IVAS_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_ftd_bwr_from_samplerate failed\n" ); + } + if ( 0 != LC3PLUS_RTP_ftd_fdi_from_frame_duration_us( &( *handle )->frame_type_descriptors[ftd_index].fdi, config.lc3plus_frame_duration_us ) ) + { + IVAS_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_ftd_fdi_from_frame_duration_us failed\n" ); + } + ( *handle )->frame_type_descriptors[ftd_index].h = LC3PLUS_RTP_FTD_H_PRIMARY; + ( *handle )->frame_type_descriptors[ftd_index].frame_data = NULL; + + /* The FTDs in the ToC are included in the following order: + * 1) First the FTD for the first channel of the first FDB (oldest frame) + * 2) Then the FTDs for the remaining channels for the first FDB in increasing CC order + * 3) Then the FTD for the first channel of the second FDB + * 4) Then the FTDs for the remaining channels for the second FDB + * 5) Etc. to the last FDB */ + is_last_media_time = num_lc3plus_media_times_per_ivas_frame - 1 == iMediaTime; + is_last_channel = ( *handle )->num_encs - 1 == iEnc; + if ( is_last_media_time && is_last_channel ) + { + ( *handle )->frame_type_descriptors[ftd_index].fc = LC3PLUS_RTP_FTD_FC_LAST_OVERALL; + } + else if ( !is_last_media_time && is_last_channel ) + { + ( *handle )->frame_type_descriptors[ftd_index].fc = LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME; + } + else + { + ( *handle )->frame_type_descriptors[ftd_index].fc = LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL; + } + } + } + +#ifdef LC3PLUS_VBR + ivas_err = IVAS_LC3PLUS_ENC_SetBitrate( *handle, bitsPerSecond ); + if ( ivas_err != IVAS_ERR_OK ) + { + IVAS_LC3PLUS_ENC_Close( handle ); + return ivas_err; + } +#endif +#endif + return IVAS_ERR_OK; +} + +#ifdef LC3PLUS_VBR +static int32_t limit_per_channel_bitrate( LC3PLUS_CONFIG config, + int32_t per_channel_bitrate ) +{ + if ( config.high_res_mode_enabled ) + { + switch ( config.lc3plus_frame_duration_us ) + { + case 10000: + return min( per_channel_bitrate, 500000 ); + case 5000: + return min( per_channel_bitrate, 600000 ); + case 2500: + return min( per_channel_bitrate, 672000 ); + default: + assert( false && "unreachable" ); + } + } + + switch ( config.samplerate ) + { + case 48000: + case 32000: + return min( per_channel_bitrate, 320000 ); + case 24000: + return min( per_channel_bitrate, 314400 ); + case 16000: + return min( per_channel_bitrate, 221600 ); + case 8000: + return min( per_channel_bitrate, 114400 ); + default: + assert( false && "unreachable" ); + } +} + +#ifdef LC3PLUS_VBR +/*-------------------------------------------------------------------* + * Function IVAS_LC3PLUS_ENC_SetBitrate() + * + * + *-------------------------------------------------------------------*/ + +ivas_error IVAS_LC3PLUS_ENC_SetBitrate( + ISAR_LC3PLUS_ENC_HANDLE handle, /* o : LC3plus encoder handle */ + const uint32_t bitsPerSecond /* i : new target bit rate */ +) +{ + int32_t num_lc3plus_media_times_per_ivas_frame; + int32_t lc3plus_num_bytes_per_frame; + int32_t diff; + int32_t targetOctetsPerFrame; + int32_t actualOctetsPerFrame; + int32_t newBitsPerSecond; + ivas_error ivasErr; + int32_t bitsPerSecondPerChannel; + LC3PLUS_Error err; + LC3PLUS_CONFIG config; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); + } + + config = handle->config; + newBitsPerSecond = bitsPerSecond; + targetOctetsPerFrame = bitsPerSecond / ( 1000000 / config.ivas_frame_duration_us ) / 8; + num_lc3plus_media_times_per_ivas_frame = handle->config.ivas_frame_duration_us / handle->config.lc3plus_frame_duration_us; + + /* Avoid exceeding max LC3plus bitrate */ + newBitsPerSecond = config.channels * limit_per_channel_bitrate( handle->config, newBitsPerSecond / config.channels ); + + /* reduce bitrate incrementally until the all codec frames + payload fits into the requested bit rate + * Note: The payload format uses variable length fields, therefore the iterative approach to find the + * target bit rate is used */ + do + { + bitsPerSecondPerChannel = newBitsPerSecond / config.channels; + for ( int32_t iCh = 0; iCh < config.channels; iCh++ ) + { + err = lc3plus_enc_set_bitrate( handle->handles[iCh], bitsPerSecondPerChannel ); + if ( err != LC3PLUS_OK ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_bitrate failed\n" ); + } + } + + // update FTD settings after bitrate change + for ( int32_t iMediaTime = 0; iMediaTime < num_lc3plus_media_times_per_ivas_frame; ++iMediaTime ) + { + for ( uint32_t iEnc = 0; iEnc < handle->num_encs; ++iEnc ) + { + int32_t ftd_index = iEnc + iMediaTime * handle->num_encs; + lc3plus_num_bytes_per_frame = lc3plus_enc_get_num_bytes( handle->handles[iEnc] ); + if ( lc3plus_num_bytes_per_frame <= 0 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc_get_num_bytes reported invalid result failed\n" ); + } + handle->frame_type_descriptors[ftd_index].frame_data_length = lc3plus_num_bytes_per_frame; + } + } + + ivasErr = IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( handle, &actualOctetsPerFrame ); + if ( ivasErr != IVAS_ERR_OK ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "IVAS_LC3PLUS_ENC_GetOutputBitstreamSize failed\n" ); + } + diff = actualOctetsPerFrame - targetOctetsPerFrame; + if ( diff <= 0 ) + { + break; + } + newBitsPerSecond -= diff * 8 * ( 1000000 / config.ivas_frame_duration_us ); + } while ( true ); + return IVAS_ERR_OK; } +#endif +#endif /*-------------------------------------------------------------------* @@ -191,7 +409,15 @@ ivas_error IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( int32_t *bsSize /* o : size of each bitstream frame in bytes */ ) { +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + LC3PLUS_RTP_ERR rtp_err; + int32_t num_lc3plus_media_times_per_ivas_frame; + int32_t iMediaTime; + int32_t ftd_frame_data_length_size, lc3plus_frame_data_length; + int32_t ftd_index; +#else int32_t bitstreamSizeMultiplier; +#endif if ( NULL == handle ) { return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); @@ -201,13 +427,54 @@ ivas_error IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bsSize is NULL\n" ); } +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + if ( 0 == handle->config.lc3plus_frame_duration_us ) + { + return IVAS_ERROR( IVAS_ERR_INIT_ERROR, "lc3plus_frame_duration_us is 0\n" ); + } + if ( handle->config.ivas_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "ivas_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); + } + + num_lc3plus_media_times_per_ivas_frame = handle->config.ivas_frame_duration_us / handle->config.lc3plus_frame_duration_us; +#endif *bsSize = 0; +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + int32_t fdl_request_length; + rtp_err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_request_length, handle->fdl_request ); + if ( rtp_err != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid LC3plus frame_data_length request\n" ); + } + *bsSize += fdl_request_length; +#endif for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) { if ( NULL == handle->handles[iEnc] ) { return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus encoder handle is NULL\n" ); } +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + lc3plus_frame_data_length = lc3plus_enc_get_num_bytes( handle->handles[iEnc] ); + for ( iMediaTime = 0; iMediaTime < num_lc3plus_media_times_per_ivas_frame; ++iMediaTime ) + { + ftd_index = iEnc + iMediaTime * handle->num_encs; + if ( lc3plus_frame_data_length != (int32_t) handle->frame_type_descriptors[ftd_index].frame_data_length ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "LC3plus FTD data not synchronised with encoder bitrate\n" ); + } + rtp_err = LC3PLUS_RTP_frame_data_length_get_size( &ftd_frame_data_length_size, handle->frame_type_descriptors[ftd_index].frame_data_length ); + if ( rtp_err != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid LC3plus frame_data_length\n" ); + } + *bsSize += LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL; + *bsSize += handle->frame_type_descriptors[ftd_index].frame_data_length; + *bsSize += ftd_frame_data_length_size; + } + } +#else *bsSize += lc3plus_enc_get_num_bytes( handle->handles[iEnc] ); } @@ -218,6 +485,7 @@ ivas_error IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( bitstreamSizeMultiplier = handle->config.ivas_frame_duration_us / handle->config.lc3plus_frame_duration_us; *bsSize *= bitstreamSizeMultiplier; +#endif return IVAS_ERR_OK; } @@ -237,6 +505,12 @@ void IVAS_LC3PLUS_ENC_Close( { return; } +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + if ( NULL != ( *handle )->frame_type_descriptors ) + { + free( ( *handle )->frame_type_descriptors ); + } +#endif for ( uint32_t iEnc = 0; iEnc < ( *handle )->num_encs; iEnc++ ) { if ( NULL != ( *handle )->handles[iEnc] ) @@ -268,13 +542,24 @@ void IVAS_LC3PLUS_ENC_Close( ivas_error IVAS_LC3PLUS_ENC_Encode( ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ float **pcm_in, /* i : pointer input samples */ - void *bitstream_out /* o : pointer to bitstream frame */ +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + void *bitstream_out, /* o : pointer to bitstream frame */ + int32_t bitstream_out_size /* i : size of the bitstream_out buffer in bytes. Must be equal to IVAS_LC3PLUS_ENC_GetOutputBitstreamSize. */ +#else + void *bitstream_out /* o : pointer to bitstream frame */ +#endif ) { - uint32_t numSamplesPerLC3plusChannel; +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + int32_t ftdIndex; + LC3PLUS_RTP_ERR rtpErr; + uint32_t num_media_times; +#else uint32_t lc3framesPerIvasFrame; - int32_t ivasSampleIndex; uint8_t *bitstream_out_iter = bitstream_out; +#endif + uint32_t numSamplesPerLC3plusChannel; + int32_t ivasSampleIndex; int32_t num_bytes = 0; LC3PLUS_Error err; @@ -297,22 +582,49 @@ ivas_error IVAS_LC3PLUS_ENC_Encode( { return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "ivas_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); } +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + num_media_times = handle->config.ivas_frame_duration_us / handle->config.lc3plus_frame_duration_us; + numSamplesPerLC3plusChannel = handle->config.samplerate / ( 1000000 / handle->config.ivas_frame_duration_us ) / num_media_times; + + size_t actual_size; + rtpErr = LC3PLUS_RTP_payload_serialize( bitstream_out, bitstream_out_size, &actual_size, LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA, handle->frame_type_descriptors, handle->num_ftds ); + if ( rtpErr != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( rtpErr ), "LC3PLUS_RTP_payload_serialize failed\n" ); + } +#else lc3framesPerIvasFrame = handle->config.ivas_frame_duration_us / handle->config.lc3plus_frame_duration_us; numSamplesPerLC3plusChannel = handle->config.samplerate / ( 1000000 / handle->config.ivas_frame_duration_us ) / lc3framesPerIvasFrame; +#endif for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) { +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + for ( uint32_t iMediaTime = 0; iMediaTime < num_media_times; iMediaTime++ ) +#else for ( uint32_t iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) +#endif { for ( uint32_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ ) { +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + ivasSampleIndex = iSampleInt16 + iMediaTime * numSamplesPerLC3plusChannel; +#else ivasSampleIndex = iSampleInt16 + iLc3plusFrame * numSamplesPerLC3plusChannel; +#endif handle->pcm_conversion_buffer[iSampleInt16] = (int16_t) max( INT16_MIN, min( pcm_in[iEnc][ivasSampleIndex], INT16_MAX ) ); } +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + ftdIndex = iMediaTime * handle->num_encs + iEnc; +#endif num_bytes = 0; push_wmops( "lc3plus_enc16" ); +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + err = lc3plus_enc16( handle->handles[iEnc], &handle->pcm_conversion_buffer, handle->frame_type_descriptors[ftdIndex].frame_data, &num_bytes, NULL ); +#else err = lc3plus_enc16( handle->handles[iEnc], &handle->pcm_conversion_buffer, bitstream_out_iter, &num_bytes, NULL ); +#endif pop_wmops(); if ( err != LC3PLUS_OK ) { @@ -322,8 +634,15 @@ ivas_error IVAS_LC3PLUS_ENC_Encode( { return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc16 did not produce output\n" ); } +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + if ( num_bytes != (int32_t) handle->frame_type_descriptors[ftdIndex].frame_data_length ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "payload format and lc3plus enc bitrate are not aligned\n" ); + } +#else bitstream_out_iter += num_bytes; +#endif } } diff --git a/lib_isar/isar_lc3plus_enc.h b/lib_isar/isar_lc3plus_enc.h index 2b7e308b30..d84138ce90 100644 --- a/lib_isar/isar_lc3plus_enc.h +++ b/lib_isar/isar_lc3plus_enc.h @@ -37,6 +37,7 @@ #include "lc3.h" #include "ivas_error.h" #include "isar_lc3plus_common.h" +#include "isar_lc3plus_payload.h" /* encoder wrapper */ typedef struct ISAR_LC3PLUS_ENC_HANDLE @@ -45,14 +46,30 @@ typedef struct ISAR_LC3PLUS_ENC_HANDLE LC3PLUS_Enc **handles; uint32_t num_encs; int16_t *pcm_conversion_buffer; +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + LC3PLUS_RTP_FTD *frame_type_descriptors; + int32_t num_ftds; + LC3PLUS_RTP_FDL fdl_request; +#endif } * ISAR_LC3PLUS_ENC_HANDLE; ivas_error IVAS_LC3PLUS_ENC_Open( - const LC3PLUS_CONFIG config, /* i : encoder configuration */ - const uint32_t bitsPerSecond, /* i : bit rate */ + const LC3PLUS_CONFIG config, /* i : encoder configuration */ +#ifdef LC3PLUS_VBR + const uint32_t initialBitsPerSecond, /* i : initial target bit rate */ +#else + const uint32_t bitsPerSecond, /* i : bit rate */ +#endif ISAR_LC3PLUS_ENC_HANDLE *handle /* o : LC3plus encoder handle */ ); +#ifdef LC3PLUS_VBR +ivas_error IVAS_LC3PLUS_ENC_SetBitrate( + ISAR_LC3PLUS_ENC_HANDLE handle, /* o : LC3plus encoder handle */ + const uint32_t bitsPerSecond /* i : new target bit rate */ +); +#endif + ivas_error IVAS_LC3PLUS_ENC_GetDelay( ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ int32_t *delayInSamples /* o : algorithmic delay of encoding and decoding in number of samples per channel */ @@ -60,7 +77,7 @@ ivas_error IVAS_LC3PLUS_ENC_GetDelay( ivas_error IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ - int32_t *bsSize /* o : size of each bitstream frame in bytes */ + int32_t *bsSize /* o : size of next bitstream frame in bytes */ ); void IVAS_LC3PLUS_ENC_Close( @@ -70,7 +87,12 @@ void IVAS_LC3PLUS_ENC_Close( ivas_error IVAS_LC3PLUS_ENC_Encode( ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ float **pcm_in, /* i : pointer input samples */ - void *bitstream_out /* o : pointer to bitstream frame */ +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + void *bitstream_out, /* o : pointer to bitstream frame */ + int32_t bitstream_out_size /* i : size of the bitstream_out buffer in bytes. Must be equal to ISAR_LC3PLUS_ENC_GetOutputBitstreamSize. */ +#else + void *bitstream_out /* o : pointer to bitstream frame */ +#endif ); -#endif /* IVAS_LC3PLUS_ENC_H */ +#endif /* ISAR_LC3PLUS_ENC_H */ diff --git a/lib_isar/isar_lc3plus_payload.c b/lib_isar/isar_lc3plus_payload.c new file mode 100644 index 0000000000..c4db05485f --- /dev/null +++ b/lib_isar/isar_lc3plus_payload.c @@ -0,0 +1,819 @@ +/****************************************************************************************************** + + (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include +#include +#include "isar_lc3plus_payload.h" +#include "options.h" + +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT +static LC3PLUS_RTP_ERR s_frame_duration_ms_from_fdi( int32_t *frame_duration_us, const LC3PLUS_RTP_FTD_FDI fdi ) +{ + if ( NULL == frame_duration_us ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + switch ( fdi ) + { + case LC3PLUS_RTP_FTD_FDI_2500_US: + *frame_duration_us = 2500; + break; + case LC3PLUS_RTP_FTD_FDI_5000_US: + *frame_duration_us = 5000; + break; + case LC3PLUS_RTP_FTD_FDI_10000_US: + *frame_duration_us = 10000; + break; + case LC3PLUS_RTP_FTD_FDI_RESERVED: + default: + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +static LC3PLUS_RTP_ERR s_sampling_rate_hz_from_bwr( int32_t *sample_rate_hz, const LC3PLUS_RTP_FTD_BWR bwr ) +{ + if ( NULL == sample_rate_hz ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + switch ( bwr ) + { + case LC3PLUS_RTP_FTD_BWR_NB: + *sample_rate_hz = 8000; + break; + case LC3PLUS_RTP_FTD_BWR_WB: + *sample_rate_hz = 16000; + break; + case LC3PLUS_RTP_FTD_BWR_SSWB: + *sample_rate_hz = 24000; + break; + case LC3PLUS_RTP_FTD_BWR_SWB: + *sample_rate_hz = 32000; + break; + case LC3PLUS_RTP_FTD_BWR_FBCD: + *sample_rate_hz = 44100; + break; + case LC3PLUS_RTP_FTD_BWR_FB: + *sample_rate_hz = 48000; + break; + case LC3PLUS_RTP_FTD_BWR_FBHR: + *sample_rate_hz = 48000; + break; + case LC3PLUS_RTP_FTD_BWR_UBHR: + *sample_rate_hz = 96000; + break; + default: + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +static LC3PLUS_RTP_ERR s_high_resolution_flag_from_bwr( int16_t *high_resolution_flag, const LC3PLUS_RTP_FTD_BWR bwr ) +{ + if ( NULL == high_resolution_flag ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + switch ( bwr ) + { + case LC3PLUS_RTP_FTD_BWR_NB: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_WB: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_SSWB: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_SWB: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_FBCD: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_FB: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_FBHR: + *high_resolution_flag = 1; + break; + case LC3PLUS_RTP_FTD_BWR_UBHR: + *high_resolution_flag = 1; + break; + default: + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +LC3PLUS_RTP_ERR LC3PLUS_RTP_frame_data_length_get_size( int32_t *length, const LC3PLUS_RTP_FDL frameDataLengthValue ) +{ + if ( frameDataLengthValue == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || frameDataLengthValue == LC3PLUS_RTP_FDL_SPEECH_BAD || frameDataLengthValue == LC3PLUS_RTP_FDL_SPEECH_SID ) + { + *length = 1; + } + else if ( frameDataLengthValue >= LC3PLUS_RTP_FDL_LENGTH_1_MIN && frameDataLengthValue <= LC3PLUS_RTP_FDL_LENGTH_1_MAX ) + { + *length = 1; + } + else if ( frameDataLengthValue >= LC3PLUS_RTP_FDL_LENGTH_2_MIN && frameDataLengthValue <= LC3PLUS_RTP_FDL_LENGTH_2_MAX ) + { + *length = 2; + } + else if ( frameDataLengthValue >= LC3PLUS_RTP_FDL_LENGTH_3_MIN && frameDataLengthValue <= LC3PLUS_RTP_FDL_LENGTH_3_MAX ) + { + *length = 3; + } + else + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +static LC3PLUS_RTP_ERR s_frame_data_length_pack( const LC3PLUS_RTP_FDL frameDataLengthValue, uint8_t *dst ) +{ + int32_t frame_data_length_size; + LC3PLUS_RTP_ERR err; + + if ( NULL == dst ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + + err = LC3PLUS_RTP_frame_data_length_get_size( &frame_data_length_size, frameDataLengthValue ); + if ( err != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return err; + } + if ( 1 == frame_data_length_size ) + { + *dst++ = frameDataLengthValue >> 0 & LC3PLUS_RTP_FDL_EXTENSION_VALUE; + } + else if ( 2 == frame_data_length_size ) + { + const int32_t frameDataLengthValueToWrite = frameDataLengthValue - LC3PLUS_RTP_FDL_EXTENSION_VALUE; + *dst++ = LC3PLUS_RTP_FDL_EXTENSION_VALUE; + *dst = frameDataLengthValueToWrite >> 0 & LC3PLUS_RTP_FDL_EXTENSION_VALUE; + } + else if ( 3 == frame_data_length_size ) + { + const int32_t frameDataLengthValueToWrite = frameDataLengthValue - ( 2 * LC3PLUS_RTP_FDL_EXTENSION_VALUE ); + *dst++ = LC3PLUS_RTP_FDL_EXTENSION_VALUE; + *dst++ = LC3PLUS_RTP_FDL_EXTENSION_VALUE; + *dst = frameDataLengthValueToWrite >> 0 & LC3PLUS_RTP_FDL_EXTENSION_VALUE; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +static int32_t s_get_size_from_fdl( const LC3PLUS_RTP_FDL fdl ) +{ + if ( fdl >= LC3PLUS_RTP_FDL_LENGTH_1_MIN && fdl <= LC3PLUS_RTP_FDL_LENGTH_3_MAX ) + { + return fdl; + } + return 0; +} + +static bool s_fdl_is_magic_value( const LC3PLUS_RTP_FDL fdl ) +{ + if ( fdl == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || fdl == LC3PLUS_RTP_FDL_SPEECH_SID || fdl == LC3PLUS_RTP_FDL_SPEECH_BAD ) + { + return true; + } + return false; +} + +static bool s_fdl_value_is_valid_request( const LC3PLUS_RTP_FDL fdl_request ) +{ + /* LC3PLUS_RTP_FDL_SPEECH_SID && LC3PLUS_RTP_FDL_SPEECH_SID are not valid values for the FDL request */ + if ( fdl_request == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || ( fdl_request >= LC3PLUS_RTP_FDL_LENGTH_1_MIN && fdl_request <= LC3PLUS_RTP_FDL_LENGTH_3_MAX ) ) + { + return true; + } + return false; +} + +static LC3PLUS_RTP_ERR s_frame_data_length_parse( LC3PLUS_RTP_FDL *frame_data_length_value, const uint8_t *src, const size_t remaining_capacity ) +{ + int32_t frame_data_length_size; + LC3PLUS_RTP_ERR err; + if ( NULL == src || NULL == frame_data_length_value || remaining_capacity < 1 ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + + if ( remaining_capacity > 2 && LC3PLUS_RTP_FDL_EXTENSION_VALUE == *src && LC3PLUS_RTP_FDL_EXTENSION_VALUE == *( src + 1 ) ) + { + *frame_data_length_value = *( src + 2 ) + 2 * LC3PLUS_RTP_FDL_EXTENSION_VALUE; + } + else if ( remaining_capacity > 1 && LC3PLUS_RTP_FDL_EXTENSION_VALUE == *src ) + { + *frame_data_length_value = *( src + 1 ) + 1 * LC3PLUS_RTP_FDL_EXTENSION_VALUE; + } + else if ( remaining_capacity > 0 ) + { + *frame_data_length_value = *src << 0; + } + else + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + + /* sanity check */ + err = LC3PLUS_RTP_frame_data_length_get_size( &frame_data_length_size, *frame_data_length_value ); + if ( err != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return err; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +static LC3PLUS_RTP_ERR s_parse_ftd( const uint8_t *p_read, LC3PLUS_RTP_FTD *receiver_ftd, int32_t *num_bytes_read, const size_t remaining_capacity ) +{ + int32_t frame_data_block_size; + LC3PLUS_RTP_FDL fdl; + LC3PLUS_RTP_ERR err; + if ( NULL == p_read || NULL == receiver_ftd || NULL == num_bytes_read || remaining_capacity < LC3PLUS_RTP_FTD_MIN_SIZE ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + + *num_bytes_read = 0; + receiver_ftd->fc = 0; + receiver_ftd->fdi = 0; + receiver_ftd->bwr = 0; + receiver_ftd->h = 0; + receiver_ftd->fc |= *p_read & LC3PLUS_RTP_FTD_FC_MASK; + receiver_ftd->fdi |= ( *p_read & LC3PLUS_RTP_FTD_FDI_MASK ); + receiver_ftd->bwr |= ( *p_read & LC3PLUS_RTP_FTD_BWR_MASK ); + receiver_ftd->h |= ( *p_read & LC3PLUS_RTP_FTD_H_MASK ); + p_read++; + *num_bytes_read = 1; + + err = s_frame_data_length_parse( &fdl, p_read, remaining_capacity - *num_bytes_read ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + frame_data_block_size = s_get_size_from_fdl( fdl ); + + receiver_ftd->frame_data_length = frame_data_block_size; + int32_t length_field_size; + err = LC3PLUS_RTP_frame_data_length_get_size( &length_field_size, receiver_ftd->frame_data_length ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + *num_bytes_read += length_field_size; + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_serialize( + uint8_t *serialized_buffer, + const size_t serialized_buffer_capacity, + size_t *packed_buffer_actual_size, + const LC3PLUS_RTP_FDL fdl_request, + LC3PLUS_RTP_FTD *sender_ftds, + const size_t sender_ftds_num ) +{ + LC3PLUS_RTP_ERR err; + uint8_t *p_write = serialized_buffer; + uint32_t i; + int32_t bytes_written = 0; + int32_t lc3plus_frame_size_sum; + uint8_t *p_frame_data; + int32_t fdl_request_length; + + if ( NULL == serialized_buffer || NULL == packed_buffer_actual_size || NULL == sender_ftds ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + + *packed_buffer_actual_size = 0; + err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_request_length, fdl_request ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( !s_fdl_value_is_valid_request( fdl_request ) ) + { + return LC3PLUS_RTP_ERR_INVALID_FDL_REQUEST; + } + if ( (int32_t) serialized_buffer_capacity < bytes_written + fdl_request_length ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + err = s_frame_data_length_pack( fdl_request, p_write ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + bytes_written += fdl_request_length; + p_write += bytes_written; + + for ( i = 0; i < sender_ftds_num; ++i ) + { + /* only the last ftd may have the LC3PLUS_RTP_FTD_FC_LAST_OVERALL value */ + if ( sender_ftds[i].fc == LC3PLUS_RTP_FTD_FC_LAST_OVERALL && i != ( sender_ftds_num - 1 ) ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + /* the last ftd must have the LC3PLUS_RTP_FTD_FC_LAST_OVERALL value */ + if ( sender_ftds[i].fc != LC3PLUS_RTP_FTD_FC_LAST_OVERALL && i == ( sender_ftds_num - 1 ) ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + if ( (int32_t) serialized_buffer_capacity < bytes_written + LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + *p_write = 0x00; + *p_write |= LC3PLUS_RTP_FTD_FC_MASK & (uint8_t) sender_ftds[i].fc; + *p_write |= LC3PLUS_RTP_FTD_FDI_MASK & (uint8_t) sender_ftds[i].fdi; + *p_write |= LC3PLUS_RTP_FTD_BWR_MASK & (uint8_t) sender_ftds[i].bwr; + *p_write |= LC3PLUS_RTP_FTD_H_MASK & (uint8_t) sender_ftds[i].h; + p_write++; + bytes_written += LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL; + + int32_t fdl_length; + err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_length, sender_ftds[i].frame_data_length ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( (int32_t) serialized_buffer_capacity < bytes_written + fdl_length ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + err = s_frame_data_length_pack( sender_ftds[i].frame_data_length, p_write ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + p_write += fdl_length; + bytes_written += fdl_length; + } + + lc3plus_frame_size_sum = 0; + p_frame_data = serialized_buffer + bytes_written; + for ( i = 0; i < sender_ftds_num; ++i ) + { + sender_ftds[i].frame_data = p_frame_data; + p_frame_data += sender_ftds[i].frame_data_length; + lc3plus_frame_size_sum += sender_ftds[i].frame_data_length; + } + *packed_buffer_actual_size = bytes_written + lc3plus_frame_size_sum; + assert( *packed_buffer_actual_size <= serialized_buffer_capacity ); + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +static LC3PLUS_RTP_ERR s_ftds_parse( + LC3PLUS_RTP_FTD *receiver_ftds, + const int32_t receiver_ftds_num_max, + int16_t *receiver_ftds_num, + uint8_t *serialized_buffer, + const size_t serialized_buffer_size ) +{ + int32_t diff; + uint8_t *p_read; + uint32_t ftds_offset_sum = 0; + int16_t i; + LC3PLUS_RTP_ERR error; + int32_t frame_offset_counter; + int32_t size; + + p_read = serialized_buffer; + if ( NULL == receiver_ftds || NULL == receiver_ftds_num || NULL == serialized_buffer ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + if ( 0 == serialized_buffer_size ) + { + return LC3PLUS_RTP_ERR_EMPTY_TOC; + } + if ( receiver_ftds_num_max <= 0 ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + { + int32_t num_bytes_read_sum = 0; + const int32_t min_num_bytes_per_ftd = 2; + int16_t receiver_ftds_index = 0; + bool another_ftd = true; + int32_t num_bytes_read_per_ftd; + + while ( another_ftd ) + { + if ( (int32_t) serialized_buffer_size < min_num_bytes_per_ftd ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + if ( num_bytes_read_sum >= (int32_t) serialized_buffer_size - min_num_bytes_per_ftd ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + num_bytes_read_per_ftd = 0; + error = s_parse_ftd( p_read, &receiver_ftds[receiver_ftds_index], &num_bytes_read_per_ftd, serialized_buffer_size - num_bytes_read_sum ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != error ) + { + return error; + } + p_read += num_bytes_read_per_ftd; + num_bytes_read_sum += num_bytes_read_per_ftd; + + if ( receiver_ftds[receiver_ftds_index].fc == LC3PLUS_RTP_FTD_FC_RESERVED ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM; + } + else if ( receiver_ftds[receiver_ftds_index].fc == LC3PLUS_RTP_FTD_FC_LAST_OVERALL ) + { + another_ftd = false; + } + + if ( another_ftd ) + { + if ( receiver_ftds_index >= receiver_ftds_num_max ) + { + return LC3PLUS_RTP_ERR_NOT_ENOUGH_FTDS_ALLOCATED; + } + ( receiver_ftds_index )++; + } + } + *receiver_ftds_num = receiver_ftds_index + 1; + } + + /* set frame-data pointers into serialized_buffer */ + for ( i = 0; i < *receiver_ftds_num; ++i ) + { + error = LC3PLUS_RTP_frame_data_length_get_size( &size, receiver_ftds[i].frame_data_length ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return error; + } + ftds_offset_sum += LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL + size; + } + + frame_offset_counter = 0; + for ( i = 0; i < *receiver_ftds_num; ++i ) + { + if ( s_fdl_is_magic_value( receiver_ftds[i].frame_data_length ) ) + { + receiver_ftds[i].frame_data = NULL; + } + else + { + receiver_ftds[i].frame_data = serialized_buffer + ftds_offset_sum + frame_offset_counter; + frame_offset_counter += receiver_ftds[i].frame_data_length; + } + } + + if ( ftds_offset_sum + frame_offset_counter != serialized_buffer_size ) + { + /* parsed content & size n bytes of input buffer do not line up */ + /* if the buffer capacity is larger and the remaining bytes are zero, we don't treat this as an error since it's due to the IVAS-Split rendering zero padding */ + diff = serialized_buffer_size - ( ftds_offset_sum + frame_offset_counter ); + if ( diff < 0 ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + /* verify that all bytes are zero */ + p_read += frame_offset_counter; + for ( i = 0; i < diff; ++i ) + { + if ( *p_read != 0 ) + { + /* non-zero byte in padding region */ + return LC3PLUS_RTP_ERR_NONZERO_PADDING_BYTES; + } + p_read++; + } + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_deserialize( + LC3PLUS_RTP_PAYLOAD *payload, + uint8_t *serialized_buffer, + const size_t serialized_buffer_size ) +{ + int32_t new_frame_duration_us; + int32_t new_sampling_rate_hz; + int16_t new_high_resolution_flag; + int16_t i = 0; + int16_t channel_id = 0; + int16_t media_time_id = 0; + const int16_t invalid_value = -1; + int16_t media_times_per_channel[LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS]; + int16_t channels_per_media_time[LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES]; + LC3PLUS_RTP_ERR err; + + if ( NULL == payload || NULL == serialized_buffer ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + if ( 0 == serialized_buffer_size ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + + for ( media_time_id = 0; media_time_id < LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES; ++media_time_id ) + { + channels_per_media_time[media_time_id] = invalid_value; + } + media_time_id = 0; + for ( channel_id = 0; channel_id < LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS; ++channel_id ) + { + media_times_per_channel[channel_id] = invalid_value; + } + channel_id = 0; + + err = s_frame_data_length_parse( &payload->fdl_request, serialized_buffer, serialized_buffer_size ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + int32_t fdl_request_length; + err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_request_length, payload->fdl_request ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( !s_fdl_value_is_valid_request( payload->fdl_request ) ) + { + return LC3PLUS_RTP_ERR_INVALID_FDL_REQUEST; + } + + err = s_ftds_parse( payload->ftds, sizeof( payload->ftds ) / sizeof( LC3PLUS_RTP_FTD ), &payload->num_ftds, serialized_buffer + fdl_request_length, serialized_buffer_size - fdl_request_length ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( 0 == payload->num_ftds ) + { + return LC3PLUS_RTP_ERR_GENERIC_ERROR; + } + /* verify shared setting between all FTDs [samplerate, frame_duration, channel count] */ + + /* initialize on the first FTD, use this as reference */ + err = s_frame_duration_ms_from_fdi( &payload->frame_duration_us, payload->ftds[0].fdi ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + err = s_sampling_rate_hz_from_bwr( &payload->sampling_rate_hz, payload->ftds[0].bwr ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + err = s_high_resolution_flag_from_bwr( &payload->high_resolution_enabled, payload->ftds[0].bwr ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + payload->num_channels = 0; + payload->num_media_times = 0; + for ( i = 0; i < payload->num_ftds; ++i ) + { + if ( payload->ftds[i].h != LC3PLUS_RTP_FTD_H_PRIMARY ) + { + /* not implemented */ + return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED; + } + + err = s_frame_duration_ms_from_fdi( &new_frame_duration_us, payload->ftds[i].fdi ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( payload->frame_duration_us != new_frame_duration_us ) + { + /* mixed frame durations not supported */ + return LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION; + } + + err = s_sampling_rate_hz_from_bwr( &new_sampling_rate_hz, payload->ftds[i].bwr ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( payload->sampling_rate_hz != new_sampling_rate_hz ) + { + /* mixed sampling frequencies not supported */ + return LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION; + } + + + err = s_high_resolution_flag_from_bwr( &new_high_resolution_flag, payload->ftds[i].bwr ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( payload->high_resolution_enabled != new_high_resolution_flag ) + { + /* mixed high resolution mode not supported */ + return LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION; + } + + switch ( payload->ftds[i].fc ) + { + case LC3PLUS_RTP_FTD_FC_LAST_OVERALL: + channels_per_media_time[media_time_id]++; + media_times_per_channel[channel_id]++; + channel_id = 0; + media_time_id = 0; + break; + case LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL: + media_times_per_channel[channel_id]++; + channels_per_media_time[media_time_id]++; + channel_id++; + break; + case LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME: + media_times_per_channel[channel_id]++; + channels_per_media_time[media_time_id]++; + channel_id = 0; + media_time_id++; + break; + case LC3PLUS_RTP_FTD_FC_RESERVED: + default: + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM; + } + } + + { + int32_t valid_num_media_times_per_channel; + int32_t iCh; + /* check whether all channels exist for each media time */ + if ( media_times_per_channel[0] == invalid_value ) + { + return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED; + } + valid_num_media_times_per_channel = media_times_per_channel[0]; + for ( iCh = 0; iCh < LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS; ++iCh ) + { + if ( media_times_per_channel[iCh] == invalid_value ) + { + break; + } + if ( valid_num_media_times_per_channel != media_times_per_channel[iCh] ) + { + return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED; + } + } + } + { + /* whether all media times exist for each channel */ + int32_t iMediaTime; + int32_t valid_num_channels_per_media_time; + if ( channels_per_media_time[0] == invalid_value ) + { + return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED; + } + valid_num_channels_per_media_time = channels_per_media_time[0]; + for ( iMediaTime = 0; iMediaTime < LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES; ++iMediaTime ) + { + if ( channels_per_media_time[iMediaTime] == invalid_value ) + { + break; + } + if ( valid_num_channels_per_media_time != channels_per_media_time[iMediaTime] ) + { + return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED; + } + } + } + + /* convert zero-index to count */ + payload->num_channels = channels_per_media_time[0] + 1; + payload->num_media_times = media_times_per_channel[0] + 1; + + /* verify that all media times have the same number of channels, partial packets are not supported */ + if ( payload->num_ftds != payload->num_channels * payload->num_media_times ) + { + return LC3PLUS_RTP_ERR_GENERIC_ERROR; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_bwr_from_samplerate( LC3PLUS_RTP_FTD_BWR *bwr, const int32_t sampling_rate, const int32_t high_res_enabled ) +{ + if ( NULL == bwr ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + switch ( sampling_rate ) + { + case 8000: + if ( high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_NB; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 16000: + if ( high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_WB; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 24000: + if ( high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_SSWB; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 32000: + if ( high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_SWB; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 44100: + if ( high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_FBCD; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 48000: + if ( 0 == high_res_enabled ) + { + *bwr = LC3PLUS_RTP_FTD_BWR_FB; + return LC3PLUS_RTP_ERR_NO_ERROR; + } + else + { + *bwr = LC3PLUS_RTP_FTD_BWR_FBHR; + return LC3PLUS_RTP_ERR_NO_ERROR; + } + case 96000: + if ( 0 == high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_UBHR; + return LC3PLUS_RTP_ERR_NO_ERROR; + default: + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } +} + +LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_fdi_from_frame_duration_us( LC3PLUS_RTP_FTD_FDI *fdi, const int32_t frame_duration_us ) +{ + if ( NULL == fdi ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + switch ( frame_duration_us ) + { + case 2500: + *fdi = LC3PLUS_RTP_FTD_FDI_2500_US; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 5000: + *fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 10000: + *fdi = LC3PLUS_RTP_FTD_FDI_10000_US; + return LC3PLUS_RTP_ERR_NO_ERROR; + default: + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } +} + +#endif /* LC3PLUS_RTP_PAYLOAD_FORMAT */ +#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/lib_isar/isar_lc3plus_payload.h b/lib_isar/isar_lc3plus_payload.h new file mode 100644 index 0000000000..76992227c3 --- /dev/null +++ b/lib_isar/isar_lc3plus_payload.h @@ -0,0 +1,215 @@ +/****************************************************************************************************** + + (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef ISAR_LC3PLUS_PAYLOAD_H +#define ISAR_LC3PLUS_PAYLOAD_H + +#include +#include +#include "lc3.h" +#include "options.h" + +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + +/* Implementation of the "B.2.6 Table of contents" part of the RTP payload format + * for LC3plus as specified in ETSI TS 103 634. */ + +typedef enum LC3PLUS_RTP_ERR +{ + LC3PLUS_RTP_ERR_NO_ERROR, + LC3PLUS_RTP_ERR_NULL_PTR, + LC3PLUS_RTP_ERR_INVALID_PARAMETERS, + LC3PLUS_RTP_ERR_EMPTY_TOC, + LC3PLUS_RTP_ERR_NOT_IMPLEMENTED, + LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION, + LC3PLUS_RTP_ERR_INVALID_BITSTREAM, + LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE, + LC3PLUS_RTP_ERR_NOT_ENOUGH_FTDS_ALLOCATED, + LC3PLUS_RTP_ERR_INVALID_FDL_REQUEST, + LC3PLUS_RTP_ERR_NONZERO_PADDING_BYTES, + LC3PLUS_RTP_ERR_GENERIC_ERROR +} LC3PLUS_RTP_ERR; + +/* + * The content of the FTD is shown in Figure B.6. + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |FC |FDI| BWR |H| FDL1 | (FDL2) | (FDL3) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +/* FC (2 bits): + * Frame and Channel (FC) indicator for subsequent frame data (if available). The meaning of the FC + * indicator is shown in Table B.2. The FC value defines the media time stamp (in integer increments + * of TSI) and the channel counter (CC, starting from 1 for the first channel) for the subsequent + * FTD (if available). */ +typedef enum LC3PLUS_RTP_FTD_FC +{ + LC3PLUS_RTP_FTD_FC_LAST_OVERALL = 0x00, /* Last FDL in ToC, no FDL follows the current FDL */ + LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL = 0x01, /* The next FDL is for the next channel for the same media time */ + LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME = 0x02, /* The next FDL is for first channel for next media time, channel counter is reset */ + LC3PLUS_RTP_FTD_FC_RESERVED = 0x03, /* Reserved */ +} LC3PLUS_RTP_FTD_FC; +#define LC3PLUS_RTP_FTD_FC_MASK 0x03 + +/* FDI (2 bits): + * Frame Duration Index, with encoding as shown in Table B.3. The FDI shall be static for a given + * payload type during the session. The FDI also dictates the TSI, needed for deriving the media + * time in case of more than one frame in the payload. */ +typedef enum LC3PLUS_RTP_FTD_FDI +{ + LC3PLUS_RTP_FTD_FDI_2500_US = 0x00, + LC3PLUS_RTP_FTD_FDI_5000_US = 0x04, + LC3PLUS_RTP_FTD_FDI_10000_US = 0x08, + LC3PLUS_RTP_FTD_FDI_RESERVED = 0x0C, +} LC3PLUS_RTP_FTD_FDI; +#define LC3PLUS_RTP_FTD_FDI_MASK 0x0C +LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_fdi_from_frame_duration_us( LC3PLUS_RTP_FTD_FDI *fdi, const int32_t frame_duration_us ); + +/* BWR (3 bits): + * Bandwidth and resolution combination used by the codec is jointly encoded into a bandwidth and + * resolution (BWR) index. The BWR index is encoded as shown in Table B.4. The BWR encoding is + * defined in Table B.4. The BWR index shall be static for a given payload type during the session. */ +typedef enum LC3PLUS_RTP_FTD_BWR +{ + LC3PLUS_RTP_FTD_BWR_NB = 0x00, + LC3PLUS_RTP_FTD_BWR_WB = 0x10, + LC3PLUS_RTP_FTD_BWR_SSWB = 0x20, + LC3PLUS_RTP_FTD_BWR_SWB = 0x30, + LC3PLUS_RTP_FTD_BWR_FBCD = 0x40, + LC3PLUS_RTP_FTD_BWR_FB = 0x50, + LC3PLUS_RTP_FTD_BWR_FBHR = 0x60, + LC3PLUS_RTP_FTD_BWR_UBHR = 0x70, +} LC3PLUS_RTP_FTD_BWR; +#define LC3PLUS_RTP_FTD_BWR_MASK 0x70 +LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_bwr_from_samplerate( LC3PLUS_RTP_FTD_BWR *bwr, const int32_t sampling_rate, const int32_t high_res_enabled ); + +/* H (1 bit): + * Indicates whether the corresponding frame is a normal frame (primary encoding) or a helper frame + * (secondary encoding). 0 indicates a primary frame, 1 indicates secondary (redundant) frame */ +typedef enum LC3PLUS_RTP_FTD_H +{ + LC3PLUS_RTP_FTD_H_PRIMARY = 0x00, + LC3PLUS_RTP_FTD_H_SECONDARY = 0x80, +} LC3PLUS_RTP_FTD_H; +#define LC3PLUS_RTP_FTD_H_MASK 0x80 + +typedef enum LC3PLUS_RTP_FDL +{ + LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA = 0, + LC3PLUS_RTP_FDL_SPEECH_BAD = 1, + LC3PLUS_RTP_FDL_SPEECH_SID = 2, + LC3PLUS_RTP_FDL_RESERVED_MIN = 3, + LC3PLUS_RTP_FDL_RESERVED_MAX = 19, + LC3PLUS_RTP_FDL_LENGTH_1_MIN = 20, + LC3PLUS_RTP_FDL_LENGTH_1_MAX = 254, + LC3PLUS_RTP_FDL_LENGTH_2_MIN = 255, + LC3PLUS_RTP_FDL_LENGTH_2_MAX = 509, + LC3PLUS_RTP_FDL_LENGTH_3_MIN = 510, + LC3PLUS_RTP_FDL_LENGTH_3_MAX = 765 +} LC3PLUS_RTP_FDL; +/* value used to indicate that the Frame Data Length (FDL) extends to the next byte */ +#define LC3PLUS_RTP_FDL_EXTENSION_VALUE 0xFF + +typedef struct LC3PLUS_RTP_FTD +{ + LC3PLUS_RTP_FTD_FC fc; + LC3PLUS_RTP_FTD_FDI fdi; + LC3PLUS_RTP_FTD_BWR bwr; + LC3PLUS_RTP_FTD_H h; + uint8_t *frame_data; + LC3PLUS_RTP_FDL frame_data_length; +} LC3PLUS_RTP_FTD; +#define LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL 1 +#define LC3PLUS_RTP_FTD_MIN_SIZE 2 /* FTD itself (1 byte) + the shortest possible length field (1 byte) */ + +/*! Serialize the sender_ftds structs and fdl_request into a linear compact buffer + * @param[out] serialized_buffer pointer to the start of the memory location where the serialized buffer will be written to + * @param[in] serialized_buffer_capacity capacity of the serialized_buffer in bytes + * @param[out] packed_buffer_actual_size actually used size of in bytes of the packed_buffer (<=serialized_buffer_capacity) + * @param[in] fdl_request frame data length request + * @param[in,out] sender_ftds the function will overwrite the frame_data pointer with the correct memory location in + * the packed_buffer (so it can subsequently be used as input for the LC3plus encode call) + * @param[in] sender_ftds_num number of sender_ftds + * @return LC3PLUS_RTP_ERR_NO_ERROR in case of success */ +LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_serialize( + uint8_t *serialized_buffer, + const size_t serialized_buffer_capacity, + size_t *packed_buffer_actual_size, + const LC3PLUS_RTP_FDL fdl_request, + LC3PLUS_RTP_FTD *sender_ftds, + const size_t sender_ftds_num ); + +/*! Get size of the frame data length field for a certain frame data length value in bytes. + * @param[out] length size of the frame data length field in bytes [1,2,3] + * @param[in] frameDataLengthValue frame data length value + * @return LC3PLUS_RTP_ERR_NO_ERROR in case of success */ +LC3PLUS_RTP_ERR LC3PLUS_RTP_frame_data_length_get_size( int32_t *length, const LC3PLUS_RTP_FDL frameDataLengthValue ); + +#define LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS 16 +#define LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES 8 /* max ivas frame duration/min lc3plus frame duration: 20000/2500 */ +#define LC3PLUS_RTP_PAYLOAD_MAX_NUM_FTDS LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS *LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES + +typedef struct LC3PLUS_RTP_PAYLOAD_CONFIG +{ + /* frame duration in us shared among all FTDs */ + int32_t frame_duration_us; + /* high resolution flag shared among all FTDs */ + int16_t high_resolution_enabled; + /* sampling frequency shared among all FTDs */ + int32_t sampling_rate_hz; + /* number of individual channels in the payload */ + int16_t num_channels; + /* number of individual media times in the payload */ + int16_t num_media_times; + /* frame data length request */ + LC3PLUS_RTP_FDL fdl_request; + /* FTD data with pointer to raw frame data */ + LC3PLUS_RTP_FTD ftds[LC3PLUS_RTP_PAYLOAD_MAX_NUM_FTDS]; + /* actual number of ftds */ + int16_t num_ftds; +} LC3PLUS_RTP_PAYLOAD; + +/*! Deserialized a serialized buffer into a LC3PLUS_RTP_PAYLOAD struct + * @param payload pointer to target LC3PLUS_RTP_PAYLOAD object. Note: frame_data pointers in the struct will point to the respective memory locations in the serialized_buffer. + * @param serialized_buffer pointer to the start of the serialized input buffer + * @param serialized_buffer_size size of the serialized input buffer in bytes + * @return LC3PLUS_RTP_ERR_NO_ERROR in case of success */ +LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_deserialize( + LC3PLUS_RTP_PAYLOAD *payload, + uint8_t *serialized_buffer, + const size_t serialized_buffer_size ); + +#endif /* LC3PLUS_RTP_PAYLOAD_FORMAT */ +#endif /* #ifdef SPLIT_REND_WITH_HEAD_ROT */ +#endif /* ISAR_LC3PLUS_PAYLOAD_H */ diff --git a/lib_isar/isar_prot.h b/lib_isar/isar_prot.h index a9917abb07..c0c8817d3c 100644 --- a/lib_isar/isar_prot.h +++ b/lib_isar/isar_prot.h @@ -272,8 +272,12 @@ ivas_error isar_set_split_rend_setup( int32_t isar_get_lc3plus_bitrate( const int32_t SplitRendBitRate, - const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, - const int16_t split_prerender_frame_size_ms ); + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode +#ifndef LC3PLUS_RTP_PAYLOAD_FORMAT + , + const int16_t split_prerender_frame_size_ms +#endif +); ivas_error isar_split_rend_validate_config( const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, @@ -283,8 +287,10 @@ int32_t isar_get_lcld_bitrate( const int32_t SplitRendBitRate, const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode ); +#ifndef LC3PLUS_RTP_PAYLOAD_FORMAT int8_t isar_get_lc3plus_bitrate_id( const int32_t SplitRendBitRate ); +#endif ivas_error isar_split_renderer_open( SPLIT_REND_WRAPPER *hSplitBinRend, @@ -338,10 +344,12 @@ int16_t wrap_a( const int16_t min_val, const int16_t max_val ); +#ifndef LC3PLUS_RTP_PAYLOAD_FORMAT int32_t isar_get_lc3plus_size_from_id( const int8_t SplitRendBitRateId, const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, const int16_t split_prerender_frame_size_ms ); +#endif void isar_renderSplitUpdateNoCorrectionPoseData( const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, diff --git a/lib_isar/isar_splitRendererPre.c b/lib_isar/isar_splitRendererPre.c index 30ba6f846d..1944e8e95d 100644 --- a/lib_isar/isar_splitRendererPre.c +++ b/lib_isar/isar_splitRendererPre.c @@ -1655,6 +1655,9 @@ ivas_error isar_set_split_rend_setup( splitRendBits->codec = ISAR_SPLIT_REND_CODEC_DEFAULT; splitRendBits->pose_correction = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; splitRendBits->codec_frame_size_ms = 0; +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + splitRendBits->lc3plus_highres = 0; +#endif if ( ( hSplitBinRend->hMultiBinCldfbData = (ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA ) ) ) == NULL ) { @@ -1754,9 +1757,19 @@ static ivas_error split_renderer_open_lc3plus( config.ivas_frame_duration_us = ( pSplitRendConfig->dof == 0 ) ? config.lc3plus_frame_duration_us * num_subframes : 20000; config.samplerate = OutSampleRate; +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + config.high_res_mode_enabled = ( pSplitRendConfig->lc3plus_highres != 0 ); +#endif config.channels = BINAURAL_CHANNELS; - if ( ( error = IVAS_LC3PLUS_ENC_Open( config, isar_get_lc3plus_bitrate( pSplitRendConfig->splitRendBitRate, pSplitRendConfig->poseCorrectionMode, (int16_t) ( config.ivas_frame_duration_us / 1000 ) ), &hSplitRendWrapper->hLc3plusEnc ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_LC3PLUS_ENC_Open( config, isar_get_lc3plus_bitrate( pSplitRendConfig->splitRendBitRate, pSplitRendConfig->poseCorrectionMode +#ifndef LC3PLUS_RTP_PAYLOAD_FORMAT + + , + (int16_t) ( config.ivas_frame_duration_us / 1000 ) +#endif + ), + &hSplitRendWrapper->hLc3plusEnc ) ) != IVAS_ERR_OK ) { return error; } @@ -2019,7 +2032,11 @@ void isar_split_renderer_close( static ivas_error splitRendLc3plusEncodeAndWrite( SPLIT_REND_WRAPPER *hSplitBin, ISAR_SPLIT_REND_BITS_HANDLE pBits, +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + const int32_t available_bits, +#else const int32_t SplitRendBitRate, +#endif float *in[] ) { ivas_error error; @@ -2039,15 +2056,28 @@ static ivas_error splitRendLc3plusEncodeAndWrite( channel_ptrs[i] = in[i]; } +#ifdef LC3PLUS_VBR + if ( ( error = IVAS_LC3PLUS_ENC_SetBitrate( hSplitBin->hLc3plusEnc, available_bits * FRAMES_PER_SEC ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + if ( ( error = IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( hSplitBin->hLc3plusEnc, &lc3plusBitstreamSize ) ) != IVAS_ERR_OK ) { return error; } +#ifndef LC3PLUS_RTP_PAYLOAD_FORMAT ISAR_SPLIT_REND_BITStream_write_int32( pBits, isar_get_lc3plus_bitrate_id( SplitRendBitRate ), 8 ); +#endif /* Write bitstream */ +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + if ( ( error = IVAS_LC3PLUS_ENC_Encode( hSplitBin->hLc3plusEnc, channel_ptrs, &pBits->bits_buf[pBits->bits_written / 8], lc3plusBitstreamSize ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_LC3PLUS_ENC_Encode( hSplitBin->hLc3plusEnc, channel_ptrs, &pBits->bits_buf[pBits->bits_written / 8] ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -2059,6 +2089,48 @@ static ivas_error splitRendLc3plusEncodeAndWrite( return IVAS_ERR_OK; } +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT +static void write_pose_correction_section( SPLIT_REND_WRAPPER *hSplitBin, + const IVAS_QUATERNION headPosition, + const int32_t SplitRendBitRate, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t low_res_pre_rend_rot, + const int16_t pcm_out_flag, + const int16_t ro_md_flag ) +{ + int32_t available_md_bits; +#ifdef SPLIT_REND_METADATA_SECTION_SIZE + int32_t md_section_start, md_section_end; + + md_section_start = pBits->bits_written; +#endif + available_md_bits = isar_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000; + +#ifdef SPLIT_REND_METADATA_SECTION_SIZE + /* Skip first few bits, where the size info of the pose correction metadata section + * will be written later (it is not yet known at this point) */ + available_md_bits -= IVAS_SPLIT_REND_MD_SIZE_BITS; + pBits->bits_written += IVAS_SPLIT_REND_MD_SIZE_BITS; +#endif + + /* Write pose correction metadata */ + if ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + isar_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, pBits, available_md_bits, low_res_pre_rend_rot, ro_md_flag ); + } + +#ifdef SPLIT_REND_METADATA_SECTION_SIZE + /* Update metadata section size field with the actual number of bits written */ + md_section_end = pBits->bits_written; + pBits->bits_written = md_section_start; /* Hack to write to the beginning of the metadata section */ + ISAR_SPLIT_REND_BITStream_write_int32( pBits, md_section_end - md_section_start, IVAS_SPLIT_REND_MD_SIZE_BITS ); + pBits->bits_written = md_section_end; +#endif +} +#endif + /*------------------------------------------------------------------------- * Function ivas_renderMultiTDBinToSplitBinaural() @@ -2079,7 +2151,11 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( const int16_t ro_md_flag ) { ivas_error error; +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + int32_t bit_len, available_bits; +#else int32_t bit_len, available_bits, target_md_bits, actual_md_bits; +#endif int16_t num_cldfb_bands, ch, slot_idx, pos_idx, num_poses; float Cldfb_In_BinReal[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; float Cldfb_In_BinImag[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; @@ -2116,7 +2192,9 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( } } +#ifndef LC3PLUS_RTP_PAYLOAD_FORMAT actual_md_bits = pBits->bits_written; +#endif if ( ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) || ( !useLc3plus && !pcm_out_flag ) ) { num_slots = ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ? CLDFB_NO_COL_MAX : ( hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ); @@ -2153,6 +2231,20 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( } } +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + if ( hSplitBin->multiBinPoseData.poseCorrectionMode != ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) + { + write_pose_correction_section( hSplitBin, + headPosition, + SplitRendBitRate, + pBits, + Cldfb_In_BinReal, + Cldfb_In_BinImag, + low_res_pre_rend_rot, + pcm_out_flag, + ro_md_flag ); + } +#else if ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { target_md_bits = isar_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000; @@ -2161,6 +2253,7 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( isar_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, pBits, target_md_bits, low_res_pre_rend_rot, ro_md_flag ); } +#endif if ( pcm_out_flag == 0 ) { @@ -2170,15 +2263,24 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( if ( !useLc3plus ) { available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + available_bits -= pBits->bits_written; +#else actual_md_bits = pBits->bits_written - actual_md_bits; available_bits -= actual_md_bits; +#endif pBits->codec_frame_size_ms = codec_frame_size_ms; isar_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal, Cldfb_In_BinImag, available_bits, pBits ); } else { +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + available_bits = ( SplitRendBitRate / FRAMES_PER_SEC ) - pBits->bits_written; + if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, available_bits, in ) ) != IVAS_ERR_OK ) +#else if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, SplitRendBitRate, in ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -2304,7 +2406,11 @@ ivas_error isar_renderMultiBinToSplitBinaural( const int16_t ro_md_flag ) { ivas_error error; +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + int32_t bit_len, available_bits; +#else int32_t bit_len, target_md_bits, actual_md_bits, available_bits; +#endif error = IVAS_ERR_OK; push_wmops( "isar_renderMultiBinToSplitBinaural" ); @@ -2340,6 +2446,20 @@ ivas_error isar_renderMultiBinToSplitBinaural( lc3plusTimeAlignCldfbPoseCorr( hSplitBin, Cldfb_In_BinReal, Cldfb_In_BinImag ); } +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + if ( hSplitBin->multiBinPoseData.poseCorrectionMode != ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) + { + write_pose_correction_section( hSplitBin, + headPosition, + SplitRendBitRate, + pBits, + Cldfb_In_BinReal, + Cldfb_In_BinImag, + low_res_pre_rend_rot, + pcm_out_flag, + ro_md_flag ); + } +#else actual_md_bits = pBits->bits_written; if ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { @@ -2349,6 +2469,7 @@ ivas_error isar_renderMultiBinToSplitBinaural( isar_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, pBits, target_md_bits, low_res_pre_rend_rot, ro_md_flag ); } +#endif if ( pcm_out_flag == 0 ) { @@ -2358,8 +2479,12 @@ ivas_error isar_renderMultiBinToSplitBinaural( if ( splitCodec == ISAR_SPLIT_REND_CODEC_LCLD ) { available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + available_bits -= pBits->bits_written; +#else actual_md_bits = pBits->bits_written - actual_md_bits; available_bits -= actual_md_bits; +#endif pBits->codec_frame_size_ms = codec_frame_size_ms; isar_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal, Cldfb_In_BinImag, available_bits, pBits ); } @@ -2386,7 +2511,12 @@ ivas_error isar_renderMultiBinToSplitBinaural( #endif } +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + available_bits = ( SplitRendBitRate / FRAMES_PER_SEC ) - pBits->bits_written; + if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, available_bits, output ) ) != IVAS_ERR_OK ) +#else if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, SplitRendBitRate, output ) ) != IVAS_ERR_OK ) +#endif { return error; } diff --git a/lib_isar/isar_splitRenderer_utils.c b/lib_isar/isar_splitRenderer_utils.c index 02ef38de44..88b21df5fb 100644 --- a/lib_isar/isar_splitRenderer_utils.c +++ b/lib_isar/isar_splitRenderer_utils.c @@ -576,15 +576,26 @@ int32_t isar_get_lcld_bitrate( * *------------------------------------------------------------------------*/ +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT +/* TODO: This is now the same as isar_get_lcld_bitrate - merge these functions into one */ +#endif int32_t isar_get_lc3plus_bitrate( const int32_t SplitRendBitRate, - ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, - const int16_t split_prerender_frame_size_ms ) + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode +#ifndef LC3PLUS_RTP_PAYLOAD_FORMAT + , + const int16_t split_prerender_frame_size_ms +#endif +) { if ( poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + return isar_get_lcld_bitrate( SplitRendBitRate, poseCorrectionMode ); +#else int32_t inBandMdBps = (int32_t) ( 8 * 1000 / split_prerender_frame_size_ms ); return isar_get_lcld_bitrate( SplitRendBitRate, poseCorrectionMode ) - inBandMdBps; +#endif } if ( poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) @@ -598,6 +609,7 @@ int32_t isar_get_lc3plus_bitrate( } +#ifndef LC3PLUS_RTP_PAYLOAD_FORMAT /*------------------------------------------------------------------------- * Function isar_get_lc3plus_bitrate_id() * @@ -691,6 +703,7 @@ int32_t isar_get_lc3plus_size_from_id( /* Return size in bytes */ return (int32_t) ( bitrate * split_prerender_frame_size_ms / 1000 / 8 ); } +#endif /*------------------------------------------------------------------------- diff --git a/lib_isar/lib_isar_post_rend.c b/lib_isar/lib_isar_post_rend.c index f25614b554..1584874d48 100644 --- a/lib_isar/lib_isar_post_rend.c +++ b/lib_isar/lib_isar_post_rend.c @@ -232,6 +232,9 @@ static void convertBitsBufferToInternalBitsBuff( hBits->codec = outBits.config.codec; hBits->pose_correction = outBits.config.poseCorrection; hBits->codec_frame_size_ms = outBits.config.codec_frame_size_ms; +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + hBits->lc3plus_highres = outBits.config.lc3plusHighRes; +#endif return; } @@ -247,6 +250,9 @@ static void convertInternalBitsBuffToBitsBuffer( hOutBits->config.codec = bits.codec; hOutBits->config.poseCorrection = bits.pose_correction; hOutBits->config.codec_frame_size_ms = bits.codec_frame_size_ms; +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + hOutBits->config.lc3plusHighRes = bits.lc3plus_highres; +#endif return; } @@ -511,6 +517,9 @@ static ivas_error updateSplitPostRendPanGains( rendCtx = inputSplitPostRend->base.ctx; isar_renderSplitGetMultiBinPoseData( hRendCfg, &inputSplitPostRend->splitPostRendWrapper.multiBinPoseData, rendCtx.pHeadRotData->sr_pose_pred_axis ); +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + config.high_res_mode_enabled = ( hRendCfg->lc3plus_highres != 0 ); +#endif config.lc3plus_frame_duration_us = hRendCfg->codec_frame_size_ms * 1000; if ( num_subframes != MAX_PARAM_SPATIAL_SUBFRAMES ) { @@ -1397,12 +1406,20 @@ ivas_error ISAR_POST_REND_SetSplitRendBFI( static ivas_error splitBinLc3plusDecode( ISAR_SPLIT_POST_REND_WRAPPER *hSplitBin, ISAR_SPLIT_REND_BITS_HANDLE bits, - float outputBuffer[BINAURAL_CHANNELS][L_FRAME48k], - ISAR_SPLIT_REND_POSE_CORRECTION_MODE pose_correction ) + float outputBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k] +#ifndef LC3PLUS_RTP_PAYLOAD_FORMAT + , + ISAR_SPLIT_REND_POSE_CORRECTION_MODE pose_correction +#endif +) { ivas_error error; float *channel_ptrs[MAX_HEAD_ROT_POSES * 2]; +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + int32_t lc3plusBitstreamSize; +#else int32_t lc3plusBitrateId, lc3plusBitstreamSize; +#endif push_wmops( "splitBinLc3plusDecode" ); assert( hSplitBin->hLc3plusDec != NULL ); @@ -1412,11 +1429,18 @@ static ivas_error splitBinLc3plusDecode( { ++bits->bits_read; } + +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + /* Size is in bytes */ + assert( ( bits->bits_written - bits->bits_read ) % 8 == 0 ); + lc3plusBitstreamSize = ( bits->bits_written - bits->bits_read ) / 8; +#else /* Read LC3plus bitstream size info */ lc3plusBitrateId = ISAR_SPLIT_REND_BITStream_read_int32( bits, 8 ); lc3plusBitstreamSize = isar_get_lc3plus_size_from_id( (int8_t) lc3plusBitrateId, pose_correction, (int16_t) ( hSplitBin->hLc3plusDec->config.ivas_frame_duration_us / 1000 ) ); +#endif - for ( int16_t i = 0; i < BINAURAL_CHANNELS; ++i ) + for ( int16_t i = 0; i < BINAURAL_CHANNELS * hSplitBin->multiBinPoseData.num_poses; ++i ) { channel_ptrs[i] = outputBuffer[i]; } @@ -1457,7 +1481,11 @@ static ivas_error renderSplitBinauralWithPostRot( uint32_t ivas_frame_duration_us; int16_t iNumBlocksPerFrame, iNumLCLDIterationsPerFrame; const IVAS_REND_HeadRotData *pHeadRotData; +#ifdef SPLIT_REND_METADATA_SECTION_SIZE + int16_t split_rend_md_section_size_bits; + split_rend_md_section_size_bits = 0; +#endif isPostRendInputCldfb = 0; push_wmops( "renderSplitBinauralWithPostRot" ); error = IVAS_ERR_OK; @@ -1493,6 +1521,15 @@ static ivas_error renderSplitBinauralWithPostRot( if ( hSplitBin->first_good_frame_received == 1 ) { +#ifdef SPLIT_REND_METADATA_SECTION_SIZE + if ( bits.pose_correction != ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) + { + // This info is currently unused, but will later be needed e.g. when packing SR bitstream into RTP + split_rend_md_section_size_bits = ISAR_SPLIT_REND_BITStream_read_int32( &bits, IVAS_SPLIT_REND_MD_SIZE_BITS ); + (void) split_rend_md_section_size_bits; + } +#endif + if ( bits.pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { if ( !SplitRendBFI ) @@ -1560,7 +1597,12 @@ static ivas_error renderSplitBinauralWithPostRot( } else { - if ( ( error = splitBinLc3plusDecode( hSplitBin, &bits, tmpCrendBuffer, bits.pose_correction ) ) != IVAS_ERR_OK ) + if ( ( error = splitBinLc3plusDecode( hSplitBin, &bits, tmpCrendBuffer +#ifndef LC3PLUS_RTP_PAYLOAD_FORMAT + , + bits.pose_correction +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -1986,7 +2028,11 @@ ivas_error IVAS_REND_SetSplitRendBitstreamHeader( ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ const ISAR_SPLIT_REND_CODEC codec, /* o: codec setting */ const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, /* o: pose correction mode */ - const int16_t codec_frame_size_ms /* o: codec frame size setting */ + const int16_t codec_frame_size_ms /* i: codec frame size setting */ +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + , + const int16_t lc3plus_highres /* i: LC3plus Hig-Res setting. Ignored if codec is not LC3plus */ +#endif ) { if ( hIvasRend == NULL ) @@ -1996,6 +2042,9 @@ ivas_error IVAS_REND_SetSplitRendBitstreamHeader( hIvasRend->splitRenderConfig.codec = codec; hIvasRend->splitRenderConfig.codec_frame_size_ms = codec_frame_size_ms; hIvasRend->splitRenderConfig.poseCorrectionMode = poseCorrection; +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + hIvasRend->splitRenderConfig.lc3plus_highres = lc3plus_highres; +#endif return IVAS_ERR_OK; } diff --git a/lib_isar/lib_isar_post_rend.h b/lib_isar/lib_isar_post_rend.h index 3f742bb730..2c849a7b2c 100644 --- a/lib_isar/lib_isar_post_rend.h +++ b/lib_isar/lib_isar_post_rend.h @@ -66,6 +66,9 @@ typedef struct ISAR_SPLIT_REND_CODEC codec; ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection; int16_t codec_frame_size_ms; +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + int16_t lc3plusHighRes; +#endif } ISAR_POST_REND_BitstreamBufferConfig; typedef struct @@ -249,7 +252,11 @@ ivas_error IVAS_REND_SetSplitRendBitstreamHeader( ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ const ISAR_SPLIT_REND_CODEC codec, /* o: codec setting */ const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, /* o: pose correction mode */ - const int16_t codec_frame_size_ms /* o: codec frame size setting */ + const int16_t codec_frame_size_ms /* i: codec frame size setting */ +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + , + const int16_t lc3plus_highres /* i: LC3plus Hig-Res setting. Ignored if codec is not LC3plus */ +#endif ); /* Split binaural rendering functions */ diff --git a/lib_rend/ivas_render_config.c b/lib_rend/ivas_render_config.c index e9c9fa749a..8f19a4dce5 100644 --- a/lib_rend/ivas_render_config.c +++ b/lib_rend/ivas_render_config.c @@ -140,6 +140,9 @@ ivas_error ivas_render_config_init_from_rom( ( *hRenderConfig )->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; ( *hRenderConfig )->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; ( *hRenderConfig )->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_DEFAULT; +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + ( *hRenderConfig )->split_rend_config.lc3plus_highres = 0; +#endif #endif return IVAS_ERR_OK; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index ac9eac2250..bab7b06a23 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -4346,6 +4346,9 @@ int16_t IVAS_REND_GetRenderConfig( hRCout->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; hRCout->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; hRCout->split_rend_config.rendererSelection = hRCin->split_rend_config.rendererSelection; +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + hRCout->split_rend_config.lc3plus_highres = 0; +#endif #endif hRCout->roomAcoustics.use_er = hRCin->roomAcoustics.use_er; diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index d8df30fad3..873cfff935 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -66,6 +66,9 @@ typedef struct ISAR_SPLIT_REND_CODEC codec; ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection; int16_t codec_frame_size_ms; +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + int16_t lc3plus_highres; +#endif } IVAS_REND_BitstreamBufferConfig; typedef struct { diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 0a29f8fe05..0478e08223 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -2565,6 +2565,15 @@ ivas_error RenderConfigReader_read( errorHandler( pValue, ERROR_VALUE_INVALID ); } } +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + else if ( strcmp( item, "LC3PLUS_HIGHRES" ) == 0 ) + { + if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.lc3plus_highres ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } +#endif #ifdef DEBUGGING else { diff --git a/lib_util/split_render_file_read_write.c b/lib_util/split_render_file_read_write.c index 066f3ecfe2..3dc75fe53d 100644 --- a/lib_util/split_render_file_read_write.c +++ b/lib_util/split_render_file_read_write.c @@ -71,7 +71,13 @@ ivas_error split_rend_reader_open( char *filename, ISAR_SPLIT_REND_CODEC *codec, ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, - int16_t *codec_frame_size_ms ) + int16_t *codec_frame_size_ms +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + , + int32_t *sampling_rate, + int16_t *lc3plus_highres +#endif +) { SplitFileReadWrite *hSplitRendFileReadWrite; size_t header_len, h; @@ -123,6 +129,18 @@ ivas_error split_rend_reader_open( { return IVAS_ERR_FAILED_FILE_READ; } +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + /* read sampling rate signalling */ + if ( fread( sampling_rate, sizeof( *sampling_rate ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + /* read LC3plus highres signalling */ + if ( fread( lc3plus_highres, sizeof( *lc3plus_highres ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } +#endif *hhSplitRendFileReadWrite = hSplitRendFileReadWrite; @@ -143,7 +161,13 @@ ivas_error split_rend_writer_open( const int32_t delayTimeScale, ISAR_SPLIT_REND_CODEC codec, ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, - int16_t codec_frame_size_ms ) + int16_t codec_frame_size_ms +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + , + int32_t sampling_rate, + int16_t lc3plus_highres +#endif +) { SplitFileReadWrite *hSplitRendFileReadWrite; size_t header_len, h; @@ -194,6 +218,18 @@ ivas_error split_rend_writer_open( { return IVAS_ERR_FAILED_FILE_WRITE; } +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + /* Write sampling rate signalling */ + if ( fwrite( &sampling_rate, sizeof( sampling_rate ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + /* Write LC3plus highres signalling */ + if ( fwrite( &lc3plus_highres, sizeof( lc3plus_highres ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } +#endif *hhSplitRendFileReadWrite = hSplitRendFileReadWrite; diff --git a/lib_util/split_render_file_read_write.h b/lib_util/split_render_file_read_write.h index 46e7b71a73..ec22cc9a7f 100644 --- a/lib_util/split_render_file_read_write.h +++ b/lib_util/split_render_file_read_write.h @@ -44,7 +44,13 @@ ivas_error split_rend_reader_open( char *filename, ISAR_SPLIT_REND_CODEC *codec, ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, - int16_t *codec_frame_size_ms ); + int16_t *codec_frame_size_ms +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + , + int32_t *sampling_rate, + int16_t *lc3plus_highres +#endif +); /* Allocates and initializes a a split renderer writer instance */ @@ -55,7 +61,13 @@ ivas_error split_rend_writer_open( const int32_t delayTimeScale, ISAR_SPLIT_REND_CODEC codec, ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, - int16_t codec_frame_size_ms ); + int16_t codec_frame_size_ms +#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + , + int32_t sampling_rate, + int16_t lc3plus_highres +#endif +); /* Closes the split renderer reader/writer and deallocates memory */ diff --git a/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test.c b/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test.c index 678e7e1ef5..d27ffde587 100644 --- a/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test.c +++ b/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test.c @@ -39,13 +39,16 @@ the United Nations Convention on Contracts on the International Sales of Goods. #include "ivas_error_utils.h" #ifdef SPLIT_REND_WITH_HEAD_ROT - +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT +#define MAX_SAMPLES_PER_CHANNEL 960 / 4 +#else #define MAX_SAMPLES_PER_CHANNEL 960 +#endif static int encodeAndDecodeOneStereoFrame( LC3PLUS_CONFIG config ) { ivas_error err; - uint32_t bps = 128000; + uint32_t bps = 256000; int32_t encDelay = -1; int32_t decDelay = -1; @@ -59,10 +62,12 @@ static int encodeAndDecodeOneStereoFrame( LC3PLUS_CONFIG config ) err = IVAS_LC3PLUS_ENC_GetDelay( encHandle, &encDelay ); if ( IVAS_ERR_OK != err ) { + IVAS_LC3PLUS_ENC_Close( &encHandle ); return err; } if ( encDelay == -1 || encDelay == 0 ) { + IVAS_LC3PLUS_ENC_Close( &encHandle ); return IVAS_ERROR( IVAS_ERR_INTERNAL, "encDelay is zero or uninitialized\n" ); } @@ -79,14 +84,24 @@ static int encodeAndDecodeOneStereoFrame( LC3PLUS_CONFIG config ) int32_t bitstreamSizePerIvasFrame = 0; err = IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame ); if ( IVAS_ERR_OK != err ) + { + IVAS_LC3PLUS_ENC_Close( &encHandle ); return err; - + } uint8_t *bitstream_out = malloc( bitstreamSizePerIvasFrame ); memset( bitstream_out, 0, bitstreamSizePerIvasFrame ); +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + err = IVAS_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out, bitstreamSizePerIvasFrame ); +#else err = IVAS_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out ); +#endif if ( IVAS_ERR_OK != err ) + { + IVAS_LC3PLUS_ENC_Close( &encHandle ); + free( bitstream_out ); return err; + } IVAS_LC3PLUS_ENC_Close( &encHandle ); /* decode one frame */ @@ -98,16 +113,21 @@ static int encodeAndDecodeOneStereoFrame( LC3PLUS_CONFIG config ) &decHandle ); if ( IVAS_ERR_OK != err ) { + free( bitstream_out ); return err; } err = IVAS_LC3PLUS_DEC_GetDelay( decHandle, &decDelay ); if ( IVAS_ERR_OK != err ) { + IVAS_LC3PLUS_DEC_Close( &decHandle ); + free( bitstream_out ); return err; } if ( decDelay == -1 || decDelay == 0 ) { + IVAS_LC3PLUS_DEC_Close( &decHandle ); + free( bitstream_out ); return IVAS_ERROR( IVAS_ERR_INTERNAL, "decDelay is zero or uninitialized\n" ); } @@ -124,18 +144,24 @@ static int encodeAndDecodeOneStereoFrame( LC3PLUS_CONFIG config ) err = IVAS_LC3PLUS_DEC_Conceal( decHandle, pcm_out ); if ( IVAS_ERR_OK != err ) { + IVAS_LC3PLUS_DEC_Close( &decHandle ); + free( bitstream_out ); return err; } err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstreamSizePerIvasFrame, pcm_out ); if ( IVAS_ERR_OK != err ) { + IVAS_LC3PLUS_DEC_Close( &decHandle ); + free( bitstream_out ); return err; } err = IVAS_LC3PLUS_DEC_Conceal( decHandle, pcm_out ); if ( IVAS_ERR_OK != err ) { + IVAS_LC3PLUS_DEC_Close( &decHandle ); + free( bitstream_out ); return err; } @@ -149,7 +175,11 @@ static int encodeAndDecodeOneStereoFrame( LC3PLUS_CONFIG config ) static int openCloseEncoder( void ) { ivas_error err; +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif uint32_t bps = 128000; ISAR_LC3PLUS_ENC_HANDLE encHandle; @@ -166,7 +196,11 @@ static int openCloseEncoder( void ) static int tryOpenEncoderWithInvalidBitrate( void ) { ivas_error err; +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif /* lc3plus max bitrate is 320000 per channel */ uint32_t invalid_high_bps = 700000; uint32_t invalid_low_bps = 8; @@ -190,7 +224,11 @@ static int tryOpenEncoderWithInvalidBitrate( void ) static int tryOpenEncoderWithInvalidFrameDuration( void ) { ivas_error err; +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif config.lc3plus_frame_duration_us = 1234; /*unsupported frame duration*/ uint32_t bps = 320000; @@ -207,7 +245,11 @@ static int tryOpenEncoderWithInvalidFrameDuration( void ) static int tryOpenEncoderWithInvalidSampleRate( void ) { ivas_error err; +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif config.samplerate = 1234; /*unsupported sample rate */ uint32_t bps = 320000; @@ -247,11 +289,19 @@ static int tryCallEncoderApiWithInvalidParams( void ) return 1; } IVAS_LC3PLUS_ENC_Close( &invalidEncHandle ); +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, invalidBitstream_out, bsSize ) ) +#else if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, invalidBitstream_out ) ) +#endif { return 1; } +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, invalidBitstream_out, bsSize ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, bitstream_out, bsSize ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, bitstream_out, bsSize ) ) +#else if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, invalidBitstream_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, bitstream_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, bitstream_out ) ) +#endif { return 1; } @@ -297,8 +347,11 @@ static int tryCallDecoderApiWithInvalidParams( void ) static int openCloseDecoderWithCaching( void ) { ivas_error err; +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; - +#endif ISAR_LC3PLUS_DEC_HANDLE decHandle; err = IVAS_LC3PLUS_DEC_Open( config, #ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING @@ -317,8 +370,11 @@ static int openCloseDecoderWithCaching( void ) static int openCloseDecoderWithoutCaching( void ) { ivas_error err; +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; - +#endif ISAR_LC3PLUS_DEC_HANDLE decHandle; err = IVAS_LC3PLUS_DEC_Open( config, #ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING @@ -338,7 +394,11 @@ static int openCloseDecoderWithoutCaching( void ) static int tryOpenDecoderWithInvalidFrameDuration( void ) { ivas_error err; +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif config.lc3plus_frame_duration_us = 1234; /*unsupported frame duration*/ ISAR_LC3PLUS_DEC_HANDLE decHandle; @@ -358,7 +418,11 @@ static int tryOpenDecoderWithInvalidFrameDuration( void ) static int tryOpenDecoderWithInvalidSampleRate( void ) { ivas_error err; +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif config.samplerate = 1234; /*unsupported sample rate*/ ISAR_LC3PLUS_DEC_HANDLE decHandle; @@ -378,7 +442,11 @@ static int tryOpenDecoderWithInvalidSampleRate( void ) static int encodeOneFrame( void ) { ivas_error err; +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif uint32_t bps = 128000; ISAR_LC3PLUS_ENC_HANDLE encHandle; @@ -399,8 +467,11 @@ static int encodeOneFrame( void ) return err; uint8_t *bitstream_out = malloc( bitstreamSizePerIvasFrame ); memset( bitstream_out, 0, bitstreamSizePerIvasFrame ); - +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + err = IVAS_LC3PLUS_ENC_Encode( encHandle, pcm, bitstream_out, bitstreamSizePerIvasFrame ); +#else err = IVAS_LC3PLUS_ENC_Encode( encHandle, pcm, bitstream_out ); +#endif if ( IVAS_ERR_OK != err ) return err; @@ -413,7 +484,11 @@ static int encodeOneFrame( void ) static int encodeAndDecodeOneMonoFrame( void ) { ivas_error err; +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif uint32_t bps = 128000; ISAR_LC3PLUS_ENC_HANDLE encHandle; @@ -437,8 +512,11 @@ static int encodeAndDecodeOneMonoFrame( void ) uint8_t *bitstream_out = malloc( bitstreamSizePerIvasFrame ); memset( bitstream_out, 0, bitstreamSizePerIvasFrame ); - +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + err = IVAS_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out, bitstreamSizePerIvasFrame ); +#else err = IVAS_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out ); +#endif if ( IVAS_ERR_OK != err ) return err; IVAS_LC3PLUS_ENC_Close( &encHandle ); @@ -481,7 +559,11 @@ static int encodeAndDecodeOneMonoFrame( void ) static int encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_48kHz( void ) { +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000 }; +#endif return encodeAndDecodeOneStereoFrame( config ); } @@ -499,30 +581,47 @@ static int encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_16kHz( void ) static int encodeAndDecodeOneStereoFrameIvas5msLc3plus5ms_48kHz( void ) { +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5 * 1000, .channels = 2, .samplerate = 48000 }; +#endif return encodeAndDecodeOneStereoFrame( config ); } static int encodeAndDecodeOneMonoFrameIvas20msLc3plus10ms_48kHz( void ) { +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 1, .samplerate = 48000 }; +#endif return encodeAndDecodeOneStereoFrame( config ); } static int encodeAndDecodeOneMonoFrameIvas5msLc3plus5ms_48kHz( void ) { +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5 * 1000, .channels = 1, .samplerate = 48000 }; +#endif return encodeAndDecodeOneStereoFrame( config ); } static int encodeAndDecodeOneStereoFrameIvas20msLc3plus2_5ms_48kHz( void ) { +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 2.5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 2.5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000 }; +#endif return encodeAndDecodeOneStereoFrame( config ); } -#include "ivas_lc3plus_unit_test_selective_decoding.c" - +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT +#include "ivas_lc3plus_unit_test_payload_format.c" +#endif int main( int argc, @@ -531,97 +630,67 @@ int main( int ret = 0; ret = openCloseEncoder(); if ( ret != 0 ) - return ret; + return 1; ret = tryOpenEncoderWithInvalidBitrate(); if ( ret != 0 ) - return ret; + return 1; ret = tryOpenEncoderWithInvalidFrameDuration(); if ( ret != 0 ) - return ret; + return 1; ret = tryOpenEncoderWithInvalidSampleRate(); if ( ret != 0 ) - return ret; + return 1; ret = tryCallEncoderApiWithInvalidParams(); if ( ret != 0 ) - return ret; + return 1; ret = openCloseDecoderWithCaching(); if ( ret != 0 ) - return ret; + return 1; ret = openCloseDecoderWithoutCaching(); if ( ret != 0 ) - return ret; + return 1; ret = tryOpenDecoderWithInvalidFrameDuration(); if ( ret != 0 ) - return ret; + return 1; ret = tryOpenDecoderWithInvalidSampleRate(); if ( ret != 0 ) - return ret; + return 1; ret = tryCallDecoderApiWithInvalidParams(); if ( ret != 0 ) - return ret; + return 1; ret = encodeOneFrame(); if ( ret != 0 ) - return ret; + return 1; ret = encodeAndDecodeOneMonoFrame(); if ( ret != 0 ) - return ret; + return 1; ret = encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_48kHz(); if ( ret != 0 ) - return ret; + return 1; ret = encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_32kHz(); if ( ret != 0 ) - return ret; + return 1; ret = encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_16kHz(); if ( ret != 0 ) - return ret; + return 1; ret = encodeAndDecodeOneStereoFrameIvas5msLc3plus5ms_48kHz(); if ( ret != 0 ) - return ret; + return 1; ret = encodeAndDecodeOneMonoFrameIvas20msLc3plus10ms_48kHz(); if ( ret != 0 ) - return ret; + return 1; ret = encodeAndDecodeOneMonoFrameIvas5msLc3plus5ms_48kHz(); if ( ret != 0 ) - return ret; + return 1; ret = encodeAndDecodeOneStereoFrameIvas20msLc3plus2_5ms_48kHz(); if ( ret != 0 ) - return ret; - ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_decode_all_subframes(); - if ( ret != 0 ) - return ret; - ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_dont_decode_last_2_subframes(); - if ( ret != 0 ) - return ret; - ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_dont_decode_last_3_subframes(); - if ( ret != 0 ) - return ret; - ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_skip_first_subframe(); - if ( ret != 0 ) - return ret; - ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_decode_cache(); - if ( ret != 0 ) - return ret; - ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_switches_skip_first(); - if ( ret != 0 ) - return ret; - ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_switches_dec_first(); - if ( ret != 0 ) - return ret; - ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_bundle_switches_dec_first(); - if ( ret != 0 ) - return ret; - ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_bundle_switches_skip_first(); - if ( ret != 0 ) - return ret; - ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_get_active_dont_cache(); - if ( ret != 0 ) - return ret; -#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING - ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_switches_dec_first_no_caching(); + return 1; +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + ret = run_all_payload_tests(); if ( ret != 0 ) - return ret; + return 1; #endif - return ret; + return 0; } #else int main( void ) diff --git a/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test_payload_format.c b/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test_payload_format.c new file mode 100644 index 0000000000..e1a5f07392 --- /dev/null +++ b/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test_payload_format.c @@ -0,0 +1,451 @@ +/****************************************************************************************************** + +(C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, +Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +contributors to this repository. All Rights Reserved. + +This software is protected by copyright law and by international treaties. +The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, +Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +contributors to this repository retain full ownership rights in their respective contributions in +the software. This notice grants no license of any kind, including but not limited to patent +license, nor is any license granted by implication, estoppel or otherwise. + +Contributors are required to enter into the IVAS codec Public Collaboration agreement before making +contributions. + +This software is provided "AS IS", without any express or implied warranties. The software is in the +development stage. It is intended exclusively for experts who have experience with such software and +solely for the purpose of inspection. All implied warranties of non-infringement, merchantability +and fitness for a particular purpose are hereby disclaimed and excluded. + +Any dispute, controversy or claim arising under or in relation to providing this software shall be +submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in +accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and +the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include +#include +#include "isar_lc3plus_payload.h" +#include "ivas_error_utils.h" +#include "isar_lc3plus_common.h" +#include "options.h" + +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + +/* included by ivas_lc3plus_unit_test.c */ + +#define LC3PLUS_MAX_NUM_CODERS 16 +#define LC3PLUS_MAX_BS_SIZE LC3PLUS_MAX_NUM_CODERS *( 720 * LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES ) +#define SIZE_70 70 +#define SIZE_160 160 +#define SIZE_320 320 +#define SIZE_600 600 + +static int pack_and_unpack_payload_config_2ch_10ms_lc3plus_20ms_ivas( void ) +{ + LC3PLUS_RTP_FTD sender_ftds[LC3PLUS_MAX_NUM_CODERS]; + int32_t sender_ftds_num = 0; + const LC3PLUS_RTP_FDL fdl_req = LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA; + + LC3PLUS_RTP_FTD *ftd_L_01 = &sender_ftds[0]; + ftd_L_01->fc = LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL; + ftd_L_01->fdi = LC3PLUS_RTP_FTD_FDI_10000_US; + ftd_L_01->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_L_01->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_L_01->frame_data = NULL; + ftd_L_01->frame_data_length = SIZE_160; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_R_01 = &sender_ftds[1]; + ftd_R_01->fc = LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME; + ftd_R_01->fdi = LC3PLUS_RTP_FTD_FDI_10000_US; + ftd_R_01->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_R_01->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_R_01->frame_data = NULL; + ftd_R_01->frame_data_length = SIZE_600; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_L_02 = &sender_ftds[2]; + ftd_L_02->fc = LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL; + ftd_L_02->fdi = LC3PLUS_RTP_FTD_FDI_10000_US; + ftd_L_02->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_L_02->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_L_02->frame_data = NULL; + ftd_L_02->frame_data_length = SIZE_320; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_R_02 = &sender_ftds[3]; + ftd_R_02->fc = LC3PLUS_RTP_FTD_FC_LAST_OVERALL; + ftd_R_02->fdi = LC3PLUS_RTP_FTD_FDI_10000_US; + ftd_R_02->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_R_02->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_R_02->frame_data = NULL; + ftd_R_02->frame_data_length = SIZE_160; + sender_ftds_num++; + + const size_t packed_buffer_capacity = LC3PLUS_MAX_BS_SIZE; + size_t packed_buffer_actual_size; + uint8_t packed_buffer[LC3PLUS_MAX_BS_SIZE]; + memset( packed_buffer, 0, packed_buffer_capacity ); + // prepare bitstream buffer headers & layout + LC3PLUS_RTP_ERR error = LC3PLUS_RTP_payload_serialize( packed_buffer, packed_buffer_capacity, &packed_buffer_actual_size, fdl_req, sender_ftds, sender_ftds_num ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_serialize failed\n" ); + } + + // copy encoded frames into their expected memory locations + uint8_t frame_data_L_01[SIZE_160]; + memset( frame_data_L_01, 0x01, sizeof( frame_data_L_01 ) ); + uint8_t frame_data_R_01[SIZE_600]; + memset( frame_data_R_01, 0x02, sizeof( frame_data_R_01 ) ); + uint8_t frame_data_L_02[SIZE_320]; + memset( frame_data_L_02, 0x03, sizeof( frame_data_L_02 ) ); + uint8_t frame_data_R_02[SIZE_160]; + memset( frame_data_R_02, 0x04, sizeof( frame_data_R_02 ) ); + memcpy( sender_ftds[0].frame_data, frame_data_L_01, sender_ftds[0].frame_data_length ); + memcpy( sender_ftds[1].frame_data, frame_data_R_01, sender_ftds[1].frame_data_length ); + memcpy( sender_ftds[2].frame_data, frame_data_L_02, sender_ftds[2].frame_data_length ); + memcpy( sender_ftds[3].frame_data, frame_data_R_02, sender_ftds[3].frame_data_length ); + + uint8_t *receiverBuffer = malloc( packed_buffer_actual_size ); + assert( NULL != receiverBuffer ); + memcpy( receiverBuffer, packed_buffer, packed_buffer_actual_size ); + + LC3PLUS_RTP_PAYLOAD payload_config; + error = LC3PLUS_RTP_payload_deserialize( &payload_config, receiverBuffer, packed_buffer_actual_size ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_deserialize failed\n" ); + } + + assert( payload_config.fdl_request == fdl_req ); + assert( payload_config.frame_duration_us == 10000 ); + assert( payload_config.high_resolution_enabled == 0 ); + assert( payload_config.sampling_rate_hz == 48000 ); + assert( payload_config.num_ftds == 4 ); + assert( payload_config.num_media_times == 2 ); + assert( payload_config.num_channels == 2 ); + for ( int32_t i = 0; i < payload_config.num_ftds; ++i ) + { + assert( payload_config.ftds[i].frame_data_length == sender_ftds[i].frame_data_length ); + assert( payload_config.ftds[i].h == sender_ftds[i].h ); + assert( payload_config.ftds[i].fdi == sender_ftds[i].fdi ); + assert( payload_config.ftds[i].bwr == sender_ftds[i].bwr ); + assert( payload_config.ftds[i].fc == sender_ftds[i].fc ); + assert( payload_config.ftds[i].frame_data_length == sender_ftds[i].frame_data_length ); + assert( payload_config.ftds[i].frame_data != sender_ftds[i].frame_data ); + assert( 0 == memcmp( payload_config.ftds[i].frame_data, sender_ftds[i].frame_data, sender_ftds[i].frame_data_length ) ); + } + + free( receiverBuffer ); + return 0; +} + +static int pack_and_unpack_payload_config_2ch_5ms_lc3plus_20ms_ivas( void ) +{ + LC3PLUS_RTP_FTD sender_ftds[LC3PLUS_MAX_NUM_CODERS]; + int32_t sender_ftds_num = 0; + const LC3PLUS_RTP_FDL fdl_req = LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA; + + LC3PLUS_RTP_FTD *ftd_L_01 = &sender_ftds[0]; + ftd_L_01->fc = LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL; + ftd_L_01->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_L_01->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_L_01->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_L_01->frame_data = NULL; + ftd_L_01->frame_data_length = SIZE_70; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_R_01 = &sender_ftds[1]; + ftd_R_01->fc = LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME; + ftd_R_01->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_R_01->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_R_01->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_R_01->frame_data = NULL; + ftd_R_01->frame_data_length = SIZE_320; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_L_02 = &sender_ftds[2]; + ftd_L_02->fc = LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL; + ftd_L_02->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_L_02->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_L_02->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_L_02->frame_data = NULL; + ftd_L_02->frame_data_length = SIZE_70; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_R_02 = &sender_ftds[3]; + ftd_R_02->fc = LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME; + ftd_R_02->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_R_02->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_R_02->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_R_02->frame_data = NULL; + ftd_R_02->frame_data_length = SIZE_160; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_L_03 = &sender_ftds[4]; + ftd_L_03->fc = LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL; + ftd_L_03->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_L_03->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_L_03->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_L_03->frame_data = NULL; + ftd_L_03->frame_data_length = SIZE_70; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_R_03 = &sender_ftds[5]; + ftd_R_03->fc = LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME; + ftd_R_03->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_R_03->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_R_03->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_R_03->frame_data = NULL; + ftd_R_03->frame_data_length = SIZE_320; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_L_04 = &sender_ftds[6]; + ftd_L_04->fc = LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL; + ftd_L_04->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_L_04->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_L_04->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_L_04->frame_data = NULL; + ftd_L_04->frame_data_length = SIZE_70; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_R_04 = &sender_ftds[7]; + ftd_R_04->fc = LC3PLUS_RTP_FTD_FC_LAST_OVERALL; + ftd_R_04->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_R_04->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_R_04->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_R_04->frame_data = NULL; + ftd_R_04->frame_data_length = SIZE_160; + sender_ftds_num++; + + const size_t packed_buffer_capacity = LC3PLUS_MAX_BS_SIZE; + size_t packed_buffer_actual_size; + uint8_t packed_buffer[LC3PLUS_MAX_BS_SIZE]; + memset( packed_buffer, 0, packed_buffer_capacity ); + // prepare bitstream buffer headers & layout + LC3PLUS_RTP_ERR error = LC3PLUS_RTP_payload_serialize( packed_buffer, packed_buffer_capacity, &packed_buffer_actual_size, fdl_req, sender_ftds, sender_ftds_num ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_serialize failed\n" ); + } + + + // copy encoded frames into their expected memory locations + uint8_t frame_data_L_01[SIZE_70]; + assert( ftd_L_01->frame_data_length == sizeof( frame_data_L_01 ) ); + memset( frame_data_L_01, 0x01, sizeof( frame_data_L_01 ) ); + uint8_t frame_data_R_01[SIZE_320]; + assert( ftd_R_01->frame_data_length == sizeof( frame_data_R_01 ) ); + memset( frame_data_R_01, 0x02, sizeof( frame_data_R_01 ) ); + uint8_t frame_data_L_02[SIZE_70]; + assert( ftd_L_02->frame_data_length == sizeof( frame_data_L_02 ) ); + memset( frame_data_L_02, 0x03, sizeof( frame_data_L_02 ) ); + uint8_t frame_data_R_02[SIZE_160]; + assert( ftd_R_02->frame_data_length == sizeof( frame_data_R_02 ) ); + memset( frame_data_R_02, 0x04, sizeof( frame_data_R_02 ) ); + uint8_t frame_data_L_03[SIZE_70]; + assert( ftd_L_03->frame_data_length == sizeof( frame_data_L_03 ) ); + memset( frame_data_L_03, 0x05, sizeof( frame_data_L_03 ) ); + uint8_t frame_data_R_03[SIZE_320]; + assert( ftd_R_03->frame_data_length == sizeof( frame_data_R_03 ) ); + memset( frame_data_R_03, 0x06, sizeof( frame_data_R_03 ) ); + uint8_t frame_data_L_04[SIZE_70]; + assert( ftd_L_04->frame_data_length == sizeof( frame_data_L_04 ) ); + memset( frame_data_L_04, 0x07, sizeof( frame_data_L_04 ) ); + uint8_t frame_data_R_04[SIZE_160]; + assert( ftd_R_04->frame_data_length == sizeof( frame_data_R_04 ) ); + memset( frame_data_R_04, 0x08, sizeof( frame_data_R_04 ) ); + memcpy( sender_ftds[0].frame_data, frame_data_L_01, sender_ftds[0].frame_data_length ); + memcpy( sender_ftds[1].frame_data, frame_data_R_01, sender_ftds[1].frame_data_length ); + memcpy( sender_ftds[2].frame_data, frame_data_L_02, sender_ftds[2].frame_data_length ); + memcpy( sender_ftds[3].frame_data, frame_data_R_02, sender_ftds[3].frame_data_length ); + memcpy( sender_ftds[4].frame_data, frame_data_L_03, sender_ftds[4].frame_data_length ); + memcpy( sender_ftds[5].frame_data, frame_data_R_03, sender_ftds[5].frame_data_length ); + memcpy( sender_ftds[6].frame_data, frame_data_L_04, sender_ftds[6].frame_data_length ); + memcpy( sender_ftds[7].frame_data, frame_data_R_04, sender_ftds[7].frame_data_length ); + + uint8_t *receiverBuffer = malloc( packed_buffer_actual_size ); + assert( NULL != receiverBuffer ); + memcpy( receiverBuffer, packed_buffer, packed_buffer_actual_size ); + + LC3PLUS_RTP_PAYLOAD payload_config; + error = LC3PLUS_RTP_payload_deserialize( &payload_config, receiverBuffer, packed_buffer_actual_size ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_deserialize failed\n" ); + } + + assert( payload_config.fdl_request == fdl_req ); + assert( payload_config.frame_duration_us == 5000 ); + assert( payload_config.high_resolution_enabled == 0 ); + assert( payload_config.sampling_rate_hz == 48000 ); + assert( payload_config.num_ftds == 8 ); + assert( payload_config.num_media_times == 4 ); + assert( payload_config.num_channels == 2 ); + for ( int32_t i = 0; i < payload_config.num_ftds; ++i ) + { + assert( payload_config.ftds[i].frame_data_length == sender_ftds[i].frame_data_length ); + assert( payload_config.ftds[i].h == sender_ftds[i].h ); + assert( payload_config.ftds[i].fdi == sender_ftds[i].fdi ); + assert( payload_config.ftds[i].bwr == sender_ftds[i].bwr ); + assert( payload_config.ftds[i].fc == sender_ftds[i].fc ); + assert( payload_config.ftds[i].frame_data_length == sender_ftds[i].frame_data_length ); + assert( payload_config.ftds[i].frame_data != sender_ftds[i].frame_data ); + assert( 0 == memcmp( payload_config.ftds[i].frame_data, sender_ftds[i].frame_data, sender_ftds[i].frame_data_length ) ); + } + + free( receiverBuffer ); + return 0; +} + +static int try_unpack_invalid_values( void ) +{ + LC3PLUS_RTP_FTD sender_ftds[LC3PLUS_MAX_NUM_CODERS]; + int32_t sender_ftds_num = 0; + const LC3PLUS_RTP_FDL fdl_req = LC3PLUS_RTP_FDL_LENGTH_3_MAX; + + LC3PLUS_RTP_FTD *ftd_L_01 = &sender_ftds[0]; + ftd_L_01->fc = LC3PLUS_RTP_FTD_FC_LAST_OVERALL; + ftd_L_01->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_L_01->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_L_01->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_L_01->frame_data = NULL; + ftd_L_01->frame_data_length = SIZE_70; + sender_ftds_num++; + + const size_t packed_buffer_capacity = LC3PLUS_MAX_BS_SIZE; + size_t packed_buffer_actual_size; + uint8_t packed_buffer[LC3PLUS_MAX_BS_SIZE]; + memset( packed_buffer, 0, packed_buffer_capacity ); + // prepare bitstream buffer headers & layout + LC3PLUS_RTP_ERR error = LC3PLUS_RTP_payload_serialize( packed_buffer, packed_buffer_capacity, &packed_buffer_actual_size, fdl_req, sender_ftds, sender_ftds_num ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_serialize failed\n" ); + } + + // copy encoded frames into their expected memory locations + uint8_t frame_data_L_01[SIZE_70]; + assert( ftd_L_01->frame_data_length == sizeof( frame_data_L_01 ) ); + memset( frame_data_L_01, 0x01, sizeof( frame_data_L_01 ) ); + + uint8_t *receiverBuffer = malloc( packed_buffer_actual_size ); + assert( NULL != receiverBuffer ); + memcpy( receiverBuffer, packed_buffer, packed_buffer_actual_size ); + + int32_t fdl_req_length; + error = LC3PLUS_RTP_frame_data_length_get_size( &fdl_req_length, fdl_req ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_frame_data_length_get_size error\n" ); + } + for ( int16_t packed_buffer_incorrect_size = 0; packed_buffer_incorrect_size < ( fdl_req_length + 2 + SIZE_70 ); ++packed_buffer_incorrect_size ) + { + LC3PLUS_RTP_PAYLOAD payload_config; + error = LC3PLUS_RTP_payload_deserialize( &payload_config, receiverBuffer, packed_buffer_incorrect_size ); + if ( error == LC3PLUS_RTP_ERR_NO_ERROR ) + { + free( receiverBuffer ); + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_deserialize failed to detect error\n" ); + } + } + + LC3PLUS_RTP_PAYLOAD payload_config; + error = LC3PLUS_RTP_payload_deserialize( &payload_config, receiverBuffer, packed_buffer_actual_size ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + free( receiverBuffer ); + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_deserialize failed\n" ); + } + free( receiverBuffer ); + return 0; +} + +#define LC3PLUS_RTP_TEST_NUM_FTDS_UT 3 +static int pack_and_unpack_different_fdl_sizes( void ) +{ + int32_t iFtdUt; + LC3PLUS_RTP_FDL fdl_requests_ut[LC3PLUS_RTP_TEST_NUM_FTDS_UT]; + fdl_requests_ut[0] = LC3PLUS_RTP_FDL_LENGTH_1_MIN; + fdl_requests_ut[1] = LC3PLUS_RTP_FDL_LENGTH_2_MIN; + fdl_requests_ut[2] = LC3PLUS_RTP_FDL_LENGTH_3_MIN; + + for ( iFtdUt = 0; iFtdUt < LC3PLUS_RTP_TEST_NUM_FTDS_UT; ++iFtdUt ) + { + LC3PLUS_RTP_FTD sender_ftds[LC3PLUS_MAX_NUM_CODERS]; + int32_t sender_ftds_num = 0; + + LC3PLUS_RTP_FTD *ftd_L_01 = &sender_ftds[0]; + ftd_L_01->fc = LC3PLUS_RTP_FTD_FC_LAST_OVERALL; + ftd_L_01->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_L_01->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_L_01->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_L_01->frame_data = NULL; + ftd_L_01->frame_data_length = fdl_requests_ut[iFtdUt]; + sender_ftds_num++; + + const size_t packed_buffer_capacity = LC3PLUS_MAX_BS_SIZE; + size_t packed_buffer_actual_size; + uint8_t packed_buffer[LC3PLUS_MAX_BS_SIZE]; + memset( packed_buffer, 0, packed_buffer_capacity ); + // prepare bitstream buffer headers & layout + LC3PLUS_RTP_ERR error = LC3PLUS_RTP_payload_serialize( packed_buffer, packed_buffer_capacity, &packed_buffer_actual_size, fdl_requests_ut[iFtdUt], sender_ftds, sender_ftds_num ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_serialize failed\n" ); + } + + // copy encoded frames into their expected memory locations + uint8_t frame_data_L_01[SIZE_600]; + assert( ftd_L_01->frame_data_length <= sizeof( frame_data_L_01 ) ); + memset( frame_data_L_01, 0x01, ftd_L_01->frame_data_length ); + + uint8_t *receiverBuffer = malloc( packed_buffer_actual_size ); + assert( NULL != receiverBuffer ); + memcpy( receiverBuffer, packed_buffer, packed_buffer_actual_size ); + + LC3PLUS_RTP_PAYLOAD payload_config; + error = LC3PLUS_RTP_payload_deserialize( &payload_config, receiverBuffer, packed_buffer_actual_size ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + free( receiverBuffer ); + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_deserialize failed\n" ); + } + assert( payload_config.fdl_request == fdl_requests_ut[iFtdUt] ); + assert( payload_config.ftds[0].frame_data_length == fdl_requests_ut[iFtdUt] ); + free( receiverBuffer ); + } + return 0; +} + +static int run_all_payload_tests( void ) +{ + if ( pack_and_unpack_payload_config_2ch_10ms_lc3plus_20ms_ivas() != 0 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); + } + if ( pack_and_unpack_payload_config_2ch_5ms_lc3plus_20ms_ivas() != 0 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); + } + if ( try_unpack_invalid_values() != 0 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); + } + if ( pack_and_unpack_different_fdl_sizes() != 0 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); + } + return 0; +} +#endif diff --git a/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test_selective_decoding.c b/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test_selective_decoding.c deleted file mode 100644 index 44d3787c27..0000000000 --- a/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test_selective_decoding.c +++ /dev/null @@ -1,1953 +0,0 @@ -/****************************************************************************************************** - -(C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, -Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., -Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, -Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other -contributors to this repository. All Rights Reserved. - -This software is protected by copyright law and by international treaties. -The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, -Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., -Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, -Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other -contributors to this repository retain full ownership rights in their respective contributions in -the software. This notice grants no license of any kind, including but not limited to patent -license, nor is any license granted by implication, estoppel or otherwise. - -Contributors are required to enter into the IVAS codec Public Collaboration agreement before making -contributions. - -This software is provided "AS IS", without any express or implied warranties. The software is in the -development stage. It is intended exclusively for experts who have experience with such software and -solely for the purpose of inspection. All implied warranties of non-infringement, merchantability -and fitness for a particular purpose are hereby disclaimed and excluded. - -Any dispute, controversy or claim arising under or in relation to providing this software shall be -submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in -accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and -the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -#include -#include -#include "isar_lc3plus_enc.h" -#include "isar_lc3plus_common.h" -#include "isar_lc3plus_dec.h" -#include "ivas_error_utils.h" - -#ifdef SPLIT_REND_WITH_HEAD_ROT - -#define MAX_SAMPLES_PER_CHANNEL 960 - -/* included by ivas_lc3plus_unit_test.c */ - -typedef int ( *ScenarioFnPtr )( const LC3PLUS_CONFIG config, - ISAR_LC3PLUS_DEC_HANDLE dec, - uint8_t *bitstream_in, - int32_t bitstream_in_size, - float **pcm_out ); - -static int encodeAndDecodeOne6chFrameFixture( LC3PLUS_CONFIG config, const int16_t enableCaching, const int32_t bps, ScenarioFnPtr scenarioFn ) -{ - ivas_error err; - int32_t encDelay = -1; - int32_t decDelay = -1; - - ISAR_LC3PLUS_ENC_HANDLE encHandle; - err = IVAS_LC3PLUS_ENC_Open( config, bps, &encHandle ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - err = IVAS_LC3PLUS_ENC_GetDelay( encHandle, &encDelay ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - if ( encDelay == -1 || encDelay == 0 ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "encDelay is zero or uninitialized\n" ); - } - - /* encode one frame */ - int16_t numSamplesPerChannels = config.samplerate / ( 1000000 / config.ivas_frame_duration_us ); - float *pcm_in[6]; - float pcm_in_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; - memset( pcm_in_ch1, 0, numSamplesPerChannels * sizeof( float ) ); - float pcm_in_ch2[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; - memset( pcm_in_ch2, 0, numSamplesPerChannels * sizeof( float ) ); - float pcm_in_ch3[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; - memset( pcm_in_ch3, 0, numSamplesPerChannels * sizeof( float ) ); - float pcm_in_ch4[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; - memset( pcm_in_ch4, 0, numSamplesPerChannels * sizeof( float ) ); - float pcm_in_ch5[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; - memset( pcm_in_ch5, 0, numSamplesPerChannels * sizeof( float ) ); - float pcm_in_ch6[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; - memset( pcm_in_ch6, 0, numSamplesPerChannels * sizeof( float ) ); - pcm_in[0] = pcm_in_ch1; - pcm_in[1] = pcm_in_ch2; - pcm_in[2] = pcm_in_ch3; - pcm_in[3] = pcm_in_ch4; - pcm_in[4] = pcm_in_ch5; - pcm_in[5] = pcm_in_ch6; - - int32_t bitstreamSizePerIvasFrame = 0; - err = IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame ); - if ( IVAS_ERR_OK != err ) - return err; - - uint8_t *bitstream_out = malloc( bitstreamSizePerIvasFrame ); - memset( bitstream_out, 0, bitstreamSizePerIvasFrame ); - - err = IVAS_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out ); - if ( IVAS_ERR_OK != err ) - return err; - IVAS_LC3PLUS_ENC_Close( &encHandle ); - - /* decode one frame */ - ISAR_LC3PLUS_DEC_HANDLE decHandle; - err = IVAS_LC3PLUS_DEC_Open( config, -#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING - enableCaching, -#endif - &decHandle ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - err = IVAS_LC3PLUS_DEC_GetDelay( decHandle, &decDelay ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - if ( decDelay == -1 || decDelay == 0 ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "decDelay is zero or uninitialized\n" ); - } - - uint8_t *bitstream_in = bitstream_out; - - float *pcm_out[6]; - float pcm_out_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; - memset( pcm_out_ch1, 0, numSamplesPerChannels * sizeof( float ) ); - float pcm_out_ch2[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; - memset( pcm_out_ch2, 0, numSamplesPerChannels * sizeof( float ) ); - float pcm_out_ch3[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; - memset( pcm_out_ch3, 0, numSamplesPerChannels * sizeof( float ) ); - float pcm_out_ch4[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; - memset( pcm_out_ch4, 0, numSamplesPerChannels * sizeof( float ) ); - float pcm_out_ch5[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; - memset( pcm_out_ch5, 0, numSamplesPerChannels * sizeof( float ) ); - float pcm_out_ch6[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; - memset( pcm_out_ch6, 0, numSamplesPerChannels * sizeof( float ) ); - pcm_out[0] = pcm_out_ch1; - pcm_out[1] = pcm_out_ch2; - pcm_out[2] = pcm_out_ch3; - pcm_out[3] = pcm_out_ch4; - pcm_out[4] = pcm_out_ch5; - pcm_out[5] = pcm_out_ch6; - - err = IVAS_LC3PLUS_DEC_Conceal( decHandle, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstreamSizePerIvasFrame, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - if ( NULL != scenarioFn ) - { - err = ( *scenarioFn )( config, decHandle, bitstream_in, bitstreamSizePerIvasFrame, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - } - - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstreamSizePerIvasFrame, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - err = IVAS_LC3PLUS_DEC_Conceal( decHandle, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - IVAS_LC3PLUS_DEC_Close( &decHandle ); - free( bitstream_out ); - - return 0; -} - -/* - * in: [dec, dec, dec, dec] - * expected out: [dec_and_use, dec_and_use, dec_and_use, dec_and_use] - */ -static int scenario_decode_all_subframes( const LC3PLUS_CONFIG config, - ISAR_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ - uint8_t *bitstream_in, /* i: pointer to input bitstream */ - int32_t bitstream_in_size, /* i: size of bitstream_in */ - float **pcm_out /* o: decoded samples */ ) -{ - ivas_error err; - const int16_t decode = 1; - // const int16_t skipDecoding = 0; - uint32_t iDec = 0; - int iLc3plusFrame = 0; - int lc3framesPerIvasFrame; - int16_t **selective_decoding_matrix; - err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* Set selective decoding scenario */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - } - - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - assert( decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame == 0 ); - if(NULL != decHandle->bitstream_caches) - { - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - } - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct post decoding state */ - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - } - - IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); - return IVAS_ERR_OK; -} - - -/* - * in: [dec, dec, skip, skip] - * expected out: [dec_and_use, dec_and_use, skip, cache] - */ -static int scenario_dont_decode_last_2_subframes( - const LC3PLUS_CONFIG config, - ISAR_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ - uint8_t *bitstream_in, /* i: pointer to input bitstream */ - int32_t bitstream_in_size, /* i: size of bitstream_in */ - float **pcm_out /* o: decoded samples */ ) -{ - ivas_error err; - const int16_t decode = 1; - const int16_t skipDecoding = 0; - uint32_t iDec = 0; - int iLc3plusFrame = 0; - int lc3framesPerIvasFrame; - int16_t **selective_decoding_matrix; - err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* Set selective decoding scenario */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); - if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ - { - /* skip the last two subframes */ - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else - { - /* decode the previous ones */ - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - } - } - - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - if(NULL != decHandle->bitstream_caches) - { - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - } - if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) - { - /* last subframe is expected to be cached */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); - } - else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) - { - /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - else - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - } - - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder caching */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); - return IVAS_ERR_OK; -} - -/* - * in: [dec, skip, skip, skip] - * expected out: [dec_and_use, skip, skip, cache] - */ -static int scenario_dont_decode_last_3_subframes( - const LC3PLUS_CONFIG config, - ISAR_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ - uint8_t *bitstream_in, /* i: pointer to input bitstream */ - int32_t bitstream_in_size, /* i: size of bitstream_in */ - float **pcm_out /* o: decoded samples */ ) -{ - ivas_error err; - const int16_t decode = 1; - const int16_t skipDecoding = 0; - uint32_t iDec = 0; - int iLc3plusFrame = 0; - int lc3framesPerIvasFrame; - int16_t **selective_decoding_matrix; - err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* Set selective decoding scenario */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); - if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 3 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ - { - /* skip the last three subframes */ - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else - { - /* decode the previous ones */ - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - } - } - - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) - { - /* last subframe is expected to be cached */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); - } - else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) - { - /* subframes before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - else if ( iLc3plusFrame == lc3framesPerIvasFrame - 3 ) - { - /* subframes before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - else - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - } - - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder caching */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); - return IVAS_ERR_OK; -} - - -/* - * in: [skip, dec, dec, dec] - * expected out: [dec_and_drop, dec_and_use, dec_and_use, dec_and_use] - */ -static int scenario_skip_first_subframe( - const LC3PLUS_CONFIG config, - ISAR_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ - uint8_t *bitstream_in, /* i: pointer to input bitstream */ - int32_t bitstream_in_size, /* i: size of bitstream_in */ - float **pcm_out /* o: decoded samples */ ) -{ - ivas_error err; - const int16_t decode = 1; - const int16_t skipDecoding = 0; - uint32_t iDec = 0; - int iLc3plusFrame = 0; - int lc3framesPerIvasFrame; - int16_t **selective_decoding_matrix; - err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* Set selective decoding scenario */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - if ( iSubframeIdx == 0 ) - { - /* skip the first subframe */ - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else - { - /* decode the following subframes */ - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - } - } - - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - - if ( iLc3plusFrame == 0 ) - { - /* first subframe is expected to be decoded and dropped */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_DROP ); - } - else - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - } - - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder caching */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); - return IVAS_ERR_OK; -} - -/* - * Step1: - * in: [dec, dec, skip, skip] - * expected out: [dec_and_use, dec_and_use, skip, cache] - * - * Step2: - * in: [dec, dec, dec, dec] - * expected out: [dec_cache & dec_and_use, dec_and_use, dec_and_use, dec_and_use] - */ -static int scenario_decode_cache( - const LC3PLUS_CONFIG config, - ISAR_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ - uint8_t *bitstream_in, /* i: pointer to input bitstream */ - int32_t bitstream_in_size, /* i: size of bitstream_in */ - float **pcm_out /* o: decoded samples */ ) -{ - ivas_error err; - const int16_t decode = 1; - const int16_t skipDecoding = 0; - uint32_t iDec = 0; - int iLc3plusFrame = 0; - int lc3framesPerIvasFrame; - int16_t **selective_decoding_matrix; - err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* Set selective decoding scenario */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); - if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ - { - /* skip the last two subframes */ - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else - { - /* decode the previous ones */ - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - } - } - - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - - if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) - { - /* last subframe is expected to be cached */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); - } - else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) - { - /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - else - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - } - - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder caching */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - /* Step 2, ensure that the cache is used */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - /* decode all */ - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - } - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - /* verify correct decoder actions */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 1 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - /* verify correct post-decoding state */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); - return IVAS_ERR_OK; -} - -/* - * Step1: - * in: [skip, skip, dec, dec] - * expected out: [skip, dec_and_drop, dec_and_use, dec_and_use] - * - * Step2: - * in: [dec, dec, dec, dec] - * expected out: [no_cache & dec_and_use, dec_and_use, dec_and_use, dec_and_use] - */ -static int scenario_get_active_dont_cache( - const LC3PLUS_CONFIG config, - ISAR_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ - uint8_t *bitstream_in, /* i: pointer to input bitstream */ - int32_t bitstream_in_size, /* i: size of bitstream_in */ - float **pcm_out /* o: decoded samples */ ) -{ - ivas_error err; - const int16_t decode = 1; - const int16_t skipDecoding = 0; - uint32_t iDec = 0; - int iLc3plusFrame = 0; - int lc3framesPerIvasFrame; - int16_t **selective_decoding_matrix; - err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* Set selective decoding scenario */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); - if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ - { - /* skip the last two subframes */ - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - else - { - /* decode the previous ones */ - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - } - } - - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions - * * expected out: [skip, dec_and_drop, dec_and_use, dec_and_use] */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) - { - /* last subframe is expected to be cached */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) - { - /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - else if ( iLc3plusFrame == lc3framesPerIvasFrame - 3 ) - { - /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_DROP ); - } - else - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - } - } - - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder caching */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - /* Step 2, ensure that there is no cache */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - /* decode all [dec, dec, dec, dec]*/ - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - } - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - /* verify correct decoder actions - * expected out: [no_cache & dec_and_use, dec_and_use, dec_and_use, dec_and_use]*/ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - /* verify correct post-decoding state */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); - return IVAS_ERR_OK; -} - - -/* - * Step1: - * in: [dec, dec, skip, skip] - * expected out: [dec_and_use, dec_and_use, skip, cache] - * - * Step2: - * in: [skip, dec, skip, dec] - * expected out: [drop_cache & dec_and_drop, dec_and_use, dec_and_drop, dec_and_use] - * */ -static int scenario_per_subframe_switches_skip_first( - const LC3PLUS_CONFIG config, - ISAR_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ - uint8_t *bitstream_in, /* i: pointer to input bitstream */ - int32_t bitstream_in_size, /* i: size of bitstream_in */ - float **pcm_out /* o: decoded samples */ ) -{ - ivas_error err; - const int16_t decode = 1; - const int16_t skipDecoding = 0; - uint32_t iDec = 0; - int iLc3plusFrame = 0; - int lc3framesPerIvasFrame; - int16_t **selective_decoding_matrix; - err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* Set selective decoding scenario */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); - if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ - { - /* skip the last two subframes */ - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else - { - /* decode the previous ones */ - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - } - } - - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) - { - /* last subframe is expected to be cached */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); - } - else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) - { - /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - else - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - } - - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder caching */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - /* Step 2 - * in: [skip, dec, skip, dec] - * */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - if(iSubframeIdx == 0 || iSubframeIdx == 2) - { - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else if(iSubframeIdx == 1 || iSubframeIdx == 3) - { - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - else - { - //unsupported iSubframeIdx count; - return 1; - } - - } - } - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions - * expected out: [drop_cache & dec_and_drop, dec_and_use, dec_and_drop, dec_and_use] - * */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - if ( iLc3plusFrame == 1 || iLc3plusFrame == 3) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - else if ( iLc3plusFrame == 0 || iLc3plusFrame == 2) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_DROP ); - } - else - { - assert(0); - } - } - } - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - /* verify correct post-decoding state */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); - return IVAS_ERR_OK; -} - -/* - * Step1: - * in: [dec, dec, skip, skip] - * expected out: [dec_and_use, dec_and_use, skip, cache] - * - * Step2: - * in: [dec, skip, dec, skip] - * expected out: [dec_cache & dec_and_use, dec_and_drop, dec_and_use, cache] - * */ -static int scenario_per_subframe_switches_dec_first( - const LC3PLUS_CONFIG config, - ISAR_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ - uint8_t *bitstream_in, /* i: pointer to input bitstream */ - int32_t bitstream_in_size, /* i: size of bitstream_in */ - float **pcm_out /* o: decoded samples */ ) -{ - ivas_error err; - const int16_t decode = 1; - const int16_t skipDecoding = 0; - uint32_t iDec = 0; - int iLc3plusFrame = 0; - int lc3framesPerIvasFrame; - int16_t **selective_decoding_matrix; - err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* Set selective decoding scenario */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); - if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ - { - /* skip the last two subframes */ - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else - { - /* decode the previous ones */ - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - } - } - - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) - { - /* last subframe is expected to be cached */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); - } - else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) - { - /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - else - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - } - - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder caching */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - /* Step 2 - * in: [dec, skip, dec, skip] - * */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - if(iSubframeIdx == 0 || iSubframeIdx == 2) - { - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - else if(iSubframeIdx == 1 || iSubframeIdx == 3) - { - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else - { - // unsupported iSubframeIdx count - return 1; - } - - } - } - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions - * expected out: [dec_cache & dec_and_use, dec_and_drop, dec_and_use, cache] - * */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 1 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - if ( iLc3plusFrame == 0 ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - else if ( iLc3plusFrame == 1 ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_DROP ); - } - else if ( iLc3plusFrame == 2 ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - else if ( iLc3plusFrame == 3) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); - } - else - { - assert(0); - } - } - } - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - /* verify correct post-decoding state */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); - return IVAS_ERR_OK; -} - -#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING -/* - * Step1: - * in: [dec, dec, skip, skip] - * expected out: [dec_and_use, dec_and_use, skip, skip] - * - * Step2: - * in: [dec, skip, dec, skip] - * expected out: [drop_cache & dec_and_use, skip, dec_and_use, skip] - * */ -static int scenario_per_subframe_switches_dec_first_no_caching( - const LC3PLUS_CONFIG config, - ISAR_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ - uint8_t *bitstream_in, /* i: pointer to input bitstream */ - int32_t bitstream_in_size, /* i: size of bitstream_in */ - float **pcm_out /* o: decoded samples */ ) -{ - ivas_error err; - const int16_t decode = 1; - const int16_t skipDecoding = 0; - uint32_t iDec = 0; - int iLc3plusFrame = 0; - int lc3framesPerIvasFrame; - int16_t **selective_decoding_matrix; - err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* Set selective decoding scenario */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); - if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ - { - /* skip the last two subframes */ - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else - { - /* decode the previous ones */ - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - } - } - - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( NULL == decHandle->bitstream_caches ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) - { - /* last subframe is expected to be cached */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) - { - /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - else - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - } - - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder caching */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( NULL == decHandle->bitstream_caches ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - /* Step 2 - * in: [dec, skip, dec, skip] - * */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - if(iSubframeIdx == 0 || iSubframeIdx == 2) - { - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - else if(iSubframeIdx == 1 || iSubframeIdx == 3) - { - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else - { - // unsupported iSubframeIdx count - return 1; - } - - } - } - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions - * expected out: [drop_cache & dec_and_use, skip, dec_and_use, skip] - * */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( NULL == decHandle->bitstream_caches ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - if ( iLc3plusFrame == 0 ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - else if ( iLc3plusFrame == 1 ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - else if ( iLc3plusFrame == 2 ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - else if ( iLc3plusFrame == 3) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - else - { - assert(0); - } - } - } - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - /* verify correct post-decoding state */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( NULL == decHandle->bitstream_caches ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); - return IVAS_ERR_OK; -} -#endif - -/* - * Step1: - * in: [dec, dec, skip, skip] - * expected out: [dec_and_use, dec_and_use, skip, cache] - * - * Step2: - * in: [dec, skip, skip, dec] - * expected out: [dec_cache & dec_and_use, skip, dec_and_drop, dec_and_use] - * */ -static int scenario_per_subframe_bundle_switches_dec_first( - const LC3PLUS_CONFIG config, - ISAR_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ - uint8_t *bitstream_in, /* i: pointer to input bitstream */ - int32_t bitstream_in_size, /* i: size of bitstream_in */ - float **pcm_out /* o: decoded samples */ ) -{ - ivas_error err; - const int16_t decode = 1; - const int16_t skipDecoding = 0; - uint32_t iDec = 0; - int iLc3plusFrame = 0; - int lc3framesPerIvasFrame; - int16_t **selective_decoding_matrix; - err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* Set selective decoding scenario */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); - if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ - { - /* skip the last two subframes */ - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else - { - /* decode the previous ones */ - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - } - } - - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) - { - /* last subframe is expected to be cached */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); - } - else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) - { - /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - else - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - } - - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder caching */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - /* Step 2 - * in: [dec, skip, skip, dec] - * */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - if(iSubframeIdx == 0 || iSubframeIdx == 3) - { - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - else if(iSubframeIdx == 1 || iSubframeIdx == 2) - { - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else - { - // unsupported iSubframeIdx count - return 1; - } - - } - } - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions - * expected out: [dec_cache & dec_and_use, skip, dec_and_drop, dec_and_use] - * */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 1 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - if ( iLc3plusFrame == 0 ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - else if ( iLc3plusFrame == 1 ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - else if ( iLc3plusFrame == 2 ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_DROP ); - } - else if ( iLc3plusFrame == 3) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - else - { - assert(0); - } - } - } - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - /* verify correct post-decoding state */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); - return IVAS_ERR_OK; -} - -/* - * Step1: - * in: [dec, dec, skip, skip] - * expected out: [dec_and_use, dec_and_use, skip, cache] - * - * Step2: - * in: [skip, dec, dec, skip] - * expected out: [drop_cache & dec_and_drop, dec_and_use, dec_and_use, cache] - * */ -static int scenario_per_subframe_bundle_switches_skip_first( - const LC3PLUS_CONFIG config, - ISAR_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ - uint8_t *bitstream_in, /* i: pointer to input bitstream */ - int32_t bitstream_in_size, /* i: size of bitstream_in */ - float **pcm_out /* o: decoded samples */ ) -{ - ivas_error err; - const int16_t decode = 1; - const int16_t skipDecoding = 0; - uint32_t iDec = 0; - int iLc3plusFrame = 0; - int lc3framesPerIvasFrame; - int16_t **selective_decoding_matrix; - err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* Set selective decoding scenario */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); - if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ - { - /* skip the last two subframes */ - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else - { - /* decode the previous ones */ - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - } - } - - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) - { - /* last subframe is expected to be cached */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); - } - else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) - { - /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - else - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - } - - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder caching */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - /* Step 2 - * in: [skip, dec, dec, skip] - * */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - if(iSubframeIdx == 1 || iSubframeIdx == 2) - { - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - else if(iSubframeIdx == 0 || iSubframeIdx == 3) - { - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else - { - // unsupported iSubframeIdx count - return 1; - } - - } - } - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions - * expected out: [drop_cache & dec_and_drop, dec_and_use, dec_and_use, cache] - * */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - if ( iLc3plusFrame == 0 ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_DROP ); - } - else if ( iLc3plusFrame == 1 ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - else if ( iLc3plusFrame == 2 ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - else if ( iLc3plusFrame == 3) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); - } - else - { - assert(0); - } - } - } - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - /* verify correct post-decoding state */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); - return IVAS_ERR_OK; -} - - -static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_decode_all_subframes( void ) -{ - int err; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; - const int16_t enableCaching = 1; - err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_decode_all_subframes ); - if ( 0 != err ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); - } - return err; -} - -static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_dont_decode_last_2_subframes( void ) -{ - int err = 0; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; - const int16_t enableCaching = 1; - err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_dont_decode_last_2_subframes ); - if ( 0 != err ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); - } - return err; -} - -static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_dont_decode_last_3_subframes( void ) -{ - int err = 0; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; - const int16_t enableCaching = 1; - err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_dont_decode_last_3_subframes ); - if ( 0 != err ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); - } - return err; -} - -static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_skip_first_subframe( void ) -{ - int err = 0; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; - const int16_t enableCaching = 1; - err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_skip_first_subframe ); - if ( 0 != err ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); - } - return err; -} - -static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_decode_cache( void ) -{ - int err = 0; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; - const int16_t enableCaching = 1; - err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_decode_cache ); - if ( 0 != err ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); - } - return err; -} - -static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_switches_skip_first( void ) -{ - int err = 0; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; - const int16_t enableCaching = 1; - err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_per_subframe_switches_skip_first ); - if ( 0 != err ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); - } - return err; -} - -static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_switches_dec_first( void ) -{ - int err = 0; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; - const int16_t enableCaching = 1; - err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_per_subframe_switches_dec_first ); - if ( 0 != err ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); - } - return err; -} - -static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_bundle_switches_dec_first( void ) -{ - int err = 0; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; - const int16_t enableCaching = 1; - err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_per_subframe_bundle_switches_dec_first ); - if ( 0 != err ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); - } - return err; -} - -static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_bundle_switches_skip_first( void ) -{ - int err = 0; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; - const int16_t enableCaching = 1; - err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_per_subframe_bundle_switches_skip_first ); - if ( 0 != err ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); - } - return err; -} - -#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING -static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_switches_dec_first_no_caching( void ) -{ - int err = 0; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; - const int16_t enableCaching = 0; - err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_per_subframe_switches_dec_first_no_caching ); - if ( 0 != err ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); - } - return err; -} -#endif - -static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_get_active_dont_cache( void ) -{ - int err = 0; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; - const int16_t enableCaching = 1; - err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_get_active_dont_cache ); - if ( 0 != err ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); - } - return err; -} -#endif /* SPLIT_REND_WITH_HEAD_ROT */ -- GitLab From 046eda1de6308b6f04f2a4eb54caba9eb36a986d Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Wed, 13 Mar 2024 17:15:58 +0100 Subject: [PATCH 02/54] FIx windows warnings --- lib_com/common_api_types.h | 2 +- lib_isar/lib_isar_post_rend.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index c8a7a38674..7d66d986e4 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -253,7 +253,7 @@ typedef struct _ISAR_SPLIT_REND_BITS_DATA ISAR_SPLIT_REND_CODEC codec; ISAR_SPLIT_REND_POSE_CORRECTION_MODE pose_correction; #ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER - int32_t lc3plus_highres; + int16_t lc3plus_highres; #endif } ISAR_SPLIT_REND_BITS_DATA, *ISAR_SPLIT_REND_BITS_HANDLE; diff --git a/lib_isar/lib_isar_post_rend.c b/lib_isar/lib_isar_post_rend.c index 1584874d48..3367c7c2ec 100644 --- a/lib_isar/lib_isar_post_rend.c +++ b/lib_isar/lib_isar_post_rend.c @@ -1525,7 +1525,7 @@ static ivas_error renderSplitBinauralWithPostRot( if ( bits.pose_correction != ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) { // This info is currently unused, but will later be needed e.g. when packing SR bitstream into RTP - split_rend_md_section_size_bits = ISAR_SPLIT_REND_BITStream_read_int32( &bits, IVAS_SPLIT_REND_MD_SIZE_BITS ); + split_rend_md_section_size_bits = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( &bits, IVAS_SPLIT_REND_MD_SIZE_BITS ); (void) split_rend_md_section_size_bits; } #endif -- GitLab From 343c37ee888dd305191426271d55b6af82af8947 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Wed, 13 Mar 2024 17:19:29 +0100 Subject: [PATCH 03/54] Fix more windows warnings --- lib_isar/isar_lc3plus_enc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib_isar/isar_lc3plus_enc.c b/lib_isar/isar_lc3plus_enc.c index 324d295d56..c0fe31f92a 100644 --- a/lib_isar/isar_lc3plus_enc.c +++ b/lib_isar/isar_lc3plus_enc.c @@ -268,6 +268,9 @@ static int32_t limit_per_channel_bitrate( LC3PLUS_CONFIG config, default: assert( false && "unreachable" ); } + + assert( false && "unreachable" ); + return -1; } #ifdef LC3PLUS_VBR -- GitLab From e9748a491716d6d57a0e01794776ab78cb456a67 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Wed, 13 Mar 2024 17:35:52 +0100 Subject: [PATCH 04/54] Add missing files to vs project --- Workspace_msvc/lib_isar.vcxproj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Workspace_msvc/lib_isar.vcxproj b/Workspace_msvc/lib_isar.vcxproj index 100d1afa75..df200e040e 100644 --- a/Workspace_msvc/lib_isar.vcxproj +++ b/Workspace_msvc/lib_isar.vcxproj @@ -146,6 +146,7 @@ + @@ -167,6 +168,7 @@ + @@ -192,4 +194,4 @@ - \ No newline at end of file + -- GitLab From 65ca85028859b97fc111acc5d9edbfdc6707dc1b Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Fri, 26 Apr 2024 18:07:27 +0200 Subject: [PATCH 05/54] Update branch - Update wrt main - Other fixes and improvements --- .gitignore | 1 + .gitlab-ci-custom.yml | 2 +- .gitlab-ci.yml | 163 +- .gitlab/issue_templates/asan_ltv_error.md | 1 + .gitlab/issue_templates/msan_ltv_error.md | 1 + .gitlab/issue_templates/usan_ltv_error.md | 6 +- CMakeLists.txt | 86 +- Makefile | 21 - Workspace_msvc/isar_post_rend.vcxproj | 2 +- Workspace_msvc/lib_isar.vcxproj | 7 +- Workspace_msvc/lib_lc3plus.vcxproj | 6 +- apps/decoder.c | 320 +- apps/isar_post_rend.c | 324 +- apps/renderer.c | 496 +- ci/check_self_test_names.py | 59 + .../mergeNewsletterRam.py | 1 - .../mergeNewsletterRom.py | 1 - ci/create_trajectories.py | 25 + ci/run_scheduled_sanitizer_test.py | 47 +- ci/smoke_test.sh | 21 +- lib_com/bitstream.c | 16 + lib_com/common_api_types.h | 30 +- lib_com/ivas_cnst.h | 104 +- lib_com/ivas_dirac_com.c | 6 +- lib_com/ivas_error_utils.h | 21 +- lib_com/ivas_prot.h | 28 +- lib_com/ivas_sba_config.c | 47 - lib_com/ivas_stat_com.h | 45 - lib_com/mslvq_com.c | 2 +- lib_com/nelp.c | 2 +- lib_com/options.h | 34 +- lib_com/prot.h | 8 - lib_debug/wmc_auto.c | 98 +- lib_debug/wmc_auto.h | 138 +- lib_dec/FEC_HQ_phase_ecu.c | 8 - lib_dec/core_dec_init.c | 4 + lib_dec/dec_LPD.c | 8 +- lib_dec/dec_tcx.c | 21 +- lib_dec/er_dec_tcx.c | 2 +- lib_dec/gs_dec.c | 4 - lib_dec/ivas_binRenderer_internal.c | 70 +- lib_dec/ivas_dirac_dec.c | 5 + lib_dec/ivas_init_dec.c | 131 +- lib_dec/ivas_ism_dec.c | 12 +- lib_dec/ivas_ism_metadata_dec.c | 77 +- lib_dec/ivas_ism_param_dec.c | 376 +- lib_dec/ivas_ism_renderer.c | 16 +- lib_dec/ivas_jbm_dec.c | 33 +- lib_dec/ivas_mc_param_dec.c | 178 +- lib_dec/ivas_mct_dec.c | 17 +- lib_dec/ivas_objectRenderer_internal.c | 8 +- lib_dec/ivas_omasa_dec.c | 115 +- lib_dec/ivas_osba_dec.c | 14 +- lib_dec/ivas_out_setup_conversion.c | 4 +- lib_dec/ivas_output_config.c | 3 - lib_dec/ivas_qmetadata_dec.c | 5 + lib_dec/ivas_rom_dec.c | 3 +- lib_dec/ivas_rom_dec.h | 3 +- lib_dec/ivas_sba_dec.c | 12 + lib_dec/ivas_stat_dec.h | 36 +- lib_dec/ivas_stereo_dft_dec.c | 8 - lib_dec/ivas_stereo_dft_dec_dmx.c | 4 - lib_dec/lib_dec.c | 276 +- lib_dec/lib_dec.h | 18 +- lib_dec/syn_outp.c | 24 - lib_dec/updt_dec.c | 2 +- lib_dec/waveadjust_fec_dec.c | 4 +- lib_enc/core_enc_updt.c | 2 +- lib_enc/gs_enc.c | 4 - lib_enc/ivas_masa_enc.c | 9 +- lib_enc/ivas_mct_core_enc.c | 15 + lib_enc/ivas_qmetadata_enc.c | 3 + lib_enc/ivas_spar_encoder.c | 12 +- lib_enc/ivas_stereo_dft_enc_itd.c | 15 +- lib_isar/isar_MSPred.c | 9 +- lib_isar/isar_PerceptualModel.c | 6 +- lib_isar/isar_PredDecoder.c | 2 +- lib_isar/isar_PredEncoder.c | 96 +- lib_isar/isar_RMSEnvGrouping.c | 14 +- lib_isar/isar_cnst.h | 133 + lib_isar/isar_lc3plus_common.c | 9 +- lib_isar/isar_lc3plus_common.h | 12 +- lib_isar/isar_lc3plus_dec.c | 140 +- lib_isar/isar_lc3plus_dec.h | 27 +- lib_isar/isar_lc3plus_enc.c | 298 +- lib_isar/isar_lc3plus_enc.h | 14 +- lib_isar/isar_lc3plus_payload.c | 8 +- lib_isar/isar_lc3plus_payload.h | 3 +- lib_isar/isar_lcld_decoder.c | 211 +- lib_isar/isar_lcld_encoder.c | 237 +- lib_isar/isar_lcld_prot.h | 22 +- lib_isar/isar_lcld_rom_tables.c | 5 +- lib_isar/isar_lcld_rom_tables.h | 11 +- lib_isar/isar_prot.h | 184 +- lib_isar/isar_rom_lcld_tables.c | 12097 ++++++++++++++++ lib_isar/isar_rom_lcld_tables.h | 197 + lib_isar/isar_rom_post_rend.c | 34 +- lib_isar/isar_rom_post_rend.h | 35 +- lib_isar/isar_splitRendererPLC.c | 75 +- lib_isar/isar_splitRendererPost.c | 122 +- lib_isar/isar_splitRendererPre.c | 731 +- lib_isar/isar_splitRenderer_utils.c | 127 +- lib_isar/isar_stat.h | 233 +- lib_isar/lib_isar_post_rend.c | 381 +- lib_isar/lib_isar_post_rend.h | 102 +- lib_isar/lib_isar_pre_rend.c | 562 + lib_isar/lib_isar_pre_rend.h | 91 + lib_lc3plus/adjust_global_gain.c | 1 + lib_lc3plus/al_fec_fl.c | 1 + lib_lc3plus/apply_global_gain.c | 1 + lib_lc3plus/ari_codec.c | 1 + lib_lc3plus/attack_detector.c | 1 + lib_lc3plus/clib.h | 1 + lib_lc3plus/constants.c | 12 +- lib_lc3plus/constants.h | 1 + lib_lc3plus/cutoff_bandwidth.c | 1 + lib_lc3plus/dct4.c | 1 + lib_lc3plus/dec_entropy.c | 1 + lib_lc3plus/dec_lc3_fl.c | 1 + lib_lc3plus/defines.h | 4 +- lib_lc3plus/detect_cutoff_warped.c | 1 + lib_lc3plus/enc_entropy.c | 1 + lib_lc3plus/enc_lc3_fl.c | 1 + lib_lc3plus/estimate_global_gain.c | 1 + lib_lc3plus/fft/cfft.c | 1 + lib_lc3plus/fft/cfft.h | 1 + lib_lc3plus/fft/iis_fft.c | 1 + lib_lc3plus/fft/iis_fft.h | 1 + lib_lc3plus/fft/iisfft.c | 1 + lib_lc3plus/fft/iisfft.h | 1 + lib_lc3plus/functions.h | 1 + lib_lc3plus/imdct.c | 1 + lib_lc3plus/lc3.c | 1 + lib_lc3plus/lc3.h | 1 + lib_lc3plus/lc3plus_fft.c | 1 + lib_lc3plus/license.h | 1 + lib_lc3plus/ltpf_coder.c | 1 + lib_lc3plus/ltpf_decoder.c | 1 + lib_lc3plus/mdct.c | 1 + lib_lc3plus/mdct_shaping.c | 1 + lib_lc3plus/near_nyquist_detector.c | 1 + lib_lc3plus/noise_factor.c | 1 + lib_lc3plus/noise_filling.c | 1 + lib_lc3plus/olpa.c | 1 + lib_lc3plus/pc_apply.c | 1 + lib_lc3plus/pc_classify.c | 1 + lib_lc3plus/pc_main.c | 1 + lib_lc3plus/pc_update.c | 1 + lib_lc3plus/per_band_energy.c | 1 + lib_lc3plus/plc_classify.c | 1 + lib_lc3plus/plc_compute_stab_fac.c | 1 + lib_lc3plus/plc_damping_scrambling.c | 1 + lib_lc3plus/plc_main.c | 1 + lib_lc3plus/plc_noise_substitution.c | 1 + lib_lc3plus/plc_phecu_f0_refine_first.c | 1 + lib_lc3plus/plc_phecu_fec_hq.c | 1 + lib_lc3plus/plc_phecu_hq_ecu.c | 1 + lib_lc3plus/plc_phecu_lf_peak_analysis.c | 1 + lib_lc3plus/plc_phecu_rec_frame.c | 1 + lib_lc3plus/plc_phecu_setf0hz.c | 1 + lib_lc3plus/plc_phecu_spec_ana.c | 1 + lib_lc3plus/plc_phecu_subst_spec.c | 10 +- lib_lc3plus/plc_phecu_tba_per_band_gain.c | 1 + lib_lc3plus/plc_phecu_tba_spect_Xavg.c | 1 + lib_lc3plus/plc_phecu_tba_trans_dect_gains.c | 5 +- lib_lc3plus/plc_phecu_trans_burst_ana_sub.c | 1 + lib_lc3plus/plc_tdc.c | 1 + lib_lc3plus/plc_tdc_tdac.c | 1 + lib_lc3plus/plc_update.c | 1 + lib_lc3plus/quantize_spec.c | 1 + lib_lc3plus/reorder_bitstream.c | 1 + lib_lc3plus/resamp12k8.c | 1 + lib_lc3plus/residual_coding.c | 1 + lib_lc3plus/residual_decoding.c | 1 + lib_lc3plus/setup_com_lc3.c | 1 + lib_lc3plus/setup_dec_lc3.c | 1 + lib_lc3plus/setup_dec_lc3.h | 1 + lib_lc3plus/setup_enc_lc3.c | 1 + lib_lc3plus/setup_enc_lc3.h | 1 + lib_lc3plus/sns_compute_scf.c | 1 + lib_lc3plus/sns_interpolate_scf.c | 1 + lib_lc3plus/sns_quantize_scf.c | 1 + lib_lc3plus/structs.h | 1 + lib_lc3plus/tns_coder.c | 1 + lib_lc3plus/tns_decoder.c | 1 + lib_lc3plus/util.h | 1 + lib_rend/ivas_crend.c | 7 +- lib_rend/ivas_dirac_dec_binaural_functions.c | 25 +- lib_rend/ivas_objectRenderer.c | 150 - lib_rend/ivas_orient_trk.c | 46 +- lib_rend/ivas_prot_rend.h | 100 +- lib_rend/ivas_render_config.c | 3 +- lib_rend/ivas_reverb.c | 122 +- lib_rend/ivas_rom_rend.h | 8 - lib_rend/ivas_stat_rend.h | 79 +- lib_rend/lib_rend.c | 279 +- lib_rend/lib_rend.h | 10 +- lib_util/render_config_reader.c | 12 +- lib_util/split_rend_bfi_file_reader.c | 4 +- lib_util/split_render_file_read_write.c | 37 +- lib_util/split_render_file_read_write.h | 10 +- readme.txt | 6 +- readme_split_rendering.txt | 21 +- scripts/batch_comp_audio.py | 3 +- scripts/config/ivas_modes.json | 459 +- scripts/config/self_test.prm | 132 +- scripts/config/self_test_ltv.prm | 137 +- scripts/mem_analysis.py | 3 - scripts/parse_mld.py | 32 - scripts/parse_mld_xml.py | 49 +- scripts/prepare_combined_format_inputs.py | 3 +- scripts/prepare_delivery.sh | 61 +- scripts/pyaudio3dtools/__init__.py | 1 - scripts/pyaudio3dtools/audio3dtools.py | 5 +- scripts/pyaudio3dtools/audiofile.py | 32 - scripts/pyivastest/IvasBaseClass.py | 1 - scripts/pyivastest/IvasModeCollector.py | 2 - scripts/pyivastest/IvasModeRunner.py | 2 - scripts/self_test.py | 2 - .../lc3plus/ivas_lc3plus_unit_test.c | 366 +- scripts/testv/stvST16c.wav | 4 +- scripts/testv/stvST16n.wav | 4 +- scripts/testv/stvST32c.wav | 4 +- scripts/testv/stvST32n.wav | 4 +- scripts/testv/stvST32noop.wav | 3 + scripts/testv/stvST48c.wav | 4 +- scripts/testv/stvST48n.wav | 4 +- scripts/tools/Darwin/wmc_tool | Bin 654432 -> 657584 bytes scripts/tools/Linux/wmc_tool | Bin 273736 -> 363992 bytes scripts/tools/Win32/wmc_tool.exe | 4 +- tests/cmp_pcm.py | 36 +- tests/codec_be_on_mr_nonselection/__init__.py | 2 + .../test_masa_enc_dec.py | 25 +- .../test_param_file.py | 23 +- .../test_sba_bs_dec_plc.py | 16 +- .../test_sba_bs_enc.py | 30 +- tests/codec_be_on_mr_selection/__init__.py | 2 +- tests/conftest.py | 22 +- tests/create_short_testvectors.py | 2 +- tests/cut_pcm.py | 3 +- tests/hrtf_binary_loading/utils.py | 3 +- tests/renderer/constants.py | 60 + tests/renderer/utils.py | 1 - tests/scale_pcm.py | 2 - tests/split_rendering/README.md | 5 +- tests/split_rendering/constants.py | 15 +- tests/split_rendering/test_split_rendering.py | 24 + tests/split_rendering/utils.py | 2 +- tests/test_26444.py | 45 +- tests/test_param_file_ltv.py | 18 +- 250 files changed, 17758 insertions(+), 4882 deletions(-) create mode 100644 ci/check_self_test_names.py create mode 100644 ci/create_trajectories.py create mode 100644 lib_isar/isar_cnst.h create mode 100644 lib_isar/isar_rom_lcld_tables.c create mode 100644 lib_isar/isar_rom_lcld_tables.h create mode 100644 lib_isar/lib_isar_pre_rend.c create mode 100644 lib_isar/lib_isar_pre_rend.h delete mode 100644 scripts/parse_mld.py mode change 100644 => 100755 scripts/testv/stvST16n.wav mode change 100644 => 100755 scripts/testv/stvST32n.wav create mode 100644 scripts/testv/stvST32noop.wav mode change 100644 => 100755 scripts/testv/stvST48n.wav diff --git a/.gitignore b/.gitignore index 376f1a4170..32b5db376a 100644 --- a/.gitignore +++ b/.gitignore @@ -56,6 +56,7 @@ scripts/testv/stvOMASA_*.met scripts/testv/stvOMASA_*.csv scripts/testv/stvOMASA_2ISM_1MASA1TC48c.wav scripts/testv/stvOMASA_3ISM_1MASA1TC48c.wav +scripts/testv/stvO* # default reference binary name IVAS_cod_ref* IVAS_dec_ref* diff --git a/.gitlab-ci-custom.yml b/.gitlab-ci-custom.yml index 86c1f487e0..62eab520a0 100644 --- a/.gitlab-ci-custom.yml +++ b/.gitlab-ci-custom.yml @@ -1,4 +1,4 @@ include: - project: $CUSTOM_CI_PROJECT - ref: $CUSTOM_CI_REF + ref: isar-lc3plus file: $CUSTOM_CI_FILE diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f4e9757d95..1c6c3474a0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -21,6 +21,7 @@ variables: - 'test-be-release' - 'test-long-self-test' - 'ivas-conformance' + - 'ivas-conformance-linux' GIT_CLEAN_FLAGS: -ffdxq TESTCASE_TIMEOUT_STV_SANITIZERS: 180 TESTCASE_TIMEOUT_LTV_SANITIZERS: 1200 @@ -58,6 +59,10 @@ workflow: variables: IVAS_PIPELINE_NAME: 'Draft IVAS Conformance test: $CI_COMMIT_BRANCH' - if: $CI_PIPELINE_SOURCE == 'trigger' + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'ivas-conformance-linux' + variables: + IVAS_PIPELINE_NAME: 'Draft IVAS Conformance test -- Linux: $CI_COMMIT_BRANCH' + stages: - .pre @@ -201,7 +206,23 @@ stages: - make clean - make -j CLANG=$CLANG_NUM - testcase_timeout=$SELFTEST_SANITY_TIMEOUT - - UBSAN_OPTIONS=suppressions=scripts/ubsan.supp,report_error_type=1 python3 -m pytest $SELF_TEST_PRM_FILE -v --update_ref 1 -m create_ref --html=report.html --self-contained-html --junit-xml=report-junit.xml --testcase_timeout=$testcase_timeout --ref_encoder_path ./IVAS_cod --ref_decoder_path ./IVAS_dec + - export UBSAN_OPTIONS=suppressions=scripts/ubsan.supp,report_error_type=1 + + - exit_code20=0 + - exit_code10=0 + - exit_code5=0 + + - if [ $CLANG_NUM -eq 1 ]; then sanitizer_type="MemorySanitizer"; elif [ $CLANG_NUM -eq 2 ]; then sanitizer_type="AddressSanitizer"; elif [ $CLANG_NUM -eq 3 ]; then sanitizer_type="UndefinedBehaviorSanitizer"; else echo "Wrong CLANG_NUM $CLANG_NUM given!"; exit 1; fi + + # run encoder and decoder with 20ms renderer framesize first, use reference creation mode + - python3 -m pytest $SELF_TEST_PRM_FILE -v --update_ref 1 -m create_ref --html=report-20ms.html --self-contained-html --junit-xml=report-junit-20ms.xml --testcase_timeout=$testcase_timeout --ref_encoder_path ./IVAS_cod --ref_decoder_path ./IVAS_dec || exit_code20=$? + # for 10ms and 5ms renderer framesize, we only need to run the decoder part as renderer framesize is a decoder-only option + # set tolerance very high do ignore any BE differences due to the different renderer framesizes, those can appear due to the limiter being active + # we are only interested in runtime errors from the sanitizers and ignore the diffs + - python3 -m pytest $SELF_TEST_PRM_FILE -v --html=report-5ms.html --self-contained-html --junit-xml=report-junit-5ms.xml --dut_fr 5 --decoder_only --abs_tol 100000 || exit_code5=$? + - python3 -m pytest $SELF_TEST_PRM_FILE -v --html=report-10ms.html --self-contained-html --junit-xml=report-junit-10ms.xml --dut_fr 10 --decoder_only --abs_tol 100000 || exit_code10=$? + + - if [ $exit_code20 -ne 0 ] || [ $exit_code10 -ne 0 ] || [ $exit_code5 -ne 0 ]; then exit 1; fi # --------------------------------------------------------------- @@ -227,6 +248,8 @@ stages: when: never - if: $MANUAL_PIPELINE_TYPE == 'ivas-conformance' when: never + - if: $MANUAL_PIPELINE_TYPE == 'ivas-conformance-linux' + when: never - when: on_success .rules-merge-request: @@ -283,12 +306,18 @@ stages: expire_in: 1 week when: always paths: - - report-junit.xml - - report.html + - report-junit-20ms.xml + - report-junit-10ms.xml + - report-junit-5ms.xml + - report-20ms.html + - report-10ms.html + - report-5ms.html expose_as: "Sanitizer selftest results" reports: junit: - - report-junit.xml + - report-junit-20ms.xml + - report-junit-10ms.xml + - report-junit-5ms.xml .sanitizer-selftest-ltv: stage: test @@ -299,12 +328,18 @@ stages: expire_in: 2 week when: always paths: - - report-junit.xml - - report.html + - report-junit-20ms.xml + - report-junit-10ms.xml + - report-junit-5ms.xml + - report-20ms.html + - report-10ms.html + - report-5ms.html expose_as: "Sanitizer selftest results" reports: junit: - - report-junit.xml + - report-junit-20ms.xml + - report-junit-10ms.xml + - report-junit-5ms.xml # --------------------------------------------------------------- # .pre jobs for setting up things @@ -344,6 +379,17 @@ branch-is-up-to-date-with-main-pre: - echo $commits_behind_count - if [ $commits_behind_count -eq 0 ]; then exit 0; else echo "Your branch is behind main, run 'git merge origin/main' to update."; exit 1; fi; +check-self-test-names-pre: + extends: + - .rules-merge-request + stage: prevalidate + needs: [] + tags: + - ivas-linux + script: + - python3 ci/check_self_test_names.py scripts/config/self_test.prm 135 + + branch-is-up-to-date-with-main-post: extends: - .rules-merge-request @@ -388,6 +434,7 @@ build-codec-instrumented-linux: timeout: "10 minutes" script: - *print-common-info + - *activate-Werror-linux - ./scripts/prepare_instrumentation.sh - make -j -C scripts/c-code_instrument @@ -500,6 +547,8 @@ codec-smoke-test: codec-msan: extends: - .sanitizer-selftest-on-mr + tags: + - ivas-linux-fast before_script: - CLANG_NUM=1 - SELFTEST_SANITY_TIMEOUT=$TESTCASE_TIMEOUT_STV_SANITIZERS @@ -520,6 +569,8 @@ codec-asan: codec-usan: extends: - .sanitizer-selftest-on-mr + tags: + - ivas-linux-fast before_script: - CLANG_NUM=3 - SELFTEST_SANITY_TIMEOUT=$TESTCASE_TIMEOUT_STV_SANITIZERS @@ -1300,21 +1351,17 @@ ivas-conformance: timeout: "60 minutes" rules: - if: ($CI_PIPELINE_SOURCE == 'web' || $CI_PIPELINE_SOURCE == 'trigger') && $MANUAL_PIPELINE_TYPE == 'ivas-conformance' +# - if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH allow_failure: exit_codes: - 123 script: - *print-common-info-windows - # Prepare reference exec, use tests and scripts from reference - - $source_branch_commit_sha = $(git rev-parse HEAD) - - git checkout main # This should be set to a relevant reference - python .\scripts\strip_split_rendering.py - MSBuild.exe -maxcpucount .\Workspace_msvc\Workspace_msvc.sln /property:Configuration=Debug - cp -force IVAS_cod.exe IVAS_cod_ref.exe - cp -force IVAS_dec.exe IVAS_dec_ref.exe - cp -force IVAS_rend.exe IVAS_rend_ref.exe - - git restore . - - git checkout $source_branch_commit_sha # Reference creation - python tests/create_short_testvectors.py @@ -1329,12 +1376,16 @@ ivas-conformance: # Copy input data and output ref data - if (Test-Path testvec) {rm -r -force testvec} + - if (Test-Path TMP_DEC) {rm -r -force TMP_DEC} + - if (Test-Path TMP_ENC) {rm -r -force TMP_ENC} + - if (Test-Path TMP_JBM) {rm -r -force TMP_JBM} + - if (Test-Path TMP_REND) {rm -r -force TMP_REND} - mkdir testvec - mkdir testvec/binauralRenderer_interface - mkdir testvec/testv - mkdir testvec/testv/renderer - mkdir testvec/bin - - cp -r -force -ErrorAction Ignore scripts/testv/* testvec/testv + - cp -force -ErrorAction Ignore scripts/testv/* testvec/testv - cp -r -force -ErrorAction Ignore scripts/ls_layouts testvec - cp -r -force -ErrorAction Ignore scripts/switchPaths testvec - cp -r -force -ErrorAction Ignore scripts/trajectories testvec @@ -1372,6 +1423,80 @@ ivas-conformance: reports: junit: report-junit.xml +ivas-conformance-linux: + tags: + - ivas-linux + stage: test + timeout: "60 minutes" + rules: + - if: ($CI_PIPELINE_SOURCE == 'web' || $CI_PIPELINE_SOURCE == 'trigger') && $MANUAL_PIPELINE_TYPE == 'ivas-conformance-linux' + allow_failure: + exit_codes: + - 123 + script: + - *print-common-info + - make -j + - cp IVAS_cod IVAS_cod_ref + - cp IVAS_dec IVAS_dec_ref + - cp IVAS_rend IVAS_rend_ref + + # Reference creation + - python3 tests/create_short_testvectors.py + - python3 scripts/prepare_combined_format_inputs.py + - python3 -m pytest tests/codec_be_on_mr_nonselection -v -n auto --update_ref 1 -m create_ref --keep_files + - python3 -m pytest tests/codec_be_on_mr_nonselection -v -n auto --update_ref 1 -m create_ref_part2 --keep_files + - python3 -m pytest tests/renderer/test_renderer.py --create_ref --keep_files + + # Output creation + - python3 -m pytest tests/codec_be_on_mr_nonselection tests/renderer/test_renderer.py -v -n auto --keep_files --create_cut --html=report_cmd.html --self-contained-html + - python3 scripts/parse_commands.py report_cmd.html Readme_IVAS.txt + + # Copy input data and output ref data + - rm -rf testvec + - mkdir testvec + - mkdir testvec/binauralRenderer_interface + - mkdir testvec/testv + - mkdir testvec/testv/renderer + - mkdir testvec/bin + - cp -r scripts/testv/* testvec/testv + - cp -r scripts/ls_layouts testvec + - cp -r scripts/switchPaths testvec + - cp -r scripts/trajectories testvec + - cp -r scripts/binauralRenderer_interface/binaural_renderers_hrtf_data testvec/binauralRenderer_interface + - cp -r tests/ref testvec/testv/ref + - cp -r tests/dut/* testvec/testv/ref + - cp -r tests/renderer/cut testvec/testv/renderer/ref + - cp -r tests/conformance-test testvec/ + - cp Readme_IVAS_dec.txt testvec + - cp Readme_IVAS_enc.txt testvec + - cp Readme_IVAS_rend.txt testvec + - cp Readme_IVAS_JBM_dec.txt testvec + - cp IVAS_cod testvec/bin + - cp IVAS_dec testvec/bin + - cp IVAS_rend testvec/bin + + # Test run generated scripts in testvec + - cd testvec + - python3 -m pytest conformance-test/test_26252.py --junit-xml=report-junit.xml --html=report.html --self-contained-html + - mv report.html .. + - mv report-junit.xml .. + + artifacts: + name: "ivas-conformance-linux-$CI_COMMIT_SHORT_SHA" + expire_in: 1 week + when: always + paths: + - report-junit.xml + - report.html + - Readme_IVAS_dec.txt + - Readme_IVAS_enc.txt + - Readme_IVAS_rend.txt + - Readme_IVAS_JBM_dec.txt + expose_as: "Draft IVAS conformance -- Linux" + reports: + junit: report-junit.xml + + test-long-self-test: tags: - ivas-linux-fast @@ -1453,7 +1578,7 @@ ltv-msan: - .sanitizer-selftest-ltv rules: - if: $SANITIZER_SCHEDULE_E - timeout: 1 hour + timeout: 2 hour tags: - ivas-linux-fast before_script: @@ -1469,10 +1594,10 @@ ltv-asan: rules: - if: $SANITIZER_SCHEDULE_E when: delayed - start_in: 1 hours + start_in: 2 hours tags: - ivas-linux-fast - timeout: 1 hour + timeout: 2 hour before_script: - CLANG_NUM=2 - SELFTEST_SANITY_TIMEOUT=$TESTCASE_TIMEOUT_LTV_SANITIZERS @@ -1486,10 +1611,10 @@ ltv-usan: rules: - if: $SANITIZER_SCHEDULE_E when: delayed - start_in: 2 hours + start_in: 3 hours tags: - ivas-linux-fast - timeout: 1 hour + timeout: 2 hour before_script: - CLANG_NUM=3 - SELFTEST_SANITY_TIMEOUT=$TESTCASE_TIMEOUT_LTV_SANITIZERS @@ -1510,6 +1635,8 @@ ltv-usan: paths: - ep_015.g192 - dly_profile.dat + - head_rot_traj.csv + - exof_traj.csv - ./LOGS_PLC - ./LOGS_noPLC diff --git a/.gitlab/issue_templates/asan_ltv_error.md b/.gitlab/issue_templates/asan_ltv_error.md index 97b3fa9ec2..f8f7c17d58 100644 --- a/.gitlab/issue_templates/asan_ltv_error.md +++ b/.gitlab/issue_templates/asan_ltv_error.md @@ -19,6 +19,7 @@ Link to test pipeline: XXX Using the [scripts](https://forge.3gpp.org/rep/ivas-codec-pc/ivas-codec/-/wikis/Software-development/pyivastest-howto#how-to-reproduce-tests): + ``` python3 scripts/IvasBuildAndRunChecks.py --checks CLANG2 -m MODE -p /path/to/my/local/ci_linux_ltv_local.json ``` diff --git a/.gitlab/issue_templates/msan_ltv_error.md b/.gitlab/issue_templates/msan_ltv_error.md index cc57222658..16dacd58ca 100644 --- a/.gitlab/issue_templates/msan_ltv_error.md +++ b/.gitlab/issue_templates/msan_ltv_error.md @@ -25,6 +25,7 @@ in the `Makefile` at lines 71 and 72. Note that this may increase runtime heavil Using the [scripts](https://forge.3gpp.org/rep/ivas-codec-pc/ivas-codec/-/wikis/Software-development/pyivastest-howto#how-to-reproduce-tests): + ``` python3 scripts/IvasBuildAndRunChecks.py --checks CLANG1 -m MODE -p /path/to/my/local/ci_linux_ltv_local.json diff --git a/.gitlab/issue_templates/usan_ltv_error.md b/.gitlab/issue_templates/usan_ltv_error.md index ef6562e866..6d90d341dc 100644 --- a/.gitlab/issue_templates/usan_ltv_error.md +++ b/.gitlab/issue_templates/usan_ltv_error.md @@ -19,6 +19,8 @@ Link to test pipeline: XXX Using the [scripts](https://forge.3gpp.org/rep/ivas-codec-pc/ivas-codec/-/wikis/Software-development/pyivastest-howto#how-to-reproduce-tests): + + ``` python3 scripts/IvasBuildAndRunChecks.py --checks CLANG3 -m MODE -p /path/to/my/local/ci_linux_ltv_local.json --usan_supp_file scripts/ubsan.supp ``` @@ -27,9 +29,9 @@ or directly: ``` make clean make -j CLANG=3 -./IVAS_cod ... +UBSAN_OPTIONS=suppressions=scripts/ubsan.supp,report_error_type=1,log_path=usan_log_catchall ./IVAS_cod ... networkSimulator_g192 dly_profile.dat bit bit_err trace_dump 1 -./IVAS_dec ... +UBSAN_OPTIONS=suppressions=scripts/ubsan.supp,report_error_type=1,log_path=usan_log_catchall ./IVAS_dec ... ``` gains [ 1.0, 32767/32768.0(first table value used) , first muted, .... ]*/ - /* burst_att_thresh ==5 --> gains [ 1.0, 1.0, 1,0 1,0, 32767/32768.0(first table value used) , first muted,... ]*/ - /* beta_mute_thr ==4 --> start of final attenuation attenuate AvgMix */ -#endif /* tabled {att_per_frame_idx_p3dB , burst_att_thresh, beta_mute_thr } */ { 1, 2, 0 + 2 + 2 }, /* 30 ms, 0.3 dB delta att in slow mutephase nominal_fadeout=0 */ { 1, 3, 0 + 3 + 2 }, /* 40 ms, 0.3 dB delta att in slow mutephase */ @@ -5746,11 +5741,6 @@ const LC3_INT16 fade_scheme_tab[24 / 2][3] = { { 11, 6, 15 + 6 },/* 140 ms, 0.3 dB delta att in slow mutephase nominal 3GPP */ }; -#if 0 -/*fade_scheme_tab[ind][0] att_per _fram_index , "points" to first column in POW_ATT TABLES */ -/*fade_scheme_tab[ind][1] is burst_att_thresh, the number of non_muted 1.0 gain frames */ -/*fade_scheme_tab[ind][2] is beta_mute_thr, the location of the start of final muting */ -#endif diff --git a/lib_lc3plus/constants.h b/lib_lc3plus/constants.h index 6d58a5798a..ace0f93830 100644 --- a/lib_lc3plus/constants.h +++ b/lib_lc3plus/constants.h @@ -12,6 +12,7 @@ #define CONSTANTS_H #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "structs.h" diff --git a/lib_lc3plus/cutoff_bandwidth.c b/lib_lc3plus/cutoff_bandwidth.c index c2d37312eb..c0ee62c62c 100644 --- a/lib_lc3plus/cutoff_bandwidth.c +++ b/lib_lc3plus/cutoff_bandwidth.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" void process_cutoff_bandwidth(LC3_FLOAT *d_fl, LC3_INT len, LC3_INT bw_bin) diff --git a/lib_lc3plus/dct4.c b/lib_lc3plus/dct4.c index 9b12627d71..055db02cbd 100644 --- a/lib_lc3plus/dct4.c +++ b/lib_lc3plus/dct4.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" void dct2_init(Dct2* dct, int length) diff --git a/lib_lc3plus/dec_entropy.c b/lib_lc3plus/dec_entropy.c index f072b82d6f..4e1f830a24 100644 --- a/lib_lc3plus/dec_entropy.c +++ b/lib_lc3plus/dec_entropy.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" static void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* bit); diff --git a/lib_lc3plus/dec_lc3_fl.c b/lib_lc3plus/dec_lc3_fl.c index 7389ffa53e..02c4fda1da 100644 --- a/lib_lc3plus/dec_lc3_fl.c +++ b/lib_lc3plus/dec_lc3_fl.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" diff --git a/lib_lc3plus/defines.h b/lib_lc3plus/defines.h index d9251c0181..4b1185c0e2 100644 --- a/lib_lc3plus/defines.h +++ b/lib_lc3plus/defines.h @@ -12,6 +12,7 @@ #define DEFINES_H #include "options.h" +#include "wmc_auto.h" #include "stdint.h" @@ -170,9 +171,6 @@ typedef int32_t LC3_INT32; /* current active settings */ # define PLC2_FADEOUT_IN_MS 30 /* 30 P800 fadeout optimized */ -#if 0 -# define PLC2_FADEOUT_LONG_IN_MS 50 /* 50 ABBA test */ -#endif # define PLC2_FADEOUT_LONG_IN_MS 120 /* 120 MUSHRA, && stable tonal fadeout optimized */ #endif diff --git a/lib_lc3plus/detect_cutoff_warped.c b/lib_lc3plus/detect_cutoff_warped.c index 239da4255f..21b73e8063 100644 --- a/lib_lc3plus/detect_cutoff_warped.c +++ b/lib_lc3plus/detect_cutoff_warped.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" void processDetectCutoffWarped_fl(LC3_FLOAT* d2, LC3_INT fs_idx, LC3_INT frame_dms, LC3_INT* bw_idx) diff --git a/lib_lc3plus/enc_entropy.c b/lib_lc3plus/enc_entropy.c index 23423b5d80..dc285088a4 100644 --- a/lib_lc3plus/enc_entropy.c +++ b/lib_lc3plus/enc_entropy.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" static const LC3_INT gainMSBbits[4] = {1, 1, 2, 2}; diff --git a/lib_lc3plus/enc_lc3_fl.c b/lib_lc3plus/enc_lc3_fl.c index 404b80fb4b..56771ce5b8 100644 --- a/lib_lc3plus/enc_lc3_fl.c +++ b/lib_lc3plus/enc_lc3_fl.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" static void Enc_LC3PLUS_Channel_fl(LC3PLUS_Enc* encoder, int channel, int32_t* s_in, uint8_t* bytes, int bps diff --git a/lib_lc3plus/estimate_global_gain.c b/lib_lc3plus/estimate_global_gain.c index fdaa977c06..2e69d239b2 100644 --- a/lib_lc3plus/estimate_global_gain.c +++ b/lib_lc3plus/estimate_global_gain.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" diff --git a/lib_lc3plus/fft/cfft.c b/lib_lc3plus/fft/cfft.c index e8a6304ee1..7ded7d3ed6 100644 --- a/lib_lc3plus/fft/cfft.c +++ b/lib_lc3plus/fft/cfft.c @@ -10,6 +10,7 @@ #include "options.h" +#include "wmc_auto.h" #include "cfft.h" #include "iisfft.h" /* for M_PIl */ #include /* for abs() */ diff --git a/lib_lc3plus/fft/cfft.h b/lib_lc3plus/fft/cfft.h index 6ba8dfccd3..18f1e80ad3 100644 --- a/lib_lc3plus/fft/cfft.h +++ b/lib_lc3plus/fft/cfft.h @@ -10,6 +10,7 @@ #include "options.h" +#include "wmc_auto.h" #include "../functions.h" #ifndef CFFT_H diff --git a/lib_lc3plus/fft/iis_fft.c b/lib_lc3plus/fft/iis_fft.c index 30ae240200..e3af5bc2f9 100644 --- a/lib_lc3plus/fft/iis_fft.c +++ b/lib_lc3plus/fft/iis_fft.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include #include #include diff --git a/lib_lc3plus/fft/iis_fft.h b/lib_lc3plus/fft/iis_fft.h index b70a3719d3..a145c490d1 100644 --- a/lib_lc3plus/fft/iis_fft.h +++ b/lib_lc3plus/fft/iis_fft.h @@ -12,6 +12,7 @@ #define IIS_FFT_H #include "options.h" +#include "wmc_auto.h" #include "../structs.h" #include "../defines.h" #include "cfft.h" diff --git a/lib_lc3plus/fft/iisfft.c b/lib_lc3plus/fft/iisfft.c index cdf7f8d2a8..a437d4902f 100644 --- a/lib_lc3plus/fft/iisfft.c +++ b/lib_lc3plus/fft/iisfft.c @@ -10,6 +10,7 @@ #include "options.h" +#include "wmc_auto.h" #include #include /* for mmove */ #include diff --git a/lib_lc3plus/fft/iisfft.h b/lib_lc3plus/fft/iisfft.h index b45e73cdec..a77a1af7e8 100644 --- a/lib_lc3plus/fft/iisfft.h +++ b/lib_lc3plus/fft/iisfft.h @@ -12,6 +12,7 @@ #define IISFFT_H #include "options.h" +#include "wmc_auto.h" #include "../defines.h" #ifndef M_PIl diff --git a/lib_lc3plus/functions.h b/lib_lc3plus/functions.h index b0997e85fa..01ad936f00 100644 --- a/lib_lc3plus/functions.h +++ b/lib_lc3plus/functions.h @@ -12,6 +12,7 @@ #define FUNCTIONS_H #include "options.h" +#include "wmc_auto.h" #include "clib.h" #include "defines.h" #include "float.h" diff --git a/lib_lc3plus/imdct.c b/lib_lc3plus/imdct.c index b1b5d4b43b..b2ef8ee925 100644 --- a/lib_lc3plus/imdct.c +++ b/lib_lc3plus/imdct.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" /* Function expects already flipped window */ diff --git a/lib_lc3plus/lc3.c b/lib_lc3plus/lc3.c index f09c53a538..e3f4491d2b 100644 --- a/lib_lc3plus/lc3.c +++ b/lib_lc3plus/lc3.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "lc3.h" #include "defines.h" #include "functions.h" diff --git a/lib_lc3plus/lc3.h b/lib_lc3plus/lc3.h index 0981cea84b..fab259e96d 100644 --- a/lib_lc3plus/lc3.h +++ b/lib_lc3plus/lc3.h @@ -26,6 +26,7 @@ #ifndef _MSC_VER #include "options.h" +#include "wmc_auto.h" #include #else typedef unsigned char uint8_t; diff --git a/lib_lc3plus/lc3plus_fft.c b/lib_lc3plus/lc3plus_fft.c index f1fc8fe714..c7911b92dd 100644 --- a/lib_lc3plus/lc3plus_fft.c +++ b/lib_lc3plus/lc3plus_fft.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" #include "fft/iis_fft.c" #include "fft/iisfft.c" diff --git a/lib_lc3plus/license.h b/lib_lc3plus/license.h index 266f91a165..077df126ea 100644 --- a/lib_lc3plus/license.h +++ b/lib_lc3plus/license.h @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "defines.h" static const char *const LICENSE = diff --git a/lib_lc3plus/ltpf_coder.c b/lib_lc3plus/ltpf_coder.c index 286d8fa166..2a000f60f8 100644 --- a/lib_lc3plus/ltpf_coder.c +++ b/lib_lc3plus/ltpf_coder.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" static LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len); diff --git a/lib_lc3plus/ltpf_decoder.c b/lib_lc3plus/ltpf_decoder.c index e95a274a46..d51c7ffe3c 100644 --- a/lib_lc3plus/ltpf_decoder.c +++ b/lib_lc3plus/ltpf_decoder.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT fs, LC3_FLOAT* mem_old_x, LC3_FLOAT* mem_old_y, diff --git a/lib_lc3plus/mdct.c b/lib_lc3plus/mdct.c index ec20993121..ef2d7c087a 100644 --- a/lib_lc3plus/mdct.c +++ b/lib_lc3plus/mdct.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" static const LC3_FLOAT* mdct_window(LC3_INT length, LC3_INT frame_dms, LC3_INT hrmode) diff --git a/lib_lc3plus/mdct_shaping.c b/lib_lc3plus/mdct_shaping.c index d3ca7dd953..eba6f32704 100644 --- a/lib_lc3plus/mdct_shaping.c +++ b/lib_lc3plus/mdct_shaping.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" void processMdctShaping_fl(LC3_FLOAT x[], LC3_FLOAT scf[], const LC3_INT bands_offset[], LC3_INT fdns_npts) diff --git a/lib_lc3plus/near_nyquist_detector.c b/lib_lc3plus/near_nyquist_detector.c index e18eb52112..534f30ee70 100644 --- a/lib_lc3plus/near_nyquist_detector.c +++ b/lib_lc3plus/near_nyquist_detector.c @@ -8,6 +8,7 @@ ******************************************************************************/ #include "options.h" +#include "wmc_auto.h" #include "functions.h" diff --git a/lib_lc3plus/noise_factor.c b/lib_lc3plus/noise_factor.c index 9cf130348f..5e4ecd7b9a 100644 --- a/lib_lc3plus/noise_factor.c +++ b/lib_lc3plus/noise_factor.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" void processNoiseFactor_fl(LC3_INT* fac_ns_idx, LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gg, LC3_INT BW_cutoff_idx, LC3_INT frame_dms, diff --git a/lib_lc3plus/noise_filling.c b/lib_lc3plus/noise_filling.c index 1ae4c8ab8c..b844aef080 100644 --- a/lib_lc3plus/noise_filling.c +++ b/lib_lc3plus/noise_filling.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" void processNoiseFilling_fl(LC3_FLOAT xq[], LC3_INT nfseed, LC3_INT fac_ns_idx, LC3_INT bw_stopband, LC3_INT frame_dms, LC3_FLOAT fac_ns_pc, LC3_INT spec_inv_idx) diff --git a/lib_lc3plus/olpa.c b/lib_lc3plus/olpa.c index b1b8f2171c..62a303f26f 100644 --- a/lib_lc3plus/olpa.c +++ b/lib_lc3plus/olpa.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" static void filter_olpa(LC3_FLOAT* in, LC3_FLOAT* out, const LC3_FLOAT* buf, LC3_INT32 len_input); diff --git a/lib_lc3plus/pc_apply.c b/lib_lc3plus/pc_apply.c index 4ca871f2fc..89bab44eb6 100644 --- a/lib_lc3plus/pc_apply.c +++ b/lib_lc3plus/pc_apply.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" diff --git a/lib_lc3plus/pc_classify.c b/lib_lc3plus/pc_classify.c index 9fa5f38d9c..9ea5e02dae 100644 --- a/lib_lc3plus/pc_classify.c +++ b/lib_lc3plus/pc_classify.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" diff --git a/lib_lc3plus/pc_main.c b/lib_lc3plus/pc_main.c index ead43deefe..6ee2bc0727 100644 --- a/lib_lc3plus/pc_main.c +++ b/lib_lc3plus/pc_main.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" diff --git a/lib_lc3plus/pc_update.c b/lib_lc3plus/pc_update.c index 214ced77d0..e57016d401 100644 --- a/lib_lc3plus/pc_update.c +++ b/lib_lc3plus/pc_update.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" diff --git a/lib_lc3plus/per_band_energy.c b/lib_lc3plus/per_band_energy.c index ec34c3d7da..ed29be5e5b 100644 --- a/lib_lc3plus/per_band_energy.c +++ b/lib_lc3plus/per_band_energy.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" void processPerBandEnergy_fl(LC3_INT bands_number, const LC3_INT* acc_coeff_per_band, LC3_INT16 hrmode, LC3_INT16 frame_dms, LC3_FLOAT* d2, LC3_FLOAT* d) diff --git a/lib_lc3plus/plc_classify.c b/lib_lc3plus/plc_classify.c index e45f08747d..3ce7aaf913 100644 --- a/lib_lc3plus/plc_classify.c +++ b/lib_lc3plus/plc_classify.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" #ifdef CR8_A_PLC_FADEOUT_TUNING diff --git a/lib_lc3plus/plc_compute_stab_fac.c b/lib_lc3plus/plc_compute_stab_fac.c index a81af2218b..5c7a736e68 100644 --- a/lib_lc3plus/plc_compute_stab_fac.c +++ b/lib_lc3plus/plc_compute_stab_fac.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" diff --git a/lib_lc3plus/plc_damping_scrambling.c b/lib_lc3plus/plc_damping_scrambling.c index a863c1621a..fd9efd7c0e 100644 --- a/lib_lc3plus/plc_damping_scrambling.c +++ b/lib_lc3plus/plc_damping_scrambling.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" diff --git a/lib_lc3plus/plc_main.c b/lib_lc3plus/plc_main.c index 4fc19f6053..c51852fd2a 100644 --- a/lib_lc3plus/plc_main.c +++ b/lib_lc3plus/plc_main.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* decoder, DecSetup* h_DecSetup, LC3_INT bfi, diff --git a/lib_lc3plus/plc_noise_substitution.c b/lib_lc3plus/plc_noise_substitution.c index 92f8b3cf21..c366015fc0 100644 --- a/lib_lc3plus/plc_noise_substitution.c +++ b/lib_lc3plus/plc_noise_substitution.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" diff --git a/lib_lc3plus/plc_phecu_f0_refine_first.c b/lib_lc3plus/plc_phecu_f0_refine_first.c index 2a580024f0..c3f8edfab2 100644 --- a/lib_lc3plus/plc_phecu_f0_refine_first.c +++ b/lib_lc3plus/plc_phecu_f0_refine_first.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" diff --git a/lib_lc3plus/plc_phecu_fec_hq.c b/lib_lc3plus/plc_phecu_fec_hq.c index 4aebbfa885..9213b9ea53 100644 --- a/lib_lc3plus/plc_phecu_fec_hq.c +++ b/lib_lc3plus/plc_phecu_fec_hq.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" diff --git a/lib_lc3plus/plc_phecu_hq_ecu.c b/lib_lc3plus/plc_phecu_hq_ecu.c index 112d965a49..577a56e83a 100644 --- a/lib_lc3plus/plc_phecu_hq_ecu.c +++ b/lib_lc3plus/plc_phecu_hq_ecu.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" diff --git a/lib_lc3plus/plc_phecu_lf_peak_analysis.c b/lib_lc3plus/plc_phecu_lf_peak_analysis.c index 225aa52560..53c10410c0 100644 --- a/lib_lc3plus/plc_phecu_lf_peak_analysis.c +++ b/lib_lc3plus/plc_phecu_lf_peak_analysis.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" diff --git a/lib_lc3plus/plc_phecu_rec_frame.c b/lib_lc3plus/plc_phecu_rec_frame.c index e56cb3dd75..4586e1d625 100644 --- a/lib_lc3plus/plc_phecu_rec_frame.c +++ b/lib_lc3plus/plc_phecu_rec_frame.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" diff --git a/lib_lc3plus/plc_phecu_setf0hz.c b/lib_lc3plus/plc_phecu_setf0hz.c index 7bdb0a8c5c..79a82d0928 100644 --- a/lib_lc3plus/plc_phecu_setf0hz.c +++ b/lib_lc3plus/plc_phecu_setf0hz.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" diff --git a/lib_lc3plus/plc_phecu_spec_ana.c b/lib_lc3plus/plc_phecu_spec_ana.c index 313b338777..463d3d1ae6 100644 --- a/lib_lc3plus/plc_phecu_spec_ana.c +++ b/lib_lc3plus/plc_phecu_spec_ana.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" diff --git a/lib_lc3plus/plc_phecu_subst_spec.c b/lib_lc3plus/plc_phecu_subst_spec.c index d494af826f..388ae3cb80 100644 --- a/lib_lc3plus/plc_phecu_subst_spec.c +++ b/lib_lc3plus/plc_phecu_subst_spec.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" #include "constants.h" @@ -100,9 +101,6 @@ void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est, } #ifdef CR8_A_PLC_FADEOUT_TUNING -#if 0 - /* align DC fs/2 muting to BASOP */ -#endif /* binary selection of fadeout scheme */ assert(PLC2_FADEOUT_LONG_IN_MS >= PLC2_FADEOUT_IN_MS_MIN && PLC2_FADEOUT_IN_MS >= PLC2_FADEOUT_IN_MS_MIN); assert(PLC2_FADEOUT_LONG_IN_MS <= PLC2_FADEOUT_IN_MS_MAX && PLC2_FADEOUT_IN_MS <= PLC2_FADEOUT_IN_MS_MAX); @@ -417,12 +415,6 @@ static LC3_INT16 plc_phEcu_nonpure_tone_ana(const LC3_INT32* plocs, const LC3_I { /* delta taper-off analysis solution, less sensitive to input bandwidth limitation and levels */ -#if 0 - /* note: in BASOP the Xavg ratios below are calculated in log2 domain on a maximally upshifted Xavg vector. - if Xavg is an all zero vector in BASOP, then the nonpure_tone_detect flag is or'ed with 0x100 , - to trigger normal valley noise generation */ -#endif - /* verify that an assumed clean sine does not have any odd HF content indications by thresholding the accumulated delta rise in LF/HF side lobes */ for (i = (sineband_ind_high + 1); i < (N_grp - 1); i++) { tmp = (Xavg[i + 1] + LC3_EPS) / (Xavg[i] + LC3_EPS); diff --git a/lib_lc3plus/plc_phecu_tba_per_band_gain.c b/lib_lc3plus/plc_phecu_tba_per_band_gain.c index 507f45a647..10aef92346 100644 --- a/lib_lc3plus/plc_phecu_tba_per_band_gain.c +++ b/lib_lc3plus/plc_phecu_tba_per_band_gain.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" diff --git a/lib_lc3plus/plc_phecu_tba_spect_Xavg.c b/lib_lc3plus/plc_phecu_tba_spect_Xavg.c index b4727cfd4c..20baf4e796 100644 --- a/lib_lc3plus/plc_phecu_tba_spect_Xavg.c +++ b/lib_lc3plus/plc_phecu_tba_spect_Xavg.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" diff --git a/lib_lc3plus/plc_phecu_tba_trans_dect_gains.c b/lib_lc3plus/plc_phecu_tba_trans_dect_gains.c index 3b58d92b42..69d6bf3968 100644 --- a/lib_lc3plus/plc_phecu_tba_trans_dect_gains.c +++ b/lib_lc3plus/plc_phecu_tba_trans_dect_gains.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" @@ -100,10 +101,6 @@ const LC3_INT32 POW_ATT_TABLE_p4x1_6[OFF_FRAMES_LIMIT + 1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; #ifdef CR8_A_PLC_FADEOUT_TUNING -#if 0 -/* POW_ATT_TABLES now ordered logically based on initial slow muting phase time */ -/* POW_ATT_TABLES[ind] is used after the initial gain==1.0 no energy muting phase */ -#endif const LC3_INT32 *const POW_ATT_TABLES[1 + 12] = { NULL, /*0.3dB col , 0.4dB col */ diff --git a/lib_lc3plus/plc_phecu_trans_burst_ana_sub.c b/lib_lc3plus/plc_phecu_trans_burst_ana_sub.c index d4d8f15e20..a25947a186 100644 --- a/lib_lc3plus/plc_phecu_trans_burst_ana_sub.c +++ b/lib_lc3plus/plc_phecu_trans_burst_ana_sub.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" diff --git a/lib_lc3plus/plc_tdc.c b/lib_lc3plus/plc_tdc.c index 89d7455433..25c4aa0640 100644 --- a/lib_lc3plus/plc_tdc.c +++ b/lib_lc3plus/plc_tdc.c @@ -13,6 +13,7 @@ \***************************************************************************/ #include "options.h" +#include "wmc_auto.h" #include #include "functions.h" diff --git a/lib_lc3plus/plc_tdc_tdac.c b/lib_lc3plus/plc_tdc_tdac.c index 3c8e99b0e6..596c23db03 100644 --- a/lib_lc3plus/plc_tdc_tdac.c +++ b/lib_lc3plus/plc_tdc_tdac.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" diff --git a/lib_lc3plus/plc_update.c b/lib_lc3plus/plc_update.c index 4ec4e86341..40520fb256 100644 --- a/lib_lc3plus/plc_update.c +++ b/lib_lc3plus/plc_update.c @@ -8,6 +8,7 @@ ******************************************************************************/ #include "options.h" +#include "wmc_auto.h" #include "functions.h" diff --git a/lib_lc3plus/quantize_spec.c b/lib_lc3plus/quantize_spec.c index 78d3486539..fdaee2890a 100644 --- a/lib_lc3plus/quantize_spec.c +++ b/lib_lc3plus/quantize_spec.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" LC3_INT32 find_last_nz_pair(LC3_INT32 x[], LC3_INT32 length); diff --git a/lib_lc3plus/reorder_bitstream.c b/lib_lc3plus/reorder_bitstream.c index 61880dbd09..118a05b6ef 100644 --- a/lib_lc3plus/reorder_bitstream.c +++ b/lib_lc3plus/reorder_bitstream.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" diff --git a/lib_lc3plus/resamp12k8.c b/lib_lc3plus/resamp12k8.c index fd8caad7c0..295b6e7f29 100644 --- a/lib_lc3plus/resamp12k8.c +++ b/lib_lc3plus/resamp12k8.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" void process_resamp12k8_fl(LC3_FLOAT x[], LC3_INT x_len, LC3_FLOAT mem_in[], LC3_INT mem_in_len, LC3_FLOAT mem_50[], LC3_FLOAT mem_out[], diff --git a/lib_lc3plus/residual_coding.c b/lib_lc3plus/residual_coding.c index bcd6637310..777b97d73a 100644 --- a/lib_lc3plus/residual_coding.c +++ b/lib_lc3plus/residual_coding.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" void processResidualCoding_fl(LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gain, LC3_INT L_spec, LC3_INT targetBits, LC3_INT nBits, uint8_t* resBits, LC3_INT* numResBits diff --git a/lib_lc3plus/residual_decoding.c b/lib_lc3plus/residual_decoding.c index 5085d999af..90084c9811 100644 --- a/lib_lc3plus/residual_decoding.c +++ b/lib_lc3plus/residual_decoding.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" void processResidualDecoding_fl(LC3_INT* bitsRead, LC3_FLOAT x[], LC3_INT L_spec, uint8_t prm[], LC3_INT resQBits diff --git a/lib_lc3plus/setup_com_lc3.c b/lib_lc3plus/setup_com_lc3.c index cecbfd7762..33574f577e 100644 --- a/lib_lc3plus/setup_com_lc3.c +++ b/lib_lc3plus/setup_com_lc3.c @@ -8,6 +8,7 @@ ******************************************************************************/ #include "options.h" +#include "wmc_auto.h" #include "functions.h" LC3_FLOAT array_max_abs(LC3_FLOAT *in, LC3_INT32 len) diff --git a/lib_lc3plus/setup_dec_lc3.c b/lib_lc3plus/setup_dec_lc3.c index 517a48b492..ba49e54bf2 100644 --- a/lib_lc3plus/setup_dec_lc3.c +++ b/lib_lc3plus/setup_dec_lc3.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "setup_dec_lc3.h" #include "functions.h" #include diff --git a/lib_lc3plus/setup_dec_lc3.h b/lib_lc3plus/setup_dec_lc3.h index 3ae6b13977..17201a4a93 100644 --- a/lib_lc3plus/setup_dec_lc3.h +++ b/lib_lc3plus/setup_dec_lc3.h @@ -12,6 +12,7 @@ #define SETUP_DEC_LC3_FL_H #include "options.h" +#include "wmc_auto.h" #include "constants.h" /* Channel state and bitrate-derived values go in this struct */ diff --git a/lib_lc3plus/setup_enc_lc3.c b/lib_lc3plus/setup_enc_lc3.c index a7c94a44e2..e991c50f46 100644 --- a/lib_lc3plus/setup_enc_lc3.c +++ b/lib_lc3plus/setup_enc_lc3.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "setup_enc_lc3.h" #include "functions.h" #include diff --git a/lib_lc3plus/setup_enc_lc3.h b/lib_lc3plus/setup_enc_lc3.h index 43c29e12bc..e3f62ba556 100644 --- a/lib_lc3plus/setup_enc_lc3.h +++ b/lib_lc3plus/setup_enc_lc3.h @@ -12,6 +12,7 @@ #define SETUP_ENC_LC3_FL_H #include "options.h" +#include "wmc_auto.h" #include "constants.h" /* Channel state and bitrate-derived values go in this struct */ diff --git a/lib_lc3plus/sns_compute_scf.c b/lib_lc3plus/sns_compute_scf.c index 586fd9ef66..7f78b36667 100644 --- a/lib_lc3plus/sns_compute_scf.c +++ b/lib_lc3plus/sns_compute_scf.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* gains, LC3_INT smooth, LC3_FLOAT sns_damping, LC3_FLOAT attdec_damping_factor, LC3_INT fs_idx) diff --git a/lib_lc3plus/sns_interpolate_scf.c b/lib_lc3plus/sns_interpolate_scf.c index fea81e6be5..98b54909b7 100644 --- a/lib_lc3plus/sns_interpolate_scf.c +++ b/lib_lc3plus/sns_interpolate_scf.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" void processSnsInterpolateScf_fl(LC3_FLOAT* gains, LC3_INT encoder_side, LC3_INT bands_number, LC3_FLOAT* gains_int) diff --git a/lib_lc3plus/sns_quantize_scf.c b/lib_lc3plus/sns_quantize_scf.c index 3cb81aee9c..e3fa34d832 100644 --- a/lib_lc3plus/sns_quantize_scf.c +++ b/lib_lc3plus/sns_quantize_scf.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" static void pvq_dec(LC3_INT k, LC3_INT m, LC3_INT LS_ind, LC3_INT MPVQ_ind, LC3_INT* pulses); diff --git a/lib_lc3plus/structs.h b/lib_lc3plus/structs.h index e311824b7f..1d82711d3c 100644 --- a/lib_lc3plus/structs.h +++ b/lib_lc3plus/structs.h @@ -12,6 +12,7 @@ #define STRUCTS_H #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "fft/iisfft.h" diff --git a/lib_lc3plus/tns_coder.c b/lib_lc3plus/tns_coder.c index e9301af9df..6870ba1e14 100644 --- a/lib_lc3plus/tns_coder.c +++ b/lib_lc3plus/tns_coder.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" static void xcorr(LC3_FLOAT* in, LC3_FLOAT* out, LC3_INT lag, LC3_INT inLen); diff --git a/lib_lc3plus/tns_decoder.c b/lib_lc3plus/tns_decoder.c index f4dff52f39..dbdadaeaff 100644 --- a/lib_lc3plus/tns_decoder.c +++ b/lib_lc3plus/tns_decoder.c @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" void processTnsDecoder_fl(LC3_FLOAT* x, LC3_INT* rc_idx, LC3_INT* order, LC3_INT numfilters, LC3_INT bw_fcbin, LC3_INT N, LC3_INT fs) diff --git a/lib_lc3plus/util.h b/lib_lc3plus/util.h index adf422cff6..069e893714 100644 --- a/lib_lc3plus/util.h +++ b/lib_lc3plus/util.h @@ -12,6 +12,7 @@ #define UTIL_H #include "options.h" +#include "wmc_auto.h" #include "clib.h" #include "math.h" diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index e2e189060f..0363ea645b 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -2036,8 +2036,8 @@ ivas_error ivas_rend_crendProcessSplitBin( const AUDIO_CONFIG inConfig, const AUDIO_CONFIG outConfig, const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - DECODER_CONFIG_HANDLE hDecoderConfig, - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, + const DECODER_CONFIG_HANDLE hDecoderConfig, + const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, const IVAS_OUTPUT_SETUP_HANDLE hIntSetup, EFAP_HANDLE hEFAPdata, float *output[], @@ -2166,9 +2166,8 @@ ivas_error ivas_rend_crendProcessSplitBin( return IVAS_ERR_OK; } -#endif -#ifdef SPLIT_REND_WITH_HEAD_ROT + /*-----------------------------------------------------------------------------------------* * Function ivas_rend_crend_ProcessSubframesSplitBin() * diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 7eaa206026..b1d682f344 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -99,8 +99,9 @@ static void ivas_dirac_dec_binaural_internal( Decoder_Struct *st_ivas, COMBINED_ static void ivas_dirac_dec_decorrelate_slot( DIRAC_DEC_BIN_HANDLE hDiracDecBin, const int16_t num_freq_bands, const int16_t slot, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float decRe[][CLDFB_NO_CHANNELS_MAX], float decIm[][CLDFB_NO_CHANNELS_MAX] ); #ifdef SPLIT_REND_WITH_HEAD_ROT -static void ivas_dirac_dec_binaural_formulate_input_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t subframe, float *subFrameTotalEne, float *IIReneLimiter ); -static void ivas_dirac_dec_binaural_formulate_target_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, float Rmat[3][3], const int16_t subframe, const int16_t isHeadtracked, const float *subFrameTotalEne, const float *IIReneLimiter, const MASA_ISM_DATA_HANDLE hMasaIsmData ); +static void ivas_dirac_dec_binaural_formulate_input_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, const SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, const PARAMBIN_REND_CONFIG_HANDLE hConfig, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t subframe, float *subFrameTotalEne, float *IIReneLimiter ); + +static void ivas_dirac_dec_binaural_formulate_target_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, const SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, const PARAMBIN_REND_CONFIG_HANDLE hConfig, float Rmat[3][3], const int16_t subframe, const int16_t isHeadtracked, const float *subFrameTotalEne, const float *IIReneLimiter, const MASA_ISM_DATA_HANDLE hMasaIsmData ); #else static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float Rmat[3][3], const int16_t subframe, const int16_t isHeadtracked, const MASA_ISM_DATA_HANDLE hMasaIsmData ); #endif @@ -832,10 +833,10 @@ static void ivas_dirac_dec_binaural_internal( for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - for ( i = 0; i < CLDFB_SLOTS_PER_SUBFRAME; i++ ) + for ( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe]; i++ ) { - mvr2r( tmp_Cldfb_out_re[ch][i], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); - mvr2r( tmp_Cldfb_out_im[ch][i], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); + mvr2r( tmp_Cldfb_out_re[ch][i], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[ch][hSpatParamRendCom->slots_rendered + i], CLDFB_NO_CHANNELS_MAX ); + mvr2r( tmp_Cldfb_out_im[ch][i], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[ch][hSpatParamRendCom->slots_rendered + i], CLDFB_NO_CHANNELS_MAX ); } } } @@ -905,10 +906,10 @@ static void ivas_dirac_dec_binaural_internal( /* copy from temporary buffer to the main split rendering buffer */ for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - for ( i = 0; i < CLDFB_SLOTS_PER_SUBFRAME; i++ ) + for ( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe]; i++ ) { - mvr2r( tmp_Cldfb_out_re[ch][i], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[pos_idx * BINAURAL_CHANNELS + ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); - mvr2r( tmp_Cldfb_out_im[ch][i], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[pos_idx * BINAURAL_CHANNELS + ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); + mvr2r( tmp_Cldfb_out_re[ch][i], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[pos_idx * BINAURAL_CHANNELS + ch][hSpatParamRendCom->slots_rendered + i], CLDFB_NO_CHANNELS_MAX ); + mvr2r( tmp_Cldfb_out_im[ch][i], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[pos_idx * BINAURAL_CHANNELS + ch][hSpatParamRendCom->slots_rendered + i], CLDFB_NO_CHANNELS_MAX ); } } @@ -984,8 +985,8 @@ static void ivas_dirac_dec_decorrelate_slot( #ifdef SPLIT_REND_WITH_HEAD_ROT static void ivas_dirac_dec_binaural_formulate_input_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, - PARAMBIN_REND_CONFIG_HANDLE hConfig, + const SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, + const PARAMBIN_REND_CONFIG_HANDLE hConfig, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t subframe, @@ -1148,8 +1149,8 @@ static void ivas_dirac_dec_binaural_formulate_input_covariance_matrices( static void ivas_dirac_dec_binaural_formulate_target_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, - PARAMBIN_REND_CONFIG_HANDLE hConfig, + const SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, + const PARAMBIN_REND_CONFIG_HANDLE hConfig, float Rmat[3][3], const int16_t subframe, const int16_t isHeadtracked, diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 1b2cfbacdb..f6a14f66f0 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -36,9 +36,6 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include "ivas_prot.h" -#endif #include #include "ivas_rom_com.h" #ifdef DEBUGGING @@ -762,153 +759,6 @@ ivas_error ivas_td_binaural_renderer_ext( } -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*---------------------------------------------------------------------* - * ObjRenderIvasFrame_splitBinaural() - * - * Render to multiple binaural pairs based on relative head positions for split rendering. - *---------------------------------------------------------------------*/ - -ivas_error ObjRenderIvasFrame_splitBinaural( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[], /* i/o: SCE channels / Binaural synthesis */ - const int16_t output_frame /* i : output frame length */ -) -{ - int16_t i; - float tmpProcessing[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - float tmpBinaural[MAX_HEAD_ROT_POSES * 2][L_FRAME48k]; - float *p_tmpProcessing[MAX_OUTPUT_CHANNELS]; - int16_t pos_idx; - IVAS_QUATERNION originalHeadRot[MAX_PARAM_SPATIAL_SUBFRAMES]; - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData; - BINAURAL_TD_OBJECT_RENDERER_HANDLE tmpTdRendHandle; - ivas_error error; - - push_wmops( "ObjRenderIvasFrame_splitBinaural" ); - pMultiBinPoseData = &st_ivas->hSplitBinRend.splitrend.multiBinPoseData; - - /* If not yet allocated, open additional instances of TD renderer */ - for ( i = 0; i < pMultiBinPoseData->num_poses - 1; ++i ) - { - if ( st_ivas->hTdRendHandles[i] != NULL ) - { - continue; - } - - if ( ( error = ivas_td_binaural_open_unwrap( &st_ivas->hHrtfTD, - st_ivas->hDecoderConfig->output_Fs, - st_ivas->nchan_transport, - st_ivas->ivas_format, - st_ivas->transport_config, - st_ivas->hRenderConfig->directivity, - st_ivas->hTransSetup, - &st_ivas->hTdRendHandles[i], - &st_ivas->binaural_latency_ns ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - /* Save current head positions */ - for ( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i ) - { - originalHeadRot[i] = st_ivas->hCombinedOrientationData->Quaternions[i]; - } - - /* Copy input audio to a processing buffer. Cannot render in-place because binaurally rendered - * audio would overwrite original material, which is still needed for rendering next head pose. */ - for ( i = 0; i < st_ivas->nchan_transport; ++i ) - { - mvr2r( output[i], tmpProcessing[i], output_frame ); - } - - for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) - { - /* Update head positions */ - if ( pos_idx != 0 ) - { - for ( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i ) - { - if ( originalHeadRot[i].w == -3.0f ) - { - st_ivas->hCombinedOrientationData->Quaternions[i].w = -3.0f; - st_ivas->hCombinedOrientationData->Quaternions[i].x = originalHeadRot[i].x + pMultiBinPoseData->relative_head_poses[pos_idx][0]; - st_ivas->hCombinedOrientationData->Quaternions[i].y = originalHeadRot[i].y + pMultiBinPoseData->relative_head_poses[pos_idx][1]; - st_ivas->hCombinedOrientationData->Quaternions[i].z = originalHeadRot[i].z + pMultiBinPoseData->relative_head_poses[pos_idx][2]; - } - else - { - st_ivas->hCombinedOrientationData->Quaternions[i].w = -3.0f; - - Quat2EulerDegree( originalHeadRot[i], /* TODO tmu : fix bug with ordering*/ - &st_ivas->hCombinedOrientationData->Quaternions[i].z, - &st_ivas->hCombinedOrientationData->Quaternions[i].y, - &st_ivas->hCombinedOrientationData->Quaternions[i].x ); - - st_ivas->hCombinedOrientationData->Quaternions[i].x += pMultiBinPoseData->relative_head_poses[pos_idx][0]; - st_ivas->hCombinedOrientationData->Quaternions[i].y += pMultiBinPoseData->relative_head_poses[pos_idx][1]; - st_ivas->hCombinedOrientationData->Quaternions[i].z += pMultiBinPoseData->relative_head_poses[pos_idx][2]; - } - } - } - - /* Handle the 1 ISM case where there is only one channel in the input buffer */ - for ( i = 0; i < max( st_ivas->nchan_transport, BINAURAL_CHANNELS ); ++i ) - { - p_tmpProcessing[i] = tmpProcessing[i]; - } - - /* Render */ - if ( pos_idx == 0 ) - { - if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_tmpProcessing, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else - { - /* Tmp swap renderer handles for rendering call */ - tmpTdRendHandle = st_ivas->hBinRendererTd; - st_ivas->hBinRendererTd = st_ivas->hTdRendHandles[pos_idx - 1]; - - if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_tmpProcessing, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - - st_ivas->hBinRendererTd = tmpTdRendHandle; - } - - /* Copy rendered audio to tmp storage buffer. Copying directly to output would - * overwrite original audio, which is still needed for rendering next head pose. */ - mvr2r( tmpProcessing[0], tmpBinaural[2 * pos_idx], output_frame ); - mvr2r( tmpProcessing[1], tmpBinaural[2 * pos_idx + 1], output_frame ); - - /* Overwrite first 2 channels with original input audio again */ - mvr2r( output[0], tmpProcessing[0], output_frame ); - mvr2r( output[1], tmpProcessing[1], output_frame ); - } - - /* Copy from storage buffer to output */ - for ( i = 0; i < pMultiBinPoseData->num_poses * BINAURAL_CHANNELS; ++i ) - { - mvr2r( tmpBinaural[i], output[i], output_frame ); - } - - /* Restore original head rotation */ - for ( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i ) - { - st_ivas->hCombinedOrientationData->Quaternions[i] = originalHeadRot[i]; - } - - pop_wmops(); - return IVAS_ERR_OK; -} -#endif - - /*---------------------------------------------------------------------* * angles_to_vec() * diff --git a/lib_rend/ivas_orient_trk.c b/lib_rend/ivas_orient_trk.c index 81cda7dd97..0e2525adb7 100644 --- a/lib_rend/ivas_orient_trk.c +++ b/lib_rend/ivas_orient_trk.c @@ -49,7 +49,9 @@ *------------------------------------------------------------------------------------------*/ #define OTR_UPDATE_RATE (float) FRAMES_PER_SEC /* rate of the Process() calls [Hz]; 1x per IVAS frame */ - +#ifdef NONBE_FIX_1067_QUATERNIONSLERP_INACCURACIES +#define COS_ONE_TENTH_DEGREE ( 0.999998476913288f ) +#endif /*------------------------------------------------------------------------------------------* * Local functions @@ -157,12 +159,53 @@ void QuaternionSlerp( const float t, IVAS_QUATERNION *const r ) { +#ifdef NONBE_FIX_1067_QUATERNIONSLERP_INACCURACIES + IVAS_QUATERNION r1, r2; + float phi, sinPhi, cosPhi, s1, s2; + + QuaternionNormalize( q1, &r1 ); + QuaternionNormalize( q2, &r2 ); + + cosPhi = QuaternionDotProduct( r1, r2 ); + + if ( cosPhi < 0 ) + { + cosPhi = -cosPhi; + r2.w = -r2.w; + r2.x = -r2.x; + r2.y = -r2.y; + r2.z = -r2.z; + } + + /* Angle less than one degree, use linear interpolation */ + if ( cosPhi >= COS_ONE_TENTH_DEGREE ) + { + r->w = r1.w + t * ( r2.w - r1.w ); + r->x = r1.x + t * ( r2.x - r1.x ); + r->y = r1.y + t * ( r2.y - r1.y ); + r->z = r1.z + t * ( r2.z - r1.z ); + } + else + { + phi = acosf( cosPhi ); + sinPhi = sinf( phi ); + + s1 = sinf( ( 1 - t ) * phi ); + s2 = sinf( t * phi ); + + r->w = ( s1 * r1.w + s2 * r2.w ) / sinPhi; + r->x = ( s1 * r1.x + s2 * r2.x ) / sinPhi; + r->y = ( s1 * r1.y + s2 * r2.y ) / sinPhi; + r->z = ( s1 * r1.z + s2 * r2.z ) / sinPhi; + } +#else float angle, denom, s, s2; s = QuaternionDotProduct( q1, q2 ); if ( fabsf( s ) >= 1.0f ) { + *r = q2; return; } @@ -177,6 +220,7 @@ void QuaternionSlerp( r->z = ( q1.z * s + q2.z * s2 ) / denom; r->w = ( q1.w * s + q2.w * s2 ) / denom; +#endif QuaternionNormalize( *r, r ); return; diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 163797e7b3..0434031c81 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -949,7 +949,7 @@ void ivas_binaural_reverb_processSubframe( ivas_error ivas_reverb_open( REVERB_HANDLE *hReverb, /* i/o: Reverberator handle */ - const HRTFS_STATISTICS_HANDLE hHrtfStatistics, /* i : HRTF statistics handle */ + const HRTFS_STATISTICS_HANDLE hHrtfStatistics, /* i : HRTF statistics handle */ RENDER_CONFIG_DATA *pConfig, /* i : Reverb configuration */ const int32_t output_Fs /* i : output sampling rate */ ); @@ -1393,82 +1393,6 @@ ivas_error ivas_orient_trk_Process( IVAS_QUATERNION *pTrkRot /* o : tracked rotation */ ); -#ifdef SPLIT_REND_WITH_HEAD_ROT - - -/*----------------------------------------------------------------------------------* - * Split binaural renderer prototypes - *----------------------------------------------------------------------------------*/ - -void isar_set_split_rend_ht_setup( - ISAR_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData -); - -void isar_init_split_rend_handles( - SPLIT_REND_WRAPPER *hSplitRendWrapper -); - -ivas_error isar_split_renderer_open( - SPLIT_REND_WRAPPER *hSplitBinRend, - const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, - const int32_t output_Fs, - const int16_t cldfb_in_flag, - const int16_t pcm_out_flag, - const int16_t num_subframes -); - -void isar_split_renderer_close( - SPLIT_REND_WRAPPER *hSplitBinRend -); - -void isar_init_multi_bin_pose_data( - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData -); - -void isar_renderSplitGetMultiBinPoseData( - const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - const ISAR_SPLIT_REND_ROT_AXIS rot_axis -); - -void isar_renderSplitUpdateNoCorrectionPoseData( - const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData -); - -ivas_error isar_renderMultiBinToSplitBinaural( - SPLIT_REND_WRAPPER *hSplitBin, - const IVAS_QUATERNION headPosition, - const int32_t SplitRendBitRate, - ISAR_SPLIT_REND_CODEC splitCodec, - int16_t codec_frame_size_ms, - ISAR_SPLIT_REND_BITS_HANDLE pBits, - float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t max_bands, - float *output[], - const int16_t low_res_pre_rend_rot, - const int16_t cldfb_in_flag, - const int16_t pcm_out_flag, - const int16_t ro_md_flag -); - -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG -void isar_log_cldfb2wav_data( - float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - HANDLE_CLDFB_FILTER_BANK *cldfbSyn, - const int16_t num_chs, - const int16_t num_freq_bands, - const int32_t output_Fs, - const int16_t start_slot_idx, - const int16_t md_band_idx, - const char *filename -); -#endif - -#endif /*----------------------------------------------------------------------------------* * Rendering & merging to MASA format @@ -1584,17 +1508,10 @@ void masaPrerendClose( * Split rendering *----------------------------------------------------------------------------------*/ -/* TODO(sgi): Rework interface */ -ivas_error ObjRenderIvasFrame_splitBinaural( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[], /* i/o: SCE channels / Binaural synthesis */ - const int16_t output_frame /* i : output frame length */ -); - ivas_error ivas_td_binaural_renderer_sf_splitBinaural( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ float *output[], /* i/o: SCE channels / Binaural synthesis */ - int16_t nSamplesRendered /* i : number of samples to render */ + const int16_t nSamplesRendered /* i : number of samples to render */ ); ivas_error ivas_rend_crendProcessSubframesSplitBin( @@ -1618,8 +1535,8 @@ ivas_error ivas_rend_crendProcessSplitBin( const AUDIO_CONFIG inConfig, const AUDIO_CONFIG outConfig, const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - DECODER_CONFIG_HANDLE hDecoderConfig, - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, + const DECODER_CONFIG_HANDLE hDecoderConfig, + const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, const IVAS_OUTPUT_SETUP_HANDLE hIntSetup, EFAP_HANDLE hEFAPdata, float *output[], @@ -1660,15 +1577,6 @@ ivas_error ivas_rend_openCldfbRend( const int32_t output_Fs ); -void ivas_mat_mult_2by2_complex( - float in_re1[2][2], - float in_im1[2][2], - float in_re2[2][2], - float in_im2[2][2], - float out_re2[2][2], - float out_im2[2][2] -); - void ivas_rend_closeCldfbRend( CLDFB_REND_WRAPPER *pCldfbRend ); diff --git a/lib_rend/ivas_render_config.c b/lib_rend/ivas_render_config.c index 8f19a4dce5..5569d6f845 100644 --- a/lib_rend/ivas_render_config.c +++ b/lib_rend/ivas_render_config.c @@ -136,11 +136,12 @@ ivas_error ivas_render_config_init_from_rom( ( *hRenderConfig )->split_rend_config.dof = 3; ( *hRenderConfig )->split_rend_config.hq_mode = 0; ( *hRenderConfig )->split_rend_config.codec_delay_ms = 0; + ( *hRenderConfig )->split_rend_config.isar_frame_size_ms = 20; ( *hRenderConfig )->split_rend_config.codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */ ( *hRenderConfig )->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; ( *hRenderConfig )->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; ( *hRenderConfig )->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_DEFAULT; -#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER +#ifdef SPLIT_REND_EXTEND_ISAR_FILE_HEADER ( *hRenderConfig )->split_rend_config.lc3plus_highres = 0; #endif #endif diff --git a/lib_rend/ivas_reverb.c b/lib_rend/ivas_reverb.c index 1f791df39c..74b3acd382 100644 --- a/lib_rend/ivas_reverb.c +++ b/lib_rend/ivas_reverb.c @@ -105,12 +105,14 @@ typedef struct ivas_reverb_params_t float *pFc; /* Center frequencies for FFT filter design */ float *pRt60; /* RT60 values at these frequencies */ float *pDsr; /* DSR values at these frequencies */ - float *pHrtf_avg_pwr_response_l; /* The HRTF set's average left ear power response */ - float *pHrtf_avg_pwr_response_r; /* The HRTF set's average right ear power response */ - float *pHrtf_inter_aural_coherence; /* The HRTF set's inter-aural coherence for diffuse sound */ - const float *pHrtf_avg_pwr_response_l_const; /* The HRTF set's average left ear power response */ - const float *pHrtf_avg_pwr_response_r_const; /* The HRTF set's average right ear power response */ - const float *pHrtf_inter_aural_coherence_const; /* The HRTF set's inter-aural coherence for diffuse sound */ +#ifndef FIX_1053_REVERB_RECONFIGURATION + float *pHrtf_avg_pwr_response_l; /* The HRTF set's average left ear power response */ + float *pHrtf_avg_pwr_response_r; /* The HRTF set's average right ear power response */ + float *pHrtf_inter_aural_coherence; /* The HRTF set's inter-aural coherence for diffuse sound */ +#endif + const float *pHrtf_avg_pwr_response_l_const; /* The HRTF set's average left ear power response */ + const float *pHrtf_avg_pwr_response_r_const; /* The HRTF set's average right ear power response */ + const float *pHrtf_inter_aural_coherence_const; /* The HRTF set's inter-aural coherence for diffuse sound */ int16_t do_corr_filter; /* Flag indicating whether correlation filters should be used. */ /* Correlation only supported and needed for binaural playback (i.e. */ @@ -977,7 +979,9 @@ static ivas_error setup_FDN_branches( { int16_t nr_coefs, branch_idx, channel_idx; ivas_error error; +#ifndef FIX_1053_REVERB_RECONFIGURATION float *pCoef_a, *pCoef_b; +#endif error = IVAS_ERR_OK; /* initialize feedback branches */ @@ -999,6 +1003,7 @@ static ivas_error setup_FDN_branches( { for ( branch_idx = 0; branch_idx < pParams->nr_loops; branch_idx++ ) { +#ifndef FIX_1053_REVERB_RECONFIGURATION pCoef_a = &pParams->pT60_filter_coeff[2 * nr_coefs * branch_idx + nr_coefs]; pCoef_b = &pParams->pT60_filter_coeff[2 * nr_coefs * branch_idx]; @@ -1006,7 +1011,7 @@ static ivas_error setup_FDN_branches( { return error; } - +#endif if ( ( error = set_feedback_delay( hReverb, branch_idx, pParams->pLoop_delays[branch_idx] ) ) != IVAS_ERR_OK ) { return error; @@ -1031,11 +1036,19 @@ static ivas_error setup_FDN_branches( } +#ifdef FIX_1053_REVERB_RECONFIGURATION +/*------------------------------------------------------------------------- + * ivas_reverb_open() + * + * Allocate and initialize FDN reverberation handle + *------------------------------------------------------------------------*/ +#else /*------------------------------------------------------------------------- * ivas_reverb_open() * * Allocate and initialize Crend reverberation handle *------------------------------------------------------------------------*/ +#endif ivas_error ivas_reverb_open( REVERB_HANDLE *hReverb, /* i/o: Reverberator handle */ @@ -1045,7 +1058,13 @@ ivas_error ivas_reverb_open( ) { ivas_error error; +#ifdef FIX_1053_REVERB_RECONFIGURATION + REVERB_HANDLE pState = *hReverb; + int16_t nr_coefs, branch_idx; + float *pCoef_a, *pCoef_b; +#else REVERB_HANDLE pState = NULL; +#endif int16_t bin_idx, subframe_len, output_frame, predelay_bf_len, loop_idx; ivas_reverb_params_t params; rv_fftwf_type_complex pFft_wf_filter_ch0[RV_LENGTH_NR_FC]; @@ -1063,17 +1082,47 @@ ivas_error ivas_reverb_open( predelay_bf_len = output_frame; nr_fc_input = hRenderConfig->roomAcoustics.nBands; +#ifdef FIX_1053_REVERB_RECONFIGURATION + if ( *hReverb == NULL ) + { + /* Allocate main reverb. handle */ + if ( ( pState = (REVERB_HANDLE) malloc( sizeof( REVERB_DATA ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for FDN Reverberator " ); + } + } +#else /* Allocate main reverb. handle */ if ( ( pState = (REVERB_HANDLE) malloc( sizeof( REVERB_DATA ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend Reverberator " ); } +#endif if ( ( error = set_base_config( ¶ms, output_Fs ) ) != IVAS_ERR_OK ) { return error; } +#ifdef FIX_1053_REVERB_RECONFIGURATION + if ( *hReverb == NULL ) + { + /* Allocate memory for feedback delay lines */ + for ( loop_idx = 0; loop_idx < IVAS_REV_MAX_NR_BRANCHES; loop_idx++ ) + { + if ( ( pState->loop_delay_buffer[loop_idx] = (float *) malloc( params.pLoop_delays[loop_idx] * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for FDN Reverberator" ); + } + } + + /* Allocate memory for the pre-delay delay line */ + if ( ( pState->pPredelay_buffer = (float *) malloc( output_frame * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for FDN Reverberator" ); + } + } +#else /* Allocate memory for feedback delay lines */ for ( loop_idx = 0; loop_idx < IVAS_REV_MAX_NR_BRANCHES; loop_idx++ ) { @@ -1088,20 +1137,26 @@ ivas_error ivas_reverb_open( { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CREND Reverberator" ); } +#endif pState->nr_of_branches = IVAS_REV_MAX_NR_BRANCHES; set_fft_and_datablock_sizes( pState, subframe_len ); + nr_fc_fft_filter = ( pState->fft_size >> 1 ) + 1; /* === 'Control logic': compute the reverb processing parameters from the === */ /* === room, source and listener acoustic information provided in the reverb config === */ /* Setting up shared temporary buffers for fc, RT60, DSR, etc. */ +#ifndef FIX_1053_REVERB_RECONFIGURATION params.pHrtf_avg_pwr_response_l = &pFft_wf_filter_ch0[0][0]; params.pHrtf_avg_pwr_response_r = params.pHrtf_avg_pwr_response_l + nr_fc_fft_filter; +#endif params.pRt60 = &pFft_wf_filter_ch1[0][0]; params.pDsr = params.pRt60 + nr_fc_fft_filter; params.pFc = &pState->fft_filter_color_0.fft_spectrum[0]; +#ifndef FIX_1053_REVERB_RECONFIGURATION params.pHrtf_inter_aural_coherence = &pState->fft_filter_color_1.fft_spectrum[0]; +#endif /* Note: these temp buffers can only be used before the final step of the FFT filter design : */ /* before calls to ivas_reverb_calc_correl_filters(...) or to ivas_reverb_calc_color_filters(...) */ @@ -1132,7 +1187,15 @@ ivas_error ivas_reverb_open( } /* set up input downmix */ +#ifdef FIX_1053_REVERB_RECONFIGURATION + if ( *hReverb == NULL ) + { + pState->dmx_gain = calc_dmx_gain(); + } +#else + /* set up input downmix */ pState->dmx_gain = calc_dmx_gain(); +#endif /* set up predelay - must be after set_base_config() and before compute_t60_coeffs() */ calc_predelay( ¶ms, hRenderConfig->roomAcoustics.acousticPreDelay, output_Fs ); @@ -1156,7 +1219,20 @@ ivas_error ivas_reverb_open( /* Compute the window used for FFT filters */ ivas_reverb_define_window_fft( pTime_window, transition_start, transition_length, nr_fc_fft_filter ); +#ifdef FIX_1053_REVERB_RECONFIGURATION + /* === Copy parameters from ivas_reverb_params_t into DSP blocks === */ + /* === to be used for subsequent audio signal processing === */ + if ( *hReverb == NULL ) + { + pState->do_corr_filter = params.do_corr_filter; + /* clear & init jot reverb fft filters */ + if ( ( error = initialize_reverb_filters( pState ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#else /* === Now, copy parameters from ivas_reverb_params_t into DSP blocks === */ /* === to be used for subsequent audio signal processing === */ @@ -1167,6 +1243,7 @@ ivas_error ivas_reverb_open( { return error; } +#endif if ( pState->do_corr_filter ) { @@ -1199,6 +1276,36 @@ ivas_error ivas_reverb_open( return error; } +#ifdef FIX_1053_REVERB_RECONFIGURATION + if ( *hReverb == NULL ) + { + /* init predelay */ + ivas_rev_delay_line_init( &( pState->predelay_line ), pState->pPredelay_buffer, params.pre_delay, predelay_bf_len ); + + /* set up feedback delay network */ + if ( ( error = setup_FDN_branches( pState, ¶ms ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + pState->predelay_line.Delay = params.pre_delay; + } + + nr_coefs = params.t60_filter_order + 1; + + for ( branch_idx = 0; branch_idx < params.nr_loops; branch_idx++ ) + { + pCoef_a = ¶ms.pT60_filter_coeff[2 * nr_coefs * branch_idx + nr_coefs]; + pCoef_b = ¶ms.pT60_filter_coeff[2 * nr_coefs * branch_idx]; + + if ( ( error = set_t60_filter( pState, branch_idx, nr_coefs, pCoef_a, pCoef_b ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#else /* init predelay */ ivas_rev_delay_line_init( &( pState->predelay_line ), pState->pPredelay_buffer, params.pre_delay, predelay_bf_len ); @@ -1207,6 +1314,7 @@ ivas_error ivas_reverb_open( { return error; } +#endif *hReverb = pState; diff --git a/lib_rend/ivas_rom_rend.h b/lib_rend/ivas_rom_rend.h index e39c438137..9988962dbe 100644 --- a/lib_rend/ivas_rom_rend.h +++ b/lib_rend/ivas_rom_rend.h @@ -137,12 +137,4 @@ extern const float ls_conversion_cicpX_stereo[12][2]; extern const LS_CONVERSION_MAPPING ls_conversion_mapping[]; -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*----------------------------------------------------------------------------------* - * Split binaural rendering ROM tables - *----------------------------------------------------------------------------------*/ - -extern const int32_t split_rend_brate_tbl[]; -#endif - #endif /* IVAS_ROM_REND_H */ diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 6cb761de28..9bbb047ce5 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -40,12 +40,6 @@ #include "stat_com.h" /* Note: Currently needed for CLDFB. */ #include "common_api_types.h" #include "isar_stat.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include "stat_com.h" -#include "isar_lcld_prot.h" -#include "isar_lc3plus_enc.h" -#include "isar_lc3plus_dec.h" -#endif /*----------------------------------------------------------------------------------* @@ -486,7 +480,9 @@ typedef struct ivas_binaural_reverb_struct uint32_t binRend_RandNext; int16_t highestBinauralCoherenceBin; +#ifndef FIX_1053_REVERB_RECONFIGURATION float dmxmtx[BINAURAL_CHANNELS][MAX_OUTPUT_CHANNELS]; +#endif float foa_enc[MAX_OUTPUT_CHANNELS][FOA_CHANNELS]; } REVERB_STRUCT, *REVERB_STRUCT_HANDLE; @@ -644,6 +640,33 @@ typedef struct EFAP * Head rotation data structure *----------------------------------------------------------------------------------*/ +typedef struct ivas_orient_trk_state_t +{ + IVAS_HEAD_ORIENT_TRK_T orientation_tracking; + float centerAdaptationRate; + float offCenterAdaptationRate; + float adaptationAngle; + + float alpha; + IVAS_QUATERNION absAvgRot; /* average absolute orientation */ + IVAS_QUATERNION refRot; /* reference orientation */ + IVAS_QUATERNION trkRot; /* tracked rotation */ + +} ivas_orient_trk_state_t; + +typedef struct +{ + int8_t headRotEnabled; + IVAS_QUATERNION headPositions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + IVAS_VECTOR3 Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + float crossfade[L_FRAME48k / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; +#endif + ivas_orient_trk_state_t *hOrientationTracker; + +} IVAS_REND_HeadRotData; + typedef struct ivas_binaural_head_track_struct { IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES]; @@ -667,6 +690,46 @@ typedef struct ivas_binaural_head_track_struct } HEAD_TRACK_DATA, *HEAD_TRACK_DATA_HANDLE; +typedef struct ivas_combined_orientation_struct +{ + int16_t enableCombinedOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; + float interpolationCoefficient; + float interpolationIncrement; + int16_t maximumFramesToTargetOrientation; + uint8_t lrSwitchedNext; + uint8_t lrSwitchedCurrent; + float lrSwitchInterpVal; + bool isInterpolationOngoing; + IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES]; + IVAS_QUATERNION Quaternion_prev_extOrientation; + IVAS_QUATERNION Quaternions_ext_interpolation_start; + IVAS_QUATERNION Quaternions_ext_interpolation_target; + float Rmat[MAX_PARAM_SPATIAL_SUBFRAMES][3][3]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + float Rmat_prev[MAX_HEAD_ROT_POSES][3][3]; +#else + float Rmat_prev[3][3]; +#endif + float chEneIIR[2][MASA_FREQUENCY_BANDS]; /* independent of the format. MASA bands are suitable for the task and readily available in ROM. */ + float procChEneIIR[2][MASA_FREQUENCY_BANDS]; + int16_t shd_rot_max_order; + IVAS_VECTOR3 listenerPos[MAX_PARAM_SPATIAL_SUBFRAMES]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; + int16_t sr_low_res_flag; +#endif + IVAS_QUATERNION Quaternion_frozen_ext; + IVAS_QUATERNION Quaternion_frozen_head; + int8_t isExtOrientationFrozen; + int8_t isHeadRotationFrozen; + int16_t num_subframes; + int16_t subframe_idx; + int16_t subframe_size; + int16_t cur_subframe_samples_rendered; + int16_t subframe_idx_start; + int16_t cur_subframe_samples_rendered_start; +} COMBINED_ORIENTATION_DATA, *COMBINED_ORIENTATION_HANDLE; + /*----------------------------------------------------------------------------------* * External orientation data structure *----------------------------------------------------------------------------------*/ @@ -765,7 +828,6 @@ typedef struct ivas_reverb_state_t uint16_t fft_subblock_size; /* fft block processing size */ uint16_t num_fft_subblocks; /* number of fft subblocks */ uint16_t full_block_size; /* full block processing size */ - } REVERB_DATA, *REVERB_HANDLE; @@ -1374,10 +1436,7 @@ typedef struct { float Cldfb_Prev_BinReal[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX]; float Cldfb_Prev_BinImag[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX]; -#if CLDFB_PLC_XF > 0 float xf_bet[2][CLDFB_NO_CHANNELS_MAX][CLDFB_PLC_XF]; -#endif - } CLDFB_PLC, *CLDFB_PLC_HANDLE; typedef struct diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index bab7b06a23..1b03f9d1bd 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -37,6 +37,7 @@ #include "ivas_prot_rend.h" #include "isar_prot.h" #include "isar_stat.h" +#include "lib_isar_pre_rend.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_rend.h" @@ -50,30 +51,10 @@ * Local constants *-------------------------------------------------------------------*/ -/* Maximum buffer length (per channel) in samples. - * Keep this separate from L_FRAME48k in case we want to support different size later */ -#define MAX_BUFFER_LENGTH_PER_CHANNEL ( L_FRAME48k ) -#ifdef SPLIT_REND_WITH_HEAD_ROT -#define MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL ( MAX_BUFFER_LENGTH_PER_CHANNEL * 2 ) -#endif - /* Maximum buffer length (total) in samples. */ -/* Maximum buffer length (total) in samples. */ -#ifdef SPLIT_REND_WITH_HEAD_ROT -#define MAX_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) -#define MAX_CLDFB_BUFFER_LENGTH ( MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) -#define MAX_BIN_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * BINAURAL_CHANNELS ) -#define MAX_CLDFB_BIN_BUFFER_LENGTH ( MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL * BINAURAL_CHANNELS ) -#else -#define MAX_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) -#endif - +#define MAX_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) #define MAX_BIN_DELAY_SAMPLES 150 /* Maximum supported rendering latency for binaural IRs */ -/* Frame size required when rendering to binaural */ -#define BINAURAL_RENDERING_FRAME_SIZE_MS 5 - - /*-------------------------------------------------------------------* * Local types *-------------------------------------------------------------------*/ @@ -3547,6 +3528,66 @@ static int16_t getCldfbRendFlag( return isCldfbRend; } +/*------------------------------------------------------------------------- + * Function ivas_pre_rend_init() + * + * + *------------------------------------------------------------------------*/ + +static ivas_error ivas_pre_rend_init( + SPLIT_REND_WRAPPER *pSplitRendWrapper, + IVAS_REND_AudioBuffer *pSplitRendEncBuffer, + ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, + IVAS_REND_HeadRotData headRotData, + const int32_t outputSampleRate, + const AUDIO_CONFIG outConfig, + const int16_t cldfb_in_flag, + const int16_t num_subframes ) +{ + ivas_error error; + IVAS_REND_AudioBufferConfig bufConfig; + + if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( pSplit_rend_config->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + ISAR_PRE_REND_GetMultiBinPoseData( pSplit_rend_config, &pSplitRendWrapper->multiBinPoseData, headRotData.sr_pose_pred_axis ); + } + else if ( pSplit_rend_config->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) + { + isar_renderSplitUpdateNoCorrectionPoseData( pSplit_rend_config, &pSplitRendWrapper->multiBinPoseData ); + } + + if ( ( error = ISAR_PRE_REND_open( pSplitRendWrapper, pSplit_rend_config, outputSampleRate, cldfb_in_flag, outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, num_subframes, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + /*allocate for CLDFB in and change to TD during process if needed*/ + bufConfig.numSamplesPerChannel = MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL; + bufConfig.numChannels = BINAURAL_CHANNELS * pSplitRendWrapper->multiBinPoseData.num_poses; + bufConfig.is_cldfb = 1; + pSplitRendEncBuffer->config = bufConfig; + + if ( ( pSplitRendEncBuffer->data = malloc( bufConfig.numChannels * bufConfig.numSamplesPerChannel * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + } + else + { + IVAS_REND_AudioBufferConfig bufConfig2; + + bufConfig2.numSamplesPerChannel = 0; + bufConfig2.numChannels = 0; + bufConfig2.is_cldfb = 0; + pSplitRendEncBuffer->config = bufConfig2; + pSplitRendEncBuffer->data = NULL; + } + + return IVAS_ERR_OK; +} + #endif @@ -3581,12 +3622,7 @@ ivas_error IVAS_REND_AddInput( int16_t cldfb_in_flag; cldfb_in_flag = getCldfbRendFlag( hIvasRend, getAudioConfigType( inConfig ) ); - if ( ( error = isar_split_rend_choose_default_codec( &hIvasRend->hRendererConfig->split_rend_config.codec, &hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( ( error = initSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_pre_rend_init( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) { return error; } @@ -4342,11 +4378,12 @@ int16_t IVAS_REND_GetRenderConfig( hRCout->split_rend_config.dof = 3; hRCout->split_rend_config.hq_mode = 0; hRCout->split_rend_config.codec_delay_ms = 0; + hRCout->split_rend_config.isar_frame_size_ms = 20; hRCout->split_rend_config.codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */ hRCout->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; hRCout->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; hRCout->split_rend_config.rendererSelection = hRCin->split_rend_config.rendererSelection; -#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER +#ifdef SPLIT_REND_EXTEND_ISAR_FILE_HEADER hRCout->split_rend_config.lc3plus_highres = 0; #endif #endif @@ -4370,8 +4407,17 @@ int16_t IVAS_REND_FeedRenderConfig( ) { RENDER_CONFIG_HANDLE hRenderConfig; +#ifdef FIX_1053_REVERB_RECONFIGURATION + uint16_t i; + input_ism *pIsmInput; + input_masa *pMasaInput; + input_mc *pMcInput; + input_sba *pSbaInput; + ivas_error error; +#else #ifdef SPLIT_REND_WITH_HEAD_ROT ivas_error error; +#endif #endif if ( hIvasRend == NULL || hIvasRend->hRendererConfig == NULL ) @@ -4403,6 +4449,141 @@ int16_t IVAS_REND_FeedRenderConfig( mvr2r( renderConfig.roomAcoustics.AbsCoeff, hRenderConfig->roomAcoustics.AbsCoeff, IVAS_ROOM_ABS_COEFF ); } +#ifdef FIX_1053_REVERB_RECONFIGURATION + /* Re-initialize reverb instance if already available */ + /* ISM inputs */ + for ( i = 0, pIsmInput = hIvasRend->inputsIsm; i < RENDERER_MAX_ISM_INPUTS; ++i, ++pIsmInput ) + { + if ( pIsmInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + /* Skip inactive inputs */ + continue; + } + if ( pIsmInput->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &pIsmInput->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pIsmInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } + if ( pIsmInput->crendWrapper != NULL && pIsmInput->crendWrapper->hCrend[0] != NULL ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_reverb_open( &pIsmInput->crendWrapper->hCrend[0]->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pIsmInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_reverb_open( &pIsmInput->crendWrapper->hCrend->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pIsmInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } + } + } + + /* MASA inputs */ + for ( i = 0, pMasaInput = hIvasRend->inputsMasa; i < RENDERER_MAX_MASA_INPUTS; ++i, ++pMasaInput ) + { + if ( pMasaInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + /* Skip inactive inputs */ + continue; + } + + if ( pMasaInput->hMasaExtRend != NULL ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( pMasaInput->hMasaExtRend->hDiracDecBin[0] != NULL && pMasaInput->hMasaExtRend->hDiracDecBin[0]->hReverb != NULL ) + { + ivas_binaural_reverb_close( &pMasaInput->hMasaExtRend->hDiracDecBin[0]->hReverb ); + if ( ( error = ivas_binaural_reverb_init( &pMasaInput->hMasaExtRend->hDiracDecBin[0]->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, pMasaInput->hMasaExtRend->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &( hRenderConfig->roomAcoustics ), *pMasaInput->base.ctx.pOutSampleRate, NULL, NULL ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#else + if ( pMasaInput->hMasaExtRend->hDiracDecBin != NULL && pMasaInput->hMasaExtRend->hDiracDecBin->hReverb != NULL ) + { + ivas_binaural_reverb_close( &pMasaInput->hMasaExtRend->hDiracDecBin->hReverb ); + if ( ( error = ivas_binaural_reverb_init( &pMasaInput->hMasaExtRend->hDiracDecBin->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, pMasaInput->hMasaExtRend->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &( hRenderConfig->roomAcoustics ), *pMasaInput->base.ctx.pOutSampleRate, NULL, NULL ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif + if ( pMasaInput->hMasaExtRend->hReverb != NULL ) + { + ivas_binaural_reverb_close( &pMasaInput->hMasaExtRend->hReverb ); + if ( ( error = ivas_binaural_reverb_init( &pMasaInput->hMasaExtRend->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, pMasaInput->hMasaExtRend->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &( hRenderConfig->roomAcoustics ), *pMasaInput->base.ctx.pOutSampleRate, NULL, NULL ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + } + + /* Multi-channel inputs */ + for ( i = 0, pMcInput = hIvasRend->inputsMc; i < RENDERER_MAX_MC_INPUTS; ++i, ++pMcInput ) + { + if ( pMcInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + /* Skip inactive inputs */ + continue; + } + + if ( pMcInput->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &pMcInput->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pMcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( pMcInput->crendWrapper != NULL && pMcInput->crendWrapper->hCrend[0] && pMcInput->crendWrapper->hCrend[0]->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &pMcInput->crendWrapper->hCrend[0]->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pMcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#else + if ( pMcInput->crendWrapper != NULL && pMcInput->crendWrapper->hCrend && pMcInput->crendWrapper->hCrend->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &pMcInput->crendWrapper->hCrend->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pMcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif + } + + /* SBA inputs */ + for ( i = 0, pSbaInput = hIvasRend->inputsSba; i < RENDERER_MAX_SBA_INPUTS; ++i, ++pSbaInput ) + { + if ( pSbaInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + /* Skip inactive inputs */ + continue; + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( pSbaInput->crendWrapper != NULL && pSbaInput->crendWrapper->hCrend[0] != NULL && pSbaInput->crendWrapper->hCrend[0]->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &pSbaInput->crendWrapper->hCrend[0]->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pSbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#else + if ( pSbaInput->crendWrapper != NULL && pSbaInput->crendWrapper->hCrend != NULL && pSbaInput->crendWrapper->hCrend->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &pSbaInput->crendWrapper->hCrend->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pSbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif + } +#endif + #ifdef SPLIT_REND_WITH_HEAD_ROT hRenderConfig->split_rend_config = renderConfig.split_rend_config; /* Overwrite any pose correction settings if 0 DOF (no pose correction) was selected */ @@ -4424,14 +4605,9 @@ int16_t IVAS_REND_FeedRenderConfig( { int16_t cldfb_in_flag; cldfb_in_flag = getCldfbRendFlag( hIvasRend, IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN ); - closeSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer ); + ISAR_PRE_REND_close( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer ); - if ( ( error = isar_split_rend_choose_default_codec( &hIvasRend->hRendererConfig->split_rend_config.codec, &hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( ( error = initSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_pre_rend_init( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) { return error; } @@ -7492,7 +7668,7 @@ ivas_error IVAS_REND_SetIsmMetadataDelay( static ivas_error getSamplesInternal( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ #ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */, + IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */ IVAS_REND_BitstreamBuffer *hBits /*i/o: buffer for input/output bitstream. Needed in split rendering mode*/ #else IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ @@ -7599,7 +7775,7 @@ static ivas_error getSamplesInternal( int16_t num_poses_orig; num_poses_orig = hIvasRend->splitRendWrapper.multiBinPoseData.num_poses; outAudio = hIvasRend->splitRendEncBuffer; - isar_renderSplitGetMultiBinPoseData( &hIvasRend->hRendererConfig->split_rend_config, &hIvasRend->splitRendWrapper.multiBinPoseData, hIvasRend->headRotData.sr_pose_pred_axis ); + ISAR_PRE_REND_GetMultiBinPoseData( &hIvasRend->hRendererConfig->split_rend_config, &hIvasRend->splitRendWrapper.multiBinPoseData, hIvasRend->headRotData.sr_pose_pred_axis ); assert( num_poses_orig == hIvasRend->splitRendWrapper.multiBinPoseData.num_poses && "number of poses should not change dynamically" ); /* Clear output buffer for split rendering bitstream */ @@ -7675,8 +7851,23 @@ static ivas_error getSamplesInternal( } } - if ( ( error = isar_renderMultiBinToSplitBinaural( &hIvasRend->splitRendWrapper, hIvasRend->headRotData.headPositions[0], hIvasRend->hRendererConfig->split_rend_config.splitRendBitRate, hIvasRend->hRendererConfig->split_rend_config.codec, hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, - &bits, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, ( const int16_t )( ( BINAURAL_MAXBANDS * hIvasRend->sampleRateOut ) / 48000 ), tmpBinaural, 1, cldfb_in_flag, ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0, ro_md_flag ) ) != IVAS_ERR_OK ) + if ( ( error = ISAR_PRE_REND_MultiBinToSplitBinaural( &hIvasRend->splitRendWrapper, + hIvasRend->headRotData.headPositions[0], + hIvasRend->hRendererConfig->split_rend_config.splitRendBitRate, + hIvasRend->hRendererConfig->split_rend_config.codec, +#ifdef SPLIT_REND_EXTEND_ISAR_FILE_HEADER + hIvasRend->hRendererConfig->split_rend_config.isar_frame_size_ms, +#endif + hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, + &bits, + Cldfb_RealBuffer_Binaural, + Cldfb_ImagBuffer_Binaural, + ( const int16_t )( ( BINAURAL_MAXBANDS * hIvasRend->sampleRateOut ) / 48000 ), + tmpBinaural, + 1, + cldfb_in_flag, + ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0, + ro_md_flag ) ) != IVAS_ERR_OK ) { return error; } @@ -7768,6 +7959,7 @@ ivas_error IVAS_REND_GetSplitRendBitstreamHeader( IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ ISAR_SPLIT_REND_CODEC *pCodec, /* o: pointer to codec setting */ ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o: pointer to pose correction mode */ + int16_t *pIsar_frame_size_ms, /* o: pointer to isar frame size setting */ int16_t *pCodec_frame_size_ms /* o: pointer to codec frame size setting */ ) { @@ -7777,6 +7969,7 @@ ivas_error IVAS_REND_GetSplitRendBitstreamHeader( } *pCodec = hIvasRend->hRendererConfig->split_rend_config.codec; *pCodec_frame_size_ms = hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms; + *pIsar_frame_size_ms = hIvasRend->hRendererConfig->split_rend_config.isar_frame_size_ms; *poseCorrection = hIvasRend->hRendererConfig->split_rend_config.poseCorrectionMode; return IVAS_ERR_OK; } @@ -7826,12 +8019,6 @@ void IVAS_REND_Close( { clearInputMasa( &hIvasRend->inputsMasa[i] ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT - // for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) - // { - // clearInputSplitRend( &hIvasRend->inputsSplitPost[i] ); - // } -#endif /* clear Config. Renderer */ ivas_render_config_close( &( hIvasRend->hRendererConfig ) ); @@ -7840,7 +8027,7 @@ void IVAS_REND_Close( #ifdef SPLIT_REND_WITH_HEAD_ROT /* Split binaural rendering */ - closeSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer ); + ISAR_PRE_REND_close( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer ); #endif closeHeadRotation( hIvasRend ); diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index 873cfff935..4acb8cc799 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -46,10 +46,6 @@ #define RENDERER_MAX_SBA_INPUTS 1 #define RENDERER_MAX_MASA_INPUTS 1 #define RENDERER_MAX_INPUT_LFE_CHANNELS 4 -#ifdef SPLIT_REND_WITH_HEAD_ROT -#define RENDERER_MAX_BIN_INPUTS 1 -#endif - /*---------------------------------------------------------------------* * Renderer structures @@ -66,7 +62,8 @@ typedef struct ISAR_SPLIT_REND_CODEC codec; ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection; int16_t codec_frame_size_ms; -#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + int16_t isar_frame_size_ms; +#ifdef SPLIT_REND_EXTEND_ISAR_FILE_HEADER int16_t lc3plus_highres; #endif } IVAS_REND_BitstreamBufferConfig; @@ -278,7 +275,8 @@ ivas_error IVAS_REND_GetSplitRendBitstreamHeader( IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ ISAR_SPLIT_REND_CODEC *pCodec, /* o: pointer to codec setting */ ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o: pointer to pose correction mode */ - int16_t *pCodec_frame_size_ms /* o: pointer to codec frame size setting */ + int16_t *pIsar_frame_size_ms, /* o: pointer to isar frame size setting */ + int16_t *pCodec_frame_size_ms /* o: pointer to codec frame size setting */ ); #endif diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 0478e08223..da439ec841 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -2241,11 +2241,7 @@ ivas_error RenderConfigReader_read( return IVAS_ERR_INVALID_RENDER_CONFIG; } idx = strtol( strtok( NULL, ":" ), NULL, 0 ); -#ifdef FIX_1020_AEID_SELECTION_ERRORS pRenderConfigReader->pAE[acIdx].id = idx; -#else - pRenderConfigReader->pAE->id = idx; -#endif aeHasFgIdx = aeHasPredelay = aeHasRt60 = aeHasDsr = FALSE; aeHasERsize = aeHasERabs = FALSE; @@ -2565,7 +2561,7 @@ ivas_error RenderConfigReader_read( errorHandler( pValue, ERROR_VALUE_INVALID ); } } -#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER +#ifdef SPLIT_REND_EXTEND_ISAR_FILE_HEADER else if ( strcmp( item, "LC3PLUS_HIGHRES" ) == 0 ) { if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.lc3plus_highres ) ) @@ -2834,6 +2830,12 @@ ivas_error RenderConfigReader_getAcousticEnvironment( pAcEnv->AbsCoeff[j] = pRenderConfigReader->pAE[n].pEarlyReflections->pAbsCoeff[j]; } } +#ifdef FIX_1053_REVERB_RECONFIGURATION + else + { + pAcEnv->use_er = false; + } +#endif return IVAS_ERR_OK; } } diff --git a/lib_util/split_rend_bfi_file_reader.c b/lib_util/split_rend_bfi_file_reader.c index 0f16e25984..9ca1000770 100644 --- a/lib_util/split_rend_bfi_file_reader.c +++ b/lib_util/split_rend_bfi_file_reader.c @@ -32,10 +32,8 @@ #include #include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT #include "split_rend_bfi_file_reader.h" -#include -#include +#ifdef SPLIT_REND_WITH_HEAD_ROT #include #include "prot.h" diff --git a/lib_util/split_render_file_read_write.c b/lib_util/split_render_file_read_write.c index 3dc75fe53d..681cdeb113 100644 --- a/lib_util/split_render_file_read_write.c +++ b/lib_util/split_render_file_read_write.c @@ -32,15 +32,10 @@ #include #include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT #include "split_render_file_read_write.h" -#include +#ifdef SPLIT_REND_WITH_HEAD_ROT #include -#include -#include -#include "cmdl_tools.h" #include "prot.h" -#include "ivas_cnst.h" /*------------------------------------------------------------------------------------------* @@ -71,8 +66,9 @@ ivas_error split_rend_reader_open( char *filename, ISAR_SPLIT_REND_CODEC *codec, ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, - int16_t *codec_frame_size_ms -#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + int16_t *codec_frame_size_ms, + int16_t *isar_frame_size_ms +#ifdef SPLIT_REND_EXTEND_ISAR_FILE_HEADER , int32_t *sampling_rate, int16_t *lc3plus_highres @@ -124,12 +120,17 @@ ivas_error split_rend_reader_open( { return IVAS_ERR_FAILED_FILE_READ; } - /* read frame size signalling */ + /* read codec frame size signalling */ if ( fread( codec_frame_size_ms, sizeof( *codec_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) { return IVAS_ERR_FAILED_FILE_READ; } -#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + /* read isar bitstream frame size signalling */ + if ( fread( isar_frame_size_ms, sizeof( *isar_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } +#ifdef SPLIT_REND_EXTEND_ISAR_FILE_HEADER /* read sampling rate signalling */ if ( fread( sampling_rate, sizeof( *sampling_rate ), 1, hSplitRendFileReadWrite->file ) != 1 ) { @@ -162,8 +163,9 @@ ivas_error split_rend_writer_open( ISAR_SPLIT_REND_CODEC codec, ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, int16_t codec_frame_size_ms -#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER +#ifdef SPLIT_REND_EXTEND_ISAR_FILE_HEADER , + int16_t isar_frame_size_ms, int32_t sampling_rate, int16_t lc3plus_highres #endif @@ -213,12 +215,17 @@ ivas_error split_rend_writer_open( { return IVAS_ERR_FAILED_FILE_WRITE; } - /* Write frame size signalling */ + /* Write codec frame size signalling */ if ( fwrite( &codec_frame_size_ms, sizeof( codec_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) { return IVAS_ERR_FAILED_FILE_WRITE; } -#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER +#ifdef SPLIT_REND_EXTEND_ISAR_FILE_HEADER + /* Write isar bit stream frame size signalling */ + if ( fwrite( &isar_frame_size_ms, sizeof( isar_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } /* Write sampling rate signalling */ if ( fwrite( &sampling_rate, sizeof( sampling_rate ), 1, hSplitRendFileReadWrite->file ) != 1 ) { @@ -243,7 +250,7 @@ ivas_error split_rend_writer_open( * *-----------------------------------------------------------------------------------------*/ -ivas_error split_rend_reader_writer_close( +void split_rend_reader_writer_close( SplitFileReadWrite **hhSplitRendFileReadWrite ) { if ( ( *hhSplitRendFileReadWrite ) != NULL ) @@ -258,7 +265,7 @@ ivas_error split_rend_reader_writer_close( *hhSplitRendFileReadWrite = NULL; } - return IVAS_ERR_OK; + return; } diff --git a/lib_util/split_render_file_read_write.h b/lib_util/split_render_file_read_write.h index ec22cc9a7f..270e30fe79 100644 --- a/lib_util/split_render_file_read_write.h +++ b/lib_util/split_render_file_read_write.h @@ -44,8 +44,9 @@ ivas_error split_rend_reader_open( char *filename, ISAR_SPLIT_REND_CODEC *codec, ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, - int16_t *codec_frame_size_ms -#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER + int16_t *codec_frame_size_ms, + int16_t *isar_frame_size_ms +#ifdef SPLIT_REND_EXTEND_ISAR_FILE_HEADER , int32_t *sampling_rate, int16_t *lc3plus_highres @@ -62,8 +63,9 @@ ivas_error split_rend_writer_open( ISAR_SPLIT_REND_CODEC codec, ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, int16_t codec_frame_size_ms -#ifdef SPLIT_REND_EXTEND_BITSTREAM_HEADER +#ifdef SPLIT_REND_EXTEND_ISAR_FILE_HEADER , + int16_t isar_frame_size_ms, int32_t sampling_rate, int16_t lc3plus_highres #endif @@ -71,7 +73,7 @@ ivas_error split_rend_writer_open( /* Closes the split renderer reader/writer and deallocates memory */ -ivas_error split_rend_reader_writer_close( +void split_rend_reader_writer_close( SplitFileReadWrite **hhSplitRendFileReadWrite ); /*write split rend coded bitstream to file */ diff --git a/readme.txt b/readme.txt index 25275a7951..415ae41cc9 100644 --- a/readme.txt +++ b/readme.txt @@ -314,7 +314,11 @@ Options: -exof File : External orientation trajectory File for simulation of external orientations -dpid ID : Directivity pattern ID(s) (space-separated list of up to 4 numbers can be specified) for binaural output configuration --aeid ID : Acoustic environment ID (number >= 0) for BINAURAL_ROOM_REVERB output config. +-aeid ID : Acoustic environment ID (number > 0) or + a sequence thereof in the format [ID1:duration1,ID2:duration2...] + without braces and spaces, with ':' character separating ID from duration and ',' separating + ID and duration pairs, where duration is specified in frames + for BINAURAL_ROOM_REVERB output configuration. -lp Position : Output LFE position. Comma-delimited triplet of [gain, azimuth, elevation] where gain is linear (like --gain, -g) and azimuth, elevation are in degrees. If specified, overrides the default behavior which attempts to map input to output LFE channel(s) diff --git a/readme_split_rendering.txt b/readme_split_rendering.txt index 60db2cc5a6..259e975de0 100644 --- a/readme_split_rendering.txt +++ b/readme_split_rendering.txt @@ -36,8 +36,9 @@ This readme_split_rendering.txt describes a usage of the binaural split rendering feature in the IVAS codec. This feature is implemented as part of the following two separate programs: - IVAS_dec Decoder - IVAS_rend Renderer + IVAS_dec Decoder + IVAS_rend Renderer + ISAR_post_rend ISAR_post_renderer @@ -57,6 +58,7 @@ Same as described in Readme.txt while the structure looks as follows: |-- lib_enc |-- lib_lc3plus |-- lib_rend + |-- lib_isar |-- lib_util |-- readme.txt |-- readme_split_rendering.txt @@ -99,10 +101,21 @@ Usage: IVAS_rend [options] Additional options: ------------------- -om File : Coded metadata File for BINAURAL_SPLIT_PCM output mode --im File : Coded metadata File for BINAURAL_SPLIT_PCM input mode --prbfi File : Split rendering option: bfi File +The usage of the "ISAR_post_rend" program: +------------------------------------- + +Usage: ISAR_post_rend [options] + +Options: +-------- +-i File : Input File (input file is bitstream if format is BINAURAL_SPLIT_CODED, PCM or WAV file if format is BINAURAL_SPLIT_PCM) +-if Format : Audio Format of input (BINAURAL_SPLIT_CODED, BINAURAL_SPLIT_PCM) +-im File : Coded metadata File for BINAURAL_SPLIT_PCM input mode +-o File : Output audio File (BINAURAL always) +-fs : Input sampling rate in kHz (48) +-prbfi File : Split rendering option: bfi File RUNNING THE SELF TEST diff --git a/scripts/batch_comp_audio.py b/scripts/batch_comp_audio.py index 6854f41f30..ce1f380c56 100755 --- a/scripts/batch_comp_audio.py +++ b/scripts/batch_comp_audio.py @@ -33,7 +33,6 @@ import argparse import concurrent.futures import os -import pathlib import re import shutil import subprocess @@ -132,7 +131,7 @@ def main(args): if num_files_diff > 0: print(f"{num_files_diff} files differ/don't exist") else: - print(f"All files are bitexact") + print("All files are bitexact") def compare_files(f, fol1, fol2, outputs_dict, tool): diff --git a/scripts/config/ivas_modes.json b/scripts/config/ivas_modes.json index 86994010aa..42b4d2b6a4 100644 --- a/scripts/config/ivas_modes.json +++ b/scripts/config/ivas_modes.json @@ -4958,7 +4958,16 @@ ], "dec": { "7_1_4": [], + "7_1": [], + "5_1_4": [], + "5_1_2": [], + "5_1": [], + "BINAURAL": [], + "BINAURAL_ROOM_IR": [], + "BINAURAL_ROOM_REVERB": [], "HOA3": [], + "HOA2": [], + "FOA": [], "mono": [], "stereo": [], "EXT": [] @@ -5033,7 +5042,16 @@ ], "dec": { "7_1_4": [], + "7_1": [], + "5_1_4": [], + "5_1_2": [], + "5_1": [], + "BINAURAL": [], + "BINAURAL_ROOM_IR": [], + "BINAURAL_ROOM_REVERB": [], "HOA3": [], + "HOA2": [], + "FOA": [], "mono": [], "stereo": [], "EXT": [] @@ -5072,7 +5090,16 @@ ], "dec": { "7_1_4": [], + "7_1": [], + "5_1_4": [], + "5_1_2": [], + "5_1": [], + "BINAURAL": [], + "BINAURAL_ROOM_IR": [], + "BINAURAL_ROOM_REVERB": [], "HOA3": [], + "HOA2": [], + "FOA": [], "mono": [], "stereo": [], "EXT": [] @@ -5089,26 +5116,100 @@ "mono": false, "bitrates": { "wb": [ + 13200, 16400, + 24400, + 32000, 48000, + 64000, + 80000, 96000, - 256000 + 128000, + 192000, + 256000, + 384000, + 512000 ], "swb": [ + 13200, + 16400, 24400, + 32000, + 48000, 64000, + 80000, + 96000, 128000, - 384000 + 192000, + 256000, + 384000, + 512000 ], "fb": [ 13200, + 16400, + 24400, 32000, + 48000, + 64000, 80000, + 96000, + 128000, 192000, + 256000, + 384000, 512000 ] } }, + "OMASA_ISM1_1TC_b{bitrate}_{bandwidth}_rs": { + "encmodeoption": [ + "-ism_masa", + "1", + "1" + ], + "encoptions": [ + "-max_band", + "{bandwidth}" + ], + "dec": { + "7_1_4": [], + "7_1": [], + "5_1_4": [], + "5_1_2": [], + "5_1": [], + "BINAURAL": [], + "BINAURAL_ROOM_IR": [], + "BINAURAL_ROOM_REVERB": [], + "HOA3": [], + "HOA2": [], + "FOA": [], + "mono": [], + "stereo": [], + "EXT": [] + }, + "in_config": "OMASA_ISM1_1TC", + "table_name": "OMASA ISM1 1TC @{table_bitrate} RS {bandwidth}", + "nummetadata": 2, + "metadatafilenames": [ + "{item}_ISM{mdi}.csv", + "{item}.met" + ], + "rs": true, + "amr": false, + "mono": false, + "bitrates": { + "wb": { + "all": "{sw_files_path}/sw_13k2_512k.bin" + }, + "swb": { + "all": "{sw_files_path}/sw_13k2_512k.bin" + }, + "fb": { + "all": "{sw_files_path}/sw_13k2_512k.bin" + } + } + }, "OMASA_ISM2_2TC_b{bitrate}_{bandwidth}_cbr": { "encmodeoption": [ "-ism_masa", @@ -5121,9 +5222,19 @@ ], "dec": { "7_1_4": [], + "7_1": [], + "5_1_4": [], + "5_1_2": [], + "5_1": [], + "BINAURAL": [], + "BINAURAL_ROOM_IR": [], + "BINAURAL_ROOM_REVERB": [], "HOA3": [], + "HOA2": [], + "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "OMASA_ISM2_2TC", "table_name": "OMASA ISM2 2TC @{table_bitrate} kbps {bandwidth}", @@ -5195,9 +5306,19 @@ ], "dec": { "7_1_4": [], + "7_1": [], + "5_1_4": [], + "5_1_2": [], + "5_1": [], + "BINAURAL": [], + "BINAURAL_ROOM_IR": [], + "BINAURAL_ROOM_REVERB": [], "HOA3": [], + "HOA2": [], + "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "OMASA_ISM2_2TC", "table_name": "OMASA ISM2 2TC @{table_bitrate} RS {bandwidth}", @@ -5233,9 +5354,19 @@ ], "dec": { "7_1_4": [], + "7_1": [], + "5_1_4": [], + "5_1_2": [], + "5_1": [], + "BINAURAL": [], + "BINAURAL_ROOM_IR": [], + "BINAURAL_ROOM_REVERB": [], "HOA3": [], + "HOA2": [], + "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "OMASA_ISM2_1TC", "table_name": "OMASA ISM2 1TC @{table_bitrate} kbps {bandwidth}", @@ -5249,27 +5380,100 @@ "mono": false, "bitrates": { "wb": [ + 13200, 16400, + 24400, + 32000, 48000, + 64000, + 80000, 96000, - 160000, - 256000 + 128000, + 192000, + 256000, + 384000, + 512000 ], "swb": [ + 13200, + 16400, 24400, + 32000, + 48000, 64000, + 80000, + 96000, 128000, - 384000 + 192000, + 256000, + 384000, + 512000 ], "fb": [ 13200, + 16400, + 24400, 32000, + 48000, + 64000, 80000, + 96000, + 128000, 192000, + 256000, + 384000, 512000 ] } }, + "OMASA_ISM2_1TC_b{bitrate}_{bandwidth}_rs": { + "encmodeoption": [ + "-ism_masa", + "2", + "1" + ], + "encoptions": [ + "-max_band", + "{bandwidth}" + ], + "dec": { + "7_1_4": [], + "7_1": [], + "5_1_4": [], + "5_1_2": [], + "5_1": [], + "BINAURAL": [], + "BINAURAL_ROOM_IR": [], + "BINAURAL_ROOM_REVERB": [], + "HOA3": [], + "HOA2": [], + "FOA": [], + "mono": [], + "stereo": [], + "EXT": [] + }, + "in_config": "OMASA_ISM2_1TC", + "table_name": "OMASA ISM2 1TC @{table_bitrate} RS {bandwidth}", + "nummetadata": 3, + "metadatafilenames": [ + "{item}_ISM{mdi}.csv", + "{item}.met" + ], + "rs": true, + "amr": false, + "mono": false, + "bitrates": { + "wb": { + "all": "{sw_files_path}/sw_13k2_512k.bin" + }, + "swb": { + "all": "{sw_files_path}/sw_13k2_512k.bin" + }, + "fb": { + "all": "{sw_files_path}/sw_13k2_512k.bin" + } + } + }, "OMASA_ISM3_2TC_b{bitrate}_{bandwidth}_cbr": { "encmodeoption": [ "-ism_masa", @@ -5282,9 +5486,19 @@ ], "dec": { "7_1_4": [], + "7_1": [], + "5_1_4": [], + "5_1_2": [], + "5_1": [], + "BINAURAL": [], + "BINAURAL_ROOM_IR": [], + "BINAURAL_ROOM_REVERB": [], "HOA3": [], + "HOA2": [], + "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "OMASA_ISM3_2TC", "table_name": "OMASA ISM3 2TC @{table_bitrate} kbps {bandwidth}", @@ -5356,9 +5570,19 @@ ], "dec": { "7_1_4": [], + "7_1": [], + "5_1_4": [], + "5_1_2": [], + "5_1": [], + "BINAURAL": [], + "BINAURAL_ROOM_IR": [], + "BINAURAL_ROOM_REVERB": [], "HOA3": [], + "HOA2": [], + "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "OMASA_ISM3_2TC", "table_name": "OMASA ISM3 2TC @{table_bitrate} RS {bandwidth}", @@ -5372,13 +5596,13 @@ "mono": false, "bitrates": { "wb": { - "all": "{sw_files_path}/sw_13k2_512k_2fr_start_24k4_omasatechs_3ism.bin" + "all": "{sw_files_path}/sw_13k2_512k.bin" }, "swb": { - "all": "{sw_files_path}/sw_13k2_512k_2fr_start_48k_omasatechs_3ism.bin" + "all": "{sw_files_path}/sw_13k2_512k.bin" }, "fb": { - "all": "{sw_files_path}/sw_13k2_512k_2fr_start_160k_omasatechs_3ism.bin" + "all": "{sw_files_path}/sw_13k2_512k.bin" } } }, @@ -5394,9 +5618,19 @@ ], "dec": { "7_1_4": [], + "7_1": [], + "5_1_4": [], + "5_1_2": [], + "5_1": [], + "BINAURAL": [], + "BINAURAL_ROOM_IR": [], + "BINAURAL_ROOM_REVERB": [], "HOA3": [], + "HOA2": [], + "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "OMASA_ISM3_1TC", "table_name": "OMASA ISM3 1TC @{table_bitrate} kbps {bandwidth}", @@ -5410,27 +5644,100 @@ "mono": false, "bitrates": { "wb": [ + 13200, 16400, + 24400, + 32000, 48000, + 64000, + 80000, 96000, - 160000, - 256000 + 128000, + 192000, + 256000, + 384000, + 512000 ], "swb": [ + 13200, + 16400, 24400, + 32000, + 48000, 64000, + 80000, + 96000, 128000, - 384000 + 192000, + 256000, + 384000, + 512000 ], "fb": [ 13200, + 16400, + 24400, 32000, + 48000, + 64000, 80000, + 96000, + 128000, 192000, + 256000, + 384000, 512000 ] } }, + "OMASA_ISM3_1TC_b{bitrate}_{bandwidth}_rs": { + "encmodeoption": [ + "-ism_masa", + "3", + "1" + ], + "encoptions": [ + "-max_band", + "{bandwidth}" + ], + "dec": { + "7_1_4": [], + "7_1": [], + "5_1_4": [], + "5_1_2": [], + "5_1": [], + "BINAURAL": [], + "BINAURAL_ROOM_IR": [], + "BINAURAL_ROOM_REVERB": [], + "HOA3": [], + "HOA2": [], + "FOA": [], + "mono": [], + "stereo": [], + "EXT": [] + }, + "in_config": "OMASA_ISM3_1TC", + "table_name": "OMASA ISM3 1TC @{table_bitrate} RS {bandwidth}", + "nummetadata": 4, + "metadatafilenames": [ + "{item}_ISM{mdi}.csv", + "{item}.met" + ], + "rs": true, + "amr": false, + "mono": false, + "bitrates": { + "wb": { + "all": "{sw_files_path}/sw_13k2_512k.bin" + }, + "swb": { + "all": "{sw_files_path}/sw_13k2_512k.bin" + }, + "fb": { + "all": "{sw_files_path}/sw_13k2_512k.bin" + } + } + }, "OMASA_ISM4_2TC_b{bitrate}_{bandwidth}_cbr": { "encmodeoption": [ "-ism_masa", @@ -5443,9 +5750,19 @@ ], "dec": { "7_1_4": [], + "7_1": [], + "5_1_4": [], + "5_1_2": [], + "5_1": [], + "BINAURAL": [], + "BINAURAL_ROOM_IR": [], + "BINAURAL_ROOM_REVERB": [], "HOA3": [], + "HOA2": [], + "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "OMASA_ISM4_2TC", "table_name": "OMASA ISM4 2TC @{table_bitrate} kbps {bandwidth}", @@ -5517,9 +5834,19 @@ ], "dec": { "7_1_4": [], + "7_1": [], + "5_1_4": [], + "5_1_2": [], + "5_1": [], + "BINAURAL": [], + "BINAURAL_ROOM_IR": [], + "BINAURAL_ROOM_REVERB": [], "HOA3": [], + "HOA2": [], + "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "OMASA_ISM4_2TC", "table_name": "OMASA ISM4 2TC @{table_bitrate} RS {bandwidth}", @@ -5533,10 +5860,10 @@ "mono": false, "bitrates": { "wb": { - "all": "{sw_files_path}/sw_13k2_512k_2fr_start_32k_omasatechs_4ism.bin" + "all": "{sw_files_path}/sw_13k2_512k.bin" }, "swb": { - "all": "{sw_files_path}/sw_13k2_512k_2fr_start_80k_omasatechs_4ism.bin" + "all": "{sw_files_path}/sw_13k2_512k.bin" }, "fb": { "all": "{sw_files_path}/sw_13k2_512k.bin" @@ -5555,9 +5882,19 @@ ], "dec": { "7_1_4": [], + "7_1": [], + "5_1_4": [], + "5_1_2": [], + "5_1": [], + "BINAURAL": [], + "BINAURAL_ROOM_IR": [], + "BINAURAL_ROOM_REVERB": [], "HOA3": [], + "HOA2": [], + "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "OMASA_ISM4_1TC", "table_name": "OMASA ISM4 1TC @{table_bitrate} kbps {bandwidth}", @@ -5571,25 +5908,99 @@ "mono": false, "bitrates": { "wb": [ + 13200, 16400, + 24400, + 32000, 48000, + 64000, + 80000, 96000, - 256000 + 128000, + 192000, + 256000, + 384000, + 512000 ], "swb": [ + 13200, + 16400, 24400, + 32000, + 48000, 64000, + 80000, + 96000, 128000, - 384000 + 192000, + 256000, + 384000, + 512000 ], "fb": [ 13200, + 16400, + 24400, 32000, + 48000, + 64000, 80000, + 96000, + 128000, 192000, + 256000, + 384000, 512000 ] } + }, + "OMASA_ISM4_1TC_b{bitrate}_{bandwidth}_rs": { + "encmodeoption": [ + "-ism_masa", + "4", + "1" + ], + "encoptions": [ + "-max_band", + "{bandwidth}" + ], + "dec": { + "7_1_4": [], + "7_1": [], + "5_1_4": [], + "5_1_2": [], + "5_1": [], + "BINAURAL": [], + "BINAURAL_ROOM_IR": [], + "BINAURAL_ROOM_REVERB": [], + "HOA3": [], + "HOA2": [], + "FOA": [], + "mono": [], + "stereo": [], + "EXT": [] + }, + "in_config": "OMASA_ISM4_1TC", + "table_name": "OMASA ISM4 1TC @{table_bitrate} RS {bandwidth}", + "nummetadata": 5, + "metadatafilenames": [ + "{item}_ISM{mdi}.csv", + "{item}.met" + ], + "rs": true, + "amr": false, + "mono": false, + "bitrates": { + "wb": { + "all": "{sw_files_path}/sw_13k2_512k.bin" + }, + "swb": { + "all": "{sw_files_path}/sw_13k2_512k.bin" + }, + "fb": { + "all": "{sw_files_path}/sw_13k2_512k.bin" + } + } } }, "OSBA": { diff --git a/scripts/config/self_test.prm b/scripts/config/self_test.prm index a9bb024f30..beb3fce813 100644 --- a/scripts/config/self_test.prm +++ b/scripts/config/self_test.prm @@ -149,10 +149,18 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g192 bit_error ../IVAS_dec STEREO 48 bit_error testv/stvST32n.wav_stereo_24400_32-48_DTX_FER5.tst +// stereo at 24.4 kbps, 48kHz in, 48kHz out, DTX on +../IVAS_cod -stereo -dtx 24400 48 testv/stvST48n.wav bit +../IVAS_dec STEREO 48 bit testv/stvST48n.wav_24400_48_48_DTX.txt + // stereo at 32 kbps, 32kHz in, 32kHz out ../IVAS_cod -stereo 32000 32 testv/stvST32c.wav bit ../IVAS_dec STEREO 32 bit testv/stvST32c.wav_stereo_32000_32-32.tst +// stereo at 32 kbps, 32kHz in, 32kHz out, NOOP +../IVAS_cod -stereo 32000 32 testv/stvST32noop.wav bit +../IVAS_dec STEREO 32 bit testv/stvST32noop.wav_stereo_32000_32-32.tst + // stereo at 32 kbps, 32kHz in, 32kHz out, random FER at 5% ../IVAS_cod -stereo 32000 32 testv/stvST32c.wav bit eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g192 bit_error @@ -242,6 +250,10 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -stereo 48000 32 testv/stvST32c.wav bit ../IVAS_dec MONO 32 bit testv/stvST32c.wav_stereo_48000_32-32_MONO.tst +// stereo at 13.2 kbps, 48kHz in, 48kHz out +../IVAS_cod -stereo 13200 48 testv/stvST48c.wav bit +../IVAS_dec STEREO 48 bit testv/stvST48c.wav_stereo_13200_48-48.tst + // stereo at 128 kbps, 48kHz in, 48kHz out, MONO out ../IVAS_cod -stereo 128000 48 testv/stvST48c.wav bit ../IVAS_dec MONO 48 bit testv/stvST48c.wav_stereo_128000_48-48_MONO.tst @@ -517,10 +529,14 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -ism 4 testv/stvISM1.csv testv/stvISM2.csv testv/stvISM3.csv testv/stvISM4.csv ../scripts/switchPaths/sw_24k4_256k.bin 48 testv/stv4ISM48s.wav bit ../IVAS_dec EXT 48 bit testv/stv4ISM48s.wav_brate_sw_48-48_EXT.tst -// 4 ISm with and without metadata bitrate switching from 24.4 kbps to 256 kbps, 48 kHz in, 48 kHz out, DTX on, HOA3 out +// 4 ISM with and without metadata bitrate switching from 24.4 kbps to 256 kbps, 48 kHz in, 48 kHz out, DTX on, HOA3 out ../IVAS_cod -dtx -ism 4 testv/stvISM1.csv NULL NULL testv/stvISM4.csv ../scripts/switchPaths/sw_24k4_256k.bin 48 testv/stv4ISM48n.wav bit ../IVAS_dec HOA3 48 bit testv/stv4ISM48n.wav_brate_sw_48-48_DTX_hoa3.tst +// 4 ISM w and wo md br switching 24.4 kbps to 256 kbps, 48 kHz in, 48 kHz out, DTX on, BINAURAL_ROOM_IR out (Model from file) +../IVAS_cod -dtx -ism 4 testv/stvISM1.csv NULL NULL testv/stvISM4.csv ../scripts/switchPaths/sw_24k4_256k.bin 48 testv/stv4ISM48n.wav bit +../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_48kHz.bin BINAURAL_ROOM_IR 48 bit testv/stv4ISM48n.wav_brate_sw_48-48_DTX_hoa3.tst + // 4 ISM with extended metadata at 256 kbps, 48 kHz in, 48 kHz out, BINAURAL out, HR, directivity configuration, random FER at 5% ../IVAS_cod -ism +4 testv/stvISM1.csv testv/stvISM2.csv testv/stvISM3.csv testv/stvISM4.csv 256000 48 testv/stv4ISM48s.wav bit eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g192 bit_error @@ -539,7 +555,7 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -dtx -ism +4 testv/stvISM1.csv NULL testv/stvISM_with_no_diegetic_switch.csv testv/stvISM4.csv 256000 48 testv/stv4ISM48n.wav bit ../IVAS_dec BINAURAL 48 bit testv/stv+4ISM48n+non_diegetic_pan.wav_brate_256000-48_DTX_binaural.tst -// 4 ISM with extended metadata at 128 kbps, 48 kHz in, 48 kHz out, BINAURAL_ROOM_REVERB out, combined render config, directivity configuration with identifiers +// 4 ISM with extended metadata at 128 kbps, 48 kHz in, 48 kHz out, BINAURAL_ROOM_REVERB out, rendconf dir w id ../IVAS_cod -ism 4 testv/stvISM1.csv testv/stvISM2.csv testv/stvISM3.csv testv/stvISM4.csv 128000 48 testv/stv4ISM48n.wav bit ../IVAS_dec -render_config testv/rend_config_combined.cfg -dpid 3 0 2 1 BINAURAL_ROOM_REVERB 48 bit testv/stv4ISM48n+combined_render_config_brate_128000-48-binaural_room_reverb.wav @@ -822,9 +838,9 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -sba 3 ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/stv3OA48c.wav bit ../IVAS_dec STEREO 48 bit testv/stv3OA48c.wav_sw_48-48_STEREO.tst -// SBA 3OA bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, BINAURAL out +// SBA 3OA bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, BINAURAL out (Model from file) ../IVAS_cod -sba 3 ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/stv3OA48c.wav bit -../IVAS_dec BINAURAL 48 bit testv/stv3OA48c.wav_sw_48-48_BINAURAL.tst +../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_48kHz.bin BINAURAL 48 bit testv/stv3OA48c.wav_sw_48-48_BINAURAL.tst // SBA 3OA bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, FOA out ../IVAS_cod -sba 3 ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/stv3OA48c.wav bit @@ -878,7 +894,7 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -sba -1 128000 48 testv/stvFOA48c.wav bit ../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_32kHz.bin -t testv/headrot_case00_3000_q.csv -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 32 bit testv/stvFOA48c.pcm_planarSBA_12800032-32_BinauralRoomReverb_Config_renderer_Headrot_BinauralFile.tst -// SBA 3OA at 128 kbps, 48kHz in 48kHz out, BINAURAL_ROOM_REVERB combined renderer configuration with selected acoustic environment +// SBA 3OA at 128 kbps, 48kHz in 48kHz out, BINAURAL_ROOM_REVERB rendconf sel acoustic env ../IVAS_cod -sba 3 128000 48 testv/stv3OA48c.wav bit ../IVAS_dec -render_config testv/rend_config_combined.cfg -aeid 1 BINAURAL_ROOM_REVERB 48 bit testv/stv3OA48c.pcm_SBA_12800048-48_BinauralRoomReverb_Config_renderer_combined_AEID_1.tst @@ -1067,9 +1083,9 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -masa 1 testv/stv1MASA1TC48n.met ../scripts/switchPaths/sw_13k2_to_128k_10fr.bin 48 testv/stv1MASA1TC48n.wav bit ../IVAS_dec FOA 48 bit testv/stv1MASA1TC48n.wav_sw_48-48_FOA.tst -// MASA 1dir 2TC bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, BINAURAL out +// MASA 1dir 2TC bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, BINAURAL out (Model from file) ../IVAS_cod -masa 2 testv/stv1MASA2TC48n.met ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/stv1MASA2TC48n.wav bit -../IVAS_dec BINAURAL 48 bit testv/stv1MASA2TC48n.wav_sw_48-48_BINAURAL.tst +../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_48kHz.bin BINAURAL 48 bit testv/stv1MASA2TC48n.wav_sw_48-48_BINAURAL.tst // MASA 1dir 2TC bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, MONO out ../IVAS_cod -masa 2 testv/stv1MASA2TC48n.met ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/stv1MASA2TC48n.wav bit @@ -1104,11 +1120,11 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 // Multi-channel 5_1 at 24.4 kbps, 48kHz in, 48kHz out, BINAURAL out, bandwidth switching ../IVAS_cod -max_band testv/ivas_bws_20fr_start_WB.txt -mc 5_1 24400 48 testv/stv51MC48c.wav bit -../IVAS_dec BINAURAL 48 bit testv/stv51MC48c.wav_MC51_24400_48-48_Binaural_Subframe.tst +../IVAS_dec BINAURAL 48 bit testv/stv51MC48c.wav_MC51_24400_48-48_Binaural_bwsw.tst -// Multi-channel 5_1 at 24.4 kbps, 48kHz in, 48kHz out, BINAURAL out, HR +// Multi-channel 5_1 at 24.4 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_IR out, HR ../IVAS_cod -mc 5_1 24400 48 testv/stv51MC48c.wav bit -../IVAS_dec -t testv/headrot.csv BINAURAL 48 bit testv/stv51MC48c.wav_MC51_24400_48-48_Binaural_Headrot.tst +../IVAS_dec -t testv/headrot.csv BINAURAL_ROOM_IR 48 bit testv/stv51MC48c.wav_MC51_24400_48-48_BinauralRoom_Headrot.tst // Multi-channel 5_1 at 24.4 kbps, 48kHz in, 48kHz out, BINAURAL out, HR, exo ../IVAS_cod -mc 5_1 24400 48 testv/stv51MC48c.wav bit @@ -1205,9 +1221,13 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -mc 5_1 24400 48 testv/stv51MC48c.wav bit ../IVAS_dec MONO 48 bit testv/stv51MC48c.wav_MC51_24400_48-48_MONO.tst +// Multi-channel 5_1_4 at 48 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_IR out, HR +../IVAS_cod -mc 5_1_4 48000 48 testv/stv514MC48c.wav bit +../IVAS_dec -t testv/headrot.csv BINAURAL_ROOM_IR 48 bit testv/stv514MC48c.wav_MC514_48000_48-48_BinauralRoom_Headrot.tst + // Multi-channel 7_1_4 at 48 kbps, 48kHz in, 48kHz out, MONO out, bandwidth switching ../IVAS_cod -max_band testv/ivas_bws_20fr_start_SWB.txt -mc 7_1_4 48000 48 testv/stv714MC48c.wav bit -../IVAS_dec MONO 48 bit testv/stv714MC48c.wav_MC714_48000_48-48_Mono.tst +../IVAS_dec MONO 48 bit testv/stv714MC48c.wav_MC714_48000_48-48_Mono_bwsw.tst // Multi-channel 7_1_4 at 64 kbps, 48kHz in, 48kHz out, MONO out, random FER at 5% ../IVAS_cod -mc 7_1_4 64000 48 testv/stv714MC48c.wav bit @@ -1227,9 +1247,13 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g192 bit_error ../IVAS_dec 5_1 48 bit_error testv/stv714MC48c.wav_MC714_96000_48-48_5_1_FER5.tst -// Multi-channel 7_1_4 at 160 kbps, 48kHz in, 48kHz out, BINAURAL out, bandwidth switching +// Multi-channel 7_1_4 at 160 kbps, 48kHz in, 48kHz out, BINAURAL out, bandwidth switching, HR ../IVAS_cod -max_band testv/ivas_bws_20fr_start_WB.txt -mc 7_1_4 160000 48 testv/stv714MC48c.wav bit -../IVAS_dec BINAURAL 48 bit testv/stv714MC48c.wav_MC714_160000_48-48_MC_binaural.tst +../IVAS_dec -t testv/headrot.csv BINAURAL 48 bit testv/stv714MC48c.wav_MC714_160000_48-48_MC_binaural-HR_bwsw.tst + +// Multi-channel 7_1_4 at 160 kbps, 48kHz in, 16kHz out, BINAURAL_ROOM_IR out, HR +../IVAS_cod -max_band FB -mc 7_1_4 160000 48 testv/stv714MC48c.wav bit +../IVAS_dec -t testv/headrot.csv BINAURAL 48 bit testv/stv714MC48c.wav_MC714_160000_48-16_MC_binaural-HR.tst // Multi-channel 7_1_4 at 160 kbps, 48kHz in, 48kHz out, 7_1_4 out ../IVAS_cod -mc 7_1_4 160000 48 testv/stv714MC48c.wav bit @@ -1242,7 +1266,7 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 // Multi-channel 5_1_2 at 32 kbps, 48kHz in, 48kHz out, STEREO out, random FER at 5% ../IVAS_cod -mc 5_1_2 32000 48 testv/stv512MC48c.wav bit eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g192 bit_error -../IVAS_dec STEREO 48 bit_error testv/stv512MC48c.wav_MC714_32000_48-48_Stereo_FER5.tst +../IVAS_dec STEREO 48 bit_error testv/stv512MC48c.wav_MC512_32000_48-48_Stereo_FER5.tst // Multi-channel 5_1_2 at 80 kbps, 48kHz in, 48kHz out, 5_1 out ../IVAS_cod -mc 5_1_2 80000 48 testv/stv512MC48c.wav bit @@ -1256,51 +1280,63 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -mc 5_1 256000 48 testv/stv51MC48c.wav bit ../IVAS_dec testv/ls_setup_16ch_8+4+4.txt 48 bit testv/stv51MC48c.wav_MC51_256000_48-48_MC_custom_setup.tst -// Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config renderer -../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit -../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 48 bit testv/stv51MC48c.wav_MC51_512000_48-48_MC_Config_renderer.tst +// Multi-channel 7_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Config renderer +../IVAS_cod -mc 7_1 512000 48 testv/stv71MC48c.wav bit +../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 48 bit testv/stv71MC48c.wav_MC71_512000_48-48_MC_Config_renderer.tst -// Multi-channel 5_1 at 512 kbps, 48kHz in, 32kHz out, BINAURAL_ROOM out Config renderer -../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit -../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 32 bit testv/stv51MC48c.wav_MC51_512000_48-32_MC_Config_renderer.tst +// Multi-channel 5_1 at 80 kbps, 48kHz in, 32kHz out, BINAURAL_ROOM_REVERB out Config renderer, HR +../IVAS_cod -mc 5_1 80000 48 testv/stv51MC48c.wav bit +../IVAS_dec -render_config testv/rend_config_renderer.cfg -t ../scripts/trajectories/full-circle-4s.csv BINAURAL_ROOM_REVERB 32 bit testv/stv51MC48c.wav_MC51_80000_48-32_MC_Config_renderer.tst -// Multi-channel 5_1 at 512 kbps, 48kHz in, 16kHz out, BINAURAL_ROOM out Config renderer +// Multi-channel 5_1 at 512 kbps, 48kHz in, 16kHz out, BINAURAL_ROOM_REVERB out Config renderer ../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 16 bit testv/stv51MC48c.wav_MC51_512000_48-16_MC_Config_renderer.tst -// Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config hospital_patientroom -../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit -../IVAS_dec -render_config testv/rend_config_hospital_patientroom.cfg BINAURAL_ROOM_REVERB 48 bit testv/stv51MC48c.wav_MC51_512000_48-48_MC_Config_hospital_patientroom.tst +// Multi-channel 5_1 at 512 kbps, 48kHz in 48kHz out, BINAURAL_ROOM_REVERB out custom acoustic environment with a sequence (CREND) +//../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit +//../IVAS_dec -render_config testv/rend_config_combined.cfg -aeid 1:200,0:100,2:500 BINAURAL_ROOM_REVERB 48 bit testv/stv51MC48c.wav_MC51_512000_48-48_MC_reverb_sequence.tst -// Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config recreation -../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit -../IVAS_dec -render_config testv/rend_config_recreation.cfg BINAURAL_ROOM_REVERB 48 bit testv/stv51MC48c.wav_MC51_512000_48-48_MC_Config_recreation.tst +// Multi-channel 5_1 at 64 kbps, 48kHz in 48kHz out, BINAURAL_ROOM_REVERB out custom acoustic environment with a sequence (FastConv) +//../IVAS_cod -mc 5_1 64000 48 testv/stv51MC48c.wav bit +//../IVAS_dec -render_config testv/rend_config_combined.cfg -aeid 1:500,2:100,0:300 BINAURAL_ROOM_REVERB 48 bit testv/stv51MC48c.wav_MC51_64000_48-48_MC_reverb_sequence.tst -// Multi-channel 5_1_2 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config renderer -../IVAS_cod -mc 5_1_2 512000 48 testv/stv512MC48c.wav bit -../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 48 bit testv/stv512MC48c.wav_MC512_512000_48-48_MC_Config_renderer.tst +// Multi-channel 5_1 at 32 kbps, 48kHz in 48kHz out, BINAURAL_ROOM_REVERB out custom acoustic environment with a sequence (ParamBin) +//../IVAS_cod -mc 5_1 32000 48 testv/stv51MC48c.wav bit +//../IVAS_dec -render_config testv/rend_config_combined.cfg -aeid 0:100,2:500,1:200 BINAURAL_ROOM_REVERB 48 bit testv/stv51MC48c.wav_MC51_32000_48-48_MC_reverb_sequence.tst -// Multi-channel 5_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config renderer, bandwidth switching +// Multi-channel 5_1 at 32 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Config hospital_patientroom +../IVAS_cod -mc 5_1 32000 48 testv/stv51MC48c.wav bit +../IVAS_dec -render_config testv/rend_config_hospital_patientroom.cfg BINAURAL_ROOM_REVERB 48 bit testv/stv51MC48c.wav_MC51_32000_48-48_MC_Config_hospital_patientroom.tst + +// Multi-channel 7_1_4 at 160 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Config recreation, HR +../IVAS_cod -mc 7_1_4 160000 48 testv/stv714MC48c.wav bit +../IVAS_dec -render_config testv/rend_config_recreation.cfg -t ../scripts/trajectories/full-circle-with-up-and-down-4s.csv BINAURAL_ROOM_REVERB 48 bit testv/stv51MC48c.wav_MC714_160000_48-48_MC_Config_recreation-HR.tst + +// Multi-channel 5_1_2 at 64 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Config renderer, HR +../IVAS_cod -mc 5_1_2 64000 48 testv/stv512MC48c.wav bit +../IVAS_dec -render_config testv/rend_config_renderer.cfg -t testv/headrot_case04_3000_q.csv BINAURAL_ROOM_REVERB 48 bit testv/stv512MC48c.wav_MC512_64000_48-48_MC_Config_renderer-HR.tst + +// Multi-channel 5_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Config renderer, bandwidth switching ../IVAS_cod -max_band testv/ivas_bws_20fr_start_SWB.txt -mc 5_1_4 512000 48 testv/stv514MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 48 bit testv/stv514MC48c.wav_MC514_512000_48-48_MC_Config_renderer.tst -// Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config renderer +// Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Config renderer ../IVAS_cod -mc 7_1_4 512000 48 testv/stv714MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 48 bit testv/stv714MC48c.wav_MC714_512000_48-48_MC_Config_renderer.tst -// Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config early reflections +// Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Config early reflections ../IVAS_cod -mc 7_1_4 512000 48 testv/stv714MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_ER_v1.cfg BINAURAL_ROOM_REVERB 48 bit testv/stv714MC48c.wav_MC714_512000_48-48_ER_v1.tst -// Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config early reflections, listener origin +// Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Config early reflections, listener origin ../IVAS_cod -mc 7_1_4 512000 48 testv/stv714MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_ER_v2.cfg BINAURAL_ROOM_REVERB 48 bit testv/stv714MC48c.wav_MC714_512000_48-48_MC_ER_v2.tst -// Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config early reflections, low complexity, listener origin +// Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Conf early refl, low complexity, listener origin ../IVAS_cod -mc 7_1_4 512000 48 testv/stv714MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_ER_v3.cfg BINAURAL_ROOM_REVERB 48 bit testv/stv714MC48c.wav_MC714_512000_48-48_MC_ER_v3.tst -// Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config early reflections, HR +// Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Config early reflections, HR ../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_ER_v1.cfg -t testv/headrot_case00_3000_q.csv BINAURAL_ROOM_REVERB 48 bit testv/stv51MC48c.wav_MC51_512000_48-48_MC_ER_v1_hrot.tst @@ -1308,6 +1344,10 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -mc 5_1 ../scripts/switchPaths/sw_mctech_5fr.bin 48 testv/stv51MC48c.wav bit ../IVAS_dec 7_1_4 48 bit testv/stv51MC48c.wav_sw_48-48_7_1_4.tst +// Multi-channel 5_1 bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 16kHz out, BINAURAL_ROOM_REVERB out +../IVAS_cod -mc 5_1 ../scripts/switchPaths/sw_mctech_5fr.bin 48 testv/stv51MC48c.wav bit +../IVAS_dec BINAURAL_ROOM_REVERB 16 bit testv/stv51MC48c.wav_sw_48-16_Binaural_room.tst + // Multi-channel 5_1 bitrate switching from 24.4 kbps to 256 kbps, 48kHz in, 48kHz out, BINAURAL out, FER at 10%, bandwidth switching ../IVAS_cod -max_band testv/ivas_bws_20fr_start_WB.txt -mc 5_1 ../scripts/switchPaths/sw_24k4_256k.bin 48 testv/stv51MC48c.wav bit eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_10pct.g192 bit_error @@ -1317,6 +1357,10 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_10pct.g ../IVAS_cod -mc 5_1_2 ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/stv512MC48c.wav bit ../IVAS_dec BINAURAL_ROOM_IR 16 bit testv/stv512MC48c.wav_sw_48-16_Binaural_room.tst +// Multi-channel 7_1 bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, BINAURAL out (model from file), head rotation +../IVAS_cod -mc 7_1 ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/stv71MC48c.wav bit +../IVAS_dec -t testv/headrot.csv -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_48kHz.bin BINAURAL 48 bit testv/stv71C48c.wav_sw_48-48_Binaural_model_file_headrot.tst + // Multi-channel 7_1_4 bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, HOA3 out ../IVAS_cod -mc 7_1_4 ../scripts/switchPaths/sw_mctech_5fr.bin 48 testv/stv714MC48c.wav bit ../IVAS_dec HOA3 48 bit testv/stv51MC48c.wav_sw_48-48_HOA3.tst @@ -1326,9 +1370,9 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_10pct.g eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g192 bit_error ../IVAS_dec STEREO 32 bit_error testv/stv714MC48c.wav_sw_48-32_stereo_FER5.tst -// Multi-channel 7_1_4 bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, BINAURAL out +// Multi-channel 7_1_4 bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, BINAURAL out (Model from file) ../IVAS_cod -mc 7_1_4 ../scripts/switchPaths/sw_mctech_5fr.bin 48 testv/stv714MC48c.wav bit -../IVAS_dec BINAURAL 48 bit testv/stv51MC48c.wav_sw_48-48_BINAURAL.tst +../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_48kHz.bin BINAURAL 48 bit testv/stv51MC48c.wav_sw_48-48_BINAURAL.tst // Multi-channel 5_1_4 at 512 kbps, 48kHz in, 16kHz out, BINAURAL_ROOM out (Model from file) ../IVAS_cod -mc 5_1_4 512000 48 testv/stv514MC48c.wav bit @@ -1592,6 +1636,10 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -ism_masa 4 2 testv/stvISM1.csv testv/stvISM2.csv testv/stvISM3.csv testv/stvISM4.csv testv/stv2MASA2TC48c.met ../scripts/switchPaths/sw_13k2_512k_2fr_start_384k_omasatechs_4ism.bin 48 testv/stvOMASA_4ISM_2MASA2TC48c.wav bit ../IVAS_dec BINAURAL_ROOM_REVERB 48 bit testv/stvOMASA_4ISM_2MASA2TC48c.wav_BINAURAL_ROOM_REVERB_sw_48-48.tst +// OMASA 2Dir2TC 4ISM at br sw techs 13.2 to 512 kbps start 384 kbps, 48kHz in, 16kHz out, BINAURAL out (Model from file) +../IVAS_cod -ism_masa 4 2 testv/stvISM1.csv testv/stvISM2.csv testv/stvISM3.csv testv/stvISM4.csv testv/stv2MASA2TC48c.met ../scripts/switchPaths/sw_13k2_512k_2fr_start_384k_omasatechs_4ism.bin 48 testv/stvOMASA_4ISM_2MASA2TC48c.wav bit +../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_16kHz.bin BINAURAL 16 bit testv/stvOMASA_4ISM_2MASA2TC48c.wav_BINAURAL_sw_48-16.tst + // OMASA 2Dir2TC 4ISM at br sw techs 13.2 to 512 kbps start 80 kbps, 48kHz in, 48kHz out, EXT out ../IVAS_cod -ism_masa 4 2 testv/stvISM1.csv NULL testv/stvISM3.csv testv/stvISM4.csv testv/stv2MASA2TC48c.met ../scripts/switchPaths/sw_13k2_512k_2fr_start_80k_omasatechs_4ism.bin 48 testv/stvOMASA_4ISM_2MASA2TC48c.wav bit ../IVAS_dec EXT 48 bit testv/stvOMASA_4ISM_2MASA2TC48c.wav_EXT_sw_48-48.tst @@ -1670,6 +1718,10 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -ism_sba 4 3 testv/stvISM1.csv testv/stvISM2.csv testv/stvISM3.csv testv/stvISM4.csv ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/stvOSBA_4ISM_3OA48c.wav bit ../IVAS_dec BINAURAL 48 bit testv/stvOSBA_4ISM_3OA48c.wav_BINAURAL_sw_13k2_512k_48-48.tst +// OSBA 3OA 4ISM bitrate switching 16.4 to 512, 48kHz in, 48kHz out, BINAURAL out, headtracking +../IVAS_cod -ism_sba 4 3 testv/stvISM1.csv testv/stvISM2.csv testv/stvISM3.csv testv/stvISM4.csv ../scripts/switchPaths/sw_16k4_512k_50fr.bin 48 testv/stvOSBA_4ISM_3OA48c.wav bit +../IVAS_dec -t testv/headrot.csv BINAURAL 48 bit testv/stvOSBA_4ISM_3OA48c.wav_BINAURAL_sw_16k4_512k_48-48.tst + // OSBA 3OA 2ISM at 256 kbps, 32kHz in, 32kHz out, HOA3 out ../IVAS_cod -ism_sba 2 3 testv/stvISM1.csv testv/stvISM2.csv 256000 32 testv/stvOSBA_2ISM_3OA32c.wav bit ../IVAS_dec HOA3 32 bit testv/stvOSBA_2ISM_3OA32c.wav_HOA3_256000_32-32.tst @@ -1686,10 +1738,10 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -ism_sba 4 3 testv/stvISM1.csv testv/stvISM2.csv testv/stvISM3.csv testv/stvISM4.csv ../scripts/switchPaths/sw_13k2_512k.bin 32 testv/stvOSBA_4ISM_3OA32c.wav bit ../IVAS_dec EXT 48 bit testv/stvOSBA_4ISM_3OA32c.wav_EXT_sw_13k2_512k_32-48.tst -// OSBA FOA 4ISM at bitrate switching 13.2 to 512 kbps, 48kHz in, 48kHz out, BINAURAL out, FER at 5%, bandwidth switching +// OSBA FOA 4ISM at br sw 13.2 to 512 kbps, 48kHz in, 16kHz out, BINAURAL out (Model from file), FER at 5%, bandwidth switching ../IVAS_cod -max_band testv/ivas_bws_20fr_start_FB.txt -ism_sba 4 1 testv/stvISM1.csv testv/stvISM2.csv testv/stvISM3.csv testv/stvISM4.csv ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/stvOSBA_4ISM_FOA48c.wav bit eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g192 bit_error -../IVAS_dec BINAURAL 48 bit_error testv/stvOSBA_4ISM_FOA48c.wav_BINAURAL_sw_48-48_FER5.tst +../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_16kHz.bin BINAURAL 16 bit_error testv/stvOSBA_4ISM_FOA48c.wav_BINAURAL_sw_48-48_FER5.tst // OSBA 3ISM 2OA at bitrate switching 13.2 to 512 kbps, 48kHz in, 32kHz out, STEREO out, FER at 10% ../IVAS_cod -ism_sba 3 2 testv/stvISM1.csv testv/stvISM2.csv testv/stvISM3.csv ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/stvOSBA_3ISM_2OA48c.wav bit diff --git a/scripts/config/self_test_ltv.prm b/scripts/config/self_test_ltv.prm index 5080418476..963847e2c6 100644 --- a/scripts/config/self_test_ltv.prm +++ b/scripts/config/self_test_ltv.prm @@ -149,10 +149,18 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g192 bit_error ../IVAS_dec STEREO 48 bit_error testv/ltv32_STEREO.wav_stereo_24400_32-48_DTX_FER5.tst +// stereo at 24.4 kbps, 48kHz in, 48kHz out, DTX on +../IVAS_cod -stereo -dtx 24400 48 testv/ltv48_STEREO.wav bit +../IVAS_dec STEREO 48 bit testv/ltv48_STEREO.wav_24400_48_48_DTX.txt + // stereo at 32 kbps, 32kHz in, 32kHz out ../IVAS_cod -stereo 32000 32 testv/ltv32_STEREO.wav bit ../IVAS_dec STEREO 32 bit testv/ltv32_STEREO.wav_stereo_32000_32-32.tst +// stereo at 32 kbps, 32kHz in, 32kHz out, NOOP +../IVAS_cod -stereo 32000 32 testv/stvST32noop.wav bit +../IVAS_dec STEREO 32 bit testv/stvST32noop.wav_stereo_32000_32-32.tst + // stereo at 32 kbps, 32kHz in, 32kHz out, random FER at 5% ../IVAS_cod -stereo 32000 32 testv/ltv32_STEREO.wav bit eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g192 bit_error @@ -241,6 +249,9 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 // stereo at 48 kbps, 32kHz in, 32kHz out, MONO out ../IVAS_cod -stereo 48000 32 testv/ltv32_STEREO.wav bit ../IVAS_dec MONO 32 bit testv/ltv32_STEREO.wav_stereo_48000_32-32_MONO.tst +// stereo at 13.2 kbps, 48kHz in, 48kHz out +../IVAS_cod -stereo 13200 48 testv/ltv48_STEREO.wav bit +../IVAS_dec STEREO 48 bit testv/ltv48_STEREO.wav_stereo_13200_48-48.tst // stereo at 128 kbps, 48kHz in, 48kHz out, MONO out ../IVAS_cod -stereo 128000 48 testv/ltv48_STEREO.wav bit @@ -517,10 +528,14 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -ism 4 testv/ltvISM1.csv testv/ltvISM2.csv testv/ltvISM3.csv testv/ltvISM4.csv ../scripts/switchPaths/sw_24k4_256k.bin 48 testv/ltv48_4ISM.wav bit ../IVAS_dec EXT 48 bit testv/ltv48_4ISM.wav_brate_sw_48-48_EXT.tst -// 4 ISm with and without metadata bitrate switching from 24.4 kbps to 256 kbps, 48 kHz in, 48 kHz out, DTX on, HOA3 out +// 4 ISM with and without metadata bitrate switching from 24.4 kbps to 256 kbps, 48 kHz in, 48 kHz out, DTX on, HOA3 out ../IVAS_cod -dtx -ism 4 testv/ltvISM1.csv NULL NULL testv/ltvISM4.csv ../scripts/switchPaths/sw_24k4_256k.bin 48 testv/ltv48_4ISM.wav bit ../IVAS_dec HOA3 48 bit testv/ltv48_4ISM.wav_brate_sw_48-48_DTX_hoa3.tst +// 4 ISM w and wo md br switching 24.4 kbps to 256 kbps, 48 kHz in, 48 kHz out, DTX on, BINAURAL_ROOM_IR out (Model from file) +../IVAS_cod -dtx -ism 4 testv/ltvISM1.csv NULL NULL testv/ltvISM4.csv ../scripts/switchPaths/sw_24k4_256k.bin 48 testv/ltv48_4ISM.wav bit +../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_48kHz.bin BINAURAL_ROOM_IR 48 bit testv/ltv48_4ISM.wav_brate_sw_48-48_DTX_hoa3.tst + // 4 ISM with extended metadata at 256 kbps, 48 kHz in, 48 kHz out, BINAURAL out, HR, directivity configuration, random FER at 5% ../IVAS_cod -ism +4 testv/ltvISM1.csv testv/ltvISM2.csv testv/ltvISM3.csv testv/ltvISM4.csv 256000 48 testv/ltv48_4ISM.wav bit eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g192 bit_error @@ -539,7 +554,7 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -dtx -ism +4 testv/ltvISM1.csv NULL testv/ltvISM3.csv testv/ltvISM4.csv 256000 48 testv/ltv48_4ISM.wav bit ../IVAS_dec BINAURAL 48 bit testv/ltv48_4ISM_non_diegetic_pan.wav_brate_256000-48_DTX_binaural.tst -// 4 ISM with extended metadata at 128 kbps, 48 kHz in, 48 kHz out, BINAURAL_ROOM_REVERB out, combined render config, directivity configuration with identifiers +// 4 ISM with extended metadata at 128 kbps, 48 kHz in, 48 kHz out, BINAURAL_ROOM_REVERB out, rendconf dir w id ../IVAS_cod -ism 4 testv/ltvISM1.csv testv/ltvISM2.csv testv/ltvISM3.csv testv/ltvISM4.csv 128000 48 testv/ltv48_4ISM.wav bit ../IVAS_dec -render_config testv/rend_config_combined.cfg -dpid 0 0 0 0 BINAURAL_ROOM_REVERB 48 bit testv/ltv48_4ISM+combined_render_config_brate_128000-48-binaural_room_reverb.wav @@ -822,9 +837,9 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -sba 3 ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/ltv48_HOA3.wav bit ../IVAS_dec STEREO 48 bit testv/ltv48_HOA3.wav_sw_48-48_STEREO.tst -// SBA 3OA bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, BINAURAL out +// SBA 3OA bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, BINAURAL out (Model from file) ../IVAS_cod -sba 3 ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/ltv48_HOA3.wav bit -../IVAS_dec BINAURAL 48 bit testv/ltv48_HOA3.wav_sw_48-48_BINAURAL.tst +../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_48kHz.bin BINAURAL 48 bit testv/ltv48_HOA3.wav_sw_48-48_BINAURAL.tst // SBA 3OA bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, FOA out ../IVAS_cod -sba 3 ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/ltv48_HOA3.wav bit @@ -878,7 +893,7 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -sba -1 128000 48 testv/ltv48_FOA.wav bit ../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_32kHz.bin -t testv/headrot_case00_3000_q.csv -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 32 bit testv/ltv48_FOA.pcm_planarSBA_12800032-32_BinauralRoomReverb_Config_renderer_Headrot_BinauralFile.tst -// SBA 3OA at 128 kbps, 48kHz in 48kHz out, BINAURAL_ROOM_REVERB combined renderer configuration with selected acoustic environment +// SBA 3OA at 128 kbps, 48kHz in 48kHz out, BINAURAL_ROOM_REVERB rendconf sel acoustic env ../IVAS_cod -sba 3 128000 48 testv/ltv48_HOA3.wav bit ../IVAS_dec -render_config testv/rend_config_combined.cfg -aeid 1 BINAURAL_ROOM_REVERB 48 bit testv/ltv48_HOA3.pcm_SBA_12800048-48_BinauralRoomReverb_Config_renderer_combined_AEID_1.tst @@ -1067,9 +1082,9 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -masa 1 testv/ltv48_MASA1TC.met ../scripts/switchPaths/sw_13k2_to_128k_10fr.bin 48 testv/ltv48_MASA1TC.wav bit ../IVAS_dec FOA 48 bit testv/ltv48_MASA1TC.wav_sw_48-48_FOA.tst -// MASA 1dir 2TC bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, BINAURAL out +// MASA 1dir 2TC bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, BINAURAL out (Model from file) ../IVAS_cod -masa 2 testv/ltv48_MASA2TC.met ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/ltv48_MASA2TC.wav bit -../IVAS_dec BINAURAL 48 bit testv/ltv48_MASA2TC.wav_sw_48-48_BINAURAL.tst +../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_48kHz.bin BINAURAL 48 bit testv/ltv48_MASA2TC.wav_sw_48-48_BINAURAL.tst // MASA 1dir 2TC bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, MONO out ../IVAS_cod -masa 2 testv/ltv48_MASA2TC.met ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/ltv48_MASA2TC.wav bit @@ -1104,11 +1119,11 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 // Multi-channel 5_1 at 24.4 kbps, 48kHz in, 48kHz out, BINAURAL out, bandwidth switching ../IVAS_cod -max_band testv/ivas_bws_20fr_start_WB.txt -mc 5_1 24400 48 testv/ltv48_MC51.wav bit -../IVAS_dec BINAURAL 48 bit testv/ltv48_MC51.wav_MC51_24400_48-48_Binaural_Subframe.tst +../IVAS_dec BINAURAL 48 bit testv/ltv48_MC51.wav_MC51_24400_48-48_Binaural_bwsw.tst -// Multi-channel 5_1 at 24.4 kbps, 48kHz in, 48kHz out, BINAURAL out, HR +// Multi-channel 5_1 at 24.4 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_IR out, HR ../IVAS_cod -mc 5_1 24400 48 testv/ltv48_MC51.wav bit -../IVAS_dec -t testv/headrot.csv BINAURAL 48 bit testv/ltv48_MC51.wav_MC51_24400_48-48_Binaural_Headrot.tst +../IVAS_dec -t testv/headrot.csv BINAURAL_ROOM_IR 48 bit testv/ltv48_MC51.wav_MC51_24400_48-48_BinauralRoom_Headrot.tst // Multi-channel 5_1 at 24.4 kbps, 48kHz in, 48kHz out, BINAURAL out, HR, exo ../IVAS_cod -mc 5_1 24400 48 testv/ltv48_MC51.wav bit @@ -1205,9 +1220,13 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -mc 5_1 24400 48 testv/ltv48_MC51.wav bit ../IVAS_dec MONO 48 bit testv/ltv48_MC51.wav_MC51_24400_48-48_MONO.tst +// Multi-channel 5_1_4 at 48 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_IR out, HR +../IVAS_cod -mc 5_1_4 48000 48 testv/stv514MC48c.wav bit +../IVAS_dec -t testv/headrot.csv BINAURAL_ROOM_IR 48 bit testv/ltv48_MC514.wav_MC514_48000_48-48_BinauralRoom_Headrot.tst + // Multi-channel 7_1_4 at 48 kbps, 48kHz in, 48kHz out, MONO out, bandwidth switching ../IVAS_cod -max_band testv/ivas_bws_20fr_start_SWB.txt -mc 7_1_4 48000 48 testv/ltv48_MC714.wav bit -../IVAS_dec MONO 48 bit testv/ltv48_MC714.wav_MC714_48000_48-48_Mono.tst +../IVAS_dec MONO 48 bit testv/ltv48_MC714.wav_MC714_48000_48-48_Mono_bwsw.tst // Multi-channel 7_1_4 at 64 kbps, 48kHz in, 48kHz out, MONO out, random FER at 5% ../IVAS_cod -mc 7_1_4 64000 48 testv/ltv48_MC714.wav bit @@ -1227,22 +1246,26 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g192 bit_error ../IVAS_dec 5_1 48 bit_error testv/ltv48_MC714.wav_MC714_96000_48-48_5_1_FER5.tst -// Multi-channel 7_1_4 at 160 kbps, 48kHz in, 48kHz out, BINAURAL out, bandwidth switching +// Multi-channel 7_1_4 at 160 kbps, 48kHz in, 48kHz out, BINAURAL out, bandwidth switching, HR ../IVAS_cod -max_band testv/ivas_bws_20fr_start_WB.txt -mc 7_1_4 160000 48 testv/ltv48_MC714.wav bit -../IVAS_dec BINAURAL 48 bit testv/ltv48_MC714.wav_MC714_160000_48-48_MC_binaural.tst +../IVAS_dec -t testv/headrot.csv BINAURAL 48 bit testv/ltv48_MC714.wav_MC714_160000_48-48_MC_binaural_bwsw.tst -// Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL out, HR -../IVAS_cod -mc 7_1_4 512000 48 testv/ltv48_MC714.wav bit -../IVAS_dec -t testv/headrot.csv BINAURAL 48 bit testv/ltv48_MC714.wav_MC714_512000_48-48_MC_binaural_hrot.tst +// Multi-channel 7_1_4 at 160 kbps, 48kHz in, 16kHz out, BINAURAL_ROOM_IR out, HR +../IVAS_cod -mc 7_1_4 160000 48 testv/ltv48_MC714.wav bit +../IVAS_dec -t testv/headrot.csv BINAURAL 48 bit testv/ltv48_MC714.wav_MC714_160000_48-48_MC_binaural_hrot.tst // Multi-channel 7_1_4 at 160 kbps, 48kHz in, 48kHz out, 7_1_4 out ../IVAS_cod -mc 7_1_4 160000 48 testv/ltv48_MC714.wav bit ../IVAS_dec 7_1_4 48 bit testv/ltv48_MC714.wav_MC714_160000_48-48_MC714.tst +// Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL out, HR +../IVAS_cod -mc 7_1_4 512000 48 testv/ltv48_MC714.wav bit +../IVAS_dec -t testv/headrot.csv BINAURAL 48 bit testv/ltv48_MC714.wav_MC714_512000_48-48_MC_binaural_hrot.tst + // Multi-channel 5_1_2 at 32 kbps, 48kHz in, 48kHz out, STEREO out, random FER at 5% ../IVAS_cod -mc 5_1_2 32000 48 testv/ltv48_MC512.wav bit eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g192 bit_error -../IVAS_dec STEREO 48 bit_error testv/ltv48_MC512.wav_MC714_32000_48-48_Stereo.tst +../IVAS_dec STEREO 48 bit_error testv/ltv48_MC512.wav_MC512_32000_48-48_Stereo_FER5.tst // Multi-channel 5_1_2 at 80 kbps, 48kHz in, 48kHz out, 5_1 out ../IVAS_cod -mc 5_1_2 80000 48 testv/ltv48_MC512.wav bit @@ -1256,51 +1279,63 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -mc 5_1 256000 48 testv/ltv48_MC51.wav bit ../IVAS_dec testv/ls_setup_16ch_8+4+4.txt 48 bit testv/ltv48_MC51.wav_MC51_256000_48-48_MC_custom_setup.tst -// Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config renderer -../IVAS_cod -mc 5_1 512000 48 testv/ltv48_MC51.wav bit -../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 48 bit testv/ltv48_MC51.wav_MC51_512000_48-48_MC_Config_renderer.tst +// Multi-channel 7_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Config renderer +../IVAS_cod -mc 7_1 512000 48 testv/ltv48_MC71.wav bit +../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 48 bit testv/ltv48_MC71.wav_MC71_512000_48-48_MC_Config_renderer.tst -// Multi-channel 5_1 at 512 kbps, 48kHz in, 32kHz out, BINAURAL_ROOM out Config renderer -../IVAS_cod -mc 5_1 512000 48 testv/ltv48_MC51.wav bit -../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 32 bit testv/ltv48_MC51.wav_MC51_512000_48-32_MC_Config_renderer.tst +// Multi-channel 5_1 at 80 kbps, 48kHz in, 32kHz out, BINAURAL_ROOM_REVERB out Config renderer, HR +../IVAS_cod -mc 5_1 80000 48 testv/ltv48_MC51.wav bit +../IVAS_dec -render_config testv/rend_config_renderer.cfg -t ../scripts/trajectories/full-circle-4s.csv BINAURAL_ROOM_REVERB 32 bit testv/ltv48_MC51.wav_MC51_80000_48-32_MC_Config_renderer.tst -// Multi-channel 5_1 at 512 kbps, 48kHz in, 16kHz out, BINAURAL_ROOM out Config renderer +// Multi-channel 5_1 at 512 kbps, 48kHz in, 16kHz out, BINAURAL_ROOM_REVERB out Config renderer ../IVAS_cod -mc 5_1 512000 48 testv/ltv48_MC51.wav bit ../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 16 bit testv/ltv48_MC51.wav_MC51_512000_48-16_MC_Config_renderer.tst -// Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config hospital_patientroom -../IVAS_cod -mc 5_1 512000 48 testv/ltv48_MC51.wav bit -../IVAS_dec -render_config testv/rend_config_hospital_patientroom.cfg BINAURAL_ROOM_REVERB 48 bit testv/ltv48_MC51.wav_MC51_512000_48-48_MC_Config_hospital_patientroom.tst +// Multi-channel 5_1 at 512 kbps, 48kHz in 48kHz out, BINAURAL_ROOM_REVERB out custom acoustic environment with a sequence (CREND) +//../IVAS_cod -mc 5_1 512000 48 testv/ltv51MC48c.wav bit +//../IVAS_dec -render_config testv/rend_config_combined.cfg -aeid 1:500,0:1000,2:500 BINAURAL_ROOM_REVERB 48 bit testv/ltv51MC48c.wav_MC51_512000_48-48_MC_reverb_sequence.tst -// Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config recreation -../IVAS_cod -mc 5_1 512000 48 testv/ltv48_MC51.wav bit -../IVAS_dec -render_config testv/rend_config_recreation.cfg BINAURAL_ROOM_REVERB 48 bit testv/ltv48_MC51.wav_MC51_512000_48-48_MC_Config_recreation.tst +// Multi-channel 5_1 at 64 kbps, 48kHz in 48kHz out, BINAURAL_ROOM_REVERB out custom acoustic environment with a sequence (FastConv) +//../IVAS_cod -mc 5_1 64000 48 testv/ltv51MC48c.wav bit +//../IVAS_dec -render_config testv/rend_config_combined.cfg -aeid 1:500,2:500,0:500 BINAURAL_ROOM_REVERB 48 bit testv/ltv51MC48c.wav_MC51_64000_48-48_MC_reverb_sequence.tst + +// Multi-channel 5_1 at 32 kbps, 48kHz in 48kHz out, BINAURAL_ROOM_REVERB out custom acoustic environment with a sequence (ParamBin) +//../IVAS_cod -mc 5_1 32000 48 testv/ltv51MC48c.wav bit +//../IVAS_dec -render_config testv/rend_config_combined.cfg -aeid 0:1000,2:500,1:500 BINAURAL_ROOM_REVERB 48 bit testv/ltv51MC48c.wav_MC51_32000_48-48_MC_reverb_sequence.tst + +// Multi-channel 5_1 at 32 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Config hospital_patientroom +../IVAS_cod -mc 5_1 32000 48 testv/ltv48_MC51.wav bit +../IVAS_dec -render_config testv/rend_config_hospital_patientroom.cfg BINAURAL_ROOM_REVERB 48 bit testv/ltv48_MC51.wav_MC51_80000_48-48_MC_Config_hospital_patientroom.tst -// Multi-channel 5_1_2 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config renderer -../IVAS_cod -mc 5_1_2 512000 48 testv/ltv48_MC512.wav bit -../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 48 bit testv/ltv48_MC512.wav_MC512_512000_48-48_MC_Config_renderer.tst +// Multi-channel 7_1_4 at 160 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Config recreation, HR +../IVAS_cod -mc 5_1 160000 48 testv/ltv48_MC51.wav bit +../IVAS_dec -render_config testv/rend_config_recreation.cfg -t ../scripts/trajectories/full-circle-with-up-and-down-4s.csv BINAURAL_ROOM_REVERB 48 bit testv/ltv48_MC51.wav_M714_160000_48-48_MC_Config_recreation.tst -// Multi-channel 5_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config renderer, bandwidth switching +// Multi-channel 5_1_2 at 64 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Config renderer, HR +../IVAS_cod -mc 5_1_2 64000 48 testv/ltv48_MC512.wav bit +../IVAS_dec -render_config testv/rend_config_renderer.cfg -t testv/headrot_case04_3000_q.csv BINAURAL_ROOM_REVERB 48 bit testv/ltv48_MC512.wav_MC512_64000_48-48_MC_Config_renderer.tst + +// Multi-channel 5_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Config renderer, bandwidth switching ../IVAS_cod -max_band testv/ivas_bws_20fr_start_SWB.txt -mc 5_1_4 512000 48 testv/ltv48_MC514.wav bit ../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 48 bit testv/ltv48_MC514.wav_MC514_512000_48-48_MC_Config_renderer.tst -// Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config renderer +// Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Config renderer ../IVAS_cod -mc 7_1_4 512000 48 testv/ltv48_MC714.wav bit ../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 48 bit testv/ltv48_MC714.wav_MC714_512000_48-48_MC_Config_renderer.tst -// Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config early reflections +// Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Config early reflections ../IVAS_cod -mc 7_1_4 512000 48 testv/ltv48_MC714.wav bit ../IVAS_dec -render_config testv/rend_config_ER_v1.cfg BINAURAL_ROOM_REVERB 48 bit testv/ltv48_MC714.wav_MC714_512000_48-48_ER_v1.tst -// Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config early reflections, listener origin +// Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Config early reflections, listener origin ../IVAS_cod -mc 7_1_4 512000 48 testv/ltv48_MC714.wav bit ../IVAS_dec -render_config testv/rend_config_ER_v2.cfg BINAURAL_ROOM_REVERB 48 bit testv/ltv48_MC714.wav_MC714_512000_48-48_MC_ER_v2.tst -// Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config early reflections, low complexity, listener origin +// Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Conf early refl, low complexity, listener origin ../IVAS_cod -mc 7_1_4 512000 48 testv/ltv48_MC714.wav bit ../IVAS_dec -render_config testv/rend_config_ER_v3.cfg BINAURAL_ROOM_REVERB 48 bit testv/ltv48_MC714.wav_MC714_512000_48-48_MC_ER_v3.tst -// Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM out Config early reflections, HR +// Multi-channel 5_1 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Config early reflections, HR ../IVAS_cod -mc 5_1 512000 48 testv/ltv48_MC51.wav bit ../IVAS_dec -render_config testv/rend_config_ER_v1.cfg -t testv/headrot_case00_3000_q.csv BINAURAL_ROOM_REVERB 48 bit testv/ltv48_MC51.wav_MC51_512000_48-48_MC_ER_v1_hrot.tst @@ -1308,6 +1343,10 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -mc 5_1 ../scripts/switchPaths/sw_mctech_5fr.bin 48 testv/ltv48_MC51.wav bit ../IVAS_dec 7_1_4 48 bit testv/ltv48_MC51.wav_sw_48-48_7_1_4.tst +// Multi-channel 5_1 bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 16kHz out, BINAURAL_ROOM_REVERB out +../IVAS_cod -mc 5_1 ../scripts/switchPaths/sw_mctech_5fr.bin 48 testv/stv51MC48c.wav bit +../IVAS_dec BINAURAL_ROOM_REVERB 16 bit testv/stv51MC48c.wav_sw_48-16_Binaural_room.tst + // Multi-channel 5_1 bitrate switching from 24.4 kbps to 256 kbps, 48kHz in, 48kHz out, BINAURAL out, FER at 10%, bandwidth switching ../IVAS_cod -max_band testv/ivas_bws_20fr_start_WB.txt -mc 5_1 ../scripts/switchPaths/sw_24k4_256k.bin 48 testv/ltv48_MC51.wav bit eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_10pct.g192 bit_error @@ -1317,6 +1356,10 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_10pct.g ../IVAS_cod -mc 5_1_2 ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/ltv48_MC512.wav bit ../IVAS_dec BINAURAL_ROOM_IR 16 bit testv/ltv48_MC512.wav_sw_48-16_Binaural_room.tst +// Multi-channel 7_1 bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, BINAURAL out (model from file), head rotation +../IVAS_cod -mc 7_1 ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/ltv48_MC71.wav bit +../IVAS_dec -t testv/headrot.csv -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_48kHz.bin BINAURAL 48 bit testv/stv71C48c.wav_sw_48-48_Binaural_model_file_headrot.tst + // Multi-channel 7_1_4 bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, HOA3 out ../IVAS_cod -mc 7_1_4 ../scripts/switchPaths/sw_mctech_5fr.bin 48 testv/ltv48_MC714.wav bit ../IVAS_dec HOA3 48 bit testv/ltv48_MC51.wav_sw_48-48_HOA3.tst @@ -1326,9 +1369,9 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_10pct.g eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g192 bit_error ../IVAS_dec STEREO 32 bit_error testv/ltv48_MC714.wav_sw_48-32_stereo_FER5.tst -// Multi-channel 7_1_4 bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, BINAURAL out +// Multi-channel 7_1_4 bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, BINAURAL out (Model from file) ../IVAS_cod -mc 7_1_4 ../scripts/switchPaths/sw_mctech_5fr.bin 48 testv/ltv48_MC714.wav bit -../IVAS_dec BINAURAL 48 bit testv/ltv48_MC51.wav_sw_48-48_BINAURAL.tst +../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_48kHz.bin BINAURAL 48 bit testv/ltv48_MC51.wav_sw_48-48_BINAURAL.tst // Multi-channel 5_1_4 at 512 kbps, 48kHz in, 16kHz out, BINAURAL_ROOM out (Model from file) ../IVAS_cod -mc 5_1_4 512000 48 testv/ltv48_MC514.wav bit @@ -1592,6 +1635,10 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -ism_masa 4 2 testv/ltv48_OMASA_4ISM_2TC_ISM1.csv testv/ltv48_OMASA_4ISM_2TC_ISM2.csv testv/ltv48_OMASA_4ISM_2TC_ISM3.csv testv/ltv48_OMASA_4ISM_2TC_ISM4.csv testv/ltv48_OMASA_4ISM_2TC.met ../scripts/switchPaths/sw_13k2_512k_2fr_start_384k_omasatechs_4ism.bin 48 testv/ltv48_OMASA_4ISM_2TC.wav bit ../IVAS_dec BINAURAL_ROOM_REVERB 48 bit testv/ltv48_OMASA_4ISM_2TC.wav_BINAURAL_ROOM_REVERB_sw_48-48.tst +// OMASA 2Dir2TC 4ISM at br sw techs 13.2 to 512 kbps start 384 kbps, 48kHz in, 16kHz out, BINAURAL out (Model from file) +../IVAS_cod -ism_masa 4 2 testv/ltv48_OMASA_4ISM_2TC_ISM1.csv testv/ltv48_OMASA_4ISM_2TC_ISM2.csv testv/ltv48_OMASA_4ISM_2TC_ISM3.csv testv/ltv48_OMASA_4ISM_2TC_ISM4.csv testv/ltv48_OMASA_4ISM_2TC.met ../scripts/switchPaths/sw_13k2_512k_2fr_start_384k_omasatechs_4ism.bin 48 testv/ltv48_OMASA_4ISM_2TC.wav bit +../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_16kHz.bin BINAURAL 16 bit testv/ltv48_OMASA_4ISM_2TC.wav_BINAURAL_sw_48-16.tst + // OMASA 2Dir2TC 4ISM at br sw techs 13.2 to 512 kbps start 80 kbps, 48kHz in, 48kHz out, EXT out ../IVAS_cod -ism_masa 4 2 testv/ltv48_OMASA_4ISM_2TC_ISM1.csv NULL testv/ltv48_OMASA_4ISM_2TC_ISM3.csv testv/ltv48_OMASA_4ISM_2TC_ISM4.csv testv/ltv48_OMASA_4ISM_2TC.met ../scripts/switchPaths/sw_13k2_512k_2fr_start_80k_omasatechs_4ism.bin 48 testv/ltv48_OMASA_4ISM_2TC.wav bit ../IVAS_dec EXT 48 bit testv/ltvOMASA_4ISM_2MASA2TC48c.wav_EXT_sw_48-48.tst @@ -1670,6 +1717,10 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -ism_sba 4 3 testv/ltvISM1.csv testv/ltvISM2.csv testv/ltvISM3.csv testv/ltvISM4.csv ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/ltv48_OSBA_4ISM_HOA3.wav bit ../IVAS_dec BINAURAL 48 bit testv/ltv48_OSBA_4ISM_HOA3.wav_BINAURAL_sw_13k2_512k_48-48.tst +// OSBA 3OA 4ISM bitrate switching 16.4 to 512, 48kHz in, 48kHz out, BINAURAL out, headtracking +../IVAS_cod -ism_sba 4 3 testv/ltvISM1.csv testv/ltvISM2.csv testv/ltvISM3.csv testv/ltvISM4.csv ../scripts/switchPaths/sw_16k4_512k_50fr.bin 48 testv/ltv48_OSBA_4ISM_HOA3.wav bit +../IVAS_dec -t testv/headrot.csv BINAURAL 48 bit testv/ltvOSBA_4ISM_3OA48c.wav_BINAURAL_sw_16k4_512k_48-48.tst + // OSBA 3OA 2ISM at 256 kbps, 32kHz in, 32kHz out, HOA3 out ../IVAS_cod -ism_sba 2 3 testv/ltvISM1.csv testv/ltvISM2.csv 256000 32 testv/ltv32_OSBA_2ISM_HOA3.wav bit ../IVAS_dec HOA3 32 bit testv/ltv32_OSBA_2ISM_HOA3.wav_HOA3_256000_32-32.tst @@ -1686,10 +1737,10 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -ism_sba 4 3 testv/ltvISM1.csv testv/ltvISM2.csv testv/ltvISM3.csv testv/ltvISM4.csv ../scripts/switchPaths/sw_13k2_512k.bin 32 testv/ltv32_OSBA_4ISM_HOA3.wav bit ../IVAS_dec EXT 48 bit testv/ltv32_OSBA_4ISM_HOA3.wav_EXT_sw_13k2_512k_32-32.tst -// OSBA FOA 4ISM at bitrate switching 13.2 to 512 kbps, 48kHz in, 48kHz out, BINAURAL out, FER at 5%, bandwidth switching +// OSBA FOA 4ISM at br sw 13.2 to 512 kbps, 48kHz in, 16kHz out, BINAURAL out (Model from file), FER at 5%, bandwidth switching ../IVAS_cod -max_band testv/ivas_bws_20fr_start_WB.txt -ism_sba 4 1 testv/ltvISM1.csv testv/ltvISM2.csv testv/ltvISM3.csv testv/ltvISM4.csv ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/ltv48_OSBA_4ISM_FOA.wav bit eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g192 bit_error -../IVAS_dec BINAURAL 48 bit_error testv/ltv48_OSBA_4ISM_FOA.wav_BINAURAL_sw_48-48_FER5.tst +../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_16kHz.bin BINAURAL 16 bit_error testv/ltv48_OSBA_4ISM_FOA.wav_BINAURAL_sw_48-48_FER5.tst // OSBA 3ISM 2OA at bitrate switching 13.2 to 512 kbps, 48kHz in, 32kHz out, STEREO out, FER at 10% // ../IVAS_cod -ism_sba 3 2 testv/ltvISM1.csv testv/ltvISM2.csv testv/ltvISM3.csv ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/ltv48_OSBA_3ISM_2OA.wav bit diff --git a/scripts/mem_analysis.py b/scripts/mem_analysis.py index e3f3d8afe4..18d1e3a554 100644 --- a/scripts/mem_analysis.py +++ b/scripts/mem_analysis.py @@ -1,10 +1,7 @@ #!/usr/bin/env python3 import argparse -import csv import os -import struct -import sys import matplotlib.pyplot as plt import numpy as np diff --git a/scripts/parse_mld.py b/scripts/parse_mld.py deleted file mode 100644 index b999e83903..0000000000 --- a/scripts/parse_mld.py +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/python3 - -import argparse -import re - -# Main routine -if __name__ == "__main__": - parser = argparse.ArgumentParser( - description="Parse HTML report to extract MLD values" - ) - parser.add_argument( - "html_report", type=str, help="HTML report input file, e.g. report.html" - ) - parser.add_argument("csv_file", type=str, help="Output CSV file, e.g. output.csv") - args = parser.parse_args() - html_report = args.html_report - csv_file = args.csv_file - - mld = {} - - with open(html_report, "r") as infile: - for line in infile.readlines(): - if "col-name" in line: - test_name = re.search("\[(.*)\]", line).group(1) - mld[test_name] = 0.0 - if "MLD" in line: - mld_val = float(line.split()[1]) - mld[test_name] = mld_val - - with open(csv_file, "w") as outfile: - for test_name in mld: - outfile.write(test_name + ";" + str(mld[test_name]) + "\n") diff --git a/scripts/parse_mld_xml.py b/scripts/parse_mld_xml.py index fb1dc8e73a..84acf4fbba 100644 --- a/scripts/parse_mld_xml.py +++ b/scripts/parse_mld_xml.py @@ -4,9 +4,12 @@ import argparse from xml.etree import ElementTree """ -Parse a junit report and create a MLD summary report. +Parse a junit report and create an MLD summary report. """ +PROPERTIES = ["MLD", "MAXIMUM ABS DIFF"] + + # Main routine if __name__ == "__main__": parser = argparse.ArgumentParser( @@ -30,22 +33,32 @@ if __name__ == "__main__": ) testcases = tree.findall(".//testcase") + + results_unsorted = {} + + for testcase in testcases: + if testcase.find(".//skipped") is None: + if testcase.get("file") is None: + fulltestname = ( + testcase.get("classname").replace(".", "/") + + ".py::" + + testcase.get("name") + ) + else: + fulltestname = testcase.get("file") + "::" + testcase.get("name") + + properties_found = { + p.get("name"): p.get("value") + for p in testcase.findall(".//property") + } + properties_values = [str(properties_found.get(p)) for p in PROPERTIES] + outline = ";".join([fulltestname] + properties_values) + "\n" + results_unsorted[fulltestname] = outline + + results_sorted = dict(sorted(results_unsorted.items())) with open(csv_file, "w") as outfile: - for testcase in testcases: - if testcase.find(".//skipped") == None: - if testcase.get("file") == None: - fulltestname = ( - testcase.get("classname").replace(".", "/") - + ".py::" - + testcase.get("name") - ) - else: - fulltestname = testcase.get("file") + "::" + testcase.get("name") - if testcase.find(".//property") == None: - mld_val = None - else: - mld_val = testcase.find(".//property").get( - "value" - ) # Currently MLD is the only set property. If more are added updates are needed here. - outfile.write(fulltestname + ";" + str(mld_val) + "\n") + headerline = ";".join(["testcase"] + PROPERTIES) + "\n" + outfile.write(headerline) + for test in results_sorted: + outfile.write(results_sorted[test]) diff --git a/scripts/prepare_combined_format_inputs.py b/scripts/prepare_combined_format_inputs.py index c081b75bb1..bb406a30b6 100755 --- a/scripts/prepare_combined_format_inputs.py +++ b/scripts/prepare_combined_format_inputs.py @@ -33,8 +33,7 @@ __license__ = """ import os import shutil -import numpy as np -from pyaudio3dtools import audioarray, audiofile +from pyaudio3dtools import audiofile def main(): diff --git a/scripts/prepare_delivery.sh b/scripts/prepare_delivery.sh index 0bd36278f1..135d13f97e 100755 --- a/scripts/prepare_delivery.sh +++ b/scripts/prepare_delivery.sh @@ -35,7 +35,6 @@ DATE=`eval date +%Y_%m_%d` OUTDIR=c-code TMPCLEANDIR=clean-c-code ROOT=$(dirname $0)/.. -STRIP_SPLITREND=0 PREPARE_ZIP=1 # check, whether coan exists @@ -56,9 +55,6 @@ while getopts "$ALL_OPTS" OPTION; do case "${OPTION}" in -) case "${OPTARG}" in - strip_sr) - STRIP_SPLITREND=1 - ;; no_zip) PREPARE_ZIP=0 ;; @@ -98,6 +94,7 @@ cp -R ${ROOT}/lib_dec $OUTDIR cp -R ${ROOT}/lib_enc $OUTDIR cp -R ${ROOT}/lib_util $OUTDIR cp -R ${ROOT}/lib_rend $OUTDIR +cp -R ${ROOT}/lib_isar $OUTDIR cp -R ${ROOT}/lib_lc3plus $OUTDIR cp -R ${ROOT}/apps $OUTDIR mkdir $OUTDIR/lib_debug @@ -131,59 +128,10 @@ recode lat1..ibmpc ${OUTDIR}/LICENSE.md # unix2dos ... cp ${ROOT}/.clang-format ${OUTDIR} # enable split rendering againg by default -# in case we strip it later, it will be explicitly disabled again belo +# in case we strip it later, it will be explicitly disabled again below sed -i.bak -e "s/\/\*\ *\(#define\ *SPLIT_REND_WITH_HEAD_ROT\ *\)\*\//\1/g" ${OUTDIR}/lib_com/options.h -########################## -# # -# Strip Split Rendering # -# # -########################## - -if [ $STRIP_SPLITREND -ne 0 ]; then - - echo "Stripping Split Rendering" - - ${ROOT}/scripts/strip_split_rendering.sh ${OUTDIR} - - # strip macros - declare -a sr_macros=( - "SPLIT_REND_WITH_HEAD_ROT" - ) - - if coan_exists; then - - for macro in ${sr_macros[@]}; do - coan source --replace --no-transients -K -U${macro} $OUTDIR/lib_{com,dec,enc,util,rend}/*.[hc] - coan source --replace --no-transients -K -U${macro} $OUTDIR/apps/*.[hc] - sed -i.bak "/#define\ *$macro/d" $OUTDIR/lib_com/options.h - done - - else - - echo "Coan required in path; Aborting. Available at https://coan2.sourceforge.net/" - exit -1 - - fi - - # patch Makefile - patch ${OUTDIR}/Makefile < ${ROOT}/scripts/makefile_noSR.patch - - # delete readme_split_rendering - rm ${OUTDIR}/readme_split_rendering.txt - - # clean-up *.bak-files - find $OUTDIR -name "*.bak" -exec rm \{\} \; - -else - - # patch Makefile so that split rendering sources are built by default - patch ${OUTDIR}/Makefile < ${ROOT}/scripts/makefile_SR.patch - -fi - - ########################## # # # Stripping # @@ -206,7 +154,7 @@ if coan_exists; then ${ROOT}/scripts/parse_options_h.sh -c $tmpfile >> $COAN_LIST # apply coan - coan source --replace --no-transients -K --file $COAN_LIST $OUTDIR/lib_{com,dec,enc,util,rend}/*.[hc] + coan source --replace --no-transients -K --file $COAN_LIST $OUTDIR/lib_{com,dec,enc,util,rend,isar}/*.[hc] coan source --replace --no-transients -K --file $COAN_LIST $OUTDIR/apps/*.[hc] # remove rejected switches from options.h @@ -292,6 +240,7 @@ if coan_exists; then echo "-UDEBUG_AGC_ENCODER_CMD_OPTION" >> $COAN_LIST echo "-UDEBUG_JBM_CMD_OPTION" >> $COAN_LIST echo "-UVARIABLE_SPEED_DECODING" >> $COAN_LIST + echo "-UDISABLE_LIMITER" >> $COAN_LIST echo "-UDBG_WAV_WRITER" >> $COAN_LIST echo "-USPLIT_REND_WITH_HEAD_ROT_DEBUG" >> $COAN_LIST echo "-USPLIT_POSE_CORRECTION_DEBUG" >> $COAN_LIST @@ -306,7 +255,7 @@ if coan_exists; then rm -f $tmpfile # apply coan - coan source --replace --no-transients -K --file $COAN_LIST $OUTDIR/lib_{com,dec,enc,util,rend}/*.[hc] + coan source --replace --no-transients -K --file $COAN_LIST $OUTDIR/lib_{com,dec,enc,util,rend,isar}/*.[hc] coan source --replace --no-transients -K --file $COAN_LIST $OUTDIR/apps/*.[hc] # remove rejected switches from options.h diff --git a/scripts/pyaudio3dtools/__init__.py b/scripts/pyaudio3dtools/__init__.py index ccf53c51e1..3df489f582 100644 --- a/scripts/pyaudio3dtools/__init__.py +++ b/scripts/pyaudio3dtools/__init__.py @@ -40,4 +40,3 @@ Imports functions class """ -from . import audioarray, audiofile, spatialaudioformat diff --git a/scripts/pyaudio3dtools/audio3dtools.py b/scripts/pyaudio3dtools/audio3dtools.py index 0fec5c6ce9..22c26e28e8 100755 --- a/scripts/pyaudio3dtools/audio3dtools.py +++ b/scripts/pyaudio3dtools/audio3dtools.py @@ -30,11 +30,8 @@ the United Nations Convention on Contracts on the International Sales of Goods. """ -import argparse import logging -import os -from pyaudio3dtools import audiofile, spatialaudioformat main_logger = logging.getLogger("__main__") logger = main_logger.getChild(__name__) @@ -43,7 +40,7 @@ logger.setLevel(logging.DEBUG) def main(): print( - f"These scripts have been deprecated! Please check out and use the latest version from https://forge.3gpp.org/rep/ivas-codec-pc/ivas-processing-scripts.git" + "These scripts have been deprecated! Please check out and use the latest version from https://forge.3gpp.org/rep/ivas-codec-pc/ivas-processing-scripts.git" ) diff --git a/scripts/pyaudio3dtools/audiofile.py b/scripts/pyaudio3dtools/audiofile.py index d3153e21db..e614bfbd49 100644 --- a/scripts/pyaudio3dtools/audiofile.py +++ b/scripts/pyaudio3dtools/audiofile.py @@ -36,7 +36,6 @@ import shutil import struct import subprocess as sp import warnings -from importlib import import_module from tempfile import TemporaryDirectory from typing import Optional, Tuple @@ -662,37 +661,6 @@ def loudnessinfo( return measured_loudness, scale_factor -def print_plot_play(x: np.ndarray, fs: int, text: Optional[str] = "") -> None: - """1. Prints information about an audio signal, 2. plots the waveform, and 3. Creates player - - Parameters - ---------- - x: np array - Input signal - fs: int - Input sampling rate - text: Optional[str] = '' - text to print - Returns - ------- - None - - """ - - plt = import_module("matplotlib.pyplot") - ipd = import_module("IPython.display") - - print("%s fs = %d, x.shape = %s, x.dtype = %s" % (text, fs, x.shape, x.dtype)) - plt.figure(figsize=(8, 2)) - plt.plot(x, color="gray") - plt.xlim([0, x.shape[0]]) - plt.xlabel("Time (samples)") - plt.ylabel("Amplitude") - plt.tight_layout() - plt.show() - ipd.display(ipd.Audio(data=x, rate=fs)) - - def get_wav_file_info(filename: str) -> dict: """ Get the format information from a WAV file. diff --git a/scripts/pyivastest/IvasBaseClass.py b/scripts/pyivastest/IvasBaseClass.py index bad578f753..c7c734c5c9 100644 --- a/scripts/pyivastest/IvasBaseClass.py +++ b/scripts/pyivastest/IvasBaseClass.py @@ -30,7 +30,6 @@ the United Nations Convention on Contracts on the International Sales of Goods. """ -import filecmp import json import logging import logging.handlers diff --git a/scripts/pyivastest/IvasModeCollector.py b/scripts/pyivastest/IvasModeCollector.py index 3255dc3a8a..90274544dc 100644 --- a/scripts/pyivastest/IvasModeCollector.py +++ b/scripts/pyivastest/IvasModeCollector.py @@ -34,8 +34,6 @@ import json import logging import os import os.path -import platform -import re from copy import deepcopy from pyivastest import IvasBaseClass, constants diff --git a/scripts/pyivastest/IvasModeRunner.py b/scripts/pyivastest/IvasModeRunner.py index 27f013ee8d..41dd4d20ab 100644 --- a/scripts/pyivastest/IvasModeRunner.py +++ b/scripts/pyivastest/IvasModeRunner.py @@ -35,8 +35,6 @@ import json import logging import logging.handlers import os -import platform -import re import subprocess import threading import time diff --git a/scripts/self_test.py b/scripts/self_test.py index c41e199939..714366bcf1 100755 --- a/scripts/self_test.py +++ b/scripts/self_test.py @@ -32,8 +32,6 @@ import errno -import multiprocessing -import operator import os import platform import re diff --git a/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test.c b/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test.c index d27ffde587..f90566b3d2 100644 --- a/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test.c +++ b/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test.c @@ -30,6 +30,7 @@ the United Nations Convention on Contracts on the International Sales of Goods. *******************************************************************************************************/ +#include #include #include #include "options.h" @@ -37,6 +38,9 @@ the United Nations Convention on Contracts on the International Sales of Goods. #include "isar_lc3plus_common.h" #include "isar_lc3plus_dec.h" #include "ivas_error_utils.h" +#ifdef LC3PLUS_VBR +#include "lc3.h" +#endif #ifdef SPLIT_REND_WITH_HEAD_ROT #ifdef LC3PLUS_RTP_PAYLOAD_FORMAT @@ -44,35 +48,35 @@ the United Nations Convention on Contracts on the International Sales of Goods. #else #define MAX_SAMPLES_PER_CHANNEL 960 #endif +#define DEFAULT_BPS 256000 -static int encodeAndDecodeOneStereoFrame( LC3PLUS_CONFIG config ) +static int encodeAndDecodeOneStereoFrame( LC3PLUS_CONFIG config, uint32_t bps ) { ivas_error err; - uint32_t bps = 256000; int32_t encDelay = -1; int32_t decDelay = -1; ISAR_LC3PLUS_ENC_HANDLE encHandle; - err = IVAS_LC3PLUS_ENC_Open( config, bps, &encHandle ); + err = ISAR_LC3PLUS_ENC_Open( config, bps, &encHandle ); if ( IVAS_ERR_OK != err ) { return err; } - err = IVAS_LC3PLUS_ENC_GetDelay( encHandle, &encDelay ); + err = ISAR_LC3PLUS_ENC_GetDelay( encHandle, &encDelay ); if ( IVAS_ERR_OK != err ) { - IVAS_LC3PLUS_ENC_Close( &encHandle ); + ISAR_LC3PLUS_ENC_Close( &encHandle ); return err; } if ( encDelay == -1 || encDelay == 0 ) { - IVAS_LC3PLUS_ENC_Close( &encHandle ); + ISAR_LC3PLUS_ENC_Close( &encHandle ); return IVAS_ERROR( IVAS_ERR_INTERNAL, "encDelay is zero or uninitialized\n" ); } /* encode one frame */ - int16_t numSamplesPerChannels = config.samplerate / ( 1000000 / config.ivas_frame_duration_us ); + int16_t numSamplesPerChannels = config.samplerate / ( 1000000 / config.isar_frame_duration_us ); float *pcm_in[2]; float pcm_in_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; memset( pcm_in_ch1, 0, numSamplesPerChannels * sizeof( float ) ); @@ -82,31 +86,45 @@ static int encodeAndDecodeOneStereoFrame( LC3PLUS_CONFIG config ) pcm_in[1] = pcm_in_ch2; int32_t bitstreamSizePerIvasFrame = 0; - err = IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame ); + err = ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame ); if ( IVAS_ERR_OK != err ) { - IVAS_LC3PLUS_ENC_Close( &encHandle ); + ISAR_LC3PLUS_ENC_Close( &encHandle ); return err; } uint8_t *bitstream_out = malloc( bitstreamSizePerIvasFrame ); memset( bitstream_out, 0, bitstreamSizePerIvasFrame ); #ifdef LC3PLUS_RTP_PAYLOAD_FORMAT - err = IVAS_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out, bitstreamSizePerIvasFrame ); + int perChannelBitrate = lc3plus_enc_get_real_bitrate(encHandle->handles[0]); + int perLc3plusFrameDataBlockOctets = encHandle->num_ftds * perChannelBitrate / 8 / (1000*1000/config.lc3plus_frame_duration_us); + int targetOctets = bps / 8 / (1000*1000/config.isar_frame_duration_us); + printf("IVAS-FS=%i LC3plus-FS=%i ch=%i targetBps=%i targetOctets=%i\n", config.isar_frame_duration_us, config.lc3plus_frame_duration_us, config.channels, bps, targetOctets); + printf(" coreBps=%i corePerChBps=%i coreCodecOctets=%i nFtds=%i \n", perChannelBitrate * encHandle->num_encs, perChannelBitrate, perLc3plusFrameDataBlockOctets, encHandle->num_ftds); + int pfOctets = bitstreamSizePerIvasFrame - perLc3plusFrameDataBlockOctets; + int pfBps = pfOctets * 8 * (1000*1000 / config.isar_frame_duration_us); + printf(" payloadFormatBps=%i payloadFormatOctets=%i \n\n", pfBps, pfOctets); + if(pfBps <= 0) + { + ISAR_LC3PLUS_ENC_Close( &encHandle ); + return err; + } + + err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out, bitstreamSizePerIvasFrame ); #else - err = IVAS_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out ); + err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out ); #endif if ( IVAS_ERR_OK != err ) { - IVAS_LC3PLUS_ENC_Close( &encHandle ); + ISAR_LC3PLUS_ENC_Close( &encHandle ); free( bitstream_out ); return err; } - IVAS_LC3PLUS_ENC_Close( &encHandle ); + ISAR_LC3PLUS_ENC_Close( &encHandle ); /* decode one frame */ ISAR_LC3PLUS_DEC_HANDLE decHandle; - err = IVAS_LC3PLUS_DEC_Open( config, + err = ISAR_LC3PLUS_DEC_Open( config, #ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING 1 /*caching enabled*/, #endif @@ -117,16 +135,16 @@ static int encodeAndDecodeOneStereoFrame( LC3PLUS_CONFIG config ) return err; } - err = IVAS_LC3PLUS_DEC_GetDelay( decHandle, &decDelay ); + err = ISAR_LC3PLUS_DEC_GetDelay( decHandle, &decDelay ); if ( IVAS_ERR_OK != err ) { - IVAS_LC3PLUS_DEC_Close( &decHandle ); + ISAR_LC3PLUS_DEC_Close( &decHandle ); free( bitstream_out ); return err; } if ( decDelay == -1 || decDelay == 0 ) { - IVAS_LC3PLUS_DEC_Close( &decHandle ); + ISAR_LC3PLUS_DEC_Close( &decHandle ); free( bitstream_out ); return IVAS_ERROR( IVAS_ERR_INTERNAL, "decDelay is zero or uninitialized\n" ); } @@ -141,31 +159,31 @@ static int encodeAndDecodeOneStereoFrame( LC3PLUS_CONFIG config ) pcm_out[0] = pcm_out_ch1; pcm_out[1] = pcm_out_ch2; - err = IVAS_LC3PLUS_DEC_Conceal( decHandle, pcm_out ); + err = ISAR_LC3PLUS_DEC_Conceal( decHandle, pcm_out ); if ( IVAS_ERR_OK != err ) { - IVAS_LC3PLUS_DEC_Close( &decHandle ); + ISAR_LC3PLUS_DEC_Close( &decHandle ); free( bitstream_out ); return err; } - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstreamSizePerIvasFrame, pcm_out ); + err = ISAR_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstreamSizePerIvasFrame, pcm_out ); if ( IVAS_ERR_OK != err ) { - IVAS_LC3PLUS_DEC_Close( &decHandle ); + ISAR_LC3PLUS_DEC_Close( &decHandle ); free( bitstream_out ); return err; } - err = IVAS_LC3PLUS_DEC_Conceal( decHandle, pcm_out ); + err = ISAR_LC3PLUS_DEC_Conceal( decHandle, pcm_out ); if ( IVAS_ERR_OK != err ) { - IVAS_LC3PLUS_DEC_Close( &decHandle ); + ISAR_LC3PLUS_DEC_Close( &decHandle ); free( bitstream_out ); return err; } - IVAS_LC3PLUS_DEC_Close( &decHandle ); + ISAR_LC3PLUS_DEC_Close( &decHandle ); free( bitstream_out ); return 0; @@ -176,20 +194,20 @@ static int openCloseEncoder( void ) { ivas_error err; #ifdef LC3PLUS_RTP_PAYLOAD_FORMAT - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; #else - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; #endif uint32_t bps = 128000; ISAR_LC3PLUS_ENC_HANDLE encHandle; - err = IVAS_LC3PLUS_ENC_Open( config, bps, &encHandle ); + err = ISAR_LC3PLUS_ENC_Open( config, bps, &encHandle ); if ( IVAS_ERR_OK != err ) { return err; } - IVAS_LC3PLUS_ENC_Close( &encHandle ); + ISAR_LC3PLUS_ENC_Close( &encHandle ); return 0; } @@ -197,27 +215,43 @@ static int tryOpenEncoderWithInvalidBitrate( void ) { ivas_error err; #ifdef LC3PLUS_RTP_PAYLOAD_FORMAT - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; #else - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; #endif /* lc3plus max bitrate is 320000 per channel */ uint32_t invalid_high_bps = 700000; uint32_t invalid_low_bps = 8; - +#ifdef LC3PLUS_VBR + uint32_t limitedBitrate; +#endif ISAR_LC3PLUS_ENC_HANDLE encHandle; - err = IVAS_LC3PLUS_ENC_Open( config, invalid_high_bps, &encHandle ); + err = ISAR_LC3PLUS_ENC_Open( config, invalid_high_bps, &encHandle ); +#ifdef LC3PLUS_VBR + /* setting an invalid bitrate should result in a limited bitrate*/ + if ( IVAS_ERR_OK != err ) +#else /* setting an invalid bitrate should trigger an error - which is what we expect */ if ( IVAS_ERR_LC3PLUS_INVALID_BITRATE != err ) +#endif { return 1; } - err = IVAS_LC3PLUS_ENC_Open( config, invalid_low_bps, &encHandle ); +#ifdef LC3PLUS_VBR + limitedBitrate = lc3plus_enc_get_real_bitrate(encHandle->handles[0]); + if(limitedBitrate != 320000) + { + return 1; + } +#endif + ISAR_LC3PLUS_ENC_Close(&encHandle); + err = ISAR_LC3PLUS_ENC_Open( config, invalid_low_bps, &encHandle ); /* setting an invalid bitrate should trigger an error - which is what we expect */ if ( IVAS_ERR_LC3PLUS_INVALID_BITRATE != err ) { return 1; } + ISAR_LC3PLUS_ENC_Close(&encHandle); return 0; } @@ -225,15 +259,15 @@ static int tryOpenEncoderWithInvalidFrameDuration( void ) { ivas_error err; #ifdef LC3PLUS_RTP_PAYLOAD_FORMAT - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; #else - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; #endif config.lc3plus_frame_duration_us = 1234; /*unsupported frame duration*/ uint32_t bps = 320000; ISAR_LC3PLUS_ENC_HANDLE encHandle; - err = IVAS_LC3PLUS_ENC_Open( config, bps, &encHandle ); + err = ISAR_LC3PLUS_ENC_Open( config, bps, &encHandle ); /* setting an invalid fame duration should trigger an error - which is what we expect */ if ( IVAS_ERR_OK == err ) { @@ -246,15 +280,15 @@ static int tryOpenEncoderWithInvalidSampleRate( void ) { ivas_error err; #ifdef LC3PLUS_RTP_PAYLOAD_FORMAT - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; #else - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; #endif config.samplerate = 1234; /*unsupported sample rate */ uint32_t bps = 320000; ISAR_LC3PLUS_ENC_HANDLE encHandle; - err = IVAS_LC3PLUS_ENC_Open( config, bps, &encHandle ); + err = ISAR_LC3PLUS_ENC_Open( config, bps, &encHandle ); /* setting an invalid sample rate should trigger an error - which is what we expect */ if ( IVAS_ERR_OK == err ) { @@ -280,27 +314,27 @@ static int tryCallEncoderApiWithInvalidParams( void ) pcm_in[0] = pcm_in_ch1; uint8_t bitstream_out[1200]; - if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_GetDelay( invalidEncHandle, invalidDelayInSamples ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_GetDelay( invalidEncHandle, &delayInSamples ) ) + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_GetDelay( invalidEncHandle, invalidDelayInSamples ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_GetDelay( invalidEncHandle, &delayInSamples ) ) { return 1; } - if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( invalidEncHandle, invalidBsSize ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( invalidEncHandle, &bsSize ) ) + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( invalidEncHandle, invalidBsSize ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( invalidEncHandle, &bsSize ) ) { return 1; } - IVAS_LC3PLUS_ENC_Close( &invalidEncHandle ); + ISAR_LC3PLUS_ENC_Close( &invalidEncHandle ); #ifdef LC3PLUS_RTP_PAYLOAD_FORMAT - if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, invalidBitstream_out, bsSize ) ) + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, invalidBitstream_out, bsSize ) ) #else - if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, invalidBitstream_out ) ) + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, invalidBitstream_out ) ) #endif { return 1; } #ifdef LC3PLUS_RTP_PAYLOAD_FORMAT - if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, invalidBitstream_out, bsSize ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, bitstream_out, bsSize ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, bitstream_out, bsSize ) ) + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, invalidBitstream_out, bsSize ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, bitstream_out, bsSize ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, bitstream_out, bsSize ) ) #else - if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, invalidBitstream_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, bitstream_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, bitstream_out ) ) + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, invalidBitstream_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, bitstream_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, bitstream_out ) ) #endif { return 1; @@ -327,17 +361,17 @@ static int tryCallDecoderApiWithInvalidParams( void ) pcm_out[0] = pcm_out_ch1; uint8_t bitstream_in[1200]; - if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_GetDelay( invalidDecHandle, invalidDelayInSamples ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_GetDelay( invalidDecHandle, &delayInSamples ) ) + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_GetDelay( invalidDecHandle, invalidDelayInSamples ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_GetDelay( invalidDecHandle, &delayInSamples ) ) { return 1; } - IVAS_LC3PLUS_DEC_Close( &invalidDecHandle ); - if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, invalidBitstream_in_size, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, invalidBitstream_in_size, pcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, bitstream_in_size, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, bitstream_in_size, pcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Decode( invalidDecHandle, bitstream_in, invalidBitstream_in_size, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Decode( invalidDecHandle, bitstream_in, invalidBitstream_in_size, pcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Decode( invalidDecHandle, bitstream_in, bitstream_in_size, pcm_out ) ) + ISAR_LC3PLUS_DEC_Close( &invalidDecHandle ); + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, invalidBitstream_in_size, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, invalidBitstream_in_size, pcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, bitstream_in_size, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, bitstream_in_size, pcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, bitstream_in, invalidBitstream_in_size, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, bitstream_in, invalidBitstream_in_size, pcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, bitstream_in, bitstream_in_size, pcm_out ) ) { return 1; } - if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Conceal( invalidDecHandle, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Conceal( invalidDecHandle, pcm_out ) ) + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Conceal( invalidDecHandle, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Conceal( invalidDecHandle, pcm_out ) ) { return 1; } @@ -348,12 +382,12 @@ static int openCloseDecoderWithCaching( void ) { ivas_error err; #ifdef LC3PLUS_RTP_PAYLOAD_FORMAT - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; #else - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; #endif ISAR_LC3PLUS_DEC_HANDLE decHandle; - err = IVAS_LC3PLUS_DEC_Open( config, + err = ISAR_LC3PLUS_DEC_Open( config, #ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING 1 /*caching enabled*/, #endif @@ -363,7 +397,7 @@ static int openCloseDecoderWithCaching( void ) return err; } - IVAS_LC3PLUS_DEC_Close( &decHandle ); + ISAR_LC3PLUS_DEC_Close( &decHandle ); return 0; } @@ -371,12 +405,12 @@ static int openCloseDecoderWithoutCaching( void ) { ivas_error err; #ifdef LC3PLUS_RTP_PAYLOAD_FORMAT - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; #else - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; #endif ISAR_LC3PLUS_DEC_HANDLE decHandle; - err = IVAS_LC3PLUS_DEC_Open( config, + err = ISAR_LC3PLUS_DEC_Open( config, #ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING 1 /*caching enabled*/, #endif @@ -386,7 +420,7 @@ static int openCloseDecoderWithoutCaching( void ) return err; } - IVAS_LC3PLUS_DEC_Close( &decHandle ); + ISAR_LC3PLUS_DEC_Close( &decHandle ); return 0; } @@ -395,14 +429,14 @@ static int tryOpenDecoderWithInvalidFrameDuration( void ) { ivas_error err; #ifdef LC3PLUS_RTP_PAYLOAD_FORMAT - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; #else - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; #endif config.lc3plus_frame_duration_us = 1234; /*unsupported frame duration*/ ISAR_LC3PLUS_DEC_HANDLE decHandle; - err = IVAS_LC3PLUS_DEC_Open( config, + err = ISAR_LC3PLUS_DEC_Open( config, #ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING 1 /*caching enabled*/, #endif @@ -419,14 +453,14 @@ static int tryOpenDecoderWithInvalidSampleRate( void ) { ivas_error err; #ifdef LC3PLUS_RTP_PAYLOAD_FORMAT - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; #else - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; #endif config.samplerate = 1234; /*unsupported sample rate*/ ISAR_LC3PLUS_DEC_HANDLE decHandle; - err = IVAS_LC3PLUS_DEC_Open( config, + err = ISAR_LC3PLUS_DEC_Open( config, #ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING 1 /*caching enabled*/, #endif @@ -443,18 +477,18 @@ static int encodeOneFrame( void ) { ivas_error err; #ifdef LC3PLUS_RTP_PAYLOAD_FORMAT - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; #else - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; #endif uint32_t bps = 128000; ISAR_LC3PLUS_ENC_HANDLE encHandle; - err = IVAS_LC3PLUS_ENC_Open( config, bps, &encHandle ); + err = ISAR_LC3PLUS_ENC_Open( config, bps, &encHandle ); if ( IVAS_ERR_OK != err ) return err; - int16_t numSamplesPerChannels = config.samplerate / ( 1000000 / config.ivas_frame_duration_us ); + int16_t numSamplesPerChannels = config.samplerate / ( 1000000 / config.isar_frame_duration_us ); float *pcm[1]; float pcm_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; @@ -462,20 +496,20 @@ static int encodeOneFrame( void ) pcm[0] = pcm_ch1; int32_t bitstreamSizePerIvasFrame = 0; - err = IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame ); + err = ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame ); if ( IVAS_ERR_OK != err ) return err; uint8_t *bitstream_out = malloc( bitstreamSizePerIvasFrame ); memset( bitstream_out, 0, bitstreamSizePerIvasFrame ); #ifdef LC3PLUS_RTP_PAYLOAD_FORMAT - err = IVAS_LC3PLUS_ENC_Encode( encHandle, pcm, bitstream_out, bitstreamSizePerIvasFrame ); + err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm, bitstream_out, bitstreamSizePerIvasFrame ); #else - err = IVAS_LC3PLUS_ENC_Encode( encHandle, pcm, bitstream_out ); + err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm, bitstream_out ); #endif if ( IVAS_ERR_OK != err ) return err; - IVAS_LC3PLUS_ENC_Close( &encHandle ); + ISAR_LC3PLUS_ENC_Close( &encHandle ); free( bitstream_out ); return 0; } @@ -485,45 +519,45 @@ static int encodeAndDecodeOneMonoFrame( void ) { ivas_error err; #ifdef LC3PLUS_RTP_PAYLOAD_FORMAT - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; #else - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; #endif uint32_t bps = 128000; ISAR_LC3PLUS_ENC_HANDLE encHandle; - err = IVAS_LC3PLUS_ENC_Open( config, bps, &encHandle ); + err = ISAR_LC3PLUS_ENC_Open( config, bps, &encHandle ); if ( IVAS_ERR_OK != err ) { return err; } /* encode one frame */ - int16_t numSamplesPerChannels = config.samplerate / ( 1000000 / config.ivas_frame_duration_us ); + int16_t numSamplesPerChannels = config.samplerate / ( 1000000 / config.isar_frame_duration_us ); float *pcm_in[1]; float pcm_in_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; memset( pcm_in_ch1, 0, numSamplesPerChannels * sizeof( float ) ); pcm_in[0] = pcm_in_ch1; int32_t bitstreamSizePerIvasFrame = 0; - err = IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame ); + err = ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame ); if ( IVAS_ERR_OK != err ) return err; uint8_t *bitstream_out = malloc( bitstreamSizePerIvasFrame ); memset( bitstream_out, 0, bitstreamSizePerIvasFrame ); #ifdef LC3PLUS_RTP_PAYLOAD_FORMAT - err = IVAS_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out, bitstreamSizePerIvasFrame ); + err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out, bitstreamSizePerIvasFrame ); #else - err = IVAS_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out ); + err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out ); #endif if ( IVAS_ERR_OK != err ) return err; - IVAS_LC3PLUS_ENC_Close( &encHandle ); + ISAR_LC3PLUS_ENC_Close( &encHandle ); /* decode one frame */ ISAR_LC3PLUS_DEC_HANDLE decHandle; - err = IVAS_LC3PLUS_DEC_Open( config, + err = ISAR_LC3PLUS_DEC_Open( config, #ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING 1 /*caching enabled*/, #endif @@ -539,19 +573,19 @@ static int encodeAndDecodeOneMonoFrame( void ) float pcm_out_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; memset( pcm_out_ch1, 0, numSamplesPerChannels * sizeof( float ) ); pcm_out[0] = pcm_out_ch1; - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstreamSizePerIvasFrame, pcm_out ); + err = ISAR_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstreamSizePerIvasFrame, pcm_out ); if ( IVAS_ERR_OK != err ) { return err; } - err = IVAS_LC3PLUS_DEC_Conceal( decHandle, pcm_out ); + err = ISAR_LC3PLUS_DEC_Conceal( decHandle, pcm_out ); if ( IVAS_ERR_OK != err ) { return err; } - IVAS_LC3PLUS_DEC_Close( &decHandle ); + ISAR_LC3PLUS_DEC_Close( &decHandle ); free( bitstream_out ); return 0; @@ -560,63 +594,156 @@ static int encodeAndDecodeOneMonoFrame( void ) static int encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_48kHz( void ) { #ifdef LC3PLUS_RTP_PAYLOAD_FORMAT - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; #else - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000 }; #endif - return encodeAndDecodeOneStereoFrame( config ); + return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS ); } static int encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_32kHz( void ) { - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 32000 }; - return encodeAndDecodeOneStereoFrame( config ); + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 32000 }; + return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS ); } static int encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_16kHz( void ) { - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 16000 }; - return encodeAndDecodeOneStereoFrame( config ); + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 16000 }; + return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS ); } static int encodeAndDecodeOneStereoFrameIvas5msLc3plus5ms_48kHz( void ) { #ifdef LC3PLUS_RTP_PAYLOAD_FORMAT - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; #else - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5 * 1000, .channels = 2, .samplerate = 48000 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5 * 1000, .channels = 2, .samplerate = 48000 }; #endif - return encodeAndDecodeOneStereoFrame( config ); + return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS ); +} + +static int encodeAndDecodeOneStereoFrameIvas10msLc3plus10ms_48kHz( void ) +{ +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS ); } static int encodeAndDecodeOneMonoFrameIvas20msLc3plus10ms_48kHz( void ) { #ifdef LC3PLUS_RTP_PAYLOAD_FORMAT - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; #else - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 1, .samplerate = 48000 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 1, .samplerate = 48000 }; #endif - return encodeAndDecodeOneStereoFrame( config ); + return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS ); } static int encodeAndDecodeOneMonoFrameIvas5msLc3plus5ms_48kHz( void ) { #ifdef LC3PLUS_RTP_PAYLOAD_FORMAT - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; #else - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5 * 1000, .channels = 1, .samplerate = 48000 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5 * 1000, .channels = 1, .samplerate = 48000 }; #endif - return encodeAndDecodeOneStereoFrame( config ); + return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS ); } static int encodeAndDecodeOneStereoFrameIvas20msLc3plus2_5ms_48kHz( void ) { #ifdef LC3PLUS_RTP_PAYLOAD_FORMAT - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 2.5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 2.5 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; #else - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 2.5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 2.5 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000 }; #endif - return encodeAndDecodeOneStereoFrame( config ); + return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS ); +} + + +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_80kbpsPerChannel( void ) +{ +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, config.channels * 82*1000 ); +} + +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_96kbpsPerChannel( void ) +{ +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, config.channels * 98*1000 ); +} + +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_124kbpsPerChannel( void ) +{ +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, config.channels * 126*1000 ); +} + +#ifdef LC3PLUS_VBR +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_800kbpsPerChannel( void ) +{ +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, config.channels * 800*1000 ); +} +#endif + +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_204800bpsPerChannel( void ) +{ +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, config.channels * 204800 ); +} + +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_205600bpsPerChannel( void ) +{ +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, config.channels * 205600 ); +} + +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_206400bpsPerChannel( void ) +{ +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, config.channels * 206400 ); +} + +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_207200bpsPerChannel( void ) +{ +#ifdef LC3PLUS_RTP_PAYLOAD_FORMAT + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, config.channels * 207200 ); } #ifdef LC3PLUS_RTP_PAYLOAD_FORMAT @@ -627,6 +754,8 @@ int main( int argc, char *argv[] ) { + (void)argc; + (void)argv; int ret = 0; ret = openCloseEncoder(); if ( ret != 0 ) @@ -674,6 +803,9 @@ int main( if ( ret != 0 ) return 1; ret = encodeAndDecodeOneStereoFrameIvas5msLc3plus5ms_48kHz(); + if ( ret != 0 ) + return 1; + ret = encodeAndDecodeOneStereoFrameIvas10msLc3plus10ms_48kHz(); if ( ret != 0 ) return 1; ret = encodeAndDecodeOneMonoFrameIvas20msLc3plus10ms_48kHz(); @@ -685,6 +817,34 @@ int main( ret = encodeAndDecodeOneStereoFrameIvas20msLc3plus2_5ms_48kHz(); if ( ret != 0 ) return 1; + ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_80kbpsPerChannel(); + if ( ret != 0 ) + return 1; + ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_96kbpsPerChannel(); + if ( ret != 0 ) + return 1; + ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_124kbpsPerChannel(); + if ( ret != 0 ) + return 1; +#ifdef LC3PLUS_VBR + ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_800kbpsPerChannel(); + if ( ret != 0 ) + return 1; +#endif + /* start configs around the FDL threshold */ + ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_204800bpsPerChannel(); + if ( ret != 0 ) + return 1; + ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_205600bpsPerChannel(); + if ( ret != 0 ) + return 1; + ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_206400bpsPerChannel(); + if ( ret != 0 ) + return 1; + ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_207200bpsPerChannel(); + if ( ret != 0 ) + return 1; + /* end configs around the FDL threshold */ #ifdef LC3PLUS_RTP_PAYLOAD_FORMAT ret = run_all_payload_tests(); if ( ret != 0 ) diff --git a/scripts/testv/stvST16c.wav b/scripts/testv/stvST16c.wav index 3fb9ec0b3b..444f13d048 100644 --- a/scripts/testv/stvST16c.wav +++ b/scripts/testv/stvST16c.wav @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:11a2f5887fe2407df03128634188d8aef6d3f76b52db14a1f834dbb98b7dd52e -size 1280048 +oid sha256:6cc535a268c7e3584c206031ac214f894f5b0d600c498d19717163fe9b86b4a3 +size 1344172 diff --git a/scripts/testv/stvST16n.wav b/scripts/testv/stvST16n.wav old mode 100644 new mode 100755 index 74c80dca93..1683379a6b --- a/scripts/testv/stvST16n.wav +++ b/scripts/testv/stvST16n.wav @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:60a8cfa5abf4e052840fea0054fec5331465149747fd7bc7eadab18b62d864f1 -size 1241648 +oid sha256:5b68254cce3ffa996753d704215f3c3ed1e16fc9e3fea21060f5983771e60a00 +size 1408112 diff --git a/scripts/testv/stvST32c.wav b/scripts/testv/stvST32c.wav index 68a4a1fa33..b8ce78bced 100644 --- a/scripts/testv/stvST32c.wav +++ b/scripts/testv/stvST32c.wav @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1182294e7c3ba44e854219698e6a3c209e24345ab2e5e4296fce38029324f374 -size 2560044 +oid sha256:d904b180759dba56d487cbe2fbd7094de2eeeffd78147adf3790746de6bfb535 +size 2688168 diff --git a/scripts/testv/stvST32n.wav b/scripts/testv/stvST32n.wav old mode 100644 new mode 100755 index 7da590907d..ecc4b75f8f --- a/scripts/testv/stvST32n.wav +++ b/scripts/testv/stvST32n.wav @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a6edbfd26681fa42f377891761ad79f97029a3380bc644e47bff1803c7904ff9 -size 2483244 +oid sha256:2e23efa8db07185e36a32ee4f15d3fee552fd3b533be7454b0d4928823fc5b6d +size 2816108 diff --git a/scripts/testv/stvST32noop.wav b/scripts/testv/stvST32noop.wav new file mode 100644 index 0000000000..f9a9b7f6da --- /dev/null +++ b/scripts/testv/stvST32noop.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50b7648f75a9d5f4d73af9953f537243d0a0068170ff706272ac51018432d9ed +size 987748 diff --git a/scripts/testv/stvST48c.wav b/scripts/testv/stvST48c.wav index df554e6521..9daeb06040 100644 --- a/scripts/testv/stvST48c.wav +++ b/scripts/testv/stvST48c.wav @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:40929eb3eb266ed78c16daa2a9c987745fe8e005a577f2dd81264ffda845c118 -size 3840044 +oid sha256:baa8bd85f9e3958adc4cdfaf4556845264e6a50fad97f2bd8667a6d846c892c9 +size 4037970 diff --git a/scripts/testv/stvST48n.wav b/scripts/testv/stvST48n.wav old mode 100644 new mode 100755 index cb2d8c4fc3..419328eba8 --- a/scripts/testv/stvST48n.wav +++ b/scripts/testv/stvST48n.wav @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6074a3a3b88c7868f62c9bcf7df56e4a8fd25ffed059886846220efc4fbc0992 -size 3724844 +oid sha256:7d152b51383cc12412f0ff075ac221e101d01a955bc979fdeba35a59d09ce4b5 +size 4233522 diff --git a/scripts/tools/Darwin/wmc_tool b/scripts/tools/Darwin/wmc_tool index a9b10dcfb2d32c87dd9c7cc40884ae675f3e4fa0..582cf452b2388031f0dbd53e525ba17d570c44f2 100755 GIT binary patch literal 657584 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

9XX=GXF4 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%0DJ}$~*NgvR-`VZRg0lSY8yuKf_b`3J` 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⪙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

a#9fxHC5=#%gy3~GY3Lz6RT5*gHWK)$~M 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 mAut*OqaiRF0;3@?3PwX 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�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

b28I$@k6!R$%r9)@L8G@|cG_{sSd%{J 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%0A3iNt{0%o4JtwG!-z<8wceK*l;O$ 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

ch^lm%b@n?7oGUdi<9|CS%p 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

6SQaRC*SARoj#It9bopz$sQ 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Dhr+0+1$ZLSS2E#ZS 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 UWiP8aSEdStE6X^&s*P0+0J5jE?*IS* diff --git a/scripts/tools/Win32/wmc_tool.exe b/scripts/tools/Win32/wmc_tool.exe index ae48b8dbd0..8bb5dd5924 100755 --- a/scripts/tools/Win32/wmc_tool.exe +++ b/scripts/tools/Win32/wmc_tool.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6569149c60e810a6f2aaed8cd003766e2e1374bd69692eb140bef4c531bb2bfc -size 381952 +oid sha256:5cf3b920a28ced03856b6288b95796eb08b674ad813339c3eeb33f3f809dba30 +size 427008 diff --git a/tests/cmp_pcm.py b/tests/cmp_pcm.py index 13a1c1ba5a..709c8ddb8d 100755 --- a/tests/cmp_pcm.py +++ b/tests/cmp_pcm.py @@ -12,7 +12,7 @@ import pyaudio3dtools import pyivastest -def cmp_pcm(file1, file2, out_config, fs, get_mld=False, mld_lim=0) -> (int, str): +def cmp_pcm(file1, file2, out_config, fs, get_mld=False, mld_lim=0, abs_tol=0) -> (int, str): """ Compare 2 PCM files for bitexactness """ @@ -49,21 +49,33 @@ def cmp_pcm(file1, file2, out_config, fs, get_mld=False, mld_lim=0) -> (int, str s1, s2, fs, per_frame=False, get_mld=get_mld ) - if cmp_result["bitexact"]: - return 0, "SUCCESS: Files are bitexact" - else: + + output_differs = 0 + reason = "SUCCESS: Files are bitexact" + + if not cmp_result["bitexact"] and cmp_result["max_abs_diff"] <= abs_tol: + reason = "SUCCESS: Maximum absolute diff below threshold" + elif not cmp_result["bitexact"]: diff_msg = f"MAXIMUM ABS DIFF ==> {cmp_result['max_abs_diff']} at sample num {cmp_result['max_abs_diff_pos_sample']} (assuming {nchannels} channels)" first_msg = f"First diff found at sample num {cmp_result['first_diff_pos_sample']} in channel {cmp_result['first_diff_pos_channel']}, frame {cmp_result['first_diff_pos_frame']} (assuming {nchannels} channels, {fs} sampling rate)" print(diff_msg) print(first_msg) - if get_mld: - mld_msg = f"MLD: {cmp_result['MLD']}" - print(mld_msg) - if cmp_result["MLD"] <= mld_lim: - return 0, f"MLD: {cmp_result['MLD']} <= {mld_lim}" - else: - return 1, f"MLD: {cmp_result['MLD']} > {mld_lim}" - return 1, "Non-BE" + + reason = f"Non-BE - MAXIMUM ABS DIFF: {cmp_result['max_abs_diff']}" + output_differs = 1 + + if get_mld: + mld_msg = f"MLD: {cmp_result['MLD']}" + reason += " - " + mld_msg + print(mld_msg) + + if cmp_result["MLD"] <= mld_lim: + output_differs = 0 + reason += f" <= {mld_lim}" + else: + reason += f" > {mld_lim}" + + return output_differs, reason if __name__ == "__main__": diff --git a/tests/codec_be_on_mr_nonselection/__init__.py b/tests/codec_be_on_mr_nonselection/__init__.py index e69de29bb2..aba85788e7 100644 --- a/tests/codec_be_on_mr_nonselection/__init__.py +++ b/tests/codec_be_on_mr_nonselection/__init__.py @@ -0,0 +1,2 @@ +MLD_PATTERN = r"MLD: ([\d\.]*)" +MAX_DIFF_PATTERN = r"MAXIMUM ABS DIFF: (\d*)" diff --git a/tests/codec_be_on_mr_nonselection/test_masa_enc_dec.py b/tests/codec_be_on_mr_nonselection/test_masa_enc_dec.py index 75b01db382..9a8d8b35d5 100644 --- a/tests/codec_be_on_mr_nonselection/test_masa_enc_dec.py +++ b/tests/codec_be_on_mr_nonselection/test_masa_enc_dec.py @@ -35,6 +35,7 @@ __doc__ = """ import errno import os +import re from filecmp import cmp from typing import Optional @@ -43,6 +44,8 @@ import pytest from tests.cmp_pcm import cmp_pcm from tests.conftest import DecoderFrontend, EncoderFrontend +from . import MLD_PATTERN, MAX_DIFF_PATTERN + # params # output_mode_list = ['MONO', 'STEREO', '5_1', '7_1', '5_1_2', '5_1_4', '7_1_4', 'FOA', 'HOA2', 'HOA3', 'BINAURAL', 'BINAURAL_ROOM', 'EXT'] output_mode_list = ["BINAURAL", "EXT"] @@ -110,6 +113,7 @@ def test_masa_enc_dec( get_mld, get_mld_lim, decoder_only, + abs_tol, ): # Input parameters in_fs = 48 @@ -214,13 +218,18 @@ def test_masa_enc_dec( int(out_fs * 1000), get_mld=get_mld, mld_lim=get_mld_lim, + abs_tol=abs_tol, ) if get_mld: - mld = 0 - if "MLD" in reason: - mld = float(reason.split(":")[1].split()[0]) + mld = re.search(MLD_PATTERN, reason).groups(1)[0] record_property("MLD", mld) + max_diff = 0 + if pcmcmp_res: + search_result = re.search(MAX_DIFF_PATTERN, reason) + max_diff = search_result.groups(1)[0] + record_property("MAXIMUM ABS DIFF", max_diff) + if get_mld and get_mld_lim > 0: if pcmcmp_res != 0: pytest.fail(reason) @@ -246,12 +255,16 @@ def test_masa_enc_dec( int(out_fs * 1000), get_mld=get_mld, mld_lim=get_mld_lim, + abs_tol=abs_tol, ) if get_mld: - mld = 0 - if "MLD" in reason: - mld = float(reason.split(":")[1].split()[0]) + mld = re.search(MLD_PATTERN, reason).groups(1)[0] record_property("MLD", mld) + + search_result = re.search(MAX_DIFF_PATTERN, reason) + max_diff = search_result.groups(1)[0] + record_property("MAXIMUM ABS DIFF", max_diff) + # Report compare result if cmp_result != 0: pytest.fail(reason) diff --git a/tests/codec_be_on_mr_nonselection/test_param_file.py b/tests/codec_be_on_mr_nonselection/test_param_file.py index 459964a186..137000976f 100644 --- a/tests/codec_be_on_mr_nonselection/test_param_file.py +++ b/tests/codec_be_on_mr_nonselection/test_param_file.py @@ -35,6 +35,7 @@ Execute tests specified via a parameter file. import errno import filecmp import os +import re import platform from pathlib import Path from subprocess import run @@ -45,6 +46,7 @@ from tests.cmp_pcm import cmp_pcm from tests.conftest import DecoderFrontend, EncoderFrontend from tests.cut_pcm import cut_samples from tests.testconfig import PARAM_FILE +from . import MLD_PATTERN, MAX_DIFF_PATTERN VALID_DEC_OUTPUT_CONF = [ "MONO", @@ -141,6 +143,7 @@ def test_param_file_tests( test_tag, get_mld, get_mld_lim, + abs_tol, ): enc_opts, dec_opts, sim_opts, eid_opts = param_file_test_dict[test_tag] @@ -338,15 +341,25 @@ def test_param_file_tests( fs, get_mld=get_mld, mld_lim=get_mld_lim, + abs_tol=abs_tol, ) md_out_files = get_expected_md_files(ref_output_file, enc_split, output_config) if get_mld: - mld = 0 - if "MLD" in reason: - mld = float(reason.split(":")[1].split()[0]) + mld = re.search(MLD_PATTERN, reason).groups(1)[0] record_property("MLD", mld) + max_diff =0 + if output_differs: + search_result = re.search(MAX_DIFF_PATTERN, reason) + if search_result: + max_diff = search_result.groups(1)[0] + else: + msg = "Error " + MAX_DIFF_PATTERN + " not found" + print(msg) + pytest.fail(msg) + record_property("MAXIMUM ABS DIFF", max_diff) + metadata_differs = False for md_file in md_out_files: dut_metadata_file = Path(f"{dut_base_path}/param_file/dec/{md_file}") @@ -357,9 +370,9 @@ def test_param_file_tests( metadata_differs = True except FileNotFoundError: if not dut_metadata_file.exists(): - print(f"DUT output metadata missing for expected file: " + md_file) + print("DUT output metadata missing for expected file: " + md_file) if not ref_metadata_file.exists(): - print(f"REF output metadata missing for expected file: " + md_file) + print("REF output metadata missing for expected file: " + md_file) metadata_differs = True if get_mld and get_mld_lim > 0: diff --git a/tests/codec_be_on_mr_nonselection/test_sba_bs_dec_plc.py b/tests/codec_be_on_mr_nonselection/test_sba_bs_dec_plc.py index 11a8aeca04..a11d1d30bf 100644 --- a/tests/codec_be_on_mr_nonselection/test_sba_bs_dec_plc.py +++ b/tests/codec_be_on_mr_nonselection/test_sba_bs_dec_plc.py @@ -34,11 +34,13 @@ __doc__ = """ import errno import os +import re import pytest from tests.cmp_pcm import cmp_pcm from tests.conftest import DecoderFrontend +from . import MLD_PATTERN, MAX_DIFF_PATTERN # params tag_list = ["stvFOA"] @@ -90,6 +92,7 @@ def test_sba_plc_system( gain_flag, get_mld, get_mld_lim, + abs_tol, ): SID = 0 if dtx == "1" and ivas_br not in ["13200", "16400", "24400", "32000", "64000"]: @@ -128,6 +131,7 @@ def test_sba_plc_system( keep_files, get_mld=get_mld, get_mld_lim=get_mld_lim, + abs_tol=abs_tol, ) @@ -151,6 +155,7 @@ def sba_dec_plc( keep_files, get_mld=False, get_mld_lim=0, + abs_tol=0, ): # ------------ run cmd ------------ @@ -207,13 +212,18 @@ def sba_dec_plc( fs, get_mld=get_mld, mld_lim=get_mld_lim, + abs_tol=abs_tol, ) if get_mld: - mld = 0 - if "MLD" in reason: - mld = float(reason.split(":")[1].split()[0]) + mld = re.search(MLD_PATTERN, reason).groups(1)[0] record_property("MLD", mld) + max_diff = 0 + if cmp_result: + search_result = re.search(MAX_DIFF_PATTERN, reason) + max_diff = search_result.groups(1)[0] + record_property("MAXIMUM ABS DIFF", max_diff) + # report compare result if cmp_result != 0: pytest.fail(reason) diff --git a/tests/codec_be_on_mr_nonselection/test_sba_bs_enc.py b/tests/codec_be_on_mr_nonselection/test_sba_bs_enc.py index 4f4c1a3271..b7effa986c 100644 --- a/tests/codec_be_on_mr_nonselection/test_sba_bs_enc.py +++ b/tests/codec_be_on_mr_nonselection/test_sba_bs_enc.py @@ -35,6 +35,7 @@ __doc__ = """ import errno import os +import re import pytest from cut_bs import cut_from_start @@ -42,6 +43,7 @@ from cut_bs import cut_from_start from tests.cmp_pcm import cmp_pcm from tests.conftest import DecoderFrontend, EncoderFrontend from tests.cut_pcm import cut_samples +from . import MLD_PATTERN, MAX_DIFF_PATTERN # params @@ -105,6 +107,7 @@ def test_pca_enc( get_mld, get_mld_lim, decoder_only, + abs_tol, ): pca = True tag = tag + fs + "c" @@ -159,6 +162,7 @@ def test_pca_enc( get_mld=get_mld, get_mld_lim=get_mld_lim, pca=pca, + abs_tol=abs_tol, ) @@ -190,6 +194,7 @@ def test_sba_enc_system( get_mld, get_mld_lim, decoder_only, + abs_tol, ): if dtx == "1" and ivas_br not in ["13200", "16400", "24400", "32000", "64000"]: # skip high bitrates for DTX until DTX issue is resolved @@ -264,6 +269,7 @@ def test_sba_enc_system( decoder_only, get_mld=get_mld, get_mld_lim=get_mld_lim, + abs_tol=abs_tol, ) @@ -286,6 +292,7 @@ def test_spar_hoa2_enc_system( get_mld, get_mld_lim, decoder_only, + abs_tol, ): fs = "48" dtx = "0" @@ -337,6 +344,7 @@ def test_spar_hoa2_enc_system( decoder_only, get_mld=get_mld, get_mld_lim=get_mld_lim, + abs_tol=abs_tol, ) @@ -359,6 +367,7 @@ def test_spar_hoa3_enc_system( get_mld, get_mld_lim, decoder_only, + abs_tol, ): fs = "48" dtx = "0" @@ -410,6 +419,7 @@ def test_spar_hoa3_enc_system( decoder_only, get_mld=get_mld, get_mld_lim=get_mld_lim, + abs_tol=abs_tol, ) @@ -436,6 +446,7 @@ def test_sba_enc_BWforce_system( get_mld, get_mld_lim, decoder_only, + abs_tol, ): if dtx == "1" and ivas_br not in ["32000", "64000"]: # skip high bitrates for DTX until DTX issue is resolved @@ -493,6 +504,7 @@ def test_sba_enc_BWforce_system( decoder_only, get_mld=get_mld, get_mld_lim=get_mld_lim, + abs_tol=abs_tol, ) @@ -542,15 +554,15 @@ def sba_enc( if gain_flag != -1: short_tag_ext += f"_Gain{gain_flag}" if SID == 1: - short_tag_ext += f"_SID" + short_tag_ext += "_SID" if pca: - short_tag_ext += f"_pca" + short_tag_ext += "_pca" # to avoid conflicting names in case of parallel test execution, differentiate all cases long_tag_ext = "" if gain_flag != -1: long_tag_ext += f"_Gain{gain_flag}" if SID == 1: - long_tag_ext += f"_SID" + long_tag_ext += "_SID" dut_pkt_file = f"{dut_out_dir}/{tag_out}{long_tag_ext}.192" ref_pkt_file = f"{ref_out_dir}/{tag_out}{short_tag_ext}.192" ref_pkt_file_dutenc = f"{ref_out_dir}/{tag_out}{short_tag_ext}_dutenc.192" @@ -662,6 +674,7 @@ def sba_dec( get_mld=False, get_mld_lim=0, pca=False, + abs_tol=0, ): # -------- run cmd ------------ # sampling rate to BW mapping @@ -725,13 +738,18 @@ def sba_dec( fs, get_mld=get_mld, mld_lim=get_mld_lim, + abs_tol=abs_tol, ) if get_mld: - mld = 0 - if "MLD" in reason: - mld = float(reason.split(":")[1].split()[0]) + mld = re.search(MLD_PATTERN, reason).groups(1)[0] record_property("MLD", mld) + max_diff = 0 + if cmp_result: + search_result = re.search(MAX_DIFF_PATTERN, reason) + max_diff = search_result.groups(1)[0] + record_property("MAXIMUM ABS DIFF", max_diff) + # report compare result if cmp_result != 0: pytest.fail(reason) diff --git a/tests/codec_be_on_mr_selection/__init__.py b/tests/codec_be_on_mr_selection/__init__.py index 2ee63a30a5..bf530e5ebc 100644 --- a/tests/codec_be_on_mr_selection/__init__.py +++ b/tests/codec_be_on_mr_selection/__init__.py @@ -174,7 +174,7 @@ def run_check( if not is_ref_creation: if compare_bitstream: if not is_be_to_ref(dut_bitstream): - pytest.fail(f"Bitstream file differs from reference") + pytest.fail("Bitstream file differs from reference") dut_bitstream_to_decoder = dut_bitstream if error_pattern is not None: diff --git a/tests/conftest.py b/tests/conftest.py index bbe16f4715..c975e409c0 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -37,10 +37,9 @@ import os from tests import testconfig import pytest import platform -import tempfile import textwrap from pathlib import Path -from subprocess import STDOUT, CalledProcessError, TimeoutExpired, run +from subprocess import TimeoutExpired, run from typing import Optional, Union logger = logging.getLogger(__name__) @@ -198,6 +197,13 @@ def pytest_addoption(parser): default=False, ) + parser.addoption( + "--abs_tol", + help="Tolerance for absolute difference in PCM output. Differences below this threshold are ignored when deciding about PASS or FAIL.", + type=int, + default=0, + ) + @pytest.fixture(scope="session", autouse=True) def update_ref(request): @@ -235,6 +241,14 @@ def get_mld_lim(request): return float(request.config.getoption("--mld-lim")) +@pytest.fixture(scope="session") +def abs_tol(request) -> int: + """ + Return tolerance value for absolute diff in PCM output. + """ + return request.config.option.abs_tol + + @pytest.fixture(scope="session") def keep_files(request) -> bool: """ @@ -332,7 +346,9 @@ class EncoderFrontend: log_dbg_msg(f"{self._type} encoder command:\n{cmd_str}") try: - result = run(command, capture_output=True, check=True, timeout=self.timeout) + result = run( + command, capture_output=True, check=False, timeout=self.timeout + ) except TimeoutExpired: pytest.fail(f"{self._type} encoder run timed out after {self.timeout}s.") diff --git a/tests/create_short_testvectors.py b/tests/create_short_testvectors.py index d80a328c14..e51f018f45 100755 --- a/tests/create_short_testvectors.py +++ b/tests/create_short_testvectors.py @@ -67,7 +67,7 @@ def collect_files(file_ids): for f in TEST_VECTOR_DIR.iterdir() if f.suffix == ".wav" and any([id in f.name for id in file_ids]) - and not "_cut" in f.name + and "_cut" not in f.name ] return files diff --git a/tests/cut_pcm.py b/tests/cut_pcm.py index 644a2ba1bc..2abc86b624 100755 --- a/tests/cut_pcm.py +++ b/tests/cut_pcm.py @@ -47,7 +47,6 @@ import platform import sys from pathlib import Path -import numpy as np HERE = Path(__file__).parent.resolve() SCRIPTS_DIR = str(HERE.joinpath("../scripts").resolve()) @@ -81,7 +80,7 @@ def cut_samples( ) if sample_rate is None and not str(in_file).endswith(".wav"): - raise ValueError(f"For non-wav files, samplerate must be explicitly given") + raise ValueError("For non-wav files, samplerate must be explicitly given") elif sample_rate is None: # set to default of pyaudio3dtools.audiofile.readfile -> for wav files it will be ignored anyway sample_rate = 48000 diff --git a/tests/hrtf_binary_loading/utils.py b/tests/hrtf_binary_loading/utils.py index 85d55a34d3..c1b34c57cd 100644 --- a/tests/hrtf_binary_loading/utils.py +++ b/tests/hrtf_binary_loading/utils.py @@ -33,11 +33,10 @@ import os import sys import uuid -from typing import Dict, Optional +from typing import Optional import pytest -from tests.renderer.compare_audio import compare_audio_arrays from tests.renderer.utils import check_BE, run_cmd, run_renderer, test_info from .constants import * diff --git a/tests/renderer/constants.py b/tests/renderer/constants.py index 9592103e1d..0e7b13c8ac 100644 --- a/tests/renderer/constants.py +++ b/tests/renderer/constants.py @@ -114,6 +114,14 @@ FORMAT_TO_FILE_SMOKETEST = { "NDP_ISM4": NCHAN_TO_FILE[4], "MASA1": NCHAN_TO_FILE[1], "MASA2": NCHAN_TO_FILE[2], + "OMASA_1_1": NCHAN_TO_FILE[2], + "OMASA_1_2": NCHAN_TO_FILE[3], + "OMASA_1_3": NCHAN_TO_FILE[4], + "OMASA_1_4": NCHAN_TO_FILE[5], + "OMASA_2_1": NCHAN_TO_FILE[3], + "OMASA_2_2": NCHAN_TO_FILE[4], + "OMASA_2_3": NCHAN_TO_FILE[5], + "OMASA_2_4": NCHAN_TO_FILE[6], "OSBA_1_1": NCHAN_TO_FILE[5], "OSBA_2_1": NCHAN_TO_FILE[6], "OSBA_3_1": NCHAN_TO_FILE[7], @@ -149,6 +157,14 @@ FORMAT_TO_FILE_COMPARETEST = { "ISM4": TESTV_DIR.joinpath("stv4ISM48s.wav"), "MASA1": TESTV_DIR.joinpath("stv1MASA1TC48c.wav"), "MASA2": TESTV_DIR.joinpath("stv2MASA2TC48c.wav"), + "OMASA_1_1": TESTV_DIR.joinpath("stvOMASA_1ISM_1MASA1TC48c.wav"), + "OMASA_1_2": TESTV_DIR.joinpath("stvOMASA_2ISM_2MASA1TC48c.wav"), + "OMASA_1_3": TESTV_DIR.joinpath("stvOMASA_3ISM_1MASA1TC48c.wav"), + "OMASA_1_4": TESTV_DIR.joinpath("stvOMASA_4ISM_2MASA1TC48c.wav"), + "OMASA_2_1": TESTV_DIR.joinpath("stvOMASA_1ISM_1MASA2TC48c.wav"), + "OMASA_2_2": TESTV_DIR.joinpath("stvOMASA_2ISM_2MASA2TC48c.wav"), + "OMASA_2_3": TESTV_DIR.joinpath("stvOMASA_3ISM_1MASA2TC48c.wav"), + "OMASA_2_4": TESTV_DIR.joinpath("stvOMASA_4ISM_2MASA2TC48c.wav"), "OSBA_1_1": TESTV_DIR.joinpath("stvOSBA_1ISM_FOA48c.wav"), "OSBA_1_2": TESTV_DIR.joinpath("stvOSBA_1ISM_2OA48c.wav"), "OSBA_1_3": TESTV_DIR.joinpath("stvOSBA_1ISM_3OA48c.wav"), @@ -192,6 +208,50 @@ FORMAT_TO_METADATA_FILES = { ], "MASA1": [str(TESTV_DIR.joinpath("stv1MASA1TC48c.met"))], "MASA2": [str(TESTV_DIR.joinpath("stv2MASA2TC48c.met"))], + "OMASA_1_1": [ + str(TESTV_DIR.joinpath("stvISM1.csv")), + str(TESTV_DIR.joinpath("stvOMASA_1ISM_1MASA1TC48c.met")), + ], + "OMASA_1_2": [ + str(TESTV_DIR.joinpath("stvISM1.csv")), + str(TESTV_DIR.joinpath("stvISM2.csv")), + str(TESTV_DIR.joinpath("stvOMASA_2ISM_2MASA1TC48c.met")), + ], + "OMASA_1_3": [ + str(TESTV_DIR.joinpath("stvISM1.csv")), + str(TESTV_DIR.joinpath("stvISM2.csv")), + str(TESTV_DIR.joinpath("stvISM3.csv")), + str(TESTV_DIR.joinpath("stvOMASA_3ISM_1MASA1TC48c.met")), + ], + "OMASA_1_4": [ + str(TESTV_DIR.joinpath("stvISM1.csv")), + str(TESTV_DIR.joinpath("stvISM2.csv")), + str(TESTV_DIR.joinpath("stvISM3.csv")), + str(TESTV_DIR.joinpath("stvISM4.csv")), + str(TESTV_DIR.joinpath("stvOMASA_4ISM_2MASA1TC48c.met")), + ], + "OMASA_2_1": [ + str(TESTV_DIR.joinpath("stvISM1.csv")), + str(TESTV_DIR.joinpath("stvOMASA_1ISM_1MASA2TC48c.met")), + ], + "OMASA_2_2": [ + str(TESTV_DIR.joinpath("stvISM1.csv")), + str(TESTV_DIR.joinpath("stvISM2.csv")), + str(TESTV_DIR.joinpath("stvOMASA_2ISM_2MASA2TC48c.met")), + ], + "OMASA_2_3": [ + str(TESTV_DIR.joinpath("stvISM1.csv")), + str(TESTV_DIR.joinpath("stvISM2.csv")), + str(TESTV_DIR.joinpath("stvISM3.csv")), + str(TESTV_DIR.joinpath("stvOMASA_3ISM_1MASA2TC48c.met")), + ], + "OMASA_2_4": [ + str(TESTV_DIR.joinpath("stvISM1.csv")), + str(TESTV_DIR.joinpath("stvISM2.csv")), + str(TESTV_DIR.joinpath("stvISM3.csv")), + str(TESTV_DIR.joinpath("stvISM4.csv")), + str(TESTV_DIR.joinpath("stvOMASA_4ISM_2MASA2TC48c.met")), + ], } diff --git a/tests/renderer/utils.py b/tests/renderer/utils.py index 52d1ccf19e..a538df7ee8 100644 --- a/tests/renderer/utils.py +++ b/tests/renderer/utils.py @@ -55,7 +55,6 @@ def test_info(request): def run_cmd(cmd, env=None): logging.info(f"\nRunning command\n{' '.join(cmd)}\n") - cmdJoin = " ".join(cmd) try: sp.run(cmd, check=True, capture_output=True, text=True, env=env) except sp.CalledProcessError as e: diff --git a/tests/scale_pcm.py b/tests/scale_pcm.py index 614e8cef3f..356cdd90e1 100755 --- a/tests/scale_pcm.py +++ b/tests/scale_pcm.py @@ -10,9 +10,7 @@ sys.path.append(os.path.join(os.path.dirname(THIS_PATH), "../scripts")) import concurrent.futures -import numpy as np import pyaudio3dtools -import pyivastest def scale_folder(folder, factor): diff --git a/tests/split_rendering/README.md b/tests/split_rendering/README.md index 0ff6b8dd0c..b63214c13b 100644 --- a/tests/split_rendering/README.md +++ b/tests/split_rendering/README.md @@ -1,5 +1,5 @@