diff --git a/lib_com/options.h b/lib_com/options.h index be3261f808c63ddbe7560694a0dab540adf8e556..66db6b7a68858631d444ee775babfc53472504ca 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -167,7 +167,7 @@ #define FIX_718_JBM_MD_UDPATE /* Fhg: fix issue #718, wrong setting of the update flag in the TD obj renderer in the JBM path */ #define FIX_719_CRASH_IN_CLEANUP /* VA: issue 719: fix Decoder crash after call to goto to cleanup */ - +/*#define FIX_312_FASTCONV_HRTF_LOAD*/ /* FhG: update loading of FastConv HRTFs from binary data - to be enabled after Matlab binary blob generation is harmonised */ /* ################## End BE DEVELOPMENT switches ######################### */ diff --git a/lib_util/hrtf_file_reader.c b/lib_util/hrtf_file_reader.c index 95d9b7c881c670d2658c59a8b43099661e9b6320..261c7f704f20bd1fb9386780e2e610599209dbfe 100644 --- a/lib_util/hrtf_file_reader.c +++ b/lib_util/hrtf_file_reader.c @@ -925,11 +925,13 @@ static ivas_error create_fastconv_HRTF_from_rawdata( hrtf_data_rptr = hrtf_data; +#ifndef FIX_312_FASTCONV_HRTF_LOAD /* BINAURAL_CONVBANDS */ if ( BINAURAL_CONVBANDS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) { return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (BINAURAL_CONVBANDS)" ); } +#endif hrtf_data_rptr += sizeof( uint16_t ); /* HRIR */ @@ -938,6 +940,13 @@ static ivas_error create_fastconv_HRTF_from_rawdata( ( *hHRTF )->FASTCONV_HRIR_latency_s = *( (float *) ( hrtf_data_rptr ) ); hrtf_data_rptr += sizeof( float ); +#ifdef FIX_312_FASTCONV_HRTF_LOAD + + if ( BINAURAL_CONVBANDS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (BINAURAL_CONVBANDS)" ); + } +#endif if ( HRTF_LS_CHANNELS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) { return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (HRTF_LS_CHANNELS)" ); @@ -989,6 +998,13 @@ static ivas_error create_fastconv_HRTF_from_rawdata( ( *hHRTF )->FASTCONV_HOA3_latency_s = *( (float *) ( hrtf_data_rptr ) ); hrtf_data_rptr += sizeof( float ); +#ifdef FIX_312_FASTCONV_HRTF_LOAD + + if ( BINAURAL_CONVBANDS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (BINAURAL_CONVBANDS)" ); + } +#endif if ( HOA3_CHANNELS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) { return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (HOA3_CHANNELS)" ); @@ -1038,6 +1054,13 @@ static ivas_error create_fastconv_HRTF_from_rawdata( /* HRIR_HOA2 */ ( *hHRTF )->FASTCONV_HOA2_latency_s = *( (float *) ( hrtf_data_rptr ) ); hrtf_data_rptr += sizeof( float ); +#ifdef FIX_312_FASTCONV_HRTF_LOAD + + if ( BINAURAL_CONVBANDS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (BINAURAL_CONVBANDS)" ); + } +#endif if ( HOA2_CHANNELS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) { return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (HOA2_CHANNELS)" ); @@ -1088,6 +1111,14 @@ static ivas_error create_fastconv_HRTF_from_rawdata( /* HRIR_FOA */ ( *hHRTF )->FASTCONV_FOA_latency_s = *( (float *) ( hrtf_data_rptr ) ); hrtf_data_rptr += sizeof( float ); +#ifdef FIX_312_FASTCONV_HRTF_LOAD + + + if ( BINAURAL_CONVBANDS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (BINAURAL_CONVBANDS)" ); + } +#endif if ( FOA_CHANNELS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) { return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (FOA_CHANNELS)" ); @@ -1139,6 +1170,12 @@ static ivas_error create_fastconv_HRTF_from_rawdata( ( *hHRTF )->FASTCONV_BRIR_latency_s = *( (float *) ( hrtf_data_rptr ) ); hrtf_data_rptr += sizeof( float ); +#ifdef FIX_312_FASTCONV_HRTF_LOAD + if ( BINAURAL_CONVBANDS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (BINAURAL_CONVBANDS)" ); + } +#endif if ( HRTF_LS_CHANNELS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) { return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (HRTF_LS_CHANNELS)" ); diff --git a/scripts/binauralRenderer_interface/Table_Format_Converter/generate_tables_from_rom_to_bin.c b/scripts/binauralRenderer_interface/Table_Format_Converter/generate_tables_from_rom_to_bin.c index fe9c9118a77c0effa26f426c885ba19b5b0f781c..98545d81d878927bd78e17dd7257ccd69f06de48 100644 --- a/scripts/binauralRenderer_interface/Table_Format_Converter/generate_tables_from_rom_to_bin.c +++ b/scripts/binauralRenderer_interface/Table_Format_Converter/generate_tables_from_rom_to_bin.c @@ -43,6 +43,7 @@ #define FILE_HEADER +#define PARAMBIN_FILE_312 /*------------------------------------------------------------------------------------------* * Constants @@ -54,9 +55,12 @@ #define DEFAULT_PATH "./" #endif -#define DEFAULT_INPUT_ROM_FILE "ivas_binaural" -#define DEFAULT_INPUT_TD_BIN_FILE "hrfilter_model" -#define DEFAULT_BIN_FILE_EXT ".bin" +#define DEFAULT_INPUT_ROM_FILE "ivas_binaural" +#define DEFAULT_INPUT_TD_BIN_FILE "hrfilter_model" +#ifdef PARAMBIN_FILE_312 +#define DEFAULT_INPUT_PARAMBIN_FILE "parambin_binary_rom" +#endif +#define DEFAULT_BIN_FILE_EXT ".bin" #define IVAS_NB_RENDERER_TYPE 7 #define IVAS_NB_AUDIO_CONFIG 4 @@ -160,8 +164,15 @@ void usage_tables_format_converter( void ) "-16 : Select 16 kHz sampling frequency (no multiple values, all frequencies by default).\n" "-32 : Select 32 kHz sampling frequency (no multiple values, all frequencies by default).\n" "-48 : Select 48 kHz sampling frequency (no multiple values, all frequencies by default).\n" ); - fprintf( stdout, "-input_td_file_path : Path of binary files for time-domain renderer (with separator, used as flag).\n" ); - fprintf( stdout, "-input_td_file_name : Name of input td file (without extension %s, default = '%s').\n", DEFAULT_BIN_FILE_EXT, DEFAULT_INPUT_TD_BIN_FILE ); + fprintf( stdout, "-input_td_file_path : Path of binary files for time-domain renderer (WITH separator, used as flag).\n" ); + fprintf( stdout, "-input_td_file_name : Name of input td file (WITHOUT extension %s, default = '%s').\n", DEFAULT_BIN_FILE_EXT, DEFAULT_INPUT_TD_BIN_FILE ); +#ifdef PARAMBIN_FILE_312 + fprintf( stdout, "-input_parambin_file_path : Path of binary files for parambin renderer (WITH separator, used as flag).\n" ); + fprintf( stdout, "-input_parambin_file_name : Name of input parambin file (WITHOUT extension %s, default = '%s').\n", DEFAULT_BIN_FILE_EXT, DEFAULT_INPUT_PARAMBIN_FILE ); + fprintf( stdout, "\n" ); + fprintf( stdout, "For example :\n" + "tables_format_converter(.exe) -output_file_path ./ -48 -input_td_file_path ./../../../td_object_renderer/hrtf_data/IVAS_default/ -input_td_file_name hrfilter_model_v003 -input_parambin_file_path ../../param_bin/ -input_parambin_file_name parambin_binary_rom\n"); +#endif fprintf( stdout, "\n" ); } @@ -177,6 +188,12 @@ char *input_td_bin_path = NULL; char *input_td_bin_file_name = NULL; char *full_in_td_path = NULL; +#ifdef PARAMBIN_FILE_312 +char *input_parambin_path = NULL; +char *input_parambin_file_name = NULL; +char *full_in_parambin_path = NULL; +#endif + int16_t nb_freq = IVAS_NB_SAMPLERATE; const int32_t *freq_ptr = sample_rates; @@ -1215,7 +1232,18 @@ char *create_hrtf_parametric( int32_t *hrtf_size ) uint32_t data_size_tmp; int16_t i, j; +#ifdef PARAMBIN_FILE_312 + uint8_t file_read_ok; + + float hrtfShCoeffsReFile[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]; + float hrtfShCoeffsImFile[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]; + float parametricReverberationTimesFile[CLDFB_NO_CHANNELS_MAX]; + float parametricReverberationEneCorrectionsFile[CLDFB_NO_CHANNELS_MAX]; + float parametricEarlyPartEneCorrectionFile[CLDFB_NO_CHANNELS_MAX]; + + FILE *input_parambin_file = NULL; +#endif hrtf_data_size = 0; /* Binary file - block description : @@ -1227,12 +1255,11 @@ char *create_hrtf_parametric( int32_t *hrtf_size ) hrtfShCoeffsIm => float[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]; BRIR-based reverb - CLDFB_NO_CHANNELS_MAX => uint16_t parametricReverberationTimes => float[CLDFB_NO_CHANNELS_MAX]; parametricReverberationEneCorrections => float[CLDFB_NO_CHANNELS_MAX]; parametricEarlyPartEneCorrection => float[CLDFB_NO_CHANNELS_MAX]; -*/ + */ // Compute total size of data to write // CLDFB SH domain HRTF-data @@ -1246,10 +1273,73 @@ char *create_hrtf_parametric( int32_t *hrtf_size ) hrtf_data_size += CLDFB_NO_CHANNELS_MAX * sizeof( float ); // parametricReverberationEneCorrections hrtf_data_size += CLDFB_NO_CHANNELS_MAX * sizeof( float ); // parametricEarlyPartEneCorrection +#ifdef PARAMBIN_FILE_312 + file_read_ok = 0; + file_read_ok = 0; + input_parambin_file = fopen( full_in_parambin_path, "rb" ); + if ( input_parambin_file != NULL ) + { + uint16_t hrtf_sh_channels, hrtf_num_bins, cldfb_no_channels_max; + + fseek( input_parambin_file, 0, SEEK_END ); + data_size_tmp = ftell( input_parambin_file ); + fseek( input_parambin_file, 0, SEEK_SET ); + + if ( data_size_tmp != hrtf_data_size ) + { + fprintf( stderr, "Inconsistent binary data file size (expected: %d, found %d). Using built-in default values.\n\n", hrtf_data_size, data_size_tmp ); + } + else + { + fread( &hrtf_sh_channels, sizeof( uint16_t ), 1, input_parambin_file ); + fread( &hrtf_num_bins, sizeof( uint16_t ), 1, input_parambin_file ); + if ( hrtf_sh_channels != HRTF_SH_CHANNELS ) + { + fprintf( stderr, "Warning: Inconsistent HRTF_SH_CHANNELS (expected: %d, found: %d).\n\n", HRTF_SH_CHANNELS, hrtf_sh_channels ); + } + if ( hrtf_num_bins != HRTF_NUM_BINS ) + { + fprintf( stderr, "Warning: Inconsistent HRTF_NUM_BINS (expected: %d, found: %d).\n\n", HRTF_NUM_BINS, hrtf_num_bins ); + } + + for ( size_t bin_chnl = 0; bin_chnl < BINAURAL_CHANNELS; bin_chnl++ ) + { + for ( size_t hrtf_chnl = 0; hrtf_chnl < HRTF_SH_CHANNELS; hrtf_chnl++ ) + { + fread( hrtfShCoeffsReFile[bin_chnl][hrtf_chnl], sizeof( float ), HRTF_NUM_BINS, input_parambin_file ); + } + } + for ( size_t bin_chnl = 0; bin_chnl < BINAURAL_CHANNELS; bin_chnl++ ) + { + for ( size_t hrtf_chnl = 0; hrtf_chnl < HRTF_SH_CHANNELS; hrtf_chnl++ ) + { + fread( hrtfShCoeffsImFile[bin_chnl][hrtf_chnl], sizeof( float ), HRTF_NUM_BINS, input_parambin_file ); + } + } + + /* reverb */ + fread( &cldfb_no_channels_max, sizeof( uint16_t ), 1, input_parambin_file ); + if ( cldfb_no_channels_max != CLDFB_NO_CHANNELS_MAX ) + { + fprintf( stderr, "Warning: Inconsistent CLDFB_NO_CHANNELS_MAX (expected: %d, found: %d).\n\n", CLDFB_NO_CHANNELS_MAX, cldfb_no_channels_max ); + } + + fread( parametricReverberationTimesFile, sizeof( float ), CLDFB_NO_CHANNELS_MAX, input_parambin_file ); + fread( parametricReverberationEneCorrectionsFile, sizeof( float ), CLDFB_NO_CHANNELS_MAX, input_parambin_file ); + fread( parametricEarlyPartEneCorrectionFile, sizeof( float ), CLDFB_NO_CHANNELS_MAX, input_parambin_file ); + + file_read_ok = 1; + } + } + else + { + fprintf( stderr, "Opening of parambin file %s failed. Using built-in default values.\n\n", full_in_parambin_path ); + } +#endif + // Allocate memory *hrtf_size = sizeof( ivas_hrtfs_header_t ) + hrtf_data_size; hrtf = (char *) malloc( *hrtf_size ); - if ( hrtf == NULL ) { fprintf( stderr, "Memory allocation for the block failed!\n\n" ); @@ -1257,6 +1347,7 @@ char *create_hrtf_parametric( int32_t *hrtf_size ) return NULL; } + // Write // Header [Declaration of the HRTF] @@ -1292,14 +1383,24 @@ char *create_hrtf_parametric( int32_t *hrtf_size ) *( (uint16_t *) ( hrtf_wptr ) ) = HRTF_NUM_BINS; hrtf_wptr += sizeof( uint16_t ); - // HRTF data_size_tmp = HRTF_NUM_BINS * sizeof( float ); for ( i = 0; i < BINAURAL_CHANNELS; i++ ) { for ( j = 0; j < HRTF_SH_CHANNELS; j++ ) { +#ifdef PARAMBIN_FILE_312 + if ( file_read_ok ) + { + memcpy( hrtf_wptr, &hrtfShCoeffsReFile[i][j], data_size_tmp ); + } + else + { + memcpy( hrtf_wptr, &hrtfShCoeffsRe[i][j], data_size_tmp ); + } +#else memcpy( hrtf_wptr, &hrtfShCoeffsRe[i][j], data_size_tmp ); +#endif hrtf_wptr += data_size_tmp; } } @@ -1307,7 +1408,18 @@ char *create_hrtf_parametric( int32_t *hrtf_size ) { for ( j = 0; j < HRTF_SH_CHANNELS; j++ ) { +#ifdef PARAMBIN_FILE_312 + if ( file_read_ok ) + { + memcpy( hrtf_wptr, &hrtfShCoeffsImFile[i][j], data_size_tmp ); + } + else + { + memcpy( hrtf_wptr, &hrtfShCoeffsIm[i][j], data_size_tmp ); + } +#else memcpy( hrtf_wptr, &hrtfShCoeffsIm[i][j], data_size_tmp ); +#endif hrtf_wptr += data_size_tmp; } } @@ -1317,13 +1429,28 @@ char *create_hrtf_parametric( int32_t *hrtf_size ) hrtf_wptr += sizeof( uint16_t ); data_size_tmp = CLDFB_NO_CHANNELS_MAX * sizeof( float ); - memcpy( hrtf_wptr, &( parametricReverberationTimes ), data_size_tmp ); // parametricReverberationTimes - hrtf_wptr += data_size_tmp; - memcpy( hrtf_wptr, &( parametricReverberationEneCorrections ), data_size_tmp ); // parametricReverberationEneCorrections - hrtf_wptr += data_size_tmp; - memcpy( hrtf_wptr, &( parametricEarlyPartEneCorrection ), data_size_tmp ); // parametricEarlyPartEneCorrection - hrtf_wptr += data_size_tmp; - +#ifdef PARAMBIN_FILE_312 + if ( file_read_ok ) + { + memcpy( hrtf_wptr, &( parametricReverberationTimesFile ), data_size_tmp ); // parametricReverberationTimes + hrtf_wptr += data_size_tmp; + memcpy( hrtf_wptr, &( parametricReverberationEneCorrectionsFile ), data_size_tmp ); // parametricReverberationEneCorrections + hrtf_wptr += data_size_tmp; + memcpy( hrtf_wptr, &( parametricEarlyPartEneCorrectionFile ), data_size_tmp ); // parametricEarlyPartEneCorrection + hrtf_wptr += data_size_tmp; + } + else + { +#endif + memcpy( hrtf_wptr, &( parametricReverberationTimes ), data_size_tmp ); // parametricReverberationTimes + hrtf_wptr += data_size_tmp; + memcpy( hrtf_wptr, &( parametricReverberationEneCorrections ), data_size_tmp ); // parametricReverberationEneCorrections + hrtf_wptr += data_size_tmp; + memcpy( hrtf_wptr, &( parametricEarlyPartEneCorrection ), data_size_tmp ); // parametricEarlyPartEneCorrection + hrtf_wptr += data_size_tmp; +#ifdef PARAMBIN_FILE_312 + } +#endif return hrtf; } @@ -2332,6 +2459,34 @@ int rom2bin_init( int argc, char *argv[] ) strcpy( input_td_bin_file_name, argv[i] ); i++; } +#ifdef PARAMBIN_FILE_312 + else if ( strcmp( to_upper( argv[i] ), "-INPUT_PARAMBIN_FILE_PATH" ) == 0 ) + { + i++; + if ( strlen( argv[i] ) == 0 ) + { + fprintf( stderr, "Wrong input parambin file path: %s\n\n", argv[i] ); + usage_tables_format_converter(); + return -1; + } + input_parambin_path = malloc( strlen( argv[i] ) + 1 ); + strcpy( input_parambin_path, argv[i] ); + i++; + } + else if ( strcmp( to_upper( argv[i] ), "-INPUT_PARAMBIN_FILE_NAME" ) == 0 ) + { + i++; + if ( strlen( argv[i] ) == 0 ) + { + fprintf( stderr, "Wrong input parambin file name: %s\n\n", argv[i] ); + usage_tables_format_converter(); + return -1; + } + input_parambin_file_name = malloc( strlen( argv[i] ) + 1 ); + strcpy( input_parambin_file_name, argv[i] ); + i++; + } +#endif else { fprintf( stderr, "Unknown option: %s\n\n", argv[i] ); @@ -2427,7 +2582,45 @@ int rom2bin_init( int argc, char *argv[] ) return -1; } } +#ifdef PARAMBIN_FILE_312 + if ( input_parambin_path == NULL ) + { + input_parambin_path = (char *) malloc( sizeof( char ) * ( strlen( DEFAULT_PATH ) + 1 ) ); + if ( input_parambin_path ) + { + strcpy( input_parambin_path, DEFAULT_PATH ); + } + else + { + fprintf( stderr, "Memory issue for input parambin file path!\n\n" ); + rom2bin_terminat(); + return -1; + } + } + if ( input_parambin_file_name == NULL ) + { + input_parambin_file_name = (char *) malloc( sizeof( char ) * ( strlen( DEFAULT_INPUT_PARAMBIN_FILE ) + 1 ) ); + if ( input_parambin_file_name ) + { + strcpy( input_parambin_file_name, DEFAULT_INPUT_PARAMBIN_FILE ); + } + else + { + fprintf( stderr, "Memory issue for input parambin file name!\n\n" ); + rom2bin_terminat(); + return -1; + } + } + full_in_parambin_path = (char *) malloc( sizeof( char ) * ( strlen( input_parambin_path ) + strlen( input_parambin_file_name ) + strlen( DEFAULT_BIN_FILE_EXT ) + 2 ) ); + if ( full_in_parambin_path == NULL ) + { + fprintf( stderr, "Memory issue for full input parambin path!\n\n" ); + rom2bin_terminat(); + return -1; + } + sprintf( full_in_parambin_path, "%s/%s%s", input_parambin_path, input_parambin_file_name, DEFAULT_BIN_FILE_EXT ); +#endif return 0; } @@ -2467,6 +2660,22 @@ void rom2bin_terminat( void ) { free( full_in_td_path ); } +#ifdef PARAMBIN_FILE_312 + if ( input_parambin_path != NULL ) + { + free( input_parambin_path ); + } + + if ( input_parambin_file_name != NULL ) + { + free( input_parambin_file_name ); + } + + if ( full_in_parambin_path != NULL ) + { + free( full_in_parambin_path ); + } +#endif } /*---------------------------------------------------------------------* diff --git a/scripts/binauralRenderer_interface/Table_Format_Converter/tables_format_converter_readme.txt b/scripts/binauralRenderer_interface/Table_Format_Converter/tables_format_converter_readme.txt index 20aba7a237ac77f5a00fbc4941b31506c335ee9e..2461679a2084c8bd212dd3dcee1bc26b46019841 100644 --- a/scripts/binauralRenderer_interface/Table_Format_Converter/tables_format_converter_readme.txt +++ b/scripts/binauralRenderer_interface/Table_Format_Converter/tables_format_converter_readme.txt @@ -37,7 +37,7 @@ The table format converter is used to generate the file containing the binary re filters for renderers (dynamic loading of generated file using –hrtf argument). This tool is able : - to generate binary file for MIXER_CONV, MIXER_CONV_ROOM (tables conversion from ROM); - - to aggregate the binary HR filter of OBJECTS_TD (to be done : FASTCONV and PARAMETRIC binaural) + - to aggregate the binary HR filter of OBJECTS_TD, PARAM_BIN (to be done : FASTCONV) First, build the converter under scripts/binauralRenderer_interface/Table_Format_Converter/ in VSCode (using CMakeList). @@ -53,8 +53,10 @@ Options : -16 : Select 16 kHz sampling frequency (no multiple values, all frequencies by default). -32 : Select 32 kHz sampling frequency (no multiple values, all frequencies by default). -48 : Select 48 kHz sampling frequency (no multiple values, all frequencies by default). --input_td_file_path : Path of binary files for time-domain renderer (with separator, used as flag). --input_td_file_name : Name of input td file (without extension .bin, default = 'hrfilter_model'). +-input_td_file_path : Path of binary files for time-domain renderer (WITH separator, used as flag). +-input_td_file_name : Name of input td file (WITHOUT extension .bin, default = 'hrfilter_model'). +-input_parambin_file_path : Path of binary files for parambin renderer (WITH separator, used as flag). +-input_parambin_file_name : Name of input parambin file (WITHOUT extension .bin, default = 'parambin_binary_rom'). For example : -tables_format_converter(.exe) -output_file_path './' -48 -input_td_file_path './../../../td_object_renderer/hrtf_data/IVAS_default/' -input_td_file_name 'hrfilter_model_v003' \ No newline at end of file +tables_format_converter(.exe) -output_file_path ./ -48 -input_td_file_path ./../../../td_object_renderer/hrtf_data/IVAS_default/ -input_td_file_name hrfilter_model_v003 -input_parambin_file_path ../../param_bin/ -input_parambin_file_name parambin_binary_rom diff --git a/scripts/binauralRenderer_interface/fastconv/README.txt b/scripts/binauralRenderer_interface/fastconv/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..3a54d1cdf9645dcc83ba4cedf4e81ccf67fce369 --- /dev/null +++ b/scripts/binauralRenderer_interface/fastconv/README.txt @@ -0,0 +1,3 @@ +WIP: +The script to generate all FastConv Renderer tables is generate_tables_for_fastconv.m +Options can be set in the script to generate either or both ROM tables and a Binary file. \ No newline at end of file diff --git a/scripts/binauralRenderer_interface/fastconv/cldfb_prototype.mat b/scripts/binauralRenderer_interface/fastconv/cldfb_prototype.mat new file mode 100644 index 0000000000000000000000000000000000000000..6e9e08fb0ed81fcc71bbe21005140d914ffcef64 --- /dev/null +++ b/scripts/binauralRenderer_interface/fastconv/cldfb_prototype.mat @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:386bbd3a02c3b95280fff7bd8f5240ee60f8858889cad0f6147e930f5f2aa7e2 +size 1246 diff --git a/scripts/binauralRenderer_interface/fastconv/fastconv_rom.bin b/scripts/binauralRenderer_interface/fastconv/fastconv_rom.bin new file mode 100644 index 0000000000000000000000000000000000000000..142a8c0cb0db343f03ea8c40bb7c0c6c4515ebfd --- /dev/null +++ b/scripts/binauralRenderer_interface/fastconv/fastconv_rom.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d51073bd85ad997196e025de2b088b3aeed20e087a3b0480076180cb02b0ab21 +size 1258230 diff --git a/scripts/binauralRenderer_interface/fastconv/generate_BRIR_CLDFB_FASTCONV.m b/scripts/binauralRenderer_interface/fastconv/generate_BRIR_CLDFB_FASTCONV.m new file mode 100644 index 0000000000000000000000000000000000000000..65b4e4d43d6bae0f05d43635f79a3b97a4189b84 --- /dev/null +++ b/scripts/binauralRenderer_interface/fastconv/generate_BRIR_CLDFB_FASTCONV.m @@ -0,0 +1,369 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% (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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function FastConv_SD_BRIR = generate_BRIR_CLDFB_FASTCONV(sofa_file, max_band) +%% generate_BRIR_CLDFB_FASTCONV(rom_c_file, sofa_file): +% script for getting the binaural room impulse response coefficients in CLDFB domain +% - loads sphere-samples BRIRs given in sofa_file (must match requested speaker positions!) +% - converts SD BRIRs to Complex Low Delay Filter Bank (CLDFB) domain using td2cldfb.m +% - truncates CLDFB BRIRs in frequency and time +% - writes CLDFB BRIRs to c-code ROM tables +if ~exist('sofa_file','var') || isempty(sofa_file) + sofa_file = fullfile(thispath,'..','BRIRs_sofa','IIS_BRIR_officialMPEG_Combined.sofa'); +end +if ~exist('max_band', 'var') || isempty(max_band) + max_band = 50; +end + +%% Load CLDFB protopyte +load('cldfb_prototype.mat'); + +%% Load HRTFs +addpath("../matlab_hrir_generation_scripts"); +sofaData = hrtf_library_loader(); +sofaData.readSOFA(char(sofa_file)); +ls_struct = get_ls_layout_config('Combined'); + +IR = permute(sofaData.Data.IR(:,:,:), [3 2 1]); + +% match required loudspeaker positions +brirAziRad = sofaData.PosSpherical(1, :).'; +brirEleRad = sofaData.PosSpherical(2, :).'; +refAziRad = deg2rad(ls_struct.azi)'; +refEleRad = deg2rad(ls_struct.ele)'; +refVectors = [cos(refAziRad).*cos(refEleRad) sin(refAziRad).*cos(refEleRad) sin(refEleRad)]; +sofaVectors = [cos(brirAziRad).*cos(brirEleRad) sin(brirAziRad).*cos(brirEleRad) sin(brirEleRad)]; +for ch = 1:length(refAziRad) + [~, maxIndex] = max(sofaVectors*refVectors(ch,:)'); + chSelect(ch) = maxIndex; +end +IR = IR(:, :, chSelect); + +% Resample IRs if needed +fs = sofaData.Lib_SampleRate; +if fs~=48000 + hrir_in = permute(IR,[2 3 1]); + IR = permute(resamp_hrir(hrir_in,fs),[3 1 2]); +end + +%% TD -> CLDFB +clear IR_cldfb; + +[BRIR_cldfb, rev_param] = compute_brir_parameters(IR,prototype,max_band); +BRIR_cldfb = permute(BRIR_cldfb, [3 1 4 2]); +BRIR_cldfb = BRIR_cldfb(:,1:max_band,:,:); + +FastConv_SD_BRIR.IR = BRIR_cldfb; +FastConv_SD_BRIR.rev_param = rev_param; +end + + +function [hrir,Nhrir] = resamp_hrir(hrir_in,fs) + +Nhrir_in = size(hrir_in,3); +nEar = size(hrir_in,1); +nDir = size(hrir_in,2); + +if fs ~= 48000 + + r = fs/48000; + fs = 48000; + + Nhrir = Nhrir_in/r; + + hrir = zeros([nEar,nDir,Nhrir]); + data(1:Nhrir_in) = 0.0; + + for iEar = 1:nEar + for iDir = 1:nDir + data(1:Nhrir_in) = hrir_in(iEar,iDir,:); + data(1:Nhrir) = decimate(data,r,'fir'); + hrir(iEar,iDir,1:Nhrir) = data(1:Nhrir); + end + end + +else + + hrir = hrir_in; + Nhrir = Nhrir_in; + +end + +end + + +function [IR_cldfb,reverb_parameters] = compute_brir_parameters(IR,prototype,max_band) +% Step 1: Compute the propogation time and remove the propogation time +in_struct.propogationTime = 0; +in_struct.fs = 48000; +[IR,in_struct] = compensate_prop_time(IR,in_struct); +in_struct.THR_DE = -20; +in_struct.max_band = max_band; +in_struct.max_index = 273; % Needs to be changed according to IRs + +% Step 2: TD -> CLDFB +IR_cldfb = []; +for chIdx = 1:size(IR,3) + for outChIdx = 1:size(IR,2) + IR_cldfb(:,:,outChIdx,chIdx) = td2cldfb( IR(:,outChIdx,chIdx), prototype, 60 ); + end +end + +% Step 3: Compute EDC (Energy Decay Curve) +in_struct.num_bands = size(IR_cldfb,1); +in_struct.timeSlots = size(IR_cldfb,2); +assert(in_struct.timeSlots > in_struct.max_index) +in_struct.num_channels = size(IR_cldfb,4); +EDC = get_EDC(IR_cldfb,in_struct); + +% Step 4: Determine Mixing Time +mixingTime = getMixingTime(EDC, in_struct); + +% Compute the time-slot where the IR is truncated +in_struct.NFft = floor((mixingTime)); +NFilter = max(in_struct.NFft(1:in_struct.max_band)); + +% Variable order Filtering +for idx = 1:5 + in_struct.NFft(idx) = NFilter; +end +for idx = 6:10 + in_struct.NFft(idx) = ceil(0.6*NFilter); +end +for idx = 11:20 + in_struct.NFft(idx) = ceil(0.5*NFilter); +end +for idx = 21:30 + in_struct.NFft(idx) = ceil(0.4*NFilter); +end +for idx = 31:in_struct.max_band + in_struct.NFft(idx) = ceil(0.3*NFilter); +end + +% Step 5: Compute reverb parameters +% compute rt60 and energy +reverb_parameters = get_Reverb_parameters(IR_cldfb,in_struct); +reverb_parameters.NFilter = NFilter; + +end + +function [IR_out,in_struct] = compensate_prop_time(IR_in,in_struct) + +% Get the min index +min_idx = zeros(1,size(IR_in,3)); +for chIdx = 1:size(IR_in,3) + [~,idx] = max(abs(IR_in(:,:,chIdx))); + min_idx(chIdx) = min(idx); +end + +prop_time = min(min_idx) - 15; +in_struct.propogationTime = prop_time; +in_struct.latency_s = (min(min_idx) - 1 - prop_time)/in_struct.fs + 31/in_struct.fs; + +IR_out = []; +for chIdx = 1:size(IR_in,3) + IR_out(:,:,chIdx) = IR_in(prop_time:end,:,chIdx); +end + +end + +function EDC = get_EDC(in,in_struct) + bands = in_struct.num_bands; + timeSlots = in_struct.timeSlots; + numChannels = in_struct.num_channels; + + % EDC: Energy decay curve + EDC = zeros(bands,timeSlots,2,numChannels); + for chIdx = 1:numChannels + tmp = in(:,:,:,chIdx); + for idx = 1:2 + for bandIdx = 1:bands + sum_1 = sum(abs(tmp(bandIdx,1:end,idx)).^2); + for timeIdx = 1:timeSlots + sum_2 = sum(abs(tmp(bandIdx,timeIdx:end,idx)).^2); + EDC(bandIdx,timeIdx,idx,chIdx) = 10*log10(sum_2/sum_1); + end + end + end + end +end + +function mixingTime = getMixingTime(EDC, in_struct) +THR_DE = in_struct.THR_DE; +bands = in_struct.num_bands; +numChannels = in_struct.num_channels; +N = size(EDC,2); +mixingTime = zeros(1,bands); + +for idx = 1:bands + mixingTime(idx) = 0; + for chIdx = 1:numChannels + THR = EDC(idx,1,1,chIdx) + THR_DE; + n = 2; + while( EDC(idx,n,1,chIdx) > THR ) + n = n + 1; + if(n > N) + break; + end + end + mixingTime(idx) = mixingTime(idx) + (n+1); + end + for chIdx = 1:numChannels + THR = EDC(idx,1,2,chIdx) + THR_DE; + n = 2; + while( EDC(idx,n,2,chIdx) > THR ) + n = n + 1; + if(n > N) + break; + end + end + mixingTime(idx) = mixingTime(idx) + (n+1); + end + mixingTime(idx) = mixingTime(idx)/(2*numChannels); +end +end + +function RT60 = computeRT60(in,s_idx,e_idx,in_struct) +% define t based on the length of reverb tail +end_idx = length(in); +s_i = (s_idx*in_struct.num_bands)/in_struct.fs; +e_i = (e_idx*in_struct.num_bands)/in_struct.fs; +t = linspace(s_i,e_i,end_idx); + +% compute EDC (Energy Decay curve) of the reverb tail +EDC = zeros(1,end_idx); +sum2 = sum(abs(in(1:end_idx)).^2); +for idx = 1:end_idx + sum1 = sum(abs(in(idx:end_idx)).^2); + EDC(idx) = 10*log10(sum1/sum2); +end + +% compute index, i5 and i35 +% i5 is the time required for EDC to reduce by 5dB +% i35 is the time required for EDC to reduce by 35dB +% Based on i5 and i35, we compute the T30 and estimate T60 +index = find(EDC==0,1,'last'); + +i0 = index; +i5 = i0+1; +while EDC(i5) > (EDC(i0)-5) + i5 = i5+1; +end + +i35 = i5+1; +while ((EDC(i35) > (EDC(i0) -35)) && (i35 < end_idx)) + i35 = i35 + 1; +end + +% Compute T(30) and T(60) +if (i35 > floor(length(EDC) * 0.95)) + i35 = round(length(EDC) * 0.95); + amp = EDC(i35); + fact = -65 / amp; +else + fact = 2; +end +if (i5) > length(EDC) * 0.5 + i5 = 1; +end + +RT30 = t(i35) - t(i5); +RT60 = fact * RT30; +end + +function reverbParameters = get_Reverb_parameters(IR_CLDFB,input_struct) + +% start the analysis for computing reverb parameters +ENRG = zeros(input_struct.num_bands,1); +RT60 = zeros(input_struct.num_bands,1); +ct_num = 0; +max_index = input_struct.max_index; + + +disp('Late Reverberation Analysis Started') +for chIdx = 1:input_struct.num_channels + disp(['Analyzing channel ' num2str(chIdx) '/' num2str(input_struct.num_channels)]) + for outChIdx = 1:2 + for bandIdx = 1:input_struct.num_bands + % the computation of reverb parameters starts with some overlap + s_idx = input_struct.NFft(bandIdx)-5; + + % Determine the truncation point based on noise floor estimates + end_idx = get_truncation_point(IR_CLDFB(bandIdx,s_idx:max_index,outChIdx,chIdx)); + e_idx = s_idx + end_idx; + if(e_idx > max_index) + e_idx = max_index; + end + + % Extract the reverb tail that is used for energy/RT60 + % computation + input_signal = IR_CLDFB(bandIdx,s_idx:e_idx,outChIdx,chIdx); + + % Estimate RT60 and Energy + ENRG_tmp = sum(abs(input_signal.^2)); + RT60_tmp = computeRT60(input_signal,s_idx,e_idx,input_struct); + + ENRG(bandIdx) = ENRG(bandIdx) + ENRG_tmp; + RT60(bandIdx) = RT60(bandIdx) + RT60_tmp; + end + end + ct_num = ct_num + 2; +end + +reverbParameters.latency_s = input_struct.latency_s; +reverbParameters.nrgLr = ENRG/ct_num; +reverbParameters.rt60 = RT60/ct_num; +reverbParameters.kAna = input_struct.num_bands; +end + +function end_index = get_truncation_point(in) +end_idx = length(in); + +% Compute the energy in log domain +log_energy = 10*log10(abs(in(1:end_idx)).^2); +noisefloor = mean(log_energy); + +% Decay line(Line Fitting to EDC) +x = 1:end_idx; +order = 1; % order of the polynomial that is used to fit +% p(1) is the slope, p(2) is the bias +p = polyfit(x,log_energy,order); +decay = p(1)*x + p(2); % Straight line equation + +% find the intersection point +cp = find(decay < noisefloor, 1, 'first'); +if isempty(cp) + cp = end_idx; +end + +end_index = cp; +end + diff --git a/scripts/binauralRenderer_interface/fastconv/generate_tables_for_fastconv.m b/scripts/binauralRenderer_interface/fastconv/generate_tables_for_fastconv.m new file mode 100644 index 0000000000000000000000000000000000000000..a385cd5511ceecd7d2885baaaf474bd8e5201e84 --- /dev/null +++ b/scripts/binauralRenderer_interface/fastconv/generate_tables_for_fastconv.m @@ -0,0 +1,73 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% (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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +clear all; +close all; +clc; + +%% add path for hrtf_library_loader.m +addpath('../matlab_hrir_generation_scripts/'); + +%% Set arguments +writeRomFileOutput = true; +writeBinaryOutput = true; +rom_file = fullfile('.', 'ivas_rom_binauralRenderer.c'); +bin_file = fullfile('.', 'fastconv_rom.bin'); + +%% Set input files +hrir_file = fullfile('..', 'HRIRs_sofa', 'HRIR_128_Meth5_IRC_53_Q10_symL_Itrp1_48000.sofa'); +brir_file = fullfile('..', 'BRIRs_sofa', 'IIS_BRIR_officialMPEG_Combined.sofa'); + +%% Generate C-code tables for RENDERER_BINAURAL_FASTCONV (SHD) +disp('Processing HRIRs (FOA) for FastConv renderer...'); +FastConv_SHD_IR_FOA = SHD_2_ROM(hrir_file, 1, 128); + +disp('Processing HRIRs (HOA2) for FastConv renderer...'); +FastConv_SHD_IR_HOA2 = SHD_2_ROM(hrir_file, 2, 128); + +disp('Processing HRIRs (HOA3) for FastConv renderer...'); +FastConv_SHD_IR_HOA3 = SHD_2_ROM(hrir_file, 3, 128); + +%% Generate C-code tables for RENDERER_BINAURAL_FASTCONV (SD) +disp('Processing HRIRs (SD) for FastConv renderer...'); +FastConv_SD_IR = SD_2_ROM(hrir_file); + +%% Generate C-code tables for RENDERER_BINAURAL_FASTCONV_ROOM (SD) +disp('Processing BRIRs (SD) for FastConv renderer...'); +FastConv_SD_BRIR = generate_BRIR_CLDFB_FASTCONV(brir_file); + +if writeRomFileOutput + write_fastconv_rom_table(rom_file, FastConv_SHD_IR_FOA, FastConv_SHD_IR_HOA2, FastConv_SHD_IR_HOA3, FastConv_SD_IR, FastConv_SD_BRIR); +end + +if writeBinaryOutput + write_fastconv_binary_data(bin_file, FastConv_SHD_IR_FOA, FastConv_SHD_IR_HOA2, FastConv_SHD_IR_HOA3, FastConv_SD_IR, FastConv_SD_BRIR); +end diff --git a/scripts/binauralRenderer_interface/fastconv/get_ivas_binary_header.m b/scripts/binauralRenderer_interface/fastconv/get_ivas_binary_header.m new file mode 100644 index 0000000000000000000000000000000000000000..91429e46e9eac861d352b3a454ed37cedc5d501c --- /dev/null +++ b/scripts/binauralRenderer_interface/fastconv/get_ivas_binary_header.m @@ -0,0 +1,85 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% (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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function header = get_ivas_binary_header(renderer_type, bin_in_fmt) +%GET_IVAS_BINARY_HEADER Returns the values required to write the binary +% header by parsing the IVAS enum values +% +% Header [Declaration of the HRTF] +% Renderer type (int32_t) : See "RENDERER_TYPE" +% Decoder output format / Binary input format (int32_t) : See "BINAURAL_INPUT_AUDIO_CONFIG" +% Sampling Frequency (int32_t) : Depends on RENDERER_TYPE! +% Raw data size (uint32_t): !!Not set by this function!! +% +%% placeholder values +header.renderer_type = 0; +header.in_fmt = 0; +header.fs = 48000; % TODO not relevant for FastConv/ParamBin +header.chunksize = 0; + +%% parse IVAS enum +% read the file +ivas_cnst_path = '../../../lib_com/ivas_cnst.h'; % must be replaced if this file is moved +c = fileread(ivas_cnst_path); + +% regex for RENDERER_TYPE +rt_expr = '^\s+(RENDERER\w+)'; +rt_tok = regexp(c, rt_expr, 'tokens', 'dotexceptnewline', 'lineanchors'); + +renderer_types = convertCharsToStrings(cat(1,rt_tok{:})); +renderer_types = strip(renderer_types); +renderer_types = replace(renderer_types, ',', ''); + +header.renderer_type = find(renderer_type == renderer_types); +if header.renderer_type + header.renderer_type = header.renderer_type - 1; % matlab index to c enum index +else + disp(renderer_types); + error('Renderer type could not be matched to IVAS enum values!'); +end + +% regex for BINAURAL_INPUT_AUDIO_CONFIG +ic_expr = '^\s+(BINAURAL_INPUT\w+)'; +ic_tok = regexp(c, ic_expr, 'tokens', 'dotexceptnewline', 'lineanchors'); +in_configs = convertCharsToStrings(cat(1,ic_tok{:})); +in_configs = strip(in_configs); +in_configs = replace(in_configs, ',', ''); + +header.in_fmt = find(bin_in_fmt == in_configs); +if header.in_fmt + header.in_fmt = header.in_fmt - 1; % matlab index to c enum index +else + disp(in_configs); + error('Binaural input config could not be matched to IVAS enum values!'); +end + +end + diff --git a/scripts/binauralRenderer_interface/fastconv/td2cldfb.m b/scripts/binauralRenderer_interface/fastconv/td2cldfb.m new file mode 100644 index 0000000000000000000000000000000000000000..19eb36a55d93b709ba8aebc791efb20f28e4c695 --- /dev/null +++ b/scripts/binauralRenderer_interface/fastconv/td2cldfb.m @@ -0,0 +1,60 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% (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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function [ out ] = td2cldfb( in, prototype, L ) +% TD2CLDFB +% This script takes the td signal along with prototype and length and +% outputs the frequemcy domain signal + +N_in = length(in); +N_prototype = length(prototype); + +K_prototype = ceil(N_prototype/L); +K_in = ceil(N_in/L); + +N = K_prototype + K_in - 1; + +hext = zeros(L*(2*K_prototype + K_in - 2),1); +hext((K_prototype-1)*L+(1:N_in)) = in; % extend to make all shifts possible + +out=zeros(L,N); + +Nmid = N_prototype/2; % midpoint +ls = -Nmid+1:Nmid; +ns = (0:L-1)'; +E = exp(-1i*(pi/L)*(ns+.5)*ls); + +for k=1:N + shift=(k-1)*L; + out(:,k)=E*(hext(shift+(1:N_prototype)).*prototype(:)); +end +end + diff --git a/scripts/binauralRenderer_interface/fastconv/write_fastconv_binary_data.m b/scripts/binauralRenderer_interface/fastconv/write_fastconv_binary_data.m new file mode 100644 index 0000000000000000000000000000000000000000..d312f23d3beb0378f8fe425b832809decbfa3219 --- /dev/null +++ b/scripts/binauralRenderer_interface/fastconv/write_fastconv_binary_data.m @@ -0,0 +1,294 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% (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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function write_fastconv_binary_data(bin_file, FastConv_SHD_IR_FOA, FastConv_SHD_IR_HOA2, FastConv_SHD_IR_HOA3, FastConv_SD_IR, FastConv_SD_BRIR) +% +% Writes HRIR & BRIR based data for FastConv binaural renderer into a binary file. +% +% write_fastconv_binary_data(rom_file, FastConv_SHD_IR_FOA, FastConv_SHD_IR_HOA2, FastConv_SHD_IR_HOA3, FastConv_SD_IR, FastConv_SD_BRIR) +% +% filename : string +% name of the file to be written +% +% +% Output file format: +% Header [Declaration of the HRTF] +% Renderer type (int32_t) : See "RENDERER_TYPE" +% Decoder output format (int32_t) : See "BINAURAL_INPUT_AUDIO_CONFIG" +% Sampling Frequency (int32_t) +% Raw data size (uint32_t) +% +% HRIRs +% latency_s => float32 +% BINAURAL_CONVBANDS => uint16_t +% num_channels => uint16_t +% BINAURAL_NTAPS => uint16_t +% leftHRIRReal => float32[BINAURAL_CONVBANDS][num_channels][num_taps] +% leftHRIRImag => float32[BINAURAL_CONVBANDS][num_channels][num_taps] +% rightHRIRReal => float32[BINAURAL_CONVBANDS][num_channels][num_taps] +% rightHRIRImag => float32[BINAURAL_CONVBANDS][num_channels][num_taps] +% +% BRIRs +% latency_s => float32 +% num_channels => uint16_t +% BINAURAL_NTAPS_MAX => uint16_t +% leftBRIRReal => float32[BINAURAL_CONVBANDS][num_channels][num_taps] +% leftBRIRImag => float32[BINAURAL_CONVBANDS][num_channels][num_taps] +% rightBRIRReal => float32[BINAURAL_CONVBANDS][num_channels][num_taps] +% rightBRIRImag => float32[BINAURAL_CONVBANDS][num_channels][num_taps] +% CLDFB_NO_CHANNELS_MAX => uint16_t +% fastConvReverberationTimes => float32[CLDFB_NO_CHANNELS_MAX] +% fastConvReverberationEneCorrections => float32[CLDFB_NO_CHANNELS_MAX] +% + +[f_id, err_msg] = fopen(bin_file, 'wb'); + +if f_id == -1 + error('Could not open file %s for writing. Error message:\n%s', filename, err_msg); +end + +%% File header +% We need to get the chunksize of all IRs to get total size +% SHD HRIRs +% FOA +IR = FastConv_SHD_IR_FOA; +[~, binaural_convbands, num_channels, binaural_ntaps] = size(IR.IR); + +header = get_ivas_binary_header('RENDERER_BINAURAL_FASTCONV', ['BINAURAL_INPUT_AUDIO_CONFIG_' IR.order]); +header.chunksize = header.chunksize + 4; % latency_s +header.chunksize = header.chunksize + 2; % BINAURAL_CONVBANDS +header.chunksize = header.chunksize + 2; % num_channels +header.chunksize = header.chunksize + 2; % num_taps +header.chunksize = header.chunksize + 4 * (binaural_convbands * num_channels * binaural_ntaps * 4 ); % HRTF L/R Re/Im + +IR.header = header; +FastConv_SHD_IR_FOA = IR; + +% HOA2 +IR = FastConv_SHD_IR_HOA2; +[~, binaural_convbands, num_channels, binaural_ntaps] = size(IR.IR); + +header = get_ivas_binary_header('RENDERER_BINAURAL_FASTCONV', ['BINAURAL_INPUT_AUDIO_CONFIG_' IR.order]); +header.chunksize = header.chunksize + 4; % latency_s +header.chunksize = header.chunksize + 2; % BINAURAL_CONVBANDS +header.chunksize = header.chunksize + 2; % num_channels +header.chunksize = header.chunksize + 2; % num_taps +header.chunksize = header.chunksize + 4 * (binaural_convbands * num_channels * binaural_ntaps * 4 ); % HRTF L/R Re/Im + +IR.header = header; +FastConv_SHD_IR_HOA2 = IR; + +% HOA3 +IR = FastConv_SHD_IR_HOA3; +[~, binaural_convbands, num_channels, binaural_ntaps] = size(IR.IR); + +header = get_ivas_binary_header('RENDERER_BINAURAL_FASTCONV', ['BINAURAL_INPUT_AUDIO_CONFIG_' IR.order]); +header.chunksize = header.chunksize + 4; % latency_s +header.chunksize = header.chunksize + 2; % BINAURAL_CONVBANDS +header.chunksize = header.chunksize + 2; % num_channels +header.chunksize = header.chunksize + 2; % num_taps +header.chunksize = header.chunksize + 4 * (binaural_convbands * num_channels * binaural_ntaps * 4 ); % HRTF L/R Re/Im + +IR.header = header; +FastConv_SHD_IR_HOA3 = IR; + +% SD HRIRs +IR = FastConv_SD_IR; +[~, binaural_convbands, num_channels, binaural_ntaps] = size(IR.IR); + +header = get_ivas_binary_header('RENDERER_BINAURAL_FASTCONV', 'BINAURAL_INPUT_AUDIO_CONFIG_COMBINED'); +header.chunksize = header.chunksize + 4; % latency_s +header.chunksize = header.chunksize + 2; % BINAURAL_CONVBANDS +header.chunksize = header.chunksize + 2; % num_channels +header.chunksize = header.chunksize + 2; % num_taps +header.chunksize = header.chunksize + 4 * (binaural_convbands * num_channels * binaural_ntaps * 4 ); % HRTF L/R Re/Im + +IR.header = header; +FastConv_SD_IR = IR; + +% SD BRIRs +IR = FastConv_SD_BRIR; +[~, binaural_convbands, num_channels, ~] = size(IR.IR); +cldfb_no_channels_max = IR.rev_param.kAna; + +header = get_ivas_binary_header('RENDERER_BINAURAL_FASTCONV_ROOM', 'BINAURAL_INPUT_AUDIO_CONFIG_COMBINED'); +header.chunksize = header.chunksize + 4; % latency_s +header.chunksize = header.chunksize + 2; % BINAURAL_CONVBANDS +header.chunksize = header.chunksize + 2; % num_channels +header.chunksize = header.chunksize + 2; % num_taps +header.chunksize = header.chunksize + 4 * (binaural_convbands * num_channels * IR.rev_param.NFilter * 4 ); % HRTF L/R Re/Im +header.chunksize = header.chunksize + 2; % CLDFB_NO_CHANNELS_MAX +header.chunksize = header.chunksize + cldfb_no_channels_max * 4; % rt60 +header.chunksize = header.chunksize + cldfb_no_channels_max * 4; % nrgLr + +IR.header = header; +FastConv_SD_BRIR = IR; + +% calculate the size of all chunks +HRTFs = {FastConv_SHD_IR_FOA, FastConv_SHD_IR_HOA2, FastConv_SHD_IR_HOA3, FastConv_SD_IR, FastConv_SD_BRIR}; +hrtf_data_size = 0; +total_file_size = 0; +for i = 1:length(HRTFs) + hrtf_data_size = hrtf_data_size + HRTFs{i}.header.chunksize; + total_file_size = total_file_size + 4 * 4; % chunk header 4 (u)int32 values +end + +total_file_size = total_file_size + 8; % 'IVASHRTF' (char[8]) +total_file_size = total_file_size + 4; % file size (int32) +total_file_size = total_file_size + 2; % number of HRTFs in file (int16) +total_file_size = total_file_size + 4; % HRTF size (int32) +total_file_size = total_file_size + hrtf_data_size; % size of all HRTF data chunks + +fwrite(f_id, 'IVASHRTF', 'char'); % identifier +fwrite(f_id, total_file_size, 'int32'); % file size +fwrite(f_id, length(HRTFs), 'int16'); % number of HRTFs +fwrite(f_id, hrtf_data_size, 'int32'); % max data size (bytes to read after this header) + +%% HRIRs + +% SHD HRIRs +SHD_HRIRs = {FastConv_SHD_IR_FOA, FastConv_SHD_IR_HOA2, FastConv_SHD_IR_HOA3}; +for i = 1:length(SHD_HRIRs) + IR = SHD_HRIRs{i}; + [~, binaural_convbands, num_channels, binaural_ntaps] = size(IR.IR); + + % write header for this chunk + fwrite(f_id, IR.header.renderer_type, 'int32'); + fwrite(f_id, IR.header.in_fmt, 'int32'); + fwrite(f_id, IR.header.fs, 'int32'); + fwrite(f_id, IR.header.chunksize, 'uint32'); + + fwrite(f_id, IR.latency_s, 'float32'); + fwrite(f_id, binaural_convbands, 'uint16'); + fwrite(f_id, num_channels, 'uint16'); + fwrite(f_id, binaural_ntaps, 'uint16'); + + for band = 1:binaural_convbands + for ch = 1:num_channels + fwrite(f_id, real(squeeze(IR.IR(1, band, ch, :))), 'float32'); + end + end + for band = 1:binaural_convbands + for ch = 1:num_channels + fwrite(f_id, imag(squeeze(IR.IR(1, band, ch, :))), 'float32'); + end + end + for band = 1:binaural_convbands + for ch = 1:num_channels + fwrite(f_id, real(squeeze(IR.IR(2, band, ch, :))), 'float32'); + end + end + for band = 1:binaural_convbands + for ch = 1:num_channels + fwrite(f_id, imag(squeeze(IR.IR(2, band, ch, :))), 'float32'); + end + end +end + +% SD HRIRs +IR = FastConv_SD_IR; +[~, binaural_convbands, num_channels, binaural_ntaps] = size(IR.IR); + +% write header for this chunk +fwrite(f_id, IR.header.renderer_type, 'int32'); +fwrite(f_id, IR.header.in_fmt, 'int32'); +fwrite(f_id, IR.header.fs, 'int32'); +fwrite(f_id, IR.header.chunksize, 'uint32'); + +fwrite(f_id, IR.latency_s, 'float32'); +fwrite(f_id, binaural_convbands, 'uint16'); +fwrite(f_id, num_channels, 'uint16'); +fwrite(f_id, binaural_ntaps, 'uint16'); +for band = 1:binaural_convbands + for ch = 1:num_channels + fwrite(f_id, real(squeeze(IR.IR(1, band, ch, :))), 'float32'); + end +end +for band = 1:binaural_convbands + for ch = 1:num_channels + fwrite(f_id, imag(squeeze(IR.IR(1, band, ch, :))), 'float32'); + end +end +for band = 1:binaural_convbands + for ch = 1:num_channels + fwrite(f_id, real(squeeze(IR.IR(2, band, ch, :))), 'float32'); + end +end +for band = 1:binaural_convbands + for ch = 1:num_channels + fwrite(f_id, imag(squeeze(IR.IR(2, band, ch, :))), 'float32'); + end +end + + +% SD BRIRs +IR = FastConv_SD_BRIR; +[~, binaural_convbands, num_channels, ~] = size(IR.IR); +cldfb_no_channels_max = IR.rev_param.kAna; + +% write header for this chunk +fwrite(f_id, IR.header.renderer_type, 'int32'); +fwrite(f_id, IR.header.in_fmt, 'int32'); +fwrite(f_id, IR.header.fs, 'int32'); +fwrite(f_id, IR.header.chunksize, 'uint32'); + +fwrite(f_id, IR.rev_param.latency_s, 'float32'); +fwrite(f_id, binaural_convbands, 'uint16'); +fwrite(f_id, num_channels, 'uint16'); +fwrite(f_id, IR.rev_param.NFilter, 'uint16'); +for band = 1:binaural_convbands + for ch = 1:num_channels + fwrite(f_id, real(squeeze(IR.IR(1, band, ch, 1:IR.rev_param.NFilter))), 'float32' ); + end +end +for band = 1:binaural_convbands + for ch = 1:num_channels + fwrite(f_id, imag(squeeze(IR.IR(1, band, ch, 1:IR.rev_param.NFilter))), 'float32' ); + end +end +for band = 1:binaural_convbands + for ch = 1:num_channels + fwrite(f_id, real(squeeze(IR.IR(2, band, ch, 1:IR.rev_param.NFilter))), 'float32' ); + end +end +for band = 1:binaural_convbands + for ch = 1:num_channels + fwrite(f_id, imag(squeeze(IR.IR(2, band, ch, 1:IR.rev_param.NFilter))), 'float32' ); + end +end + +fwrite(f_id, cldfb_no_channels_max, 'uint16'); +fwrite(f_id, IR.rev_param.rt60, 'float32'); +fwrite(f_id, IR.rev_param.nrgLr, 'float32'); + +fclose(f_id); + +end \ No newline at end of file diff --git a/scripts/binauralRenderer_interface/fastconv/write_fastconv_rom_table.m b/scripts/binauralRenderer_interface/fastconv/write_fastconv_rom_table.m new file mode 100644 index 0000000000000000000000000000000000000000..ed7fc502db259f33cf8cbdf8cef0c512b0f9007c --- /dev/null +++ b/scripts/binauralRenderer_interface/fastconv/write_fastconv_rom_table.m @@ -0,0 +1,101 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% (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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function write_fastconv_rom_table(output_file, FastConv_SHD_IR_FOA, FastConv_SHD_IR_HOA2, FastConv_SHD_IR_HOA3, FastConv_SD_IR, FastConv_SD_BRIR) + % TODO move this to common script that writes all tables? + %% Open file and write header + if ismac + username = getenv('USER'); + else + username = getenv('username'); + end + fid = fopen(output_file, 'wt'); + fprintf(fid, '/*\n'); + fprintf(fid, ' * Generated on %s with Matlab version %s by %s.\n', date, version, username); + fprintf(fid, '*/\n'); + + %% HRIRs (SHD) + % HOA3 + fprintf(fid, ['const float FASTCONV_' FastConv_SHD_IR_HOA3.order '_latency_s = %10.9ff;\n'], FastConv_SHD_IR_HOA3.latency_s); + writeData3L(fid, ['const float leftHRIRReal_' FastConv_SHD_IR_HOA3.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA3.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], real(squeeze(FastConv_SHD_IR_HOA3.IR(1,:,:,:)))); + writeData3L(fid, ['const float leftHRIRImag_' FastConv_SHD_IR_HOA3.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA3.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], imag(squeeze(FastConv_SHD_IR_HOA3.IR(1,:,:,:)))); + writeData3L(fid, ['const float rightHRIRReal_' FastConv_SHD_IR_HOA3.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA3.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], real(squeeze(FastConv_SHD_IR_HOA3.IR(2,:,:,:)))); + writeData3L(fid, ['const float rightHRIRImag_' FastConv_SHD_IR_HOA3.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA3.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], imag(squeeze(FastConv_SHD_IR_HOA3.IR(2,:,:,:)))); + % HOA2 + fprintf(fid, ['const float FASTCONV_' FastConv_SHD_IR_HOA2.order '_latency_s = %10.9ff;\n'], FastConv_SHD_IR_HOA2.latency_s); + writeData3L(fid, ['const float leftHRIRReal_' FastConv_SHD_IR_HOA2.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA2.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], real(squeeze(FastConv_SHD_IR_HOA2.IR(1,:,:,:)))); + writeData3L(fid, ['const float leftHRIRImag_' FastConv_SHD_IR_HOA2.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA2.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], imag(squeeze(FastConv_SHD_IR_HOA2.IR(1,:,:,:)))); + writeData3L(fid, ['const float rightHRIRReal_' FastConv_SHD_IR_HOA2.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA2.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], real(squeeze(FastConv_SHD_IR_HOA2.IR(2,:,:,:)))); + writeData3L(fid, ['const float rightHRIRImag_' FastConv_SHD_IR_HOA2.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA2.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], imag(squeeze(FastConv_SHD_IR_HOA2.IR(2,:,:,:)))); + % FOA + fprintf(fid, ['const float FASTCONV_' FastConv_SHD_IR_FOA.order '_latency_s = %10.9ff;\n'], FastConv_SHD_IR_FOA.latency_s); + writeData3L(fid, ['const float leftHRIRReal_' FastConv_SHD_IR_FOA.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_FOA.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], real(squeeze(FastConv_SHD_IR_FOA.IR(1,:,:,:)))); + writeData3L(fid, ['const float leftHRIRImag_' FastConv_SHD_IR_FOA.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_FOA.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], imag(squeeze(FastConv_SHD_IR_FOA.IR(1,:,:,:)))); + writeData3L(fid, ['const float rightHRIRReal_' FastConv_SHD_IR_FOA.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_FOA.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], real(squeeze(FastConv_SHD_IR_FOA.IR(2,:,:,:)))); + writeData3L(fid, ['const float rightHRIRImag_' FastConv_SHD_IR_FOA.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_FOA.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], imag(squeeze(FastConv_SHD_IR_FOA.IR(2,:,:,:)))); + + %% HRIRs (SD) + fprintf(fid, 'const float FASTCONV_HRIR_latency_s = %10.9ff;\n', FastConv_SD_IR.latency_s); + writeData3L(fid, 'const float leftHRIRReal[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]', real(squeeze(FastConv_SD_IR.IR(1,:,:,:)))); + writeData3L(fid, 'const float leftHRIRImag[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]', imag(squeeze(FastConv_SD_IR.IR(1,:,:,:)))); + writeData3L(fid, 'const float rightHRIRReal[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]', real(squeeze(FastConv_SD_IR.IR(2,:,:,:)))); + writeData3L(fid, 'const float rightHRIRImag[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]', imag(squeeze(FastConv_SD_IR.IR(2,:,:,:)))); + + %% BRIRs (SD) + fprintf(fid, '/* Binaural rendering data set based on BRIRs */\n'); + fprintf(fid, '/* Tables derived from Mozart IIS BRIRs.*/\n'); + fprintf(fid, 'const float FASTCONV_BRIR_latency_s = %10.9ff;\n', FastConv_SD_BRIR.rev_param.latency_s); + writeData3L(fid, 'const float leftBRIRReal[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS_MAX]', real(squeeze(FastConv_SD_BRIR.IR(1,:,:,1:FastConv_SD_BRIR.rev_param.NFilter)))); + writeData3L(fid, 'const float leftBRIRImag[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS_MAX]', imag(squeeze(FastConv_SD_BRIR.IR(1,:,:,1:FastConv_SD_BRIR.rev_param.NFilter)))); + writeData3L(fid, 'const float rightBRIRReal[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS_MAX]', real(squeeze(FastConv_SD_BRIR.IR(2,:,:,1:FastConv_SD_BRIR.rev_param.NFilter)))); + writeData3L(fid, 'const float rightBRIRImag[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS_MAX]', imag(squeeze(FastConv_SD_BRIR.IR(2,:,:,1:FastConv_SD_BRIR.rev_param.NFilter)))); + + % RT60 + fprintf(fid,'const float fastconvReverberationTimes[CLDFB_NO_CHANNELS_MAX] = \n{'); + fprintf(fid,'\n\t'); + for bandIdx = 1:FastConv_SD_BRIR.rev_param.kAna + fprintf(fid,'%f%s, ', FastConv_SD_BRIR.rev_param.rt60(bandIdx),'f'); + end + fprintf(fid,'\n};\n'); + fprintf(fid,'\n\n'); + + % energyReverb + fprintf(fid,'const float fastconvReverberationEneCorrections[CLDFB_NO_CHANNELS_MAX] = \n{'); + fprintf(fid,'\n\t'); + for bandIdx = 1:FastConv_SD_BRIR.rev_param.kAna + fprintf(fid,'%f%s, ', FastConv_SD_BRIR.rev_param.nrgLr(bandIdx),'f'); + end + fprintf(fid,'\n};\n'); + fprintf(fid,'\n\n'); + + fclose(fid); + +end \ No newline at end of file diff --git a/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/SD_2_ROM.m b/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/SD_2_ROM.m new file mode 100644 index 0000000000000000000000000000000000000000..bbc9e3861af4a4f8b4ec9613f02bc52abadc2bce --- /dev/null +++ b/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/SD_2_ROM.m @@ -0,0 +1,122 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% (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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function FastConv_SD_IR = SD_2_ROM(sofa_file) +% SD_2_ROM( rom_c_file, sofa_file, ambisonics_order, hrir_length ) +% +% Derived from SHD_2_ROM.m +% - loads sphere-sampled Head Related Impulse Responses (HRIRs) given in sofa_file +% - converts SD HRIRs to Complex Low Delay Filter Bank (CLDFB) domain using fir_to_cldfb_fir.m +[thispath,~,~] = fileparts(mfilename('fullpath')); +thispath = [thispath,filesep]; + +if ~exist('sofa_file','var') || isempty(sofa_file) + sofa_file = fullfile(thispath,'..','HRIRs_sofa','HRIR_128_Meth5_IRC_53_Q10_symL_Itrp1_48000.sofa'); +end +%% load SD HRIRs +H = hrtf_library_loader(); +H.readSOFA(char(sofa_file)); +ls_struct = get_ls_layout_config('Combined'); +IR_SD = H.XYZ_to_IR_SD([deg2rad(ls_struct.azi); deg2rad(ls_struct.ele)]); + +%% SD -> CLDFB via least squares error optimization +[~,num_ears,num_ch] = size(IR_SD); +num_cldfb_taps = 3; +IR_cldfb = zeros(60,num_cldfb_taps,num_ears,num_ch); % 60 frequency bands +eval_flag = 0; % optional, = 1 requires signal processing toolbox (fftfilt) +legacy_flag = 1; % = 1 used to indicate slightly too short buffers as used to generate tested coefficients +for pos = 1:num_ch + disp(['Channel ',num2str(pos),'/',num2str(num_ch)]) + for ear = 1:num_ears + IR_cldfb(:,:,ear,pos) = fir_to_cldfb_fir( IR_SD(:,ear,pos), num_cldfb_taps, eval_flag, legacy_flag ); + end +end + +%% CLDFB -> ROM +latency_s = 0.000666667; % No added latency from conversion method +max_band = 50; % Compute 60 bands, but only use 50 in ROM table + +IR_cldfb = permute(IR_cldfb, [3 1 4 2]); % after permute: [ears(2), bands(60), chans(15), taps(3)] +IR_cldfb = IR_cldfb(:,1:max_band,:,:); + +FastConv_SD_IR.IR = IR_cldfb; +FastConv_SD_IR.latency_s = latency_s; + +% if ~exist('rom_c_file','var') || isempty(rom_c_file) +% rom_c_file = [thispath,'ivas_rom_binauralRenderer_combined.c']; % fullfile(thispath,'..','..','..','lib_rend',['ivas_rom_binauralRenderer_',order,'.c']); +% end + +% fid = fopen(rom_c_file,'wt'); + +% fprintf(fid, 'const float FASTCONV_HRIR_latency_s = %10.9ff;\n', latency_s); +% write_one_ear( fid, 'const float leftHRIRReal[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]=', real(IR_cldfb(1,:,:,:))); +% write_one_ear( fid, 'const float leftHRIRImag[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]=', imag(IR_cldfb(1,:,:,:))); +% write_one_ear( fid, 'const float rightHRIRReal[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]=', real(IR_cldfb(2,:,:,:))); +% write_one_ear( fid, 'const float rightHRIRImag[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]=', imag(IR_cldfb(2,:,:,:))); + +% fclose(fid); + +% function write_one_ear( fid, first_line, IR_cldfb_rom) +% IR_cldfb_rom = squeeze(IR_cldfb_rom); +% [num_bands,num_chans, num_taps] = size(IR_cldfb_rom); +% num_spaces = 4; +% num_spaces_cur = 0; +% fprintf(fid,[first_line,'\n{\n']); +% num_spaces_cur = num_spaces_cur + num_spaces; +% for band = 1:num_bands +% fprintf(fid,[blanks(num_spaces_cur),'{\n']); +% num_spaces_cur = num_spaces_cur + num_spaces; +% for chan = 1:num_chans +% fprintf(fid,[blanks(num_spaces_cur),'{']); +% for tap = 1:num_taps +% if tap == num_taps +% fprintf(fid,'%+ff',IR_cldfb_rom(band,chan,tap)); +% else +% fprintf(fid,'%+ff, ',IR_cldfb_rom(band,chan,tap)); +% end +% end +% if chan == num_chans +% fprintf(fid,'}\n'); +% else +% fprintf(fid,'},\n'); +% end +% end +% num_spaces_cur = num_spaces_cur - num_spaces; +% if band == num_bands +% fprintf(fid,[blanks(num_spaces_cur),'}\n']); +% else +% fprintf(fid,[blanks(num_spaces_cur),'},\n']); +% end +% end +% fprintf(fid,'};\n\n'); + +% end +end \ No newline at end of file diff --git a/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/SHD_2_ROM.m b/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/SHD_2_ROM.m index c6c98ec46bb3f52533cd21093a35abab4b83b737..642ad84a18efc901d13ed50c1519c54802028e53 100644 --- a/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/SHD_2_ROM.m +++ b/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/SHD_2_ROM.m @@ -29,7 +29,7 @@ % the United Nations Convention on Contracts on the International Sales of Goods. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -function IR_cldfb = SHD_2_ROM( rom_c_file, sofa_file, ambi_order, hrir_len ) +function FastConv_SHD_IR = SHD_2_ROM( sofa_file, ambi_order, hrir_len ) % SHD_2_ROM( rom_c_file, sofa_file, ambisonics_order, hrir_length ) % % - converts sphere-sampled Head Related Impulse Responses (HRIRs) given in sofa_file @@ -39,7 +39,6 @@ function IR_cldfb = SHD_2_ROM( rom_c_file, sofa_file, ambi_order, hrir_len ) [thispath,~,~] = fileparts(mfilename('fullpath')); thispath = [thispath,filesep]; -%py_path = 'C:\Users\xxxx\AppData\Local\Programs\Python\Python39\python.exe'; % may look like this if ~exist('sofa_file','var') || isempty(sofa_file) sofa_file = fullfile(thispath,'..','HRIRs_sofa','HRIR_128_Meth5_IRC_53_Q10_symL_Itrp1_48000.sofa'); end @@ -50,11 +49,6 @@ if ~exist('hrir_len','var') hrir_len = 128; end %% convert sphere-sampled HRIRs to SHD HRIRs -% requires: -% python -m pip install sofar -% python -m pip install numpy - -% convert sphere-sampled HRIRs to SHD HRIRs [sofa_path,sofa_name, sofa_ext] = fileparts(sofa_file); IR = generate_HOA_HRIRs_MOD_lens(ambi_order, sofa_path, [sofa_name,sofa_ext], hrir_len); @@ -82,50 +76,55 @@ if ambi_order == 1 else order = ['HOA' int2str(ambi_order)]; end -if ~exist('rom_c_file','var') || isempty(rom_c_file) - rom_c_file = [thispath,'ivas_rom_binauralRenderer_',order,'.c']; % fullfile(thispath,'..','..','..','lib_rend',['ivas_rom_binauralRenderer_',order,'.c']); -end +FastConv_SHD_IR.IR = IR_cldfb_rom; +FastConv_SHD_IR.latency_s = latency_s; +FastConv_SHD_IR.order = order; +% if ~exist('rom_c_file','var') || isempty(rom_c_file) +% rom_c_file = [thispath,'ivas_rom_binauralRenderer_',order,'.c']; % fullfile(thispath,'..','..','..','lib_rend',['ivas_rom_binauralRenderer_',order,'.c']); +% end -fid = fopen(rom_c_file,'wt'); +% fid = fopen(rom_c_file,'wt'); -fprintf(fid, ['const float FASTCONV_' order '_latency_s = %10.9ff;\n'], latency_s); -write_one_ear( fid, ['const float leftHRIRReal_' order '[BINAURAL_CONVBANDS][' order '_CHANNELS][BINAURAL_NTAPS_SBA]='], real(IR_cldfb_rom(1,:,:,:))); -write_one_ear( fid, ['const float leftHRIRImag_' order '[BINAURAL_CONVBANDS][' order '_CHANNELS][BINAURAL_NTAPS_SBA]='], imag(IR_cldfb_rom(1,:,:,:))); -write_one_ear( fid, ['const float rightHRIRReal_' order '[BINAURAL_CONVBANDS][' order '_CHANNELS][BINAURAL_NTAPS_SBA]='], real(IR_cldfb_rom(2,:,:,:))); -write_one_ear( fid, ['const float rightHRIRImag_' order '[BINAURAL_CONVBANDS][' order '_CHANNELS][BINAURAL_NTAPS_SBA]='], imag(IR_cldfb_rom(2,:,:,:))); +% fprintf(fid, ['const float FASTCONV_' order '_latency_s = %10.9ff;\n'], latency_s); +% write_one_ear( fid, ['const float leftHRIRReal_' order '[BINAURAL_CONVBANDS][' order '_CHANNELS][BINAURAL_NTAPS_SBA]='], real(IR_cldfb_rom(1,:,:,:))); +% write_one_ear( fid, ['const float leftHRIRImag_' order '[BINAURAL_CONVBANDS][' order '_CHANNELS][BINAURAL_NTAPS_SBA]='], imag(IR_cldfb_rom(1,:,:,:))); +% write_one_ear( fid, ['const float rightHRIRReal_' order '[BINAURAL_CONVBANDS][' order '_CHANNELS][BINAURAL_NTAPS_SBA]='], real(IR_cldfb_rom(2,:,:,:))); +% write_one_ear( fid, ['const float rightHRIRImag_' order '[BINAURAL_CONVBANDS][' order '_CHANNELS][BINAURAL_NTAPS_SBA]='], imag(IR_cldfb_rom(2,:,:,:))); -fclose(fid); +% fclose(fid); -function write_one_ear( fid, first_line, IR_cldfb_rom) -IR_cldfb_rom = squeeze(IR_cldfb_rom); -[num_bands,num_chans, num_taps] = size(IR_cldfb_rom); -num_spaces = 4; -num_spaces_cur = 0; -fprintf(fid,[first_line,'\n{\n']); -num_spaces_cur = num_spaces_cur + num_spaces; -for band = 1:num_bands - fprintf(fid,[blanks(num_spaces_cur),'{\n']); - num_spaces_cur = num_spaces_cur + num_spaces; - for chan = 1:num_chans - fprintf(fid,[blanks(num_spaces_cur),'{']); - for tap = 1:num_taps - if tap == num_taps - fprintf(fid,'%+ff',IR_cldfb_rom(band,chan,tap)); - else - fprintf(fid,'%+ff, ',IR_cldfb_rom(band,chan,tap)); - end - end - if chan == num_chans - fprintf(fid,'}\n'); - else - fprintf(fid,'},\n'); - end - end - num_spaces_cur = num_spaces_cur - num_spaces; - if band == num_bands - fprintf(fid,[blanks(num_spaces_cur),'}\n']); - else - fprintf(fid,[blanks(num_spaces_cur),'},\n']); - end +% function write_one_ear( fid, first_line, IR_cldfb_rom) +% IR_cldfb_rom = squeeze(IR_cldfb_rom); +% [num_bands,num_chans, num_taps] = size(IR_cldfb_rom); +% num_spaces = 4; +% num_spaces_cur = 0; +% fprintf(fid,[first_line,'\n{\n']); +% num_spaces_cur = num_spaces_cur + num_spaces; +% for band = 1:num_bands +% fprintf(fid,[blanks(num_spaces_cur),'{\n']); +% num_spaces_cur = num_spaces_cur + num_spaces; +% for chan = 1:num_chans +% fprintf(fid,[blanks(num_spaces_cur),'{']); +% for tap = 1:num_taps +% if tap == num_taps +% fprintf(fid,'%+ff',IR_cldfb_rom(band,chan,tap)); +% else +% fprintf(fid,'%+ff, ',IR_cldfb_rom(band,chan,tap)); +% end +% end +% if chan == num_chans +% fprintf(fid,'}\n'); +% else +% fprintf(fid,'},\n'); +% end +% end +% num_spaces_cur = num_spaces_cur - num_spaces; +% if band == num_bands +% fprintf(fid,[blanks(num_spaces_cur),'}\n']); +% else +% fprintf(fid,[blanks(num_spaces_cur),'},\n']); +% end +% end +% fprintf(fid,'};\n\n'); +% end end -fprintf(fid,'};\n\n'); diff --git a/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/fir_to_cldfb_fir.m b/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/fir_to_cldfb_fir.m index 5043f4f2c7577e11b070a33c18ae8bcffb6bef5f..c4defd458823b23b73a26f8b8c997df07052b92a 100644 --- a/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/fir_to_cldfb_fir.m +++ b/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/fir_to_cldfb_fir.m @@ -169,136 +169,3 @@ set(gca,'xlim',[1,num_samples]) fprintf('SNR: %.1f dB \n', 10*log10(sum(y1.^2)/sum((y1-y2).^2))); legend('time domain','CLDFB domain','difference') title('Filtered noise') - -function [h, D, S, L] = get_cldfb_filter() -% const float LDQMF_60[] in \lib_com\rom_com.c, line 5219 -S = 60; % stride -L = 60; % frequency bands -D = 240 + S - 1; % system delay -h = [ - 0.0000953076, 0.0001230230, 0.0001279964, 0.0001260533, 0.0001211219 - 0.0001122123, 0.0001010860, 0.0000876540, 0.0000719883, 0.0000545472 - 0.0000352143, 0.0000145686, -0.0000074264, -0.0000303788, -0.0000539205 - -0.0000782743, -0.0001028838, -0.0001275374, -0.0001520015, -0.0001760167 - -0.0001997108, -0.0002226708, -0.0002446725, -0.0002655797, -0.0002852145 - -0.0003034996, -0.0003203036, -0.0003356283, -0.0003493345, -0.0003614030 - -0.0003719004, -0.0003807641, -0.0003881051, -0.0003939842, -0.0003985357 - -0.0004019095, -0.0004041938, -0.0004056677, -0.0004065430, -0.0004069925 - -0.0004072535, -0.0004075877, -0.0004083676, -0.0004098394, -0.0004122990 - -0.0004160839, -0.0004214063, -0.0004285777, -0.0004378651, -0.0004495422 - -0.0004637682, -0.0004806494, -0.0005003878, -0.0005231378, -0.0005489803 - -0.0005777747, -0.0006095612, -0.0006443121, -0.0006813223, -0.0007226231 - -0.0007722576, -0.0008268412, -0.0008839625, -0.0009417336, -0.0010004630 - -0.0010601623, -0.0011206097, -0.0011817788, -0.0012432419, -0.0013045983 - -0.0013656860, -0.0014260965, -0.0014855355, -0.0015435946, -0.0015999591 - -0.0016543545, -0.0017062968, -0.0017554691, -0.0018015467, -0.0018441341 - -0.0018829798, -0.0019177221, -0.0019480695, -0.0019736972, -0.0019943134 - -0.0020097434, -0.0020197174, -0.0020240925, -0.0020226294, -0.0020152442 - -0.0020017736, -0.0019820682, -0.0019561697, -0.0019240153, -0.0018855907 - -0.0018409232, -0.0017900462, -0.0017330211, -0.0016699535, -0.0016009507 - -0.0015261442, -0.0014456788, -0.0013597424, -0.0012685407, -0.0011722331 - -0.0010710671, -0.0009652392, -0.0008549765, -0.0007405236, -0.0006221444 - -0.0005001140, -0.0003745670, -0.0002458634, -0.0001142541, 0.0000199491 - 0.0001564174, 0.0002949402, 0.0004350246, 0.0005769439, 0.0007203126 - -0.0008803223, -0.0010328424, -0.0011841310, -0.0013346316, -0.0014848098 - -0.0016343417, -0.0017832819, -0.0019316213, -0.0020790498, -0.0022252349 - -0.0023701149, -0.0025136294, -0.0026556554, -0.0027960713, -0.0029348312 - -0.0030717771, -0.0032068293, -0.0033399195, -0.0034709862, -0.0035999804 - -0.0037267797, -0.0038513308, -0.0039736414, -0.0040935921, -0.0042111278 - -0.0043262239, -0.0044388464, -0.0045489701, -0.0046565188, -0.0047614835 - -0.0048637423, -0.0049632201, -0.0050599808, -0.0051539382, -0.0052450863 - -0.0053333500, -0.0054187514, -0.0055012843, -0.0055808770, -0.0056575472 - -0.0057313135, -0.0058021732, -0.0058701355, -0.0059352517, -0.0059975707 - -0.0060571772, -0.0061141332, -0.0061685541, -0.0062205540, -0.0062703062 - -0.0063179093, -0.0063635921, -0.0064075105, -0.0064498796, -0.0064908965 - -0.0065308069, -0.0065698619, -0.0066083665, -0.0066466411, -0.0066849431 - -0.0067233290, -0.0067621553, -0.0068021296, -0.0068436749, -0.0068870094 - -0.0069324085, -0.0069801519, -0.0070305937, -0.0070840055, -0.0071406048 - -0.0072006541, -0.0072644479, -0.0073321410, -0.0074039386, -0.0074799177 - -0.0075602704, -0.0076450342, -0.0077342330, -0.0078278277, -0.0079257628 - -0.0080279401, -0.0081341872, -0.0082442267, -0.0083577875, -0.0084744738 - -0.0085938899, -0.0087156557, -0.0088391500, -0.0089637861, -0.0090888245 - -0.0092134504, -0.0093367994, -0.0094579896, -0.0095760096, -0.0096898535 - -0.0097982995, -0.0099003557, -0.0099947909, -0.0100801717, -0.0101551116 - -0.0102182031, -0.0102678994, -0.0103026126, -0.0103207529, -0.0103206923 - -0.0103006857, -0.0102590285, -0.0101939747, -0.0101036867, -0.0099863587 - -0.0098401112, -0.0096632261, -0.0094537362, -0.0092098210, -0.0089295702 - -0.0086111929, -0.0082527259, -0.0078523541, -0.0074084769, -0.0069190590 - 0.0063841688, 0.0057985946, 0.0051621343, 0.0044734711, 0.0037309236 - 0.0029329660, 0.0020781513, 0.0011651339, 0.0001925042, -0.0008409545 - -0.0019364181, -0.0030950012, -0.0043176264, -0.0056051607, -0.0069584334 - -0.0083780792, -0.0098646237, -0.0114185056, -0.0130400723, -0.0147295250 - -0.0164868534, -0.0183120724, -0.0202049762, -0.0221651513, -0.0241921283 - -0.0262852497, -0.0284437388, -0.0306666382, -0.0329528190, -0.0353010744 - -0.0377098918, -0.0401776619, -0.0427025780, -0.0452826768, -0.0479161367 - -0.0506004691, -0.0533332452, -0.0561118126, -0.0589331910, -0.0617944039 - -0.0646922663, -0.0676232576, -0.0705836788, -0.0735698044, -0.0765774846 - -0.0796026587, -0.0826408863, -0.0856874809, -0.0887378305, -0.0917868018 - -0.0948293805, -0.0978601947, -0.1008738130, -0.1038645208, -0.1068264544 - -0.1097536832, -0.1126400903, -0.1154794544, -0.1182654947, -0.1209914312 - -0.1236500666, -0.1262341589, -0.1287376434, -0.1311538219, -0.1334753036 - -0.1356947273, -0.1378047168, -0.1397978216, -0.1416664869, -0.1434033662 - -0.1450008005, -0.1464512348, -0.1477471888, -0.1488809884, -0.1498452872 - -0.1506324410, -0.1512351334, -0.1516460329, -0.1518578976, -0.1518635303 - -0.1516559124, -0.1512281001, -0.1505732536, -0.1496847868, -0.1485562176 - -0.1471813470, -0.1455538720, -0.1436681300, -0.1415183097, -0.1390990764 - -0.1364052594, -0.1334318966, -0.1301742792, -0.1266280264, -0.1227891371 - -0.1186537445, -0.1142183766, -0.1094799563, -0.1044355705, -0.0990828425 - -0.0934195668, -0.0874440819, -0.0811550021, -0.0745511875, -0.0676321834 - -0.0603975877, -0.0528475679, -0.0449828543, -0.0368040986, -0.0283128861 - -0.0195108838, -0.0104003223, -0.0009837818, 0.0087356847, 0.0187546927 - 0.0290693250, 0.0396753438, 0.0505682528, 0.0617432520, 0.0731955394 - -0.0849232078, -0.0969054326, -0.1091460735, -0.1216373071, -0.1343720406 - -0.1473424733, -0.1605402082, -0.1739567965, -0.1875831038, -0.2014097124 - -0.2154271752, -0.2296251506, -0.2439934313, -0.2585212290, -0.2731975317 - -0.2880111337, -0.3029502928, -0.3180032372, -0.3331578076, -0.3484017253 - -0.3637222052, -0.3791064322, -0.3945416212, -0.4100143015, -0.4255111217 - -0.4410185516, -0.4565227628, -0.4720100164, -0.4874662757, -0.5028775334 - -0.5182296634, -0.5335084200, -0.5486994982, -0.5637886524, -0.5787616372 - -0.5936041474, -0.6083019376, -0.6228409410, -0.6372069120, -0.6513859630 - -0.6653640866, -0.6791275144, -0.6926627755, -0.7059561610, -0.7189947963 - -0.7317654490, -0.7442554235, -0.7564523220, -0.7683438063, -0.7799182534 - -0.7911639810, -0.8020697832, -0.8126249313, -0.8228194118, -0.8326428533 - -0.8420860767, -0.8511404991, -0.8597975969, -0.8680517077, -0.8758881092 - -0.8832823634, -0.8902196884, -0.8967157602, -0.9027729034, -0.9083824754 - -0.9135394692, -0.9182395935, -0.9224776030, -0.9262499809, -0.9295535684 - -0.9323854446, -0.9347436428, -0.9366261959, -0.9380323887, -0.9389615655 - -0.9394137263, -0.9393896461, -0.9388904572, -0.9379178882, -0.9364743829 - -0.9345626831, -0.9321863055, -0.9293491840, -0.9260557890, -0.9223110080 - -0.9181203246, -0.9134896994, -0.9084255695, -0.9029349089, -0.8970250487 - -0.8907034993, -0.8839784265, -0.8768582940, -0.8693521619, -0.8614694476 - -0.8532197475, -0.8446131349, -0.8356599212, -0.8263708353, -0.8167568445 - -0.8068289757, -0.7965991497, -0.7860788107, -0.7752800584, -0.7642148733 - -0.7528960109, -0.7413358092, -0.7295469642, -0.7175422311, -0.7053351402 - -0.6929380894, -0.6803644896, -0.6676273942, -0.6547405124, -0.6417166591 - -0.6285686493, -0.6153115034, -0.6019562483, -0.5885198116, -0.5750215650 - 0.5615197420, 0.5478612781, 0.5341838002, 0.5204906464, 0.5067980289 - 0.4931168854, 0.4794588387, 0.4658361673, 0.4522601366, 0.4387422502 - 0.4252935350, 0.4119254053, 0.3986486793, 0.3854739666, 0.3724119067 - 0.3594728410, 0.3466667533, 0.3340034485, 0.3214924335, 0.3091430366 - 0.2969639599, 0.2849639654, 0.2731511295, 0.2615332901, 0.2501178682 - 0.2389119864, 0.2279221565, 0.2171545923, 0.2066148520, 0.1963084787 - 0.1862401515, 0.1764142811, 0.1668347418, 0.1575049609, 0.1484276950 - 0.1396053135, 0.1310400218, 0.1227331311, 0.1146853194, 0.1068974212 - 0.0993694067, 0.0921007246, 0.0850901082, 0.0783365741, 0.0718384907 - 0.0655927584, 0.0595967993, 0.0538481586, 0.0483424664, 0.0430756323 - 0.0380428955, 0.0332404599, 0.0286619961, 0.0242999699, 0.0201510899 - 0.0162059069, 0.0124559226, 0.0088928537, 0.0054926532, 0.0023052765 - -0.0005515143, -0.0030201224, -0.0052712574, -0.0073737046, -0.0093160523 - -0.0111072771, -0.0127562135, -0.0142635731, -0.0156361461, -0.0168790054 - -0.0179969221, -0.0189934950, -0.0198726747, -0.0206398536, -0.0212980714 - -0.0218509119, -0.0223025978, -0.0226570386, -0.0229178313, -0.0230882075 - -0.0231725387, -0.0231746566, -0.0230979007, -0.0229462404, -0.0227237809 - -0.0224345829, -0.0220820960, -0.0216706358, -0.0212045144, -0.0206875466 - -0.0201238506, -0.0195175279, -0.0188730918, -0.0181944817, -0.0174855441 - -0.0167510118, -0.0159947462, -0.0152208358, -0.0144332750, -0.0136361914 - -0.0128338682, -0.0120294262, -0.0112272501, -0.0104311826, -0.0096443929 - -0.0088709844, -0.0081134979, -0.0073764324, -0.0066623385, -0.0059733889 - -0.0053142183, -0.0046856776, -0.0040914025, -0.0035321070, -0.0030089030 - -0.0025271603, -0.0020749648, -0.0016621647, -0.0012705614, -0.0008115423 -]; -h = h.'; -h = h(:); -h(1*120+(1:120)) = -h(1*120+(1:120)); -h(3*120+(1:120)) = -h(3*120+(1:120)); -h(:) = h(end:-1:1); \ No newline at end of file diff --git a/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/generate_HOA_HRIRs_MOD_lens.m b/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/generate_HOA_HRIRs_MOD_lens.m index 22a42dd1905059166cded0c4009222b4c7c96e35..b509031b726cc42bf74687d2469e7ff812197adf 100644 --- a/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/generate_HOA_HRIRs_MOD_lens.m +++ b/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/generate_HOA_HRIRs_MOD_lens.m @@ -116,7 +116,7 @@ IR_HOA = IR_HOA(:,1:ir_len,:) .* sin(interp1([0,150/192*ir_len,ir_len+1],[1,1,0] IR = permute(IR_HOA, [2, 1, 3]); HOAformat_str = ['HOA',num2str(order),'S']; -save(fullfile(erase(sofa_file_name, ".sofa") + "_converted_" + HOAformat_str + ".mat"), "IR") +% save(fullfile(erase(sofa_file_name, ".sofa") + "_converted_" + HOAformat_str + ".mat"), "IR") IR_data = IR; diff --git a/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/get_cldfb_filter.m b/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/get_cldfb_filter.m new file mode 100644 index 0000000000000000000000000000000000000000..f796dd9ee09ce2d98e18bca7151359f353a60aea --- /dev/null +++ b/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/get_cldfb_filter.m @@ -0,0 +1,163 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% (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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function [h, D, S, L] = get_cldfb_filter() +% const float LDQMF_60[] in \lib_com\rom_com.c, line 5219 +S = 60; % stride +L = 60; % frequency bands +D = 240 + S - 1; % system delay +h = [ + 0.0000953076, 0.0001230230, 0.0001279964, 0.0001260533, 0.0001211219 + 0.0001122123, 0.0001010860, 0.0000876540, 0.0000719883, 0.0000545472 + 0.0000352143, 0.0000145686, -0.0000074264, -0.0000303788, -0.0000539205 + -0.0000782743, -0.0001028838, -0.0001275374, -0.0001520015, -0.0001760167 + -0.0001997108, -0.0002226708, -0.0002446725, -0.0002655797, -0.0002852145 + -0.0003034996, -0.0003203036, -0.0003356283, -0.0003493345, -0.0003614030 + -0.0003719004, -0.0003807641, -0.0003881051, -0.0003939842, -0.0003985357 + -0.0004019095, -0.0004041938, -0.0004056677, -0.0004065430, -0.0004069925 + -0.0004072535, -0.0004075877, -0.0004083676, -0.0004098394, -0.0004122990 + -0.0004160839, -0.0004214063, -0.0004285777, -0.0004378651, -0.0004495422 + -0.0004637682, -0.0004806494, -0.0005003878, -0.0005231378, -0.0005489803 + -0.0005777747, -0.0006095612, -0.0006443121, -0.0006813223, -0.0007226231 + -0.0007722576, -0.0008268412, -0.0008839625, -0.0009417336, -0.0010004630 + -0.0010601623, -0.0011206097, -0.0011817788, -0.0012432419, -0.0013045983 + -0.0013656860, -0.0014260965, -0.0014855355, -0.0015435946, -0.0015999591 + -0.0016543545, -0.0017062968, -0.0017554691, -0.0018015467, -0.0018441341 + -0.0018829798, -0.0019177221, -0.0019480695, -0.0019736972, -0.0019943134 + -0.0020097434, -0.0020197174, -0.0020240925, -0.0020226294, -0.0020152442 + -0.0020017736, -0.0019820682, -0.0019561697, -0.0019240153, -0.0018855907 + -0.0018409232, -0.0017900462, -0.0017330211, -0.0016699535, -0.0016009507 + -0.0015261442, -0.0014456788, -0.0013597424, -0.0012685407, -0.0011722331 + -0.0010710671, -0.0009652392, -0.0008549765, -0.0007405236, -0.0006221444 + -0.0005001140, -0.0003745670, -0.0002458634, -0.0001142541, 0.0000199491 + 0.0001564174, 0.0002949402, 0.0004350246, 0.0005769439, 0.0007203126 + -0.0008803223, -0.0010328424, -0.0011841310, -0.0013346316, -0.0014848098 + -0.0016343417, -0.0017832819, -0.0019316213, -0.0020790498, -0.0022252349 + -0.0023701149, -0.0025136294, -0.0026556554, -0.0027960713, -0.0029348312 + -0.0030717771, -0.0032068293, -0.0033399195, -0.0034709862, -0.0035999804 + -0.0037267797, -0.0038513308, -0.0039736414, -0.0040935921, -0.0042111278 + -0.0043262239, -0.0044388464, -0.0045489701, -0.0046565188, -0.0047614835 + -0.0048637423, -0.0049632201, -0.0050599808, -0.0051539382, -0.0052450863 + -0.0053333500, -0.0054187514, -0.0055012843, -0.0055808770, -0.0056575472 + -0.0057313135, -0.0058021732, -0.0058701355, -0.0059352517, -0.0059975707 + -0.0060571772, -0.0061141332, -0.0061685541, -0.0062205540, -0.0062703062 + -0.0063179093, -0.0063635921, -0.0064075105, -0.0064498796, -0.0064908965 + -0.0065308069, -0.0065698619, -0.0066083665, -0.0066466411, -0.0066849431 + -0.0067233290, -0.0067621553, -0.0068021296, -0.0068436749, -0.0068870094 + -0.0069324085, -0.0069801519, -0.0070305937, -0.0070840055, -0.0071406048 + -0.0072006541, -0.0072644479, -0.0073321410, -0.0074039386, -0.0074799177 + -0.0075602704, -0.0076450342, -0.0077342330, -0.0078278277, -0.0079257628 + -0.0080279401, -0.0081341872, -0.0082442267, -0.0083577875, -0.0084744738 + -0.0085938899, -0.0087156557, -0.0088391500, -0.0089637861, -0.0090888245 + -0.0092134504, -0.0093367994, -0.0094579896, -0.0095760096, -0.0096898535 + -0.0097982995, -0.0099003557, -0.0099947909, -0.0100801717, -0.0101551116 + -0.0102182031, -0.0102678994, -0.0103026126, -0.0103207529, -0.0103206923 + -0.0103006857, -0.0102590285, -0.0101939747, -0.0101036867, -0.0099863587 + -0.0098401112, -0.0096632261, -0.0094537362, -0.0092098210, -0.0089295702 + -0.0086111929, -0.0082527259, -0.0078523541, -0.0074084769, -0.0069190590 + 0.0063841688, 0.0057985946, 0.0051621343, 0.0044734711, 0.0037309236 + 0.0029329660, 0.0020781513, 0.0011651339, 0.0001925042, -0.0008409545 + -0.0019364181, -0.0030950012, -0.0043176264, -0.0056051607, -0.0069584334 + -0.0083780792, -0.0098646237, -0.0114185056, -0.0130400723, -0.0147295250 + -0.0164868534, -0.0183120724, -0.0202049762, -0.0221651513, -0.0241921283 + -0.0262852497, -0.0284437388, -0.0306666382, -0.0329528190, -0.0353010744 + -0.0377098918, -0.0401776619, -0.0427025780, -0.0452826768, -0.0479161367 + -0.0506004691, -0.0533332452, -0.0561118126, -0.0589331910, -0.0617944039 + -0.0646922663, -0.0676232576, -0.0705836788, -0.0735698044, -0.0765774846 + -0.0796026587, -0.0826408863, -0.0856874809, -0.0887378305, -0.0917868018 + -0.0948293805, -0.0978601947, -0.1008738130, -0.1038645208, -0.1068264544 + -0.1097536832, -0.1126400903, -0.1154794544, -0.1182654947, -0.1209914312 + -0.1236500666, -0.1262341589, -0.1287376434, -0.1311538219, -0.1334753036 + -0.1356947273, -0.1378047168, -0.1397978216, -0.1416664869, -0.1434033662 + -0.1450008005, -0.1464512348, -0.1477471888, -0.1488809884, -0.1498452872 + -0.1506324410, -0.1512351334, -0.1516460329, -0.1518578976, -0.1518635303 + -0.1516559124, -0.1512281001, -0.1505732536, -0.1496847868, -0.1485562176 + -0.1471813470, -0.1455538720, -0.1436681300, -0.1415183097, -0.1390990764 + -0.1364052594, -0.1334318966, -0.1301742792, -0.1266280264, -0.1227891371 + -0.1186537445, -0.1142183766, -0.1094799563, -0.1044355705, -0.0990828425 + -0.0934195668, -0.0874440819, -0.0811550021, -0.0745511875, -0.0676321834 + -0.0603975877, -0.0528475679, -0.0449828543, -0.0368040986, -0.0283128861 + -0.0195108838, -0.0104003223, -0.0009837818, 0.0087356847, 0.0187546927 + 0.0290693250, 0.0396753438, 0.0505682528, 0.0617432520, 0.0731955394 + -0.0849232078, -0.0969054326, -0.1091460735, -0.1216373071, -0.1343720406 + -0.1473424733, -0.1605402082, -0.1739567965, -0.1875831038, -0.2014097124 + -0.2154271752, -0.2296251506, -0.2439934313, -0.2585212290, -0.2731975317 + -0.2880111337, -0.3029502928, -0.3180032372, -0.3331578076, -0.3484017253 + -0.3637222052, -0.3791064322, -0.3945416212, -0.4100143015, -0.4255111217 + -0.4410185516, -0.4565227628, -0.4720100164, -0.4874662757, -0.5028775334 + -0.5182296634, -0.5335084200, -0.5486994982, -0.5637886524, -0.5787616372 + -0.5936041474, -0.6083019376, -0.6228409410, -0.6372069120, -0.6513859630 + -0.6653640866, -0.6791275144, -0.6926627755, -0.7059561610, -0.7189947963 + -0.7317654490, -0.7442554235, -0.7564523220, -0.7683438063, -0.7799182534 + -0.7911639810, -0.8020697832, -0.8126249313, -0.8228194118, -0.8326428533 + -0.8420860767, -0.8511404991, -0.8597975969, -0.8680517077, -0.8758881092 + -0.8832823634, -0.8902196884, -0.8967157602, -0.9027729034, -0.9083824754 + -0.9135394692, -0.9182395935, -0.9224776030, -0.9262499809, -0.9295535684 + -0.9323854446, -0.9347436428, -0.9366261959, -0.9380323887, -0.9389615655 + -0.9394137263, -0.9393896461, -0.9388904572, -0.9379178882, -0.9364743829 + -0.9345626831, -0.9321863055, -0.9293491840, -0.9260557890, -0.9223110080 + -0.9181203246, -0.9134896994, -0.9084255695, -0.9029349089, -0.8970250487 + -0.8907034993, -0.8839784265, -0.8768582940, -0.8693521619, -0.8614694476 + -0.8532197475, -0.8446131349, -0.8356599212, -0.8263708353, -0.8167568445 + -0.8068289757, -0.7965991497, -0.7860788107, -0.7752800584, -0.7642148733 + -0.7528960109, -0.7413358092, -0.7295469642, -0.7175422311, -0.7053351402 + -0.6929380894, -0.6803644896, -0.6676273942, -0.6547405124, -0.6417166591 + -0.6285686493, -0.6153115034, -0.6019562483, -0.5885198116, -0.5750215650 + 0.5615197420, 0.5478612781, 0.5341838002, 0.5204906464, 0.5067980289 + 0.4931168854, 0.4794588387, 0.4658361673, 0.4522601366, 0.4387422502 + 0.4252935350, 0.4119254053, 0.3986486793, 0.3854739666, 0.3724119067 + 0.3594728410, 0.3466667533, 0.3340034485, 0.3214924335, 0.3091430366 + 0.2969639599, 0.2849639654, 0.2731511295, 0.2615332901, 0.2501178682 + 0.2389119864, 0.2279221565, 0.2171545923, 0.2066148520, 0.1963084787 + 0.1862401515, 0.1764142811, 0.1668347418, 0.1575049609, 0.1484276950 + 0.1396053135, 0.1310400218, 0.1227331311, 0.1146853194, 0.1068974212 + 0.0993694067, 0.0921007246, 0.0850901082, 0.0783365741, 0.0718384907 + 0.0655927584, 0.0595967993, 0.0538481586, 0.0483424664, 0.0430756323 + 0.0380428955, 0.0332404599, 0.0286619961, 0.0242999699, 0.0201510899 + 0.0162059069, 0.0124559226, 0.0088928537, 0.0054926532, 0.0023052765 + -0.0005515143, -0.0030201224, -0.0052712574, -0.0073737046, -0.0093160523 + -0.0111072771, -0.0127562135, -0.0142635731, -0.0156361461, -0.0168790054 + -0.0179969221, -0.0189934950, -0.0198726747, -0.0206398536, -0.0212980714 + -0.0218509119, -0.0223025978, -0.0226570386, -0.0229178313, -0.0230882075 + -0.0231725387, -0.0231746566, -0.0230979007, -0.0229462404, -0.0227237809 + -0.0224345829, -0.0220820960, -0.0216706358, -0.0212045144, -0.0206875466 + -0.0201238506, -0.0195175279, -0.0188730918, -0.0181944817, -0.0174855441 + -0.0167510118, -0.0159947462, -0.0152208358, -0.0144332750, -0.0136361914 + -0.0128338682, -0.0120294262, -0.0112272501, -0.0104311826, -0.0096443929 + -0.0088709844, -0.0081134979, -0.0073764324, -0.0066623385, -0.0059733889 + -0.0053142183, -0.0046856776, -0.0040914025, -0.0035321070, -0.0030089030 + -0.0025271603, -0.0020749648, -0.0016621647, -0.0012705614, -0.0008115423 +]; +h = h.'; +h = h(:); +h(1*120+(1:120)) = -h(1*120+(1:120)); +h(3*120+(1:120)) = -h(3*120+(1:120)); +h(:) = h(end:-1:1); diff --git a/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/get_ls_layout_config.m b/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/get_ls_layout_config.m new file mode 100644 index 0000000000000000000000000000000000000000..2b57aadfcb9b76b02b79dc5fedcd3fee7dc1adb5 --- /dev/null +++ b/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/get_ls_layout_config.m @@ -0,0 +1,167 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% (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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function ls_struct = get_ls_layout_config(ls_layout_config) + +ls_struct = struct; +switch ls_layout_config + case 'FOA' + ls_struct.name = 'FOA'; + ls_struct.nb_channel = 4; + ls_struct.azi = [0 0 0 0]; + ls_struct.ele = [0 0 0 0]; + ls_struct.isloudspeaker = 0; + ls_struct.sba_order = 1; + ls_struct.num_lfe = 0; + ls_struct.lfe_index = zeros(0,0); + case 'HOA2' + ls_struct.name = 'HOA2'; + ls_struct.nb_channel = 9; + ls_struct.azi = [0 0 0 0 0 0 0 0 0]; + ls_struct.ele = [0 0 0 0 0 0 0 0 0]; + ls_struct.isloudspeaker = 0; + ls_struct.sba_order = 2; + ls_struct.num_lfe = 0; + ls_struct.lfe_index = zeros(0,0); + case 'HOA3' + ls_struct.name = 'HOA3'; + ls_struct.nb_channel = 16; + ls_struct.azi = [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]; + ls_struct.ele = [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]; + ls_struct.isloudspeaker = 0; + ls_struct.sba_order = 3; + ls_struct.num_lfe = 0; + ls_struct.lfe_index = zeros(0,0); + case {'CICP2', '2d0'} + ls_struct.name = 'CICP2'; + ls_struct.nb_channel = 2; + ls_struct.azi = [30 -30]; + ls_struct.ele = [0 0]; + ls_struct.isloudspeaker = 1; + ls_struct.sba_order = -1; + ls_struct.num_lfe = 0; + ls_struct.lfe_index = zeros(0,0); + case {'CICP6', 'cicp6', '5d1'} + ls_struct.name = 'CICP6'; + ls_struct.nb_channel = 6; + ls_struct.azi = [30 -30 0 0 110 -110]; + ls_struct.ele = [0 0 0 0 0 0]; + ls_struct.isloudspeaker = 1; + ls_struct.sba_order = -1; + ls_struct.num_lfe = 1; + ls_struct.lfe_index = [4]; + case {'CICP12', 'cicp12', '7d1'} % 3 front, 4 surround + 1LFE + ls_struct.name = 'CICP12'; + ls_struct.nb_channel = 8; + ls_struct.azi = [30 -30 0 0 110 -110 135 -135]; + ls_struct.ele = [0 0 0 0 0 0 0 0]; + ls_struct.isloudspeaker = 1; + ls_struct.sba_order = -1; + ls_struct.num_lfe = 1; + ls_struct.lfe_index = [4]; + case {'CICP16', 'cicp16', '5d1p4'} + ls_struct.name = 'CICP16'; + ls_struct.nb_channel = 10; + ls_struct.azi = [30 -30 0 0 110 -110 30 -30 110 -110]; + ls_struct.ele = [0 0 0 0 0 0 35 35 35 35]; + ls_struct.isloudspeaker = 1; + ls_struct.sba_order = -1; + ls_struct.num_lfe = 1; + ls_struct.lfe_index = [4]; + case {'CICP13', 'cicp13','22d2'} + ls_struct.name = 'CICP13'; + ls_struct.nb_channel = 24; + ls_struct.azi = [60 -60 0 0 135 -135 30 -30 180 0 90 -90 45 -45 0 0 135 -135 90 -90 180 0 45 -45]; + ls_struct.ele = [0 0 0 0 0 0 0 0 0 0 0 0 35 35 35 90 35 35 35 35 35 -15 -15 -15]; + ls_struct.isloudspeaker = 1; + ls_struct.sba_order = -1; + ls_struct.num_lfe = 2; + ls_struct.lfe_index = [4 10]; + case {'CICP19', 'cicp19','7d1p4'} + ls_struct.name = 'CICP19'; + ls_struct.nb_channel = 12; + ls_struct.azi = [30 -30 0 0 135 -135 90 -90 30 -30 135 -135]; + ls_struct.ele = [0 0 0 0 0 0 0 0 35 35 35 35]; + ls_struct.isloudspeaker = 1; + ls_struct.sba_order = -1; + ls_struct.num_lfe = 1; + ls_struct.lfe_index = [4]; + case {'Combined'} + ls_struct.name = 'Combined'; + ls_struct.nb_channel = 15; + ls_struct.azi = [30 -30 0 135 -135 110 -110 90 -90 30 -30 110 -110 135 -135]; + ls_struct.ele = [0 0 0 0 0 0 0 0 0 35 35 35 35 35 35]; + ls_struct.isloudspeaker = 1; + ls_struct.sba_order = -1; + ls_struct.num_lfe = 0; + case {'Lebedev_26'} + ls_struct.name = 'Leb26'; + ls_struct.nb_channel = 26; + ls_struct.azi = [0 180.0 90.0 270.0 0 0 90.0 90.0 270.0 270.0 0 0 180.0 180.0 45.0 315.0 135.0 225.0 45.0 45.0 315.0 315.0 135.0 135.0 225.0 225.0]; + ls_struct.ele = [0 0 0 0 90.0 -90.0 45.0 -45.0 45.0 -45.0 45.0 -45.0 45.0 -45.0 0 0 0 0 35.3 -35.3 35.3 -35.3 35.3 -35.3 35.3 -35.3]; + ls_struct.isloudspeaker = 1; + ls_struct.sba_order = -1; + ls_struct.num_lfe = 0; + case {'cube_8'} + ls_struct.name = 'Cub8'; + ls_struct.nb_channel = 8; + ls_struct.azi = [45 45 135 135 225 225 315 315]; + ls_struct.ele = [35.3 -35.3 35.3 -35.3 35.3 -35.3 35.3 -35.3]; + ls_struct.isloudspeaker = 1; + ls_struct.sba_order = -1; + ls_struct.num_lfe = 0; + case {'BINAURAL', 'BINAURAL_ROOM'} + ls_struct.name = 'BINAURAL'; + ls_struct.nb_channel = 2; + ls_struct.azi = [90 -90]; + ls_struct.ele = [0 0]; + ls_struct.isloudspeaker = 2; + ls_struct.sba_order = -1; + ls_struct.num_lfe = 0; + case {'STEREO'} + ls_struct.name = 'STEREO'; + ls_struct.nb_channel = 2; + ls_struct.azi = [90 -90]; + ls_struct.ele = [0 0]; + ls_struct.isloudspeaker = 2; + ls_struct.sba_order = -1; + ls_struct.num_lfe = 0; + case {'MONO'} + ls_struct.name = 'MONO'; + ls_struct.nb_channel = 1; + ls_struct.azi = [0]; + ls_struct.ele = [0]; + ls_struct.isloudspeaker = 1; + ls_struct.sba_order = -1; + ls_struct.num_lfe = 0; + otherwise + error('Loudspeaker layout not supported!'); +end diff --git a/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/hrtf_library_loader.m b/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/hrtf_library_loader.m index c8d41d7e06b244bd7b283ee9203a5557b5742a20..5459fbcc771dbd129cf25c74a81f09828f06955d 100644 --- a/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/hrtf_library_loader.m +++ b/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/hrtf_library_loader.m @@ -46,6 +46,8 @@ classdef hrtf_library_loader < handle SourceRadius = []; % The source distance for HRTFs in this library PlaybackRadius = []; % The radius for HRTFs during playback Info = {''}; % A cell array of strings with info about this library + PosSpherical = []; % source positiona in spherical representation (rads, meters) + Data = []; end properties (Access=protected) % Define the set of uni-vectors for the HRTF directions in a discrete Library @@ -100,6 +102,7 @@ classdef hrtf_library_loader < handle if strcmpi(Units{2},'degree'), Pos(2,:)=Pos(2,:)*pi/180; end assert( any(strcmpi(Units{3}, {'metre','meter','inch'})), 'Unknown units'); if strcmpi(Units{3},'inch' ), Pos(3,:)=Pos(3,:)*0.0254; end + PosSpherical = Pos; Pos = Pos(3,:) .* ... [cos(Pos(2,:)).*[cos(Pos(1,:));sin(Pos(1,:))];sin(Pos(2,:))]; @@ -146,6 +149,7 @@ classdef hrtf_library_loader < handle H.UnitVectors = XYZ; H.HRTF_L = HRTF_L; H.HRTF_R = HRTF_R; + H.PosSpherical = PosSpherical; [~,NameRoot,~] = fileparts(Lib_Name); H.Info.Name = NameRoot; @@ -154,12 +158,19 @@ classdef hrtf_library_loader < handle H.Info.FilterSize = sprintf('%d-tap FIR',IRLen); H.Info.Scaling = 'Normalised to unity gain at 1kHz'; + H.Data = Data; + obj.process_lib(H, Data.SamplingRate); end function IR = XYZ_to_IR( this, XYZ ) IR = permute(cat(3,this.getHRTF_L(XYZ),this.getHRTF_R(XYZ)),[1,3,2]); end + + function IR = XYZ_to_IR_SD( this, XYZ ) + [HRTF_L, HRTF_R] = this.getHRTF_SD(XYZ); + IR = permute(cat(3,HRTF_L,HRTF_R),[1,3,2]); + end end % methods @@ -212,6 +223,8 @@ classdef hrtf_library_loader < handle obj.buildGDMag(); obj.Last_UV=[]; obj.setLen(512); + obj.PosSpherical = hrtf_lib.PosSpherical; + obj.Data = hrtf_lib.Data; end function setLen(obj,Len) @@ -223,7 +236,20 @@ classdef hrtf_library_loader < handle obj.Window = sin(min(1,(Len:-1:1)'*4/Len)*pi/2).^2; obj.Last_UV=[]; end - + + function [HRTFs_L, HRTFs_R] = getHRTF_SD(obj, varargin) + % GETHRTF_SD Get the SD HRTFs for both ears from the library + % Given [N] direction-of-arrival vectors, returns an array + % of size [Len]x[N], containing the N HRTFs. + % Examples: + % HRTFs = H.getHRTF_SD(Az,El) % Az and El are both Nx1 or 1xN vectors (in radians) + % HRTFs = H.getHRTF_SD( Angles ) % Angles is a 2xN array of Az,El column pairs (in radians) + % HRTFs = H.getHRTF_SD(X, Y, Z) % X,Y,Z are all 1xN or Nx1 vectors + % HRTFs = H.getHRTF_SD(Vects) % Vects is a 3xN array of X,Y,Z column vectors + UnitVecs = make_unit_vectors(varargin{:}); + [HRTFs_L, HRTFs_R] = obj.Fetch_Discrete_HRTFs(UnitVecs); + end + function HRTFs = getHRTF_L(obj,varargin) % GETHRTF_L Get one or more Left-ear HRTFs from the library % Given [N] direction-of-arrival vectors, returns an array @@ -343,6 +369,29 @@ classdef hrtf_library_loader < handle end end + function [TempL,TempR]=Fetch_Discrete_HRTFs(obj, UnitVecs) + % We have set of unit-vectors, so we need to fetch the Left/Right + % HRTFs at these (interpolated) angle positions + NoVecs=size(UnitVecs,2); + TempL=zeros(size(obj.Discrete_HRTFs,1),NoVecs); + TempR=zeros(size(obj.Discrete_HRTFs,1),NoVecs); + for k=1:NoVecs + % For each direction (specified by a column of UnitVecs), we need + % to figure out which HRTF Direction Vectors match the + % given position + IndSubset=1:size(obj.Discrete_UnitVectors,2); + Dists=sum( (obj.Discrete_UnitVectors - repmat(UnitVecs(:,k),[1 size(obj.Discrete_UnitVectors,2)])).^2); + [minDist, Dir] = min(Dists(IndSubset)); + % 10e-e4 is roughly the error for 1deg offset on the sphere + if abs(minDist) > 10e-3 + error("Could not find an IR exactly matching this position, please check HRTF set!"); + end + + TempL(:,k)=obj.Discrete_HRTFs(:,Dir,1); + TempR(:,k)=obj.Discrete_HRTFs(:,Dir,2); + end + end + function [TempL,TempR]=Interpolate_Discrete_HRTFs(obj,UnitVecs) % We have set of unit-vectors, so we need to buld the Left/Right diff --git a/scripts/binauralRenderer_interface/param_bin/SH_GainComputation.m b/scripts/binauralRenderer_interface/param_bin/SH_GainComputation.m new file mode 100644 index 0000000000000000000000000000000000000000..2128779acfe2bb037a3c4071132a1f06c370f5b2 --- /dev/null +++ b/scripts/binauralRenderer_interface/param_bin/SH_GainComputation.m @@ -0,0 +1,71 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% (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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function sh_gains = SH_GainComputation(dirs_deg, max_order) +% Computation of real-valued spherical harmonic coefficients in ACN/orthonormal +% normalization format + +num_sh = (max_order+1)^2; +az_rad = dirs_deg(:,1)*pi/180; +coel_rad = pi/2-dirs_deg(:,2)*pi/180; +num_el = length(coel_rad); + +% Compute real-valued spherical harmonic coefficients +sh_gains = zeros(num_sh,num_el); +indx = 0; +% l: SH-level (SH-order) +for l = 0:max_order + P = legendre(l,cos(coel_rad)).'; + + % m: SH-mode + for m = -l:l + indx = indx + 1; + % N3D normalization term + norm_term = sqrt((2*l+1)*factorial(l-abs(m))/(4*pi*factorial(l+abs(m)))); + + % trigonometric term + if m > 0 + trg_term = sqrt(2)*cos(m*az_rad); + elseif m == 0 + trg_term = 1; + else + trg_term = -sqrt(2)*sin(m*az_rad); + end + + % associate Legendre function (with compensation of the Condon-Shortley phase term) + Pnm = P(:,abs(m)+1)*(-1)^m; + + % final direct gain + sh_gains(indx,:) = norm_term.*Pnm.*trg_term; + end +end + +end \ No newline at end of file diff --git a/scripts/binauralRenderer_interface/param_bin/equalDistributionUnitVectors.mat b/scripts/binauralRenderer_interface/param_bin/equalDistributionUnitVectors.mat new file mode 100644 index 0000000000000000000000000000000000000000..b242a66423323324236637a8bece44527a5d3fbf --- /dev/null +++ b/scripts/binauralRenderer_interface/param_bin/equalDistributionUnitVectors.mat @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f47ff2387079ac315e2ea4bdf9f6f9c67d47173d9740eef86eec3a7d409f24d7 +size 3844 diff --git a/scripts/binauralRenderer_interface/param_bin/generate_BRIR_in_SHD_CLDFB_PARAMETRIC.m b/scripts/binauralRenderer_interface/param_bin/generate_BRIR_in_SHD_CLDFB_PARAMETRIC.m new file mode 100644 index 0000000000000000000000000000000000000000..5a30bcbf8da4803a49f12787b31817154085f291 --- /dev/null +++ b/scripts/binauralRenderer_interface/param_bin/generate_BRIR_in_SHD_CLDFB_PARAMETRIC.m @@ -0,0 +1,195 @@ +% +% (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. +% + +function [T60, lateEnes, earlyEnes] = generate_BRIR_in_SHD_CLDFB_PARAMETRIC(brir_inputfile, SHhrtf) +% +% [T60, lateEnes, earlyEnes] = generate_BRIR_in_SHD_CLDFB_PARAMETRIC(brir_inputfile, SHhrtf) +% +% First parameter is the name with path to BRIR file in SOFA format +% Second parameter is the HRIR set in SHD created before. +% Return value contains the tables derived from BRIR set. + +%% Load BRIR input file +sofaData = hrtf_library_loader(); +sofaData.readSOFA(brir_inputfile); + +%% Get data and format it for us +% Input VRIR data from SOFA. After permuation, in order (response, ear, dirIndex) +brirs = permute(sofaData.Data.IR(:, :, :), [3 2 1]); + +% Sampling rate of the BRIR set. Currently only checked. +brirFS = sofaData.Data.SamplingRate; +if brirFS ~= 48000 + error('Only 48 kHz sampling rate BRIR is supported for now.') +end + +% Measurement directions for responses. We discard the distance but there should +% be solution that uses only measurements from same distance. +brirAziRad = sofaData.PosSpherical(1, :).'; +brirEleRad = sofaData.PosSpherical(2, :).'; + +% Determine nearest subset corresponding to 5.0 layout. +% All BRIR related parameters are determined based on them + +refAnglesRad = [30 0 -30 110 -110]' * pi/180; +refVectors = [cos(refAnglesRad) sin(refAnglesRad) zeros(size(refAnglesRad))]; +sofaVectors = [cos(brirAziRad).*cos(brirEleRad) sin(brirAziRad).*cos(brirEleRad) sin(brirEleRad)]; +for ch = 1:length(refAnglesRad) + [~, maxIndex] = max(sofaVectors*refVectors(ch,:)'); + chSelect(ch) = maxIndex; +end +brirs = brirs(:, :, chSelect); + +% Remove low frequencies which would cause T60 estimation errors +[B,A] = butter(5, 80/24000, 'high'); +brirs = filter(B, A, brirs); + +% Determine energies for the 5 BRIR pairs in 60 CLDFB frequency bins +nFFT = 120; % 60 frequency bins +window = hanning(nFFT); +freqShiftWindow = window.*exp(-1i*[1:nFFT]'*pi/nFFT); % half bin offset as in CLDFB +enes = []; +for ch = 1:length(refAnglesRad) + % Make low-pass energy enevelope and find its maximum energy position, + % for each BRIR pair separately since the measurements may be not in sync + brirEne = sum(abs(brirs(:, :, ch)).^2,2); + maxEneSearchEnvelope = fftfilt(window, brirEne); + [~, maxEnePos] = max(maxEneSearchEnvelope); + + % Set the first frame to match the maximum energy (i.e., catch the the direct component) + timeIndices = maxEnePos - nFFT + [1:nFFT]'; + + % Determine the energy from that position onwards in 60 sample hops + frameIndex = 1; + while timeIndices(end) < length(brirs) + brirFrame = brirs(timeIndices, :, ch).*repmat(freqShiftWindow, [1 2]); + frameF = fft(brirFrame); + enes(:, frameIndex, ch) = sum(abs(frameF(1:nFFT/2, :)).^2,2); + frameIndex = frameIndex + 1; + timeIndices = timeIndices + nFFT/2; + end +end +% Combine energies across all directions +enes = sum(enes, 3); + +% Determine search range for the T60 determination. In other words, find +% where noise floor starts at each band +for band = 1:nFFT/2 + % This position is a maximum value after the early part + [~, lateStart] = max(enes(band, 5:15)); + + % Ene envelope in dB for the band + eneDb = 10*log10(enes(band, :)); + index = 1; + + % Estimate a linear fit to the energy decay and determine RMSE:s with + % respect to the actual energt decay + for p = lateStart+5:length(eneDb) + indices = [lateStart:p]'; + P = polyfit(indices, eneDb(indices).', 1); + est = polyval(P, indices); + RMSE(index) = rms(est'-eneDb(indices)); + index = index+1; + end + % Find minimum RMSE, but then find the longest sequence that has + % smaller than 1dB larger RMSE + rmseIndicesInRange = (RMSE < (min(RMSE) + 1)); + maxIndexInRange(band) = 1; + for index = 1:length(RMSE) + if rmseIndicesInRange(index) + maxIndexInRange(band) = index; + end + end + % Truncate a little bit from the end, otherwise the start of the noise + % floor slightly appears at the tail + maxIndexInRange(band) = round(maxIndexInRange(band)*0.9); +end + +% Smooth the length of the responses (starts of the noise floor) across +% frequency. This clears any occasional errors at the estimates +maxIndexInRangeSmooth = zeros(nFFT/2, 1); +for band = 1:nFFT/2 + range = band + [-2:2]; + range=range(range > 0); + range=range(range <= nFFT/2); + maxIndexInRangeSmooth(band) = round(median(maxIndexInRange(range))); +end + +% Determine T60, early energies, and late energies +T60 = zeros(nFFT/2,1); +for band = 1:nFFT/2 + [~, lateStart] = max(enes(band, 5:15)); + eneDb = 10*log10(enes(band, :)); + indices = [lateStart:maxIndexInRangeSmooth(band)]; + + % Linear fitting a line, determining T60 based on it + P = polyfit(indices, eneDb(indices), 1); + dbDropPerFrame = P(1); + frames60dBdropped = -60 / dbDropPerFrame; + T60(band) = frames60dBdropped / 48000 * nFFT /2; + + % Formulate early and late part enes + earlyEnes(band) = sum(enes(band, 1:25)); + lateEnes(band) = sum(enes(band, 26:maxIndexInRangeSmooth(band))); +end + +% Compensate earlyEnes with HRIR energy as it is used together with the +% BRIR set in rendering. +order = 3; +SH = SH_GainComputation([refAnglesRad*180/pi zeros(size(refAnglesRad))], order)/0.2821; +SH(2:4, :) = SH(2:4, :) / sqrt(3); +SH(5:9, :) = SH(5:9, :) / sqrt(5); +SH(10:16, :) = SH(10:16,: ) / sqrt(7); +refHrtfEnes = zeros(60, 1); +for band = 1:60 + for ch = 1:length(refAnglesRad) + hrtf = SHhrtf(:, :, band) * SH(:, ch); + refHrtfEnes(band) = refHrtfEnes(band) + mean(abs(hrtf).^2); + end +end +refHrtfEnes = refHrtfEnes / length(refAnglesRad); + +% Limit reference energies such that close to zero or zero HRTF energy would not generate high compensation +% factors for earlyEnes. +refHrtfEnes = max(0.2*median(refHrtfEnes), refHrtfEnes); + +earlyEnes = earlyEnes./refHrtfEnes'; +earlyEnes(1) = earlyEnes(1)*10^(1/10); % 1dB LF boost at first bin to compensate for the high-pass filter + +% Smoothing of the high frequency T60s. Highest range near Nyquist are +% prone for T60 estimation errors. Linearly expand from lower frequencies. +indices = [30:50]'; +P = polyfit(indices, T60(indices), 1); +interp = min(1, [0:30]'/20); +T60(30:60) = T60(30:60).*(1-interp) + polyval(P, [30:60]').*interp; + +% Late part energies are multiplied by sqrt(2), since parametric +% expects such normalization. +lateEnes = lateEnes * sqrt(2); diff --git a/scripts/binauralRenderer_interface/param_bin/generate_HRIR_in_SHD_CLDFB_PARAMETRIC.m b/scripts/binauralRenderer_interface/param_bin/generate_HRIR_in_SHD_CLDFB_PARAMETRIC.m new file mode 100644 index 0000000000000000000000000000000000000000..439b2a6cf6d88424672de0ff34b5bc040bcb00ae --- /dev/null +++ b/scripts/binauralRenderer_interface/param_bin/generate_HRIR_in_SHD_CLDFB_PARAMETRIC.m @@ -0,0 +1,166 @@ +% +% (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. +% + +function SHhrtf = generate_HRIR_in_SHD_CLDFB_PARAMETRIC(hrir_inputfile) +% +% SHhrtf = generate_HRIR_in_SHD_CLDFB_PARAMETRIC(hrir_inputfile) +% +% Parameter is the input HRIR file in sofa-format. +% Formulated HRTF in SHD CLDFB domain is given as return value. + +%% Load HRIR input file +sofaData = hrtf_library_loader(); +sofaData.readSOFA(hrir_inputfile); + +%% Get data and format it for us +% Input HRIR data from SOFA. After permuation, in order (ear, dirIndex, response) +hrirRaw = permute(sofaData.Data.IR(:, :, :), [2 1 3]); +hrirl = squeeze(hrirRaw(1, :, :)); +hrirr = squeeze(hrirRaw(2, :, :)); + +% Sampling rate of the HRIR set. Currently only checked. +hrirFS = sofaData.Data.SamplingRate; +if hrirFS ~= 48000 + error('Only 48 kHz sampling rate HRIR is supported for now.') +end + +% Measurement directions for responses. We discard the distance but there should +% be solution that uses only measurements from same distance. +HRTFanglesRad = sofaData.PosSpherical(1:2, :).'; + +% Conversion code starts +nBins = 60; +binCenterF = ([0:59] + 0.5) / 60 * 24000; +IRlen = 1200; + +nDirs = length(HRTFanglesRad); +groupDelays = zeros(nDirs, 1); +HRIR = zeros(IRlen, 2, nDirs); +HRTFvectors = zeros(nDirs, 3); + +for dirIndex=1:nDirs + azi = HRTFanglesRad(dirIndex, 1); + ele = HRTFanglesRad(dirIndex, 2); + + %% transform coordinates to XYZ vectors + HRTFvectors(dirIndex, 1) = cos(azi)*cos(ele); + HRTFvectors(dirIndex, 2) = sin(azi)*cos(ele); + HRTFvectors(dirIndex, 3) = sin(ele); + + HRIRthis = double([hrirl(dirIndex,: )' hrirr(dirIndex, :)']); + + HRIR(1:length(HRIRthis), :, dirIndex) = HRIRthis; + groupDelays(dirIndex) = median([grpdelay(HRIR(1:512, 1, dirIndex)); grpdelay(HRIR(1:512, 2, dirIndex))]); +end + +HRTF = fft(HRIR, 1200); +HRTF = HRTF(1:end/2, :, :); + +%% Reference impulse for estimating the steering vectors (transfer functions) +refImpulse = zeros(IRlen, 1); +refImpulse(round(median(groupDelays))) = 1; + +ref = CLDFB(refImpulse); +refEne = repmat(sum(abs(ref).^2,2), [1 2]); + +%% IVAS filter-bank assumed +HRTFs = zeros(nBins, 2, nDirs); + +%% HRIR -> HRTF +for dirIndex = 1:nDirs + HRTFs_this = CLDFB(HRIR(:, :, dirIndex)); + phase = angle(squeeze(sum(HRTFs_this.*conj(repmat(ref, [1 1 2])), 2))); + energy = squeeze(sum(abs(HRTFs_this).^2, 2))./refEne; + HRTFs(:, :, dirIndex) = sqrt(energy).*exp(1i*phase); +end + +%% Diffuse field equalization and formulation of the diffuse field response +load equalDistributionUnitVectors +srcVec = equalDistributionUnitVectors; +diffEne = zeros(nBins,1); + +for k = 1:length(srcVec) + dirVec = srcVec(k, :); + [~, maxIndex] = max(HRTFvectors * dirVec'); + HRTF_this = HRTFs(:, :, maxIndex); + diffEne = diffEne + sum(abs(HRTF_this).^2, 2); +end + +%% +diffEne = diffEne/length(srcVec)/2; +EQ = sqrt(1./diffEne); +EQ = min(EQ, median(EQ)*5); % Avoid multiply non-existent data with large values (e.g. HF is missing in data) +HRTFs = HRTFs.*repmat(EQ, [1 2 nDirs]); + +order = 3; +SH = SH_GainComputation(HRTFanglesRad / pi * 180, order)/0.2821; +SH(2:4, :) = SH(2:4, :) / sqrt(3); +SH(5:9, :) = SH(5:9, :) / sqrt(5); +SH(10:16, :) = SH(10:16, :) / sqrt(7); +SH = SH'; +SHhrtf = zeros(size(SH,2), 2, 60); +SHpinv = pinv(SH); +for bin = 1:nBins + hrtfThis = permute(HRTFs(bin, :, :), [3 2 1]); + if binCenterF(bin) > 2000 % Hz + hrtfThis = abs(hrtfThis); + end + SHhrtf(:, :, bin) = (SHpinv*hrtfThis); +end + +SHhrtf = permute(SHhrtf, [2 1 3]); + +end % function + + +function FD = CLDFB(sig) + % retrieve filter prototype + [h, D, S, L] = get_cldfb_filter(); + proto = h(end:-1:1); + + % Modulate prototype by half bin, and scale to match C implementation + proto = proto.*exp(-1j*[0.5:1:600]'/120*pi) / 0.75; + numCh = size(sig, 2); + sig = sig(1:end-mod(size(sig),60), :); + FD = zeros(60, size(sig,1)/60, numCh); + sig = [zeros(540, numCh); sig]; + indices = [1:600]'; + FDindex = 1; + while indices(end) <= length(sig) + frame = sig(indices, :).*repmat(proto, [1 numCh]); + frameWrap = frame(1:120, :) + frame(121:240, :) + frame(241:360, :) + frame(361:480, :) + frame(481:600, :); + frameWrap = circshift(frameWrap, [60 0]); + FDsig = fft(frameWrap); + phase = [0:59]'/60*pi/2 + pi/2; + FD(:, FDindex, :) = FDsig(1:60, :).*repmat(exp(-1i*phase), [1 numCh]); + FDindex = FDindex + 1; + indices = indices + 60; + end +end diff --git a/scripts/binauralRenderer_interface/param_bin/generate_tables_for_parametric_binauralizer.m b/scripts/binauralRenderer_interface/param_bin/generate_tables_for_parametric_binauralizer.m new file mode 100644 index 0000000000000000000000000000000000000000..dad321fc7c50522c582bb67deb4fd667233bc2e2 --- /dev/null +++ b/scripts/binauralRenderer_interface/param_bin/generate_tables_for_parametric_binauralizer.m @@ -0,0 +1,138 @@ +% +% (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. +% + +% +% Generate tables from given HRIRs and BRIRs for IVAS binaural renderers PARAMETRIC and FASTCONV +% +clear all; +close all; +clc; + +%% Add path to routines get_cldfb_filter.m and hrtf_library_loader.m +addpath('../matlab_hrir_generation_scripts/'); + +%% Set arguments +writeRomFileOutput = true; +writeBinaryOutput = true; + +%% Set input files +hrir_file = fullfile('..', 'HRIRs_sofa', 'HRIR_128_Meth5_IRC_53_Q10_symL_Itrp1_48000.sofa'); +brir_file = fullfile('..', 'BRIRs_sofa', 'IIS_BRIR_officialMPEG_Combined.sofa'); + +if writeRomFileOutput + %% Open file and write header + if ismac + username = getenv('USER'); + else + username = getenv('username'); + end + fid = fopen(fullfile('.', 'ivas_rom_binauralRenderer.c'), 'wt'); + fprintf(fid, '/*\n'); + fprintf(fid, ' * Generated on %s with Matlab version %s by %s.\n', date, version, username); + fprintf(fid, '*/\n'); +end + + +%% Generate C-code tables for RENDERER_BINAURAL_PARAMETRIC (SHD) +disp('Processing HRIR for parametric renderer...'); +SHhrtf = generate_HRIR_in_SHD_CLDFB_PARAMETRIC(hrir_file); + +if writeRomFileOutput + writeData3L(fid, 'const float hrtfShCoeffsRe[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]', real(SHhrtf)); + writeData3L(fid, 'const float hrtfShCoeffsIm[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]', imag(SHhrtf)); +end + +%% Generate C-code tables for RENDERER_BINAURAL_PARAMETRIC_ROOM (SHD) +disp('Processing BRIR for parametric renderer...'); +[T60, lateEnes, earlyEnes] = generate_BRIR_in_SHD_CLDFB_PARAMETRIC(brir_file, SHhrtf); + +if writeRomFileOutput + % Write BRIR parameters to file + fprintf(fid, 'const float parametricReverberationTimes[CLDFB_NO_CHANNELS_MAX] = {\n'); + for k = 1:60 + if mod(k-1, 10)==0 + fprintf(fid, ' '); + end + if k < 60 + fprintf(fid, '%ff,', T60(k)); + else + fprintf(fid, '%ff\n};', T60(k)); + end + if k>1 && mod(k, 10)==0 + fprintf(fid, '\n'); + else + fprintf(fid, ' '); + end + end + + fprintf(fid, '\n\nconst float parametricReverberationEneCorrections[CLDFB_NO_CHANNELS_MAX] = {\n'); + for k = 1:60 + if mod(k-1, 10)==0 + fprintf(fid,' '); + end + if k < 60 + fprintf(fid, '%ff,', lateEnes(k)); + else + fprintf(fid, '%ff\n};', lateEnes(k)); + end + if k>1 && mod(k, 10)==0 + fprintf(fid, '\n'); + else + fprintf(fid, ' '); + end + end + + fprintf(fid, '\n\nconst float parametricEarlyPartEneCorrection[CLDFB_NO_CHANNELS_MAX] = {\n'); + for k = 1:60 + if mod(k-1, 10)==0 + fprintf(fid, ' '); + end + if k < 60 + fprintf(fid, '%ff,', earlyEnes(k)); + else + fprintf(fid, '%ff\n};', earlyEnes(k)); + end + if k>1 && mod(k, 10)==0 + fprintf(fid, '\n'); + else + fprintf(fid, ' '); + end + end +end + +if writeRomFileOutput + fclose(fid); +end + +%% +if writeBinaryOutput + write_parametric_binauralizer_binary_data('parambin_binary_rom.bin', SHhrtf, T60, lateEnes, earlyEnes); + %save('parambin_binary_rom.mat', 'SHhrtf', 'T60', 'lateEnes', 'earlyEnes'); % debug saving +end diff --git a/scripts/binauralRenderer_interface/param_bin/write_parametric_binauralizer_binary_data.m b/scripts/binauralRenderer_interface/param_bin/write_parametric_binauralizer_binary_data.m new file mode 100644 index 0000000000000000000000000000000000000000..5fd8c79b02f43064846ca1447b7b420b16f7bf8c --- /dev/null +++ b/scripts/binauralRenderer_interface/param_bin/write_parametric_binauralizer_binary_data.m @@ -0,0 +1,96 @@ +% +% (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. +% + +function write_parametric_binauralizer_binary_data(filename, SHhrtf, T60, late_enes, early_enes) +% +% Writes HRIR & BRIR based data for parametric binauralizer into a binary file. +% +% write_parametric_binauralizer_binary_data(filename, SHhrtf, T60, late_enes, early_enes) +% +% filename : string +% name of the file to be written +% SHhrtf : array of shape (2, 16, 60) i.e., (BINAURAL_CHANNELS, HRTF_SH_CHANNELS, HRTF_NUM_BINS), complex-valued +% HRTF coefficients +% T60 : array of shape (60, 1), i.e., (CLDFB_NO_CHANNELS_MAX, 1), double +% late_enes : array of shape (1, 60), i.e., (1, CLDFB_NO_CHANNELS_MAX), double +% early_enes : array of shape (1, 60), i.e., (1, CLDFB_NO_CHANNELS_MAX), double +% +% +% Output file format: +% HRTFs +% HRTF_SH_CHANNELS => uint16_t +% HRTF_NUM_BINS => uint16_t +% hrtfShCoeffsRe => float[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]; +% hrtfShCoeffsIm => float[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]; +% +% BRIR-based reverb +% CLDFB_NO_CHANNELS_MAX => uint16_t +% parametricReverberationTimes => float[CLDFB_NO_CHANNELS_MAX]; +% parametricReverberationEneCorrections => float[CLDFB_NO_CHANNELS_MAX]; +% parametricEarlyPartEneCorrection => float[CLDFB_NO_CHANNELS_MAX]; +% + +[f_id, err_msg] = fopen(filename, 'wb'); + +if f_id == -1 + error('Could not open file %s for writing. Error message:\n%s', filename, err_msg); +end + +% HRTFs +n_chnls_bin = 2; +hrtf_sh_channels = size(SHhrtf, 2); +hrtf_num_bins = size(SHhrtf, 3); + +fwrite(f_id, hrtf_sh_channels, 'uint16'); +fwrite(f_id, hrtf_num_bins, 'uint16'); + +% hrtfShCoeffsRe +for bin_chnl_idx = 1:n_chnls_bin + for hrtf_chnl_idx = 1:hrtf_sh_channels + fwrite(f_id, real(SHhrtf(bin_chnl_idx, hrtf_chnl_idx, :)), 'float32'); % HRTF_NUM_BINS elements + end +end + +% hrtfShCoeffsIm +for bin_chnl_idx = 1:n_chnls_bin + for hrtf_chnl_idx = 1:hrtf_sh_channels + fwrite(f_id, imag(SHhrtf(bin_chnl_idx, hrtf_chnl_idx, :)), 'float32'); % HRTF_NUM_BINS elements + end +end + +% BRIR-based reverb +cldfb_no_channels_max = size(T60, 1); + +fwrite(f_id, cldfb_no_channels_max, 'uint16'); +fwrite(f_id, T60, 'float32'); % parametricReverberationTimes +fwrite(f_id, late_enes, 'float32'); % parametricReverberationEneCorrections +fwrite(f_id, early_enes, 'float32'); % parametricEarlyPartEneCorrection + +fclose(f_id);