From 8376503e1cca18d6db3ef8d9a320ff8abea0f269 Mon Sep 17 00:00:00 2001 From: Lauros Pajunen Date: Wed, 8 Feb 2023 10:58:14 +0200 Subject: [PATCH 1/7] Add MATLAB conversion scripts from SOFA to ParaBin format including binary file support. Add loading of the binary file in the main aggregation program. --- .../generate_tables_from_rom_to_bin.c | 236 ++++++++++++++++-- .../equalDistributionUnitVectors.mat | 3 + .../generate_BRIR_in_SHD_CLDFB_PARAMETRIC.m | 196 +++++++++++++++ .../generate_HRIR_in_SHD_CLDFB_PARAMETRIC.m | 163 ++++++++++++ ...erate_tables_for_parametric_binauralizer.m | 143 +++++++++++ ...rite_parametric_binauralizer_binary_data.m | 96 +++++++ 6 files changed, 822 insertions(+), 15 deletions(-) create mode 100644 scripts/binauralRenderer_interface/param_bin/equalDistributionUnitVectors.mat create mode 100644 scripts/binauralRenderer_interface/param_bin/generate_BRIR_in_SHD_CLDFB_PARAMETRIC.m create mode 100644 scripts/binauralRenderer_interface/param_bin/generate_HRIR_in_SHD_CLDFB_PARAMETRIC.m create mode 100644 scripts/binauralRenderer_interface/param_bin/generate_tables_for_parametric_binauralizer.m create mode 100644 scripts/binauralRenderer_interface/param_bin/write_parametric_binauralizer_binary_data.m 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 89a33e1d45..4c4a678da1 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 @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (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 @@ -40,6 +40,7 @@ #include "ivas_stat_dec.h" #define FILE_HEADER +#define PARABIN_FILE_312 /*------------------------------------------------------------------------------------------* * Constants @@ -51,9 +52,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 PARABIN_FILE_312 +#define DEFAULT_INPUT_PARABIN_FILE "parabin_binary_rom" +#endif +#define DEFAULT_BIN_FILE_EXT ".bin" #define IVAS_NB_RENDERER_TYPE 7 #define IVAS_NB_AUDIO_CONFIG 2 @@ -156,6 +160,10 @@ void usage_tables_format_converter( void ) "-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 ); +#ifdef PARABIN_FILE_312 + fprintf( stdout, "-input_parabin_file_path : Path of binary files for parabin renderer (with separator, used as flag).\n" ); + fprintf( stdout, "-input_parabin_file_name : Name of input parabin file (without extension %s, default = '%s').\n", DEFAULT_BIN_FILE_EXT, DEFAULT_INPUT_PARABIN_FILE ); +#endif fprintf( stdout, "\n" ); } @@ -171,6 +179,12 @@ char *input_td_bin_path = NULL; char *input_td_bin_file_name = NULL; char *full_in_td_path = NULL; +#ifdef PARABIN_FILE_312 +char *input_parabin_path = NULL; +char *input_parabin_file_name = NULL; +char *full_in_parabin_path = NULL; +#endif + int16_t nb_freq = IVAS_NB_SAMPLERATE; const int32_t *freq_ptr = sample_rates; @@ -1055,7 +1069,18 @@ char *create_hrtf_parametric( int32_t *hrtf_size ) uint32_t data_size_tmp; int16_t i, j; +#ifdef PARABIN_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_parabin_file = NULL; +#endif hrtf_data_size = 0; /* Binary file - block description : @@ -1067,12 +1092,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 @@ -1086,10 +1110,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 PARABIN_FILE_312 + file_read_ok = 0; + file_read_ok = 0; + input_parabin_file = fopen( full_in_parabin_path, "rb" ); + if ( input_parabin_file != NULL ) + { + uint16_t hrtf_sh_channels, hrtf_num_bins, cldfb_no_channels_max; + + fseek( input_parabin_file, 0, SEEK_END ); + data_size_tmp = ftell( input_parabin_file ); + fseek( input_parabin_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_parabin_file ); + fread( &hrtf_num_bins, sizeof( uint16_t ), 1, input_parabin_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_parabin_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_parabin_file ); + } + } + + /* reverb */ + fread( &cldfb_no_channels_max, sizeof( uint16_t ), 1, input_parabin_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_parabin_file ); + fread( parametricReverberationEneCorrectionsFile, sizeof( float ), CLDFB_NO_CHANNELS_MAX, input_parabin_file ); + fread( parametricEarlyPartEneCorrectionFile, sizeof( float ), CLDFB_NO_CHANNELS_MAX, input_parabin_file ); + + file_read_ok = 1; + } + } + else + { + fprintf( stderr, "Opening of parabin file %s failed. Using built-in default values.\n\n", full_in_parabin_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" ); @@ -1097,6 +1184,7 @@ char *create_hrtf_parametric( int32_t *hrtf_size ) return NULL; } + // Write // Header [Declaration of the HRTF] @@ -1132,14 +1220,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 PARABIN_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; } } @@ -1147,7 +1245,18 @@ char *create_hrtf_parametric( int32_t *hrtf_size ) { for ( j = 0; j < HRTF_SH_CHANNELS; j++ ) { +#ifdef PARABIN_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; } } @@ -1157,13 +1266,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 PARABIN_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 PARABIN_FILE_312 + } +#endif return hrtf; } @@ -2060,6 +2184,34 @@ int rom2bin_init( int argc, char *argv[] ) strcpy( input_td_bin_file_name, argv[i] ); i++; } +#ifdef PARABIN_FILE_312 + else if ( strcmp( to_upper( argv[i] ), "-INPUT_PARABIN_FILE_PATH" ) == 0 ) + { + i++; + if ( strlen( argv[i] ) == 0 ) + { + fprintf( stderr, "Wrong input parabin file path: %s\n\n", argv[i] ); + usage_tables_format_converter(); + return -1; + } + input_parabin_path = malloc( strlen( argv[i] ) + 1 ); + strcpy( input_parabin_path, argv[i] ); + i++; + } + else if ( strcmp( to_upper( argv[i] ), "-INPUT_PARABIN_FILE_NAME" ) == 0 ) + { + i++; + if ( strlen( argv[i] ) == 0 ) + { + fprintf( stderr, "Wrong input parabin file name: %s\n\n", argv[i] ); + usage_tables_format_converter(); + return -1; + } + input_parabin_file_name = malloc( strlen( argv[i] ) + 1 ); + strcpy( input_parabin_file_name, argv[i] ); + i++; + } +#endif else { fprintf( stderr, "Unknown option: %s\n\n", argv[i] ); @@ -2155,7 +2307,45 @@ int rom2bin_init( int argc, char *argv[] ) return -1; } } +#ifdef PARABIN_FILE_312 + if ( input_parabin_path == NULL ) + { + input_parabin_path = (char *) malloc( sizeof( char ) * ( strlen( DEFAULT_PATH ) + 1 ) ); + if ( input_parabin_path ) + { + strcpy( input_parabin_path, DEFAULT_PATH ); + } + else + { + fprintf( stderr, "Memory issue for input parabin file path!\n\n" ); + rom2bin_terminat(); + return -1; + } + } + if ( input_parabin_file_name == NULL ) + { + input_parabin_file_name = (char *) malloc( sizeof( char ) * ( strlen( DEFAULT_INPUT_PARABIN_FILE ) + 1 ) ); + if ( input_parabin_file_name ) + { + strcpy( input_parabin_file_name, DEFAULT_INPUT_PARABIN_FILE ); + } + else + { + fprintf( stderr, "Memory issue for input parabin file name!\n\n" ); + rom2bin_terminat(); + return -1; + } + } + full_in_parabin_path = (char *) malloc( sizeof( char ) * ( strlen( input_parabin_path ) + strlen( input_parabin_file_name ) + strlen( DEFAULT_BIN_FILE_EXT ) + 2 ) ); + if ( full_in_parabin_path == NULL ) + { + fprintf( stderr, "Memory issue for full input parabin path!\n\n" ); + rom2bin_terminat(); + return -1; + } + sprintf( full_in_parabin_path, "%s/%s%s", input_parabin_path, input_parabin_file_name, DEFAULT_BIN_FILE_EXT ); +#endif return 0; } @@ -2195,6 +2385,22 @@ void rom2bin_terminat( void ) { free( full_in_td_path ); } +#ifdef PARABIN_FILE_312 + if ( input_parabin_path != NULL ) + { + free( input_parabin_path ); + } + + if ( input_parabin_file_name != NULL ) + { + free( input_parabin_file_name ); + } + + if ( full_in_parabin_path != NULL ) + { + free( full_in_parabin_path ); + } +#endif } /*---------------------------------------------------------------------* diff --git a/scripts/binauralRenderer_interface/param_bin/equalDistributionUnitVectors.mat b/scripts/binauralRenderer_interface/param_bin/equalDistributionUnitVectors.mat new file mode 100644 index 0000000000..b242a66423 --- /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 0000000000..7f53f6f62d --- /dev/null +++ b/scripts/binauralRenderer_interface/param_bin/generate_BRIR_in_SHD_CLDFB_PARAMETRIC.m @@ -0,0 +1,196 @@ +% +% (C) 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. +% Note: it is assumed that SOFAstart has been called as prerequisite + + +%% Load BRIR input file +sofaData = SOFAload(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. +BRIRanglesDeg = sofaData.SourcePosition(:, 1:2); + +% Determine nearest subset corresponding to 5.0 layout. +% All BRIR related parameters are determined based on them +brirAziRad = BRIRanglesDeg(:, 1)*pi/180; +brirEleRad = BRIRanglesDeg(:, 2)*pi/180; +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 0000000000..ae2a0170a0 --- /dev/null +++ b/scripts/binauralRenderer_interface/param_bin/generate_HRIR_in_SHD_CLDFB_PARAMETRIC.m @@ -0,0 +1,163 @@ +% +% (C) 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. +% Note: it is assumed that SOFAstart has been called as prerequisite + +%% Load HRIR input file +sofaData = SOFAload(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. +HRTFanglesDeg = sofaData.SourcePosition(:, 1:2); + +% Conversion code starts +nBins = 60; +binCenterF = ([0:59]+0.5)/60*24000; +IRlen = 1200; + +nDirs = length(HRTFanglesDeg); +groupDelays = zeros(nDirs, 1); +HRIR = zeros(IRlen, 2, nDirs); +HRTFvectors = zeros(nDirs, 3); + +for dirIndex=1:nDirs + azi = HRTFanglesDeg(dirIndex, 1)*pi/180; + ele = HRTFanglesDeg(dirIndex, 2)*pi/180; + + %% 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(HRTFanglesDeg, 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) + load cldfb_proto.mat proto + % 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 0000000000..e64be6f567 --- /dev/null +++ b/scripts/binauralRenderer_interface/param_bin/generate_tables_for_parametric_binauralizer.m @@ -0,0 +1,143 @@ +% +% (C) 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; + +%% 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'); + + +%% Get SOFA API for Matlab/Octave +% url = +% https://sourceforge.net/projects/sofacoustics/files/SOFA%20API%20for%20Matlab%20and%20Octave%201.1.3.zip/download +% then, run: +% addpath('/path_to/SOFA API for Matlab and Octave 1.1.3/API_MO'); +SOFAstart + +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('parabin_binary_rom.bin', SHhrtf, T60, lateEnes, earlyEnes); + %save('parabin_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 0000000000..2a06205e9f --- /dev/null +++ b/scripts/binauralRenderer_interface/param_bin/write_parametric_binauralizer_binary_data.m @@ -0,0 +1,96 @@ +% +% (C) 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); -- GitLab From 9298048b8247843b933c1e082b5b629207109697 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Wed, 8 Feb 2023 13:21:19 +0100 Subject: [PATCH 2/7] add missing helper files --- .../param_bin/SH_GainComputation.m | 40 ++++++++++++++ .../param_bin/cldfb_prototype.mat | 3 ++ .../param_bin/writeData3L.m | 54 +++++++++++++++++++ 3 files changed, 97 insertions(+) create mode 100644 scripts/binauralRenderer_interface/param_bin/SH_GainComputation.m create mode 100644 scripts/binauralRenderer_interface/param_bin/cldfb_prototype.mat create mode 100644 scripts/binauralRenderer_interface/param_bin/writeData3L.m 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 0000000000..263a96ffe4 --- /dev/null +++ b/scripts/binauralRenderer_interface/param_bin/SH_GainComputation.m @@ -0,0 +1,40 @@ +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/cldfb_prototype.mat b/scripts/binauralRenderer_interface/param_bin/cldfb_prototype.mat new file mode 100644 index 0000000000..6e9e08fb0e --- /dev/null +++ b/scripts/binauralRenderer_interface/param_bin/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/param_bin/writeData3L.m b/scripts/binauralRenderer_interface/param_bin/writeData3L.m new file mode 100644 index 0000000000..ccdd9aa0e6 --- /dev/null +++ b/scripts/binauralRenderer_interface/param_bin/writeData3L.m @@ -0,0 +1,54 @@ +function writeData3L(fid_source, startstring, data) +indices=size(data); + +indent = 4; + +fprintf(fid_source,startstring); +fprintf(fid_source,'=\n{'); +for A = 1:indices(1) + fprintf(fid_source,'\n'); + fprintf(fid_source,repmat(' ',1,indent)); + fprintf(fid_source,'{'); + for B = 1:indices(2) + fprintf(fid_source,'\n'); + fprintf(fid_source,repmat(' ',1,indent*2)); + fprintf(fid_source,'{'); + if( indices(3) > 10 ) + fprintf(fid_source,'\n'); + fprintf(fid_source,repmat(' ',1,indent*3)); + end + counter=1; + for C = 1:indices(3) + fprintf(fid_source,'%+ff',real(data(A,B,C))); + if C < indices(3) + if mod(counter,10) == 0 + fprintf(fid_source,','); + else + fprintf(fid_source,', '); + end + end + if mod(counter,10) == 0 && counter ~= indices(3) + fprintf(fid_source,'\n'); + fprintf(fid_source,repmat(' ',1,indent*3)); + end + counter = counter+1; + end + if( indices(3) > 10 ) + fprintf(fid_source,'\n'); + fprintf(fid_source,repmat(' ',1,indent*2)); + end + fprintf(fid_source,'}'); + if B < indices(2) + fprintf(fid_source,','); + end + end + fprintf(fid_source,'\n'); + fprintf(fid_source,repmat(' ',1,indent)); + fprintf(fid_source,'}'); + if A < indices(1) + fprintf(fid_source,','); + end +end +fprintf(fid_source,'\n};\n\n'); + +end % function \ No newline at end of file -- GitLab From 6fcc3f828e6b9ed31fd57e4f092d1adb59bf9c07 Mon Sep 17 00:00:00 2001 From: Jouni Paulus Date: Wed, 23 Aug 2023 08:51:07 +0200 Subject: [PATCH 3/7] update parambin binary table creation to omit dependency from external sofa reader and use interally provided cldfb coefficients: remove explicit cldfb_prototype.mat, separate get_cldfb_filter() from fir_to_cldfb_fir.m and use that instead, expose internal data needed by the parambin conversion routines from hrtf_library_loader. update copyright header year. --- .../fir_to_cldfb_fir.m | 133 -------------- .../get_cldfb_filter.m | 163 ++++++++++++++++++ .../hrtf_library_loader.m | 8 + .../param_bin/cldfb_prototype.mat | 3 - .../generate_BRIR_in_SHD_CLDFB_PARAMETRIC.m | 13 +- .../generate_HRIR_in_SHD_CLDFB_PARAMETRIC.m | 23 +-- ...erate_tables_for_parametric_binauralizer.m | 13 +- ...rite_parametric_binauralizer_binary_data.m | 2 +- 8 files changed, 195 insertions(+), 163 deletions(-) create mode 100644 scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/get_cldfb_filter.m delete mode 100644 scripts/binauralRenderer_interface/param_bin/cldfb_prototype.mat 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 5043f4f2c7..c4defd4588 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/get_cldfb_filter.m b/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/get_cldfb_filter.m new file mode 100644 index 0000000000..f796dd9ee0 --- /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/hrtf_library_loader.m b/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/hrtf_library_loader.m index c8d41d7e06..6d6264828f 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,6 +158,8 @@ 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 @@ -212,6 +218,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) diff --git a/scripts/binauralRenderer_interface/param_bin/cldfb_prototype.mat b/scripts/binauralRenderer_interface/param_bin/cldfb_prototype.mat deleted file mode 100644 index 6e9e08fb0e..0000000000 --- a/scripts/binauralRenderer_interface/param_bin/cldfb_prototype.mat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:386bbd3a02c3b95280fff7bd8f5240ee60f8858889cad0f6147e930f5f2aa7e2 -size 1246 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 index 7f53f6f62d..5a30bcbf8d 100644 --- 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 @@ -1,5 +1,5 @@ % -% (C) 2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, +% (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 @@ -35,11 +35,10 @@ function [T60, lateEnes, earlyEnes] = generate_BRIR_in_SHD_CLDFB_PARAMETRIC(brir % 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. -% Note: it is assumed that SOFAstart has been called as prerequisite - %% Load BRIR input file -sofaData = SOFAload(brir_inputfile); +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) @@ -53,12 +52,12 @@ end % Measurement directions for responses. We discard the distance but there should % be solution that uses only measurements from same distance. -BRIRanglesDeg = sofaData.SourcePosition(:, 1:2); +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 -brirAziRad = BRIRanglesDeg(:, 1)*pi/180; -brirEleRad = BRIRanglesDeg(:, 2)*pi/180; + 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)]; 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 index ae2a0170a0..439b2a6cf6 100644 --- 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 @@ -1,5 +1,5 @@ % -% (C) 2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, +% (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 @@ -34,10 +34,10 @@ function 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. -% Note: it is assumed that SOFAstart has been called as prerequisite %% Load HRIR input file -sofaData = SOFAload(hrir_inputfile); +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) @@ -53,21 +53,21 @@ end % Measurement directions for responses. We discard the distance but there should % be solution that uses only measurements from same distance. -HRTFanglesDeg = sofaData.SourcePosition(:, 1:2); +HRTFanglesRad = sofaData.PosSpherical(1:2, :).'; % Conversion code starts nBins = 60; -binCenterF = ([0:59]+0.5)/60*24000; +binCenterF = ([0:59] + 0.5) / 60 * 24000; IRlen = 1200; -nDirs = length(HRTFanglesDeg); +nDirs = length(HRTFanglesRad); groupDelays = zeros(nDirs, 1); HRIR = zeros(IRlen, 2, nDirs); HRTFvectors = zeros(nDirs, 3); for dirIndex=1:nDirs - azi = HRTFanglesDeg(dirIndex, 1)*pi/180; - ele = HRTFanglesDeg(dirIndex, 2)*pi/180; + azi = HRTFanglesRad(dirIndex, 1); + ele = HRTFanglesRad(dirIndex, 2); %% transform coordinates to XYZ vectors HRTFvectors(dirIndex, 1) = cos(azi)*cos(ele); @@ -120,7 +120,7 @@ EQ = min(EQ, median(EQ)*5); % Avoid multiply non-existent data with large values HRTFs = HRTFs.*repmat(EQ, [1 2 nDirs]); order = 3; -SH = SH_GainComputation(HRTFanglesDeg, order)/0.2821; +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); @@ -141,7 +141,10 @@ end % function function FD = CLDFB(sig) - load cldfb_proto.mat proto + % 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); 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 index e64be6f567..b302da231a 100644 --- a/scripts/binauralRenderer_interface/param_bin/generate_tables_for_parametric_binauralizer.m +++ b/scripts/binauralRenderer_interface/param_bin/generate_tables_for_parametric_binauralizer.m @@ -1,5 +1,5 @@ % -% (C) 2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, +% (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 @@ -35,6 +35,9 @@ 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; @@ -43,14 +46,6 @@ writeBinaryOutput = true; 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'); - -%% Get SOFA API for Matlab/Octave -% url = -% https://sourceforge.net/projects/sofacoustics/files/SOFA%20API%20for%20Matlab%20and%20Octave%201.1.3.zip/download -% then, run: -% addpath('/path_to/SOFA API for Matlab and Octave 1.1.3/API_MO'); -SOFAstart - if writeRomFileOutput %% Open file and write header if ismac 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 index 2a06205e9f..5fd8c79b02 100644 --- a/scripts/binauralRenderer_interface/param_bin/write_parametric_binauralizer_binary_data.m +++ b/scripts/binauralRenderer_interface/param_bin/write_parametric_binauralizer_binary_data.m @@ -1,5 +1,5 @@ % -% (C) 2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, +% (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 -- GitLab From e2f532034ba67c58b64528dcc170a1ff47dcbe8f Mon Sep 17 00:00:00 2001 From: Jouni Paulus Date: Wed, 23 Aug 2023 10:09:41 +0200 Subject: [PATCH 4/7] remove the extra copy of writeData3L.m. harmonize the use of naming "parambin". update readme --- .../generate_tables_from_rom_to_bin.c | 131 +++++++++--------- .../tables_format_converter_readme.txt | 10 +- ...erate_tables_for_parametric_binauralizer.m | 4 +- .../param_bin/writeData3L.m | 54 -------- 4 files changed, 75 insertions(+), 124 deletions(-) delete mode 100644 scripts/binauralRenderer_interface/param_bin/writeData3L.m 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 7d52fe7735..98545d81d8 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,7 +43,7 @@ #define FILE_HEADER -#define PARABIN_FILE_312 +#define PARAMBIN_FILE_312 /*------------------------------------------------------------------------------------------* * Constants @@ -57,8 +57,8 @@ #define DEFAULT_INPUT_ROM_FILE "ivas_binaural" #define DEFAULT_INPUT_TD_BIN_FILE "hrfilter_model" -#ifdef PARABIN_FILE_312 -#define DEFAULT_INPUT_PARABIN_FILE "parabin_binary_rom" +#ifdef PARAMBIN_FILE_312 +#define DEFAULT_INPUT_PARAMBIN_FILE "parambin_binary_rom" #endif #define DEFAULT_BIN_FILE_EXT ".bin" @@ -164,11 +164,14 @@ 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 ); -#ifdef PARABIN_FILE_312 - fprintf( stdout, "-input_parabin_file_path : Path of binary files for parabin renderer (with separator, used as flag).\n" ); - fprintf( stdout, "-input_parabin_file_name : Name of input parabin file (without extension %s, default = '%s').\n", DEFAULT_BIN_FILE_EXT, DEFAULT_INPUT_PARABIN_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" ); } @@ -185,10 +188,10 @@ char *input_td_bin_path = NULL; char *input_td_bin_file_name = NULL; char *full_in_td_path = NULL; -#ifdef PARABIN_FILE_312 -char *input_parabin_path = NULL; -char *input_parabin_file_name = NULL; -char *full_in_parabin_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; @@ -1229,7 +1232,7 @@ char *create_hrtf_parametric( int32_t *hrtf_size ) uint32_t data_size_tmp; int16_t i, j; -#ifdef PARABIN_FILE_312 +#ifdef PARAMBIN_FILE_312 uint8_t file_read_ok; float hrtfShCoeffsReFile[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]; @@ -1239,7 +1242,7 @@ char *create_hrtf_parametric( int32_t *hrtf_size ) float parametricReverberationEneCorrectionsFile[CLDFB_NO_CHANNELS_MAX]; float parametricEarlyPartEneCorrectionFile[CLDFB_NO_CHANNELS_MAX]; - FILE *input_parabin_file = NULL; + FILE *input_parambin_file = NULL; #endif hrtf_data_size = 0; @@ -1270,17 +1273,17 @@ 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 PARABIN_FILE_312 +#ifdef PARAMBIN_FILE_312 file_read_ok = 0; file_read_ok = 0; - input_parabin_file = fopen( full_in_parabin_path, "rb" ); - if ( input_parabin_file != NULL ) + 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_parabin_file, 0, SEEK_END ); - data_size_tmp = ftell( input_parabin_file ); - fseek( input_parabin_file, 0, SEEK_SET ); + 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 ) { @@ -1288,8 +1291,8 @@ char *create_hrtf_parametric( int32_t *hrtf_size ) } else { - fread( &hrtf_sh_channels, sizeof( uint16_t ), 1, input_parabin_file ); - fread( &hrtf_num_bins, sizeof( uint16_t ), 1, input_parabin_file ); + 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 ); @@ -1303,34 +1306,34 @@ char *create_hrtf_parametric( int32_t *hrtf_size ) { 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_parabin_file ); + 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_parabin_file ); + 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_parabin_file ); + 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_parabin_file ); - fread( parametricReverberationEneCorrectionsFile, sizeof( float ), CLDFB_NO_CHANNELS_MAX, input_parabin_file ); - fread( parametricEarlyPartEneCorrectionFile, sizeof( float ), CLDFB_NO_CHANNELS_MAX, input_parabin_file ); + 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 parabin file %s failed. Using built-in default values.\n\n", full_in_parabin_path ); + fprintf( stderr, "Opening of parambin file %s failed. Using built-in default values.\n\n", full_in_parambin_path ); } #endif @@ -1386,7 +1389,7 @@ char *create_hrtf_parametric( int32_t *hrtf_size ) { for ( j = 0; j < HRTF_SH_CHANNELS; j++ ) { -#ifdef PARABIN_FILE_312 +#ifdef PARAMBIN_FILE_312 if ( file_read_ok ) { memcpy( hrtf_wptr, &hrtfShCoeffsReFile[i][j], data_size_tmp ); @@ -1405,7 +1408,7 @@ char *create_hrtf_parametric( int32_t *hrtf_size ) { for ( j = 0; j < HRTF_SH_CHANNELS; j++ ) { -#ifdef PARABIN_FILE_312 +#ifdef PARAMBIN_FILE_312 if ( file_read_ok ) { memcpy( hrtf_wptr, &hrtfShCoeffsImFile[i][j], data_size_tmp ); @@ -1426,7 +1429,7 @@ char *create_hrtf_parametric( int32_t *hrtf_size ) hrtf_wptr += sizeof( uint16_t ); data_size_tmp = CLDFB_NO_CHANNELS_MAX * sizeof( float ); -#ifdef PARABIN_FILE_312 +#ifdef PARAMBIN_FILE_312 if ( file_read_ok ) { memcpy( hrtf_wptr, &( parametricReverberationTimesFile ), data_size_tmp ); // parametricReverberationTimes @@ -1445,7 +1448,7 @@ char *create_hrtf_parametric( int32_t *hrtf_size ) hrtf_wptr += data_size_tmp; memcpy( hrtf_wptr, &( parametricEarlyPartEneCorrection ), data_size_tmp ); // parametricEarlyPartEneCorrection hrtf_wptr += data_size_tmp; -#ifdef PARABIN_FILE_312 +#ifdef PARAMBIN_FILE_312 } #endif return hrtf; @@ -2456,31 +2459,31 @@ int rom2bin_init( int argc, char *argv[] ) strcpy( input_td_bin_file_name, argv[i] ); i++; } -#ifdef PARABIN_FILE_312 - else if ( strcmp( to_upper( argv[i] ), "-INPUT_PARABIN_FILE_PATH" ) == 0 ) +#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 parabin file path: %s\n\n", argv[i] ); + fprintf( stderr, "Wrong input parambin file path: %s\n\n", argv[i] ); usage_tables_format_converter(); return -1; } - input_parabin_path = malloc( strlen( argv[i] ) + 1 ); - strcpy( input_parabin_path, argv[i] ); + input_parambin_path = malloc( strlen( argv[i] ) + 1 ); + strcpy( input_parambin_path, argv[i] ); i++; } - else if ( strcmp( to_upper( argv[i] ), "-INPUT_PARABIN_FILE_NAME" ) == 0 ) + else if ( strcmp( to_upper( argv[i] ), "-INPUT_PARAMBIN_FILE_NAME" ) == 0 ) { i++; if ( strlen( argv[i] ) == 0 ) { - fprintf( stderr, "Wrong input parabin file name: %s\n\n", argv[i] ); + fprintf( stderr, "Wrong input parambin file name: %s\n\n", argv[i] ); usage_tables_format_converter(); return -1; } - input_parabin_file_name = malloc( strlen( argv[i] ) + 1 ); - strcpy( input_parabin_file_name, argv[i] ); + input_parambin_file_name = malloc( strlen( argv[i] ) + 1 ); + strcpy( input_parambin_file_name, argv[i] ); i++; } #endif @@ -2579,44 +2582,44 @@ int rom2bin_init( int argc, char *argv[] ) return -1; } } -#ifdef PARABIN_FILE_312 - if ( input_parabin_path == NULL ) +#ifdef PARAMBIN_FILE_312 + if ( input_parambin_path == NULL ) { - input_parabin_path = (char *) malloc( sizeof( char ) * ( strlen( DEFAULT_PATH ) + 1 ) ); - if ( input_parabin_path ) + input_parambin_path = (char *) malloc( sizeof( char ) * ( strlen( DEFAULT_PATH ) + 1 ) ); + if ( input_parambin_path ) { - strcpy( input_parabin_path, DEFAULT_PATH ); + strcpy( input_parambin_path, DEFAULT_PATH ); } else { - fprintf( stderr, "Memory issue for input parabin file path!\n\n" ); + fprintf( stderr, "Memory issue for input parambin file path!\n\n" ); rom2bin_terminat(); return -1; } } - if ( input_parabin_file_name == NULL ) + if ( input_parambin_file_name == NULL ) { - input_parabin_file_name = (char *) malloc( sizeof( char ) * ( strlen( DEFAULT_INPUT_PARABIN_FILE ) + 1 ) ); - if ( input_parabin_file_name ) + input_parambin_file_name = (char *) malloc( sizeof( char ) * ( strlen( DEFAULT_INPUT_PARAMBIN_FILE ) + 1 ) ); + if ( input_parambin_file_name ) { - strcpy( input_parabin_file_name, DEFAULT_INPUT_PARABIN_FILE ); + strcpy( input_parambin_file_name, DEFAULT_INPUT_PARAMBIN_FILE ); } else { - fprintf( stderr, "Memory issue for input parabin file name!\n\n" ); + fprintf( stderr, "Memory issue for input parambin file name!\n\n" ); rom2bin_terminat(); return -1; } } - full_in_parabin_path = (char *) malloc( sizeof( char ) * ( strlen( input_parabin_path ) + strlen( input_parabin_file_name ) + strlen( DEFAULT_BIN_FILE_EXT ) + 2 ) ); - if ( full_in_parabin_path == NULL ) + 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 parabin path!\n\n" ); + fprintf( stderr, "Memory issue for full input parambin path!\n\n" ); rom2bin_terminat(); return -1; } - sprintf( full_in_parabin_path, "%s/%s%s", input_parabin_path, input_parabin_file_name, DEFAULT_BIN_FILE_EXT ); + sprintf( full_in_parambin_path, "%s/%s%s", input_parambin_path, input_parambin_file_name, DEFAULT_BIN_FILE_EXT ); #endif return 0; } @@ -2657,20 +2660,20 @@ void rom2bin_terminat( void ) { free( full_in_td_path ); } -#ifdef PARABIN_FILE_312 - if ( input_parabin_path != NULL ) +#ifdef PARAMBIN_FILE_312 + if ( input_parambin_path != NULL ) { - free( input_parabin_path ); + free( input_parambin_path ); } - if ( input_parabin_file_name != NULL ) + if ( input_parambin_file_name != NULL ) { - free( input_parabin_file_name ); + free( input_parambin_file_name ); } - if ( full_in_parabin_path != NULL ) + if ( full_in_parambin_path != NULL ) { - free( full_in_parabin_path ); + 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 20aba7a237..2461679a20 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/param_bin/generate_tables_for_parametric_binauralizer.m b/scripts/binauralRenderer_interface/param_bin/generate_tables_for_parametric_binauralizer.m index b302da231a..dad321fc7c 100644 --- a/scripts/binauralRenderer_interface/param_bin/generate_tables_for_parametric_binauralizer.m +++ b/scripts/binauralRenderer_interface/param_bin/generate_tables_for_parametric_binauralizer.m @@ -133,6 +133,6 @@ end %% if writeBinaryOutput - write_parametric_binauralizer_binary_data('parabin_binary_rom.bin', SHhrtf, T60, lateEnes, earlyEnes); - %save('parabin_binary_rom.mat', 'SHhrtf', 'T60', 'lateEnes', 'earlyEnes'); % debug saving + 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/writeData3L.m b/scripts/binauralRenderer_interface/param_bin/writeData3L.m deleted file mode 100644 index ccdd9aa0e6..0000000000 --- a/scripts/binauralRenderer_interface/param_bin/writeData3L.m +++ /dev/null @@ -1,54 +0,0 @@ -function writeData3L(fid_source, startstring, data) -indices=size(data); - -indent = 4; - -fprintf(fid_source,startstring); -fprintf(fid_source,'=\n{'); -for A = 1:indices(1) - fprintf(fid_source,'\n'); - fprintf(fid_source,repmat(' ',1,indent)); - fprintf(fid_source,'{'); - for B = 1:indices(2) - fprintf(fid_source,'\n'); - fprintf(fid_source,repmat(' ',1,indent*2)); - fprintf(fid_source,'{'); - if( indices(3) > 10 ) - fprintf(fid_source,'\n'); - fprintf(fid_source,repmat(' ',1,indent*3)); - end - counter=1; - for C = 1:indices(3) - fprintf(fid_source,'%+ff',real(data(A,B,C))); - if C < indices(3) - if mod(counter,10) == 0 - fprintf(fid_source,','); - else - fprintf(fid_source,', '); - end - end - if mod(counter,10) == 0 && counter ~= indices(3) - fprintf(fid_source,'\n'); - fprintf(fid_source,repmat(' ',1,indent*3)); - end - counter = counter+1; - end - if( indices(3) > 10 ) - fprintf(fid_source,'\n'); - fprintf(fid_source,repmat(' ',1,indent*2)); - end - fprintf(fid_source,'}'); - if B < indices(2) - fprintf(fid_source,','); - end - end - fprintf(fid_source,'\n'); - fprintf(fid_source,repmat(' ',1,indent)); - fprintf(fid_source,'}'); - if A < indices(1) - fprintf(fid_source,','); - end -end -fprintf(fid_source,'\n};\n\n'); - -end % function \ No newline at end of file -- GitLab From 6a49f7f31a6a85608036f9e4b6c73d0b9f98a920 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Wed, 23 Aug 2023 18:08:55 +0200 Subject: [PATCH 5/7] - consolidate FastConv scripts into one entry point to generate ROM tables or binary data - modify SD/SHD_2_ROM.m to return a struct with required data - modify hrtf_library_loader to return normalised IRs for SD - add script for generating FastConv BRIR tables --- .../fastconv/README.txt | 3 + .../fastconv/cldfb_prototype.mat | 3 + .../fastconv/generate_BRIR_CLDFB_FASTCONV.m | 369 ++++++++++++++++++ .../fastconv/generate_tables_for_fastconv.m | 71 ++++ .../fastconv/td2cldfb.m | 60 +++ .../fastconv/write_fastconv_binary_data.m | 172 ++++++++ .../fastconv/write_fastconv_rom_table.m | 99 +++++ .../matlab_hrir_generation_scripts/SD_2_ROM.m | 122 ++++++ .../SHD_2_ROM.m | 97 +++-- .../generate_HOA_HRIRs_MOD_lens.m | 2 +- .../get_ls_layout_config.m | 167 ++++++++ .../hrtf_library_loader.m | 43 +- 12 files changed, 1157 insertions(+), 51 deletions(-) create mode 100644 scripts/binauralRenderer_interface/fastconv/README.txt create mode 100644 scripts/binauralRenderer_interface/fastconv/cldfb_prototype.mat create mode 100644 scripts/binauralRenderer_interface/fastconv/generate_BRIR_CLDFB_FASTCONV.m create mode 100644 scripts/binauralRenderer_interface/fastconv/generate_tables_for_fastconv.m create mode 100644 scripts/binauralRenderer_interface/fastconv/td2cldfb.m create mode 100644 scripts/binauralRenderer_interface/fastconv/write_fastconv_binary_data.m create mode 100644 scripts/binauralRenderer_interface/fastconv/write_fastconv_rom_table.m create mode 100644 scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/SD_2_ROM.m create mode 100644 scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/get_ls_layout_config.m diff --git a/scripts/binauralRenderer_interface/fastconv/README.txt b/scripts/binauralRenderer_interface/fastconv/README.txt new file mode 100644 index 0000000000..3a54d1cdf9 --- /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 0000000000..6e9e08fb0e --- /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/generate_BRIR_CLDFB_FASTCONV.m b/scripts/binauralRenderer_interface/fastconv/generate_BRIR_CLDFB_FASTCONV.m new file mode 100644 index 0000000000..5101ab83bd --- /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 = 45; +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 0000000000..073ac3b149 --- /dev/null +++ b/scripts/binauralRenderer_interface/fastconv/generate_tables_for_fastconv.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. +% +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/td2cldfb.m b/scripts/binauralRenderer_interface/fastconv/td2cldfb.m new file mode 100644 index 0000000000..19eb36a55d --- /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 0000000000..15b9d4d876 --- /dev/null +++ b/scripts/binauralRenderer_interface/fastconv/write_fastconv_binary_data.m @@ -0,0 +1,172 @@ +% +% (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: +% +% 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 + +%% 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); + + 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'); + % TODO probably need to write order? + 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); +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); +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, :))), '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 + +cldfb_no_channels_max = IR.rev_param.kAna; +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 0000000000..3b7a8d0d5e --- /dev/null +++ b/scripts/binauralRenderer_interface/fastconv/write_fastconv_rom_table.m @@ -0,0 +1,99 @@ +% +% (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[%d] = \n{',FastConv_SD_BRIR.rev_param.kAna); + fprintf(fid,'\n\t'); + for bandIdx = 1:FastConv_SD_BRIR.rev_param.kAna + fprintf(fid,'%f%s,\t', FastConv_SD_BRIR.rev_param.rt60(bandIdx),'f'); + end + fprintf(fid,'\n};\n'); + fprintf(fid,'\n\n'); + + % energyReverb + fprintf(fid,'const float fastconvReverberationEneCorrections[%d] = \n{',FastConv_SD_BRIR.rev_param.kAna); + fprintf(fid,'\n\t'); + for bandIdx = 1:FastConv_SD_BRIR.rev_param.kAna + fprintf(fid,'%f%s,\t', 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 0000000000..bbc9e3861a --- /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 c6c98ec46b..642ad84a18 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/generate_HOA_HRIRs_MOD_lens.m b/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/generate_HOA_HRIRs_MOD_lens.m index 22a42dd190..b509031b72 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_ls_layout_config.m b/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/get_ls_layout_config.m new file mode 100644 index 0000000000..2b57aadfcb --- /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 6d6264828f..5459fbcc77 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 @@ -166,6 +166,11 @@ classdef hrtf_library_loader < handle 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 @@ -231,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 @@ -351,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 -- GitLab From 7623c9f940a22ee0b7f3dfb7d402e8f1965e55d5 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Thu, 24 Aug 2023 14:25:00 +0200 Subject: [PATCH 6/7] - add a script to directly generate the binary file consumed by the decoder, bypassing tables_format_converter - update hrtf_file_reader.c with a minor change (BINAURAL_CONVBANDS stored per set of HRTF instead of a common value) - add helper script to parse the IVAS enum values for writing to binary file --- lib_com/options.h | 2 +- lib_util/hrtf_file_reader.c | 37 +++++ .../fastconv/fastconv_rom.bin | 3 + .../fastconv/generate_BRIR_CLDFB_FASTCONV.m | 2 +- .../fastconv/get_ivas_binary_header.m | 83 ++++++++++ .../fastconv/write_fastconv_binary_data.m | 148 ++++++++++++++++-- .../fastconv/write_fastconv_rom_table.m | 8 +- 7 files changed, 263 insertions(+), 20 deletions(-) create mode 100644 scripts/binauralRenderer_interface/fastconv/fastconv_rom.bin create mode 100644 scripts/binauralRenderer_interface/fastconv/get_ivas_binary_header.m diff --git a/lib_com/options.h b/lib_com/options.h index be3261f808..5280d1f4e9 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 */ /* ################## End BE DEVELOPMENT switches ######################### */ diff --git a/lib_util/hrtf_file_reader.c b/lib_util/hrtf_file_reader.c index 95d9b7c881..261c7f704f 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/fastconv/fastconv_rom.bin b/scripts/binauralRenderer_interface/fastconv/fastconv_rom.bin new file mode 100644 index 0000000000..142a8c0cb0 --- /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 index 5101ab83bd..65b4e4d43d 100644 --- a/scripts/binauralRenderer_interface/fastconv/generate_BRIR_CLDFB_FASTCONV.m +++ b/scripts/binauralRenderer_interface/fastconv/generate_BRIR_CLDFB_FASTCONV.m @@ -40,7 +40,7 @@ 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 = 45; + max_band = 50; end %% Load CLDFB protopyte 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 0000000000..4034102d3a --- /dev/null +++ b/scripts/binauralRenderer_interface/fastconv/get_ivas_binary_header.m @@ -0,0 +1,83 @@ +% +% (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/write_fastconv_binary_data.m b/scripts/binauralRenderer_interface/fastconv/write_fastconv_binary_data.m index 15b9d4d876..524cd65c9b 100644 --- a/scripts/binauralRenderer_interface/fastconv/write_fastconv_binary_data.m +++ b/scripts/binauralRenderer_interface/fastconv/write_fastconv_binary_data.m @@ -27,7 +27,6 @@ % 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. @@ -39,6 +38,11 @@ function write_fastconv_binary_data(bin_file, FastConv_SHD_IR_FOA, FastConv_SHD_ % % % 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 @@ -69,19 +73,122 @@ 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, 5, '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]; +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 = 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'); - % TODO probably need to write order? + for band = 1:binaural_convbands for ch = 1:num_channels fwrite(f_id, real(squeeze(IR.IR(1, band, ch, :))), 'float32'); @@ -106,7 +213,14 @@ end % SD HRIRs IR = FastConv_SD_IR; -[~, binaural_convbands, num_channels, binaural_ntaps] = size(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'); @@ -135,38 +249,44 @@ end % SD BRIRs IR = FastConv_SD_BRIR; -[~, binaural_convbands, num_channels, ~] = size(IR); +[~, 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, :))), 'float32' ); + 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, :))), 'float32' ); + 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, :))), 'float32' ); + 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, :))), 'float32' ); + fwrite(f_id, imag(squeeze(IR.IR(2, band, ch, 1:IR.rev_param.NFilter))), 'float32' ); end end -cldfb_no_channels_max = IR.rev_param.kAna; 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 index 3b7a8d0d5e..6b97326e48 100644 --- a/scripts/binauralRenderer_interface/fastconv/write_fastconv_rom_table.m +++ b/scripts/binauralRenderer_interface/fastconv/write_fastconv_rom_table.m @@ -77,19 +77,19 @@ function write_fastconv_rom_table(output_file, FastConv_SHD_IR_FOA, FastConv_SHD 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[%d] = \n{',FastConv_SD_BRIR.rev_param.kAna); + 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,\t', FastConv_SD_BRIR.rev_param.rt60(bandIdx),'f'); + 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[%d] = \n{',FastConv_SD_BRIR.rev_param.kAna); + 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,\t', FastConv_SD_BRIR.rev_param.nrgLr(bandIdx),'f'); + fprintf(fid,'%f%s, ', FastConv_SD_BRIR.rev_param.nrgLr(bandIdx),'f'); end fprintf(fid,'\n};\n'); fprintf(fid,'\n\n'); -- GitLab From 71581b9cd2d5b2a6dd9c2ebe59997d4c78d22d96 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Thu, 24 Aug 2023 15:50:04 +0200 Subject: [PATCH 7/7] update copyright headers and disable FIX_312_FASTCONV_HRTF_LOAD --- lib_com/options.h | 2 +- .../fastconv/generate_tables_for_fastconv.m | 2 ++ .../fastconv/get_ivas_binary_header.m | 2 ++ .../fastconv/write_fastconv_binary_data.m | 4 ++- .../fastconv/write_fastconv_rom_table.m | 2 ++ .../param_bin/SH_GainComputation.m | 31 +++++++++++++++++++ 6 files changed, 41 insertions(+), 2 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 5280d1f4e9..66db6b7a68 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 */ +/*#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/scripts/binauralRenderer_interface/fastconv/generate_tables_for_fastconv.m b/scripts/binauralRenderer_interface/fastconv/generate_tables_for_fastconv.m index 073ac3b149..a385cd5511 100644 --- a/scripts/binauralRenderer_interface/fastconv/generate_tables_for_fastconv.m +++ b/scripts/binauralRenderer_interface/fastconv/generate_tables_for_fastconv.m @@ -1,3 +1,4 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % (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., @@ -27,6 +28,7 @@ % 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; diff --git a/scripts/binauralRenderer_interface/fastconv/get_ivas_binary_header.m b/scripts/binauralRenderer_interface/fastconv/get_ivas_binary_header.m index 4034102d3a..91429e46e9 100644 --- a/scripts/binauralRenderer_interface/fastconv/get_ivas_binary_header.m +++ b/scripts/binauralRenderer_interface/fastconv/get_ivas_binary_header.m @@ -1,3 +1,4 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % (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., @@ -27,6 +28,7 @@ % 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 diff --git a/scripts/binauralRenderer_interface/fastconv/write_fastconv_binary_data.m b/scripts/binauralRenderer_interface/fastconv/write_fastconv_binary_data.m index 524cd65c9b..d312f23d3b 100644 --- a/scripts/binauralRenderer_interface/fastconv/write_fastconv_binary_data.m +++ b/scripts/binauralRenderer_interface/fastconv/write_fastconv_binary_data.m @@ -1,3 +1,4 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % (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., @@ -27,6 +28,7 @@ % 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. @@ -167,7 +169,7 @@ total_file_size = total_file_size + hrtf_data_size; % size of all HRTF data fwrite(f_id, 'IVASHRTF', 'char'); % identifier fwrite(f_id, total_file_size, 'int32'); % file size -fwrite(f_id, 5, 'int16'); % number of HRTFs +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 diff --git a/scripts/binauralRenderer_interface/fastconv/write_fastconv_rom_table.m b/scripts/binauralRenderer_interface/fastconv/write_fastconv_rom_table.m index 6b97326e48..ed7fc502db 100644 --- a/scripts/binauralRenderer_interface/fastconv/write_fastconv_rom_table.m +++ b/scripts/binauralRenderer_interface/fastconv/write_fastconv_rom_table.m @@ -1,3 +1,4 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % (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., @@ -27,6 +28,7 @@ % 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 diff --git a/scripts/binauralRenderer_interface/param_bin/SH_GainComputation.m b/scripts/binauralRenderer_interface/param_bin/SH_GainComputation.m index 263a96ffe4..2128779acf 100644 --- a/scripts/binauralRenderer_interface/param_bin/SH_GainComputation.m +++ b/scripts/binauralRenderer_interface/param_bin/SH_GainComputation.m @@ -1,3 +1,34 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% (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 -- GitLab