From fde101818c899d25b71619b9dada8ad29a8ce12c Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Tue, 2 May 2023 16:03:07 +0200 Subject: [PATCH 1/6] Script update to generate acoustic environments metadata including early reflections --- ...enerate_acoustic_environments_metadata.py} | 225 +++++++++++++++++- 1 file changed, 218 insertions(+), 7 deletions(-) rename scripts/reverb/{generate_reverb_metadata.py => generate_acoustic_environments_metadata.py} (64%) diff --git a/scripts/reverb/generate_reverb_metadata.py b/scripts/reverb/generate_acoustic_environments_metadata.py similarity index 64% rename from scripts/reverb/generate_reverb_metadata.py rename to scripts/reverb/generate_acoustic_environments_metadata.py index a05bbeb2d8..c7d49bf3f4 100644 --- a/scripts/reverb/generate_reverb_metadata.py +++ b/scripts/reverb/generate_acoustic_environments_metadata.py @@ -196,10 +196,8 @@ def get_frequency_code(f): def get_frequency_hop_code(index): assert 0 <= index < 9 return [ - '1100', # 2^(1/8) - '1101', # 2^(1/7) - '0010', # 2^(1/6) - '0011', # 2^(1/5) + '0010', # 2^(1/12) + '0011', # 2^(1/6) '0000', # 2^(1/4) '01', # 2^(1/3) '0001', # 2^(1/2) @@ -241,6 +239,93 @@ class fgdMethod(Enum): Default_Banding = '10' +def get_distance_code(dist, isSmallScene = True): + # 0, 1, ... 99 + metersCode = [ + '111101', '110010', '110011', '110000', '110001', '110110', '110111', '110100', '110101', '001010', + '001011', '001000', '001001', '001110', '001111', '001100', '001101', '000010', '000011', '000000', + '000001', '000110', '000111', '000100', '000101', '011010', '011011', '011000', '011001', '011110', + '011111', '011100', '011101', '010010', '010011', '010000', '010001', '010110', '010111', '010100', + '010101', '101010', '101011', '101000', '101001', '101110', '101111', '101100', '101101', '10000', + '1000100', '1000101', '10001110', '10001111', '10001100', '10001101', '10011010', '10011011', '10011000', '10011001', + '10011110', '10011111', '10011100', '10011101', '10010010', '10010011', '10010000', '10010001', '10010110', '10010111', + '10010100', '10010101', '11101010', '11101011', '11101000', '11101001', '11101110', '11101111', '11101100', '11101101', + '11100010', '11100011', '11100000', '11100001', '11100110', '11100111', '11100100', '11100101', '11111010', '11111011', + '11111000', '11111001', '11111110', '11111111', '11111100', '11111101', '11110010', '11110011', '11110000', '11110001' ] + + # 0, 1, ... 9 + hectometersCode = [ + '000', '001', '110', '111', '100', '101', '0110', '0111', '0100', '0101' ] + + # 1, 2, ... 10 + kilometersCode = [ + '10', '011', '001', '000', '111', '0101', '0100', '1101', '11001', '11000' ] + + # 0, 1, ... 99 + centimetersCode = [ + '110010', '110011', '110000', '110001', '110110', '110111', '110100', '110101', '0101010', '0101011', + '0101000', '0101001', '0101110', '0101111', '0101100', '0101101', '0100010', '0100011', '0100000', '0100001', + '0100110', '0100111', '0100100', '0100101', '0111010', '0111011', '0111000', '0111001', '0111110', '0111111', + '0111100', '0111101', '0110010', '0110011', '0110000', '0110001', '0110110', '0110111', '0110100', '0110101', + '0001010', '0001011', '0001000', '0001001', '0001110', '0001111', '0001100', '0001101', '0000010', '0000011', + '0000000', '0000001', '0000110', '0000111', '0000100', '0000101', '0011010', '0011011', '0011000', '0011001', + '0011110', '0011111', '0011100', '0011101', '0010010', '0010011', '0010000', '0010001', '0010110', '0010111', + '0010100', '0010101', '101010', '101011', '101000', '101001', '101110', '101111', '101100', '101101', + '100010', '100011', '100000', '100001', '100110', '100111', '100100', '100101', '1111010', '1111011', + '1111000', '1111001', '1111110', '1111111', '1111100', '1111101', '111010', '111011', '111000', '111001' ] + + distance_mm = int(round(np.float32(distance) * np.float32(1000))) # distance in mm + if print_cfg: + print('distance: ', distance_mm) + + mm = distance_mm # [mm] + cm = mm // 10 # [cm] + m = cm // 100 # [m] + hm = m // 100 # [hm] + km = hm // 10 # [km] + + mm = (mm % 10) # 0, 1, ... 9 [mm] + cm = (cm % 100) # 0, 1, ... 99 [cm] + m = (m % 100) # 0, 1, ... 99 [m] + hm = (hm % 9) # 0, 1, ... 9 [hm] + + assert 0 <= mm <= 9 + assert 0 <= cm <= 99 + assert 0 <= m <= 99 + assert 0 <= hm <= 9 + assert distance_mm == km * 1000000 + hm * 100000 + m * 1000 + cm * 10 + mm + + code = metersCode[m] + + if not isSmallScene: + # large scenes + if hm > 0 or km > 0: + # hectometers + code += '1' + hectometersCode[hm] + while km > 0: + # kilometers + code += '1' + kilometersCode[min(km, 10)] + km = km - 10 + code += '0' + else: + code += '0' + + # centimeters + if cm > 0: + code += '1' + centimetersCode[cm] + else: + code += '0' + + return code + + +def get_absorption_code(absorption): + assert 0.0 <= absorption <= 1.0 + + index = round(absorption * 10.0) + + return ['110', '100', '101', '0110', '0111', '111', '0100', '0101', '0010', '0011', '000' ][index] + # apply function to elements of list and concatenate the resulting strings def concatenate(function, data): return ''.join([function(d) for d in data]) @@ -248,6 +333,7 @@ def concatenate(function, data): def test(): # generate binary output which can be compared with the Matlab implementation output + string = '' # count or index encoding @@ -282,7 +368,8 @@ def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg(): # based on config_renderer.cfg # note that because of encoding, resolution is lost and behaviour may not be bit-exact compared to .cfg file based values data = bitarray( - get_count_or_index_code(1) # fgdNrGrids + '1' # hasAcEnv + + get_count_or_index_code(1) # fgdNrGrids + fgdMethod.Individual_Frequencies.value # fgdMethod + get_count_or_index_code(31) # fgdNrBands @@ -308,6 +395,62 @@ def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg(): 3.702e-07, 6.1341e-07, 7.1432e-07, 6.5331e-07, 4.6094e-07, 5.4683e-07, 7.0134e-07, 6.856e-07, 7.114e-07, 6.9604e-07, 5.2939e-07, 5.699e-07, 6.1773e-07, 5.7488e-07, 4.7748e-07, 2.7213e-07, 1.3681e-07, 1.0941e-07, 6.2001e-08, 2.8483e-08, 2.6267e-08 ]) + + '0' # hasEarlyReflections + , endian='big') + + file = open('rend_config_renderer.dat', 'wb') + data.tofile(file) + file.close() + +def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_reflections_no_listener_origin(): + # based on config_renderer.cfg + # note that because of encoding, resolution is lost and behaviour may not be bit-exact compared to .cfg file based values + data = bitarray( + '1' # hasAcEnv + + get_count_or_index_code(2) # fgdNrGrids + # frequency grid #1 + + fgdMethod.Individual_Frequencies.value # fgdMethod + + get_count_or_index_code(1) # fgdNrBands + + + concatenate(get_frequency_code, # fgdCenterFreq + [ 10000.0 ]) + + # frequency grid #2 + + fgdMethod.Individual_Frequencies.value # fgdMethod + + get_count_or_index_code(31) # fgdNrBands + + + concatenate(get_frequency_code, # fgdCenterFreq + [ 20.0, 25.0, 31.5, 40.0, 50.0, 63.0, 80.0, 100.0, 125.0, 160.0, + 200.0, 250.0, 315.0, 400.0, 500.0, 630.0, 800.0, 1000.0, 1250.0, 1600.0, + 2000.0, 2500.0, 3150.0, 4000.0, 5000.0, 6300.0, 8000.0, 10000.0, 12500.0, 16000.0, + 20000.0 ]) + + + get_count_or_index_code(1) # AcousticEnvCount + + get_id_code(0) # ID + + get_count_or_index_code(1) # FreqGridID + + get_duration_code(0.1) # (input)Predelay + + + concatenate(get_duration_code, # RT60 + [ 1.3622, 1.4486, 1.3168, 1.5787, 1.4766, 1.3954, 1.2889, 1.3462, 1.0759, 1.0401, + 1.0970, 1.0850, 1.0910, 1.0404, 1.0499, 1.0699, 1.1028, 1.1714, 1.1027, 1.0666, + 1.0550, 1.0553, 1.0521, 1.0569, 1.0421, 0.97822, 0.80487, 0.75944, 0.71945, 0.61682, + 0.60031 ]) + + + concatenate(get_dsr_code, # DSR + [ 1.8811e-08, 2.1428e-08, 1.3972e-08, 1.51e-08, 1.287e-08, 1.8747e-08, 2.413e-08, 3.9927e-08, 8.9719e-08, 1.902e-07, + 3.702e-07, 6.1341e-07, 7.1432e-07, 6.5331e-07, 4.6094e-07, 5.4683e-07, 7.0134e-07, 6.856e-07, 7.114e-07, 6.9604e-07, + 5.2939e-07, 5.699e-07, 6.1773e-07, 5.7488e-07, 4.7748e-07, 2.7213e-07, 1.3681e-07, 1.0941e-07, 6.2001e-08, 2.8483e-08, + 2.6267e-08 ]) + + + '1' # hasEarlyReflections + + concatenate(get_distance_code, # room dimensions + [ 3.0, 4.0, 2.5 ]) + + + get_count_or_index_code(0) # FreqGridID + + concatenate(get_absorption_code, # absorptionCode + [ 0.8, 0.8, 0.8, 0.8, 0.2, 0.6 ]) + + + '0' # listener origin flag , endian='big') @@ -316,11 +459,74 @@ def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg(): file.close() +def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_reflections_listener_origin(): + # based on config_renderer.cfg + # note that because of encoding, resolution is lost and behaviour may not be bit-exact compared to .cfg file based values + data = bitarray( + '1' # hasAcEnv + + get_count_or_index_code(2) # fgdNrGrids + # frequency grid #1 + + fgdMethod.Individual_Frequencies.value # fgdMethod + + get_count_or_index_code(1) # fgdNrBands + + + concatenate(get_frequency_code, # fgdCenterFreq + [ 10000.0 ]) + + # frequency grid #2 + + fgdMethod.Individual_Frequencies.value # fgdMethod + + get_count_or_index_code(31) # fgdNrBands + + + concatenate(get_frequency_code, # fgdCenterFreq + [ 20.0, 25.0, 31.5, 40.0, 50.0, 63.0, 80.0, 100.0, 125.0, 160.0, + 200.0, 250.0, 315.0, 400.0, 500.0, 630.0, 800.0, 1000.0, 1250.0, 1600.0, + 2000.0, 2500.0, 3150.0, 4000.0, 5000.0, 6300.0, 8000.0, 10000.0, 12500.0, 16000.0, + 20000.0 ]) + + + get_count_or_index_code(1) # AcousticEnvCount + + get_id_code(0) # ID + + get_count_or_index_code(1) # FreqGridID + + get_duration_code(0.1) # (input)Predelay + + + concatenate(get_duration_code, # RT60 + [ 1.3622, 1.4486, 1.3168, 1.5787, 1.4766, 1.3954, 1.2889, 1.3462, 1.0759, 1.0401, + 1.0970, 1.0850, 1.0910, 1.0404, 1.0499, 1.0699, 1.1028, 1.1714, 1.1027, 1.0666, + 1.0550, 1.0553, 1.0521, 1.0569, 1.0421, 0.97822, 0.80487, 0.75944, 0.71945, 0.61682, + 0.60031 ]) + + + concatenate(get_dsr_code, # DSR + [ 1.8811e-08, 2.1428e-08, 1.3972e-08, 1.51e-08, 1.287e-08, 1.8747e-08, 2.413e-08, 3.9927e-08, 8.9719e-08, 1.902e-07, + 3.702e-07, 6.1341e-07, 7.1432e-07, 6.5331e-07, 4.6094e-07, 5.4683e-07, 7.0134e-07, 6.856e-07, 7.114e-07, 6.9604e-07, + 5.2939e-07, 5.699e-07, 6.1773e-07, 5.7488e-07, 4.7748e-07, 2.7213e-07, 1.3681e-07, 1.0941e-07, 6.2001e-08, 2.8483e-08, + 2.6267e-08 ]) + + + '1' # hasEarlyReflections + + concatenate(get_distance_code, # room dimensions + [ 3.0, 4.0, 2.5 ]) + + + get_count_or_index_code(0) # FreqGridID + + concatenate(get_absorption_code, # absorptionCode + [ 0.8, 0.8, 0.8, 0.8, 0.2, 0.6 ]) + + + '1' # listener origin flag + + '1' # positive x origin + + '0' # negative y origin + + concatenate(get_distance_code, # listener origin (x, y, z) + [ 0.5, 0.5, 1.5 ]) + + , endian='big') + + file = open('rend_config_renderer.dat', 'wb') + data.tofile(file) + file.close() + + + def generate_reverb_payload_equivalent_to_rend_config_hospital_patientroom_cfg(): # based on config_hospital_patientroom.cfg # note that because of encoding, resolution is lost and behaviour may not be bit-exact compared to .cfg file based values data = bitarray( - get_count_or_index_code(1) # fgdNrGrids + 1 # hasAcEnv + + get_count_or_index_code(1) # fgdNrGrids + fgdMethod.Individual_Frequencies.value # fgdMethod + get_count_or_index_code(31) # fgdNrBands @@ -348,6 +554,8 @@ def generate_reverb_payload_equivalent_to_rend_config_hospital_patientroom_cfg() 6.379496e-06, 6.358105e-06, 6.6696e-06, 6.369334e-06, 6.378474e-06, 3.339913e-06, 3.129318e-06, 2.892564e-06, 6.00202e-07, 3.40124e-07, 3.37705e-07 ]) + + '0' # hasEarlyReflections + , endian='big') file = open('rend_config_hospital_patientroom.dat', 'wb') @@ -359,7 +567,8 @@ def generate_reverb_payload_equivalent_to_rend_config_recreation_cfg(): # based on config_recreation.cfg # note that because of encoding, resolution is lost and behaviour may not be bit-exact compared to .cfg file based values data = bitarray( - get_count_or_index_code(1) # fgdNrGrids + 1 # hasAcEnv + + get_count_or_index_code(1) # fgdNrGrids + fgdMethod.Individual_Frequencies.value # fgdMethod + get_count_or_index_code(31) # fgdNrBands @@ -387,6 +596,8 @@ def generate_reverb_payload_equivalent_to_rend_config_recreation_cfg(): 2.958383e-06, 2.725911e-06, 7.94912e-07, 6.20198e-07, 5.71181e-07, 5.5546e-08, 1.3987e-08, 1.338e-08, 1.322e-09, 1.3e-11, 4e-12 ]) + + '0' # hasEarlyReflections + , endian='big') file = open('rend_config_recreation.dat', 'wb') -- GitLab From 2e820810273e7f5ec2ae8cd1976c00bfe17302b2 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Wed, 3 May 2023 10:29:47 +0200 Subject: [PATCH 2/6] Reverb control metadata parser extension to support early reflections --- lib_com/options.h | 5 +- lib_util/render_config_reader.c | 382 +++++++++++++++++++++++++++++++- 2 files changed, 375 insertions(+), 12 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 23fc0f759f..86de207929 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -141,7 +141,10 @@ #endif #define DISABLE_ADAP_RES_COD_TMP /* temporary fix for IVAS-403, disables adaptive residual coding */ /*#define FIX_I4_OL_PITCH*/ /* fix open-loop pitch used for EVS core switching */ -#define CONTROL_METADATA_REVERB /* Philips: renderer configuration change to binary format */ +#define CONTROL_METADATA_REVERB /* Philips: reverb configuration change to binary format */ +#ifdef CONTROL_METADATA_REVERB +#define CONTROL_METADATA_EARLY_REFLECTIONS /* Philips/Qualcomm: early reflections extension to reverb configuration */ +#endif #define COMMAND_LINE_OPTION_LATE_REVERB /* Philips: late reverb command line option */ #define FIX_ISM_DTX_CNG_BWIDTH_ALT /* VA: issue 396 - alternative fix for bw changes on CNG frames in ISM DTX for objects that use the decoder-side noise estimation */ diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index c6e68eae25..71dea98dc1 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -48,6 +48,8 @@ #define MAX_LINE_LENGTH ( 1024 ) #define MAX_ITEM_LENGTH ( 64 ) #define N_REVERB_VECTORS ( 3 ) +#else +#define N_ABS_COEFFS ( 6 ) #endif #define SHORTEST_REV_DEL_LINE ( 0.015f ) @@ -84,13 +86,26 @@ typedef enum _FREQ_GRID_MODE FREQ_GRID_MODE_DEFAULT_BANDING = 2 } FREQ_GRID_MODE; +#ifdef CONTROL_METADATA_EARLY_REFLECTIONS +typedef struct +{ + IVAS_VECTOR3 dimensions; /* Room dimensions [m] */ + FrequencyGrid *pFG; /* Pointer to a frequency grid for absorption coeffs */ + float ( *pAbsCoeff )[N_ABS_COEFFS]; /* Absorption coeffs table pointer */ + IVAS_VECTOR3 *pListenerOrigin; /* Listener origin */ +} EarlyReflectionsConfig; +#endif + typedef struct { uint32_t id; /* Acoustic environment ID */ - FrequencyGrid *pFG; /* Pointer into Frequency grids table */ + FrequencyGrid *pFG; /* Pointer into Frequency grids table for late reverb coeffs */ float *pRT60; /* RT60 table */ float *pDSR; /* DSR table */ float preDelay; /* Pre-delay */ +#ifdef CONTROL_METADATA_EARLY_REFLECTIONS + EarlyReflectionsConfig *pEarlyReflections; /* Early reflections configuration */ +#endif } AcousticEnv; struct RenderConfigReader @@ -121,6 +136,11 @@ typedef enum _RC_LUT RC_LUT_FREQ, RC_LUT_FREQ_HOP, RC_LUT_DSR, + RC_LUT_METERS, + RC_LUT_HECTOMETERS, + RC_LUT_KILOMETERS, + RC_LUT_CENTIMETERS, + RC_LUT_ABSORPTION } RC_LUT; /*------------------------------------------------------------------------------------------* @@ -223,9 +243,9 @@ const float lutFreq_Value[] = { const uint16_t lutFreq_Code[] = { 35, 14, 15, 9, 12, 13, 0, 26, 27, 1, 24, 25, 14, 30, 31, 15, 28, 29, 12, 18, 19, 13, 16, 17, 10, 22, 23, 11, 20, 21, 2, 16, 138, 139, 68 }; const uint8_t lutFreq_Len[] = { 6, 6, 6, 4, 6, 6, 4, 6, 6, 4, 6, 6, 4, 6, 6, 4, 6, 6, 4, 6, 6, 4, 6, 6, 4, 6, 6, 4, 6, 6, 4, 5, 8, 8, 7 }; -const float lutFreqHop_Value[] = { 1.090507733f, 1.104089514f, 1.122462048f, 1.148698355f, 1.189207115f, 1.25992105f, 1.414213562f, 2.0f, 4.0f }; -const uint16_t lutFreqHop_Code[] = { 12, 13, 2, 3, 0, 1, 1, 2, 7 }; -const uint8_t lutFreqHop_Len[] = { 4, 4, 4, 4, 4, 2, 4, 2, 3 }; +const float lutFreqHop_Value[] = { 1.059463094f, 1.122462048f, 1.189207115f, 1.259921050f, 1.414213562f, 2.0f, 4.0f }; +const uint16_t lutFreqHop_Code[] = { 2, 3, 0, 1, 1, 3, 2 }; +const uint8_t lutFreqHop_Len[] = { 4, 4, 4, 2, 4, 2, 2 }; const float lutDsr_Value[] = { -150.0f, -149.0f, -148.0f, -147.0f, -146.0f, -145.0f, -144.0f, -143.0f, -142.0f, -141.0f, @@ -265,6 +285,96 @@ const uint8_t lutDsr_Len[] = { 8 }; +const float lutMeters_Value[] = { + 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, + 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f, + 20.0f, 21.0f, 22.0f, 23.0f, 24.0f, 25.0f, 26.0f, 27.0f, 28.0f, 29.0f, + 30.0f, 31.0f, 32.0f, 33.0f, 34.0f, 35.0f, 36.0f, 37.0f, 38.0f, 39.0f, + 40.0f, 41.0f, 42.0f, 43.0f, 44.0f, 45.0f, 46.0f, 47.0f, 48.0f, 49.0f, + 50.0f, 51.0f, 52.0f, 53.0f, 54.0f, 55.0f, 56.0f, 57.0f, 58.0f, 59.0f, + 60.0f, 61.0f, 62.0f, 63.0f, 64.0f, 65.0f, 66.0f, 67.0f, 68.0f, 69.0f, + 70.0f, 71.0f, 72.0f, 73.0f, 74.0f, 75.0f, 76.0f, 77.0f, 78.0f, 79.0f, + 80.0f, 81.0f, 82.0f, 83.0f, 84.0f, 85.0f, 86.0f, 87.0f, 88.0f, 89.0f, + 90.0f, 91.0f, 92.0f, 93.0f, 94.0f, 95.0f, 96.0f, 97.0f, 98.0f, 99.0f +}; + +const uint16_t lutMeters_Code[] = { + 61, 50, 51, 48, 49, 54, 55, 52, 53, 10, + 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, + 1, 6, 7, 4, 5, 26, 27, 24, 25, 30, + 31, 28, 29, 18, 19, 16, 17, 22, 23, 20, + 21, 42, 43, 40, 41, 46, 47, 44, 45, 16, + 68, 69, 142, 143, 140, 141, 154, 155, 152, 153, + 158, 159, 156, 157, 146, 147, 144, 145, 150, 151, + 148, 149, 234, 235, 232, 233, 238, 239, 236, 237, + 226, 227, 224, 225, 230, 231, 228, 229, 250, 251, + 248, 249, 254, 255, 252, 253, 242, 243, 240, 241 +}; + +const uint8_t lutMeters_Len[] = { + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, + 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 +}; + +const float lutHectometers_Value[] = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f }; +const uint16_t lutHectometers_Code[] = { 0, 1, 6, 7, 4, 5, 6, 7, 4, 5 }; +const uint8_t lutHectometers_Len[] = { 3, 3, 3, 3, 3, 3, 4, 4, 4, 4 }; + +const float lutKilometers_Value[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f }; +const uint16_t lutKilometers_Code[] = { 2, 3, 1, 0, 7, 5, 4, 13, 25, 24 }; +const uint8_t lutKilometers_Len[] = { 2, 3, 3, 3, 3, 4, 4, 4, 5, 5 }; + +const float lutCentimeters_Value[] = { + 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, + 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f, + 20.0f, 21.0f, 22.0f, 23.0f, 24.0f, 25.0f, 26.0f, 27.0f, 28.0f, 29.0f, + 30.0f, 31.0f, 32.0f, 33.0f, 34.0f, 35.0f, 36.0f, 37.0f, 38.0f, 39.0f, + 40.0f, 41.0f, 42.0f, 43.0f, 44.0f, 45.0f, 46.0f, 47.0f, 48.0f, 49.0f, + 50.0f, 51.0f, 52.0f, 53.0f, 54.0f, 55.0f, 56.0f, 57.0f, 58.0f, 59.0f, + 60.0f, 61.0f, 62.0f, 63.0f, 64.0f, 65.0f, 66.0f, 67.0f, 68.0f, 69.0f, + 70.0f, 71.0f, 72.0f, 73.0f, 74.0f, 75.0f, 76.0f, 77.0f, 78.0f, 79.0f, + 80.0f, 81.0f, 82.0f, 83.0f, 84.0f, 85.0f, 86.0f, 87.0f, 88.0f, 89.0f, + 90.0f, 91.0f, 92.0f, 93.0f, 94.0f, 95.0f, 96.0f, 97.0f, 98.0f, 99.0f +}; + +const uint16_t lutCentimeters_Code[] = { + 50, 51, 48, 49, 54, 55, 52, 53, 42, 43, + 40, 41, 46, 47, 44, 45, 34, 35, 32, 33, + 38, 39, 36, 37, 58, 59, 56, 57, 62, 63, + 60, 61, 50, 51, 48, 49, 54, 55, 52, 53, + 10, 11, 8, 9, 14, 15, 12, 13, 2, 3, + 0, 1, 6, 7, 4, 5, 26, 27, 24, 25, + 30, 31, 28, 29, 18, 19, 16, 17, 22, 23, + 20, 21, 42, 43, 40, 41, 46, 47, 44, 45, + 34, 35, 32, 33, 38, 39, 36, 37, 122, 123, + 120, 121, 126, 127, 124, 125, 58, 59, 56, 57 +}; + +const uint8_t lutCentimeters_Len[] = { + 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, + 7, 7, 7, 7, 7, 7, 6, 6, 6, 6 +}; + +const float lutAbsorption_Value[] = { 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f }; +const uint16_t lutAbsorption_Code[] = { 6, 4, 5, 6, 7, 7, 4, 5, 2, 3, 0 }; +const uint8_t lutAbsorption_Len[] = { 3, 3, 3, 4, 4, 3, 4, 4, 4, 4, 3 }; + /*------------------------------------------------------------------------------------------* * Default frequency grids *------------------------------------------------------------------------------------------*/ @@ -470,16 +580,46 @@ static ivas_error read_code_word( pLengths = lutDsr_Len; size = sizeof lutDsr_Len / sizeof( uint8_t ); break; + case RC_LUT_METERS: + pValues = lutMeters_Value; + pCodes = lutMeters_Code; + pLengths = lutMeters_Len; + size = sizeof lutMeters_Len / sizeof( uint8_t ); + break; + case RC_LUT_HECTOMETERS: + pValues = lutHectometers_Value; + pCodes = lutHectometers_Code; + pLengths = lutHectometers_Len; + size = sizeof lutHectometers_Len / sizeof( uint8_t ); + break; + case RC_LUT_KILOMETERS: + pValues = lutKilometers_Value; + pCodes = lutKilometers_Code; + pLengths = lutKilometers_Len; + size = sizeof lutKilometers_Len / sizeof( uint8_t ); + break; + case RC_LUT_CENTIMETERS: + pValues = lutCentimeters_Value; + pCodes = lutCentimeters_Code; + pLengths = lutCentimeters_Len; + size = sizeof lutCentimeters_Len / sizeof( uint8_t ); + break; + case RC_LUT_ABSORPTION: + pValues = lutAbsorption_Value; + pCodes = lutAbsorption_Code; + pLengths = lutAbsorption_Len; + size = sizeof lutAbsorption_Len / sizeof( uint8_t ); + break; case RC_LUT_INVALID: default: return IVAS_ERR_INVALID_RENDER_CONFIG; } /* First read minLen bits, then add one bit per iteration to find the correct value */ - for (n = 0; n < size; n++) + for ( n = 0; n < size; n++ ) { - minLen = min(minLen, pLengths[n]); - maxLen = max(maxLen, pLengths[n]); + minLen = min( minLen, pLengths[n] ); + maxLen = max( maxLen, pLengths[n] ); } for ( len = minLen; len <= maxLen; len++ ) { @@ -671,6 +811,106 @@ static ivas_error get_dsr( return IVAS_ERR_OK; } +/*-----------------------------------------------------------------------------------------* + * Function get_distance() + * Gets a distance value (in meters) + *-----------------------------------------------------------------------------------------*/ + +static ivas_error get_distance( + RenderConfigReader *this, /* i/o : Render config reader handle */ + uint16_t isSmall, /* i : Flag indicating a small distance */ + float *pResult /* o : Distance value */ +) +{ + ivas_error error; + float value; + uint32_t flag; + + if ( ( error = read_code_word( this, RC_LUT_METERS, pResult ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( isSmall == false ) + { + /* addHectometers flag */ + if ( ( error = read_bits( this, &flag, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( flag == true ) + { + /* Hectometers */ + if ( ( error = read_code_word( this, RC_LUT_HECTOMETERS, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult += value * 100.0f; + + /* addKilometers flag */ + if ( ( error = read_bits( this, &flag, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + + while ( flag == true ) + { + /* Kilometers */ + if ( ( error = read_code_word( this, RC_LUT_KILOMETERS, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult += value * 1000.0f; + + /* addKilometers flag */ + if ( ( error = read_bits( this, &flag, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + + /* addCentimeters flag */ + if ( ( error = read_bits( this, &flag, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( flag == true ) + { + /* Centimeters */ + /* Kilometers */ + if ( ( error = read_code_word( this, RC_LUT_CENTIMETERS, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult += value * 0.01f; + } + } + + return IVAS_ERR_OK; +} + +/*-----------------------------------------------------------------------------------------* + * Function get_absorption() + * Gets an absorption value + *-----------------------------------------------------------------------------------------*/ + +static ivas_error get_absorption( + RenderConfigReader *this, /* i/o : Render config reader handle */ + float *pResult /* o : Distance value */ +) +{ + ivas_error error; + + if ( ( error = read_code_word( this, RC_LUT_ABSORPTION, pResult ) ) != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} + #else /*-----------------------------------------------------------------------------------------* * Function read_bool() @@ -971,7 +1211,10 @@ ivas_error RenderConfigReader_read( { uint32_t file_size; uint32_t value; - uint32_t i, n, m; +#ifdef CONTROL_METADATA_EARLY_REFLECTIONS + uint32_t signx, signy, k; +#endif + uint32_t i, m, n; ivas_error error; float freqHop; uint32_t gridLen; @@ -992,6 +1235,20 @@ ivas_error RenderConfigReader_read( fread( pRenderConfigReader->pBitstream, sizeof( uint8_t ), file_size, pRenderConfigReader->pConfigFile ); pRenderConfigReader->length = file_size; + /****************************/ + /* Read the presence flag */ + /****************************/ + if ( ( error = read_bits( pRenderConfigReader, &value, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Just return in case no acoustic environment data available */ + if ( value == false ) + { + return IVAS_ERR_OK; + } + /****************************/ /* Read the frequency grids */ /****************************/ @@ -1241,6 +1498,98 @@ ivas_error RenderConfigReader_read( return IVAS_ERR_INVALID_RENDER_CONFIG; } } + +#ifdef CONTROL_METADATA_EARLY_REFLECTIONS + /* Has early reflections */ + if ( ( error = read_bits( pRenderConfigReader, &value, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( value == true ) + { + if ( ( pRenderConfigReader->pAE[n].pEarlyReflections = (EarlyReflectionsConfig *) malloc( sizeof( EarlyReflectionsConfig ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + + /* Room sizes */ + if ( ( error = get_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.x ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = get_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.y ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = get_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.z ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Frequency grid ID */ + if ( ( error = get_count_or_index( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + pRenderConfigReader->pAE[n].pEarlyReflections->pFG = &pRenderConfigReader->pFG[value]; + + /* Absorption coefficients */ + if ( ( pRenderConfigReader->pAE[n].pEarlyReflections->pAbsCoeff = malloc( pRenderConfigReader->pAE[n].pEarlyReflections->pFG->nrBands * sizeof( float[N_ABS_COEFFS] ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + + for ( m = 0; m < pRenderConfigReader->pAE[n].pEarlyReflections->pFG->nrBands; m++ ) + { + for ( k = 0; k < N_ABS_COEFFS; k++ ) + { + if ( ( error = get_absorption( pRenderConfigReader, &pRenderConfigReader->pAE[n].pEarlyReflections->pAbsCoeff[m][k] ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + + /* Has listener origin */ + if ( ( error = read_bits( pRenderConfigReader, &value, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( value == true ) + { + if ( ( pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin = malloc( sizeof( IVAS_VECTOR3 ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + + if ( ( error = read_bits( pRenderConfigReader, &signx, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = read_bits( pRenderConfigReader, &signy, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = get_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->x ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( signx == 0 ) + { + pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->x *= -1.0f; + } + if ( ( error = get_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( signy == 0 ) + { + pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y *= -1.0f; + } + } + } +#endif } /* Cleanup */ @@ -1315,7 +1664,7 @@ ivas_error RenderConfigReader_read( while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) { hRenderConfig->room_acoustics.override = TRUE; - params_idx += ( int32_t )( strlen( item ) + strlen( pValue ) + 2 ); + params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); #ifdef DEBUGGING fprintf( stderr, " PARAM: %s -> %s\n", item, pValue ); #endif @@ -1402,7 +1751,7 @@ ivas_error RenderConfigReader_read( pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) { - params_idx += ( int32_t )( strlen( item ) + strlen( pValue ) + 2 ); + params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); fprintf( stderr, " PARAM: %s -> %s\n", item, pValue ); if ( strcmp( item, "RENDERER" ) == 0 ) { @@ -1517,7 +1866,7 @@ void RenderConfigReader_close( ) { #ifdef CONTROL_METADATA_REVERB - uint16_t n; + uint32_t n; #endif if ( ppRenderConfigReader == NULL || *ppRenderConfigReader == NULL ) @@ -1529,6 +1878,17 @@ void RenderConfigReader_close( /* Free the acoustic environments */ for ( n = 0; n < ( *ppRenderConfigReader )->nAE; n++ ) { +#ifdef CONTROL_METADATA_EARLY_REFLECTIONS + if ( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections != NULL ) + { + if ( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections->pListenerOrigin != NULL ) + { + free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections->pListenerOrigin ); + } + free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections->pAbsCoeff ); + free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections ); + } +#endif free( ( *ppRenderConfigReader )->pAE[n].pRT60 ); free( ( *ppRenderConfigReader )->pAE[n].pDSR ); } -- GitLab From 8537b1dd6e85c309bfe13d27b849626d490f4af3 Mon Sep 17 00:00:00 2001 From: Jan Brouwer Date: Wed, 3 May 2023 10:32:43 +0200 Subject: [PATCH 3/6] further updates to acoustic environments metadata including early reflections --- ...generate_acoustic_environments_metadata.py | 91 ++++++++++--------- 1 file changed, 50 insertions(+), 41 deletions(-) diff --git a/scripts/reverb/generate_acoustic_environments_metadata.py b/scripts/reverb/generate_acoustic_environments_metadata.py index c7d49bf3f4..77c9841b40 100644 --- a/scripts/reverb/generate_acoustic_environments_metadata.py +++ b/scripts/reverb/generate_acoustic_environments_metadata.py @@ -117,9 +117,9 @@ def get_duration_code(duration): '110100000', '111010', '110100001', '111011', '110100110', '111000', '110100111', '111001', '110100100', '111110', '110100101', '111111', '110111010', '111100', '110111011', '111101', '110111000', '11000', '110111001' ] - duration_dus = int(round(np.float32(duration) * np.float32(100000))) # [deca us] + duration_dus = round(np.float32(duration) * np.float32(100000)) # [deca us] if print_cfg: - print('duration: ', duration_dus) + print('duration: ', duration_dus, 'dus') dus = duration_dus # [deca us] s = dus // 100000 # 0, 1, ... 30 [s] @@ -168,7 +168,7 @@ def get_frequency_code(f): assert 16 <= f <= 40000 if f in frequencyCode.keys(): if print_cfg: - print('frequency:', f) + print('frequency:', f, 'Hz') return frequencyCode[f] + '0' else: # exact frequency not found, use frequency refinement to aproximate @@ -185,25 +185,24 @@ def get_frequency_code(f): if refinement >= 16: # choose next higer frequency if print_cfg: - print('frequency:', list(frequencyCode)[f_high]) + print('frequency:', list(frequencyCode)[f_high], 'Hz') return frequencyCode[f_high] + '0' else: if print_cfg: - print('frequency:', list(frequencyCode)[f_low], ', refined: ', f_low * 2 ** ((refinement + 1) / 51)) + print('frequency:', list(frequencyCode)[f_low], ', Hz, refined: ', f_low * 2 ** ((refinement + 1) / 51), 'Hz') return frequencyCode[f_low] + '1' + format(refinement, '04b') def get_frequency_hop_code(index): - assert 0 <= index < 9 + assert 0 <= index < 7 return [ - '0010', # 2^(1/12) - '0011', # 2^(1/6) - '0000', # 2^(1/4) - '01', # 2^(1/3) - '0001', # 2^(1/2) - '10', # 2^1 - '111'][index] # 2^2 - + '0010', # 2^(1/12) + '0011', # 2^(1/6) + '0000', # 2^(1/4) + '01', # 2^(1/3) + '0001', # 2^(1/2) + '11', # 2^1 + '10'][index] # 2^2 def get_dsr_code(dsr): @@ -239,7 +238,7 @@ class fgdMethod(Enum): Default_Banding = '10' -def get_distance_code(dist, isSmallScene = True): +def get_distance_code(distance, isSmallScene = True): # 0, 1, ... 99 metersCode = [ '111101', '110010', '110011', '110000', '110001', '110110', '110111', '110100', '110101', '001010', @@ -274,37 +273,36 @@ def get_distance_code(dist, isSmallScene = True): '100010', '100011', '100000', '100001', '100110', '100111', '100100', '100101', '1111010', '1111011', '1111000', '1111001', '1111110', '1111111', '1111100', '1111101', '111010', '111011', '111000', '111001' ] - distance_mm = int(round(np.float32(distance) * np.float32(1000))) # distance in mm + distance_cm = round(np.float32(distance) * np.float32(100)) # distance in cm if print_cfg: - print('distance: ', distance_mm) + print('distance: ', distance_cm, 'cm') - mm = distance_mm # [mm] - cm = mm // 10 # [cm] + cm = distance_cm # [cm] m = cm // 100 # [m] hm = m // 100 # [hm] km = hm // 10 # [km] - mm = (mm % 10) # 0, 1, ... 9 [mm] cm = (cm % 100) # 0, 1, ... 99 [cm] m = (m % 100) # 0, 1, ... 99 [m] - hm = (hm % 9) # 0, 1, ... 9 [hm] + hm = (hm % 10) # 0, 1, ... 9 [hm] - assert 0 <= mm <= 9 assert 0 <= cm <= 99 assert 0 <= m <= 99 assert 0 <= hm <= 9 - assert distance_mm == km * 1000000 + hm * 100000 + m * 1000 + cm * 10 + mm + assert distance_cm == km * 100000 + hm * 10000 + m * 100 + cm code = metersCode[m] - if not isSmallScene: + if isSmallScene: + assert(m == hm == km == 0) + else: # large scenes if hm > 0 or km > 0: # hectometers code += '1' + hectometersCode[hm] while km > 0: # kilometers - code += '1' + kilometersCode[min(km, 10)] + code += '1' + kilometersCode[min(km, 10) - 1] km = km - 10 code += '0' else: @@ -326,6 +324,7 @@ def get_absorption_code(absorption): return ['110', '100', '101', '0110', '0111', '111', '0100', '0101', '0010', '0011', '000' ][index] + # apply function to elements of list and concatenate the resulting strings def concatenate(function, data): return ''.join([function(d) for d in data]) @@ -333,16 +332,15 @@ def concatenate(function, data): def test(): # generate binary output which can be compared with the Matlab implementation output - string = '' # count or index encoding - string += concatenate(get_count_or_index_code, [n for n in range(0, 16 * 64)]) + string += concatenate(get_count_or_index_code, [n for n in range(16 * 64)]) # duration encoding - string += concatenate(get_duration_code, [d / 1000 for d in range(0, 30 * 1000)]) - string += concatenate(get_duration_code, [d / 10000 for d in range(0, 30 * 1000)]) - string += concatenate(get_duration_code, [d / 100000 for d in range(0, 30 * 1000)]) + string += concatenate(get_duration_code, [d / 1000 for d in range(30 * 1000)]) + string += concatenate(get_duration_code, [d / 10000 for d in range(30 * 1000)]) + string += concatenate(get_duration_code, [d / 100000 for d in range(30 * 1000)]) # frequency encoding string += concatenate(get_frequency_code, @@ -352,11 +350,20 @@ def test(): 16000, 20000, 25000, 31500, 40000]) # frequency hop encoding - string += concatenate(get_frequency_hop_code, [index for index in range(0, 9)]) + string += concatenate(get_frequency_hop_code, [index for index in range(7)]) # DSR encoding string += concatenate(get_dsr_code, [math.pow(10, dsr / 10) for dsr in range(-150, -10 + 1)]) + # distance encoding + string += concatenate(lambda d : get_distance_code(d, False), [d for d in range(20 * 1000)]) + string += concatenate(lambda d : get_distance_code(d, False), [d / 10 for d in range(20 * 1000)]) + string += concatenate(lambda d : get_distance_code(d, False), [d / 100 for d in range(20 * 1000)]) + string += concatenate(lambda d : get_distance_code(d, True), [d / 100 for d in range( 100)]) + + # absorption encoding + string += concatenate(get_absorption_code, [a / 100 for a in range(100 + 1)]) + data = bitarray(string, endian='big') file = open('test_python.dat', 'wb') @@ -443,8 +450,8 @@ def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_re 2.6267e-08 ]) + '1' # hasEarlyReflections - + concatenate(get_distance_code, # room dimensions - [ 3.0, 4.0, 2.5 ]) + + concatenate(lambda d : get_distance_code(d, False), + [ 3.0, 4.0, 2.5 ]) # room dimensions + get_count_or_index_code(0) # FreqGridID + concatenate(get_absorption_code, # absorptionCode @@ -500,9 +507,9 @@ def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_re 2.6267e-08 ]) + '1' # hasEarlyReflections - + concatenate(get_distance_code, # room dimensions - [ 3.0, 4.0, 2.5 ]) - + + concatenate(lambda code : get_distance_code(code, False), + [ 3.0, 4.0, 2.5 ]) # room dimensions + + get_count_or_index_code(0) # FreqGridID + concatenate(get_absorption_code, # absorptionCode [ 0.8, 0.8, 0.8, 0.8, 0.2, 0.6 ]) @@ -510,8 +517,8 @@ def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_re + '1' # listener origin flag + '1' # positive x origin + '0' # negative y origin - + concatenate(get_distance_code, # listener origin (x, y, z) - [ 0.5, 0.5, 1.5 ]) + + concatenate(lambda d : get_distance_code(d, False), + [ 0.5, 0.5, 1.5 ]) # listener origin (x, y, z) , endian='big') @@ -520,12 +527,11 @@ def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_re file.close() - def generate_reverb_payload_equivalent_to_rend_config_hospital_patientroom_cfg(): # based on config_hospital_patientroom.cfg # note that because of encoding, resolution is lost and behaviour may not be bit-exact compared to .cfg file based values data = bitarray( - 1 # hasAcEnv + '1' # hasAcEnv + get_count_or_index_code(1) # fgdNrGrids + fgdMethod.Individual_Frequencies.value # fgdMethod + get_count_or_index_code(31) # fgdNrBands @@ -567,7 +573,7 @@ def generate_reverb_payload_equivalent_to_rend_config_recreation_cfg(): # based on config_recreation.cfg # note that because of encoding, resolution is lost and behaviour may not be bit-exact compared to .cfg file based values data = bitarray( - 1 # hasAcEnv + '1' # hasAcEnv + get_count_or_index_code(1) # fgdNrGrids + fgdMethod.Individual_Frequencies.value # fgdMethod + get_count_or_index_code(31) # fgdNrBands @@ -609,3 +615,6 @@ def generate_reverb_payload_equivalent_to_rend_config_recreation_cfg(): generate_reverb_payload_equivalent_to_rend_config_renderer_cfg() generate_reverb_payload_equivalent_to_rend_config_hospital_patientroom_cfg() generate_reverb_payload_equivalent_to_rend_config_recreation_cfg() + +#generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_reflections_no_listener_origin() +#generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_reflections_listener_origin() -- GitLab From 63535b6d53de5a4ac5bfd5335121536e0029a1c4 Mon Sep 17 00:00:00 2001 From: Jan Brouwer Date: Wed, 3 May 2023 16:52:03 +0200 Subject: [PATCH 4/6] fixed a small error; generated new format binary reverb files --- lib_util/render_config_reader.c | 1 + scripts/testv/rend_config_hospital_patientroom.dat | 2 +- scripts/testv/rend_config_recreation.dat | 4 ++-- scripts/testv/rend_config_renderer.dat | 4 ++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index e7002f9e61..d8edca110b 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -1445,6 +1445,7 @@ static ivas_error RenderConfigReader_readReverb( { pRenderConfigReader->pAE[n].pRT60 = 0; pRenderConfigReader->pAE[n].pDSR = 0; + pRenderConfigReader->pAE[n].pEarlyReflections = 0; } for ( n = 0; n < pRenderConfigReader->nAE; n++ ) diff --git a/scripts/testv/rend_config_hospital_patientroom.dat b/scripts/testv/rend_config_hospital_patientroom.dat index 20455a95b7..dd09f2ddb4 100644 --- a/scripts/testv/rend_config_hospital_patientroom.dat +++ b/scripts/testv/rend_config_hospital_patientroom.dat @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a3b4cf6b770f85bc82129901324078afc0953661b3ff753796d7d4bd15d8c468 +oid sha256:84321b26550df78456eea5595f8e7d99cca2b558117cddf117b738f1d8c2e316 size 136 diff --git a/scripts/testv/rend_config_recreation.dat b/scripts/testv/rend_config_recreation.dat index 456eedbbf7..d17f39b2f1 100644 --- a/scripts/testv/rend_config_recreation.dat +++ b/scripts/testv/rend_config_recreation.dat @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6cb9adc877960d2a7e827126c2f44612569e5554e974b5bb98d3be92cb1ee14a -size 149 +oid sha256:6329e3e202458bfae10c8811f4018e8df2c7f2dc8789850ef2d17b72e490f23d +size 150 diff --git a/scripts/testv/rend_config_renderer.dat b/scripts/testv/rend_config_renderer.dat index 6ea8ed4f1d..979bbf9a87 100644 --- a/scripts/testv/rend_config_renderer.dat +++ b/scripts/testv/rend_config_renderer.dat @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7941266900de8753e847cfef95298b5ee529e3f8f90ca5421ba46d71bc353821 -size 130 +oid sha256:24a7142edde4f689273970edc73f0ed5c9ac0bbdcc75736ce3c1604e925a6fbf +size 131 -- GitLab From 1b7ecd9898acbd07616afabc70366c2f1c0a33c7 Mon Sep 17 00:00:00 2001 From: Jan Brouwer Date: Thu, 4 May 2023 16:46:01 +0200 Subject: [PATCH 5/6] added missing #ifdef CONTROL_METADATA_EARLY_REFLECTIONS; removed nested #ifdef DEBUGGING --- lib_util/render_config_reader.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index d8edca110b..581a240a52 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -1445,7 +1445,9 @@ static ivas_error RenderConfigReader_readReverb( { pRenderConfigReader->pAE[n].pRT60 = 0; pRenderConfigReader->pAE[n].pDSR = 0; +#ifdef CONTROL_METADATA_EARLY_REFLECTIONS pRenderConfigReader->pAE[n].pEarlyReflections = 0; +#endif } for ( n = 0; n < pRenderConfigReader->nAE; n++ ) @@ -1830,13 +1832,11 @@ ivas_error RenderConfigReader_read( errorHandler( item, ERROR_VALUE_INVALID ); } } -#ifdef DEBUGGING else { fprintf( stderr, "Unsupported configuration property %s\n", item ); } #endif -#endif #ifdef CONTROL_METADATA_REVERB params_idx += params_length; #endif -- GitLab From 81183cb776db7ae68164a3e0b1227874844dffd4 Mon Sep 17 00:00:00 2001 From: Jan Brouwer Date: Wed, 31 May 2023 16:12:49 +0200 Subject: [PATCH 6/6] Corrected bugs reported as part of crosscheck feedback --- lib_util/render_config_reader.c | 57 ++++++++++--------- ...generate_acoustic_environments_metadata.py | 20 +++---- 2 files changed, 41 insertions(+), 36 deletions(-) diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 581a240a52..68296169de 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -412,7 +412,7 @@ const float defaultFrequencyGrid_8[] = { *-----------------------------------------------------------------------------------------*/ static ivas_error read_bits( RenderConfigReader *this, /* i/o : Renderer config reader handle */ - uint32_t *pTarget, /* i/o : Target read data pointer */ + uint32_t *pTarget, /* o : Target read data pointer */ const size_t nBits /* i : Number of bits to read */ ) { @@ -430,6 +430,7 @@ static ivas_error read_bits( return IVAS_ERR_INVALID_RENDER_CONFIG; } + *pTarget = 0; for ( n = 0; n < nBits; n++ ) { nByte = ( this->readOffset + n ) >> 3; @@ -451,7 +452,6 @@ static ivas_error read_bool( uint32_t *pResult /* o : Target read data pointer */ ) { - *pResult = false; return read_bits( this, pResult, 1 ); } @@ -513,10 +513,14 @@ static ivas_error read_code_word( uint8_t size; uint8_t n; uint32_t code; + uint32_t bits; + uint32_t nr_bits; uint8_t len; minLen = 255; maxLen = 0; + bits = 0; + nr_bits = 0; code = 0; if ( pResult == NULL ) @@ -624,11 +628,12 @@ static ivas_error read_code_word( } for ( len = minLen; len <= maxLen; len++ ) { - if ( ( error = read_bits( this, &code, ( len == minLen ) ? minLen : 1 ) ) != IVAS_ERR_OK ) + nr_bits = ( len == minLen ) ? minLen : 1; + if ( ( error = read_bits( this, &bits, nr_bits ) ) != IVAS_ERR_OK ) { return error; } - + code = ( code << nr_bits ) | bits; for ( n = 0; n < size; n++ ) { if ( code == pCodes[n] && len == pLengths[n] ) @@ -835,7 +840,7 @@ static ivas_error get_distance( if ( isSmall == false ) { /* addHectometers flag */ - if ( ( error = read_bits( this, &flag, 1 ) ) != IVAS_ERR_OK ) + if ( ( error = read_bool( this, &flag ) ) != IVAS_ERR_OK ) { return error; } @@ -850,7 +855,7 @@ static ivas_error get_distance( *pResult += value * 100.0f; /* addKilometers flag */ - if ( ( error = read_bits( this, &flag, 1 ) ) != IVAS_ERR_OK ) + if ( ( error = read_bool( this, &flag ) ) != IVAS_ERR_OK ) { return error; } @@ -865,28 +870,27 @@ static ivas_error get_distance( *pResult += value * 1000.0f; /* addKilometers flag */ - if ( ( error = read_bits( this, &flag, 1 ) ) != IVAS_ERR_OK ) + if ( ( error = read_bool( this, &flag ) ) != IVAS_ERR_OK ) { return error; } } } + } - /* addCentimeters flag */ - if ( ( error = read_bits( this, &flag, 1 ) ) != IVAS_ERR_OK ) + /* addCentimeters flag */ + if ( ( error = read_bool( this, &flag ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( flag == true ) + { + /* Centimeters */ + if ( ( error = read_code_word( this, RC_LUT_CENTIMETERS, &value ) ) != IVAS_ERR_OK ) { return error; } - if ( flag == true ) - { - /* Centimeters */ - /* Kilometers */ - if ( ( error = read_code_word( this, RC_LUT_CENTIMETERS, &value ) ) != IVAS_ERR_OK ) - { - return error; - } - *pResult += value * 0.01f; - } + *pResult += value * 0.01f; } return IVAS_ERR_OK; @@ -1240,7 +1244,7 @@ static ivas_error RenderConfigReader_readReverb( /****************************/ /* Read the presence flag */ /****************************/ - if ( ( error = read_bits( pRenderConfigReader, &value, 1 ) ) != IVAS_ERR_OK ) + if ( ( error = read_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) { return error; } @@ -1506,7 +1510,7 @@ static ivas_error RenderConfigReader_readReverb( #ifdef CONTROL_METADATA_EARLY_REFLECTIONS /* Has early reflections */ - if ( ( error = read_bits( pRenderConfigReader, &value, 1 ) ) != IVAS_ERR_OK ) + if ( ( error = read_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) { return error; } @@ -1556,7 +1560,7 @@ static ivas_error RenderConfigReader_readReverb( } /* Has listener origin */ - if ( ( error = read_bits( pRenderConfigReader, &value, 1 ) ) != IVAS_ERR_OK ) + if ( ( error = read_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) { return error; } @@ -1592,6 +1596,10 @@ static ivas_error RenderConfigReader_readReverb( { pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y *= -1.0f; } + if ( ( error = get_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->z ) ) != IVAS_ERR_OK ) + { + return error; + } } } #endif @@ -1942,10 +1950,7 @@ void RenderConfigReader_close( #ifdef CONTROL_METADATA_EARLY_REFLECTIONS if ( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections != NULL ) { - if ( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections->pListenerOrigin != NULL ) - { - free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections->pListenerOrigin ); - } + free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections->pListenerOrigin ); free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections->pAbsCoeff ); free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections ); } diff --git a/scripts/reverb/generate_acoustic_environments_metadata.py b/scripts/reverb/generate_acoustic_environments_metadata.py index 77c9841b40..9fc9c6a3ca 100644 --- a/scripts/reverb/generate_acoustic_environments_metadata.py +++ b/scripts/reverb/generate_acoustic_environments_metadata.py @@ -294,7 +294,7 @@ def get_distance_code(distance, isSmallScene = True): code = metersCode[m] if isSmallScene: - assert(m == hm == km == 0) + assert(hm == km == 0) else: # large scenes if hm > 0 or km > 0: @@ -359,7 +359,7 @@ def test(): string += concatenate(lambda d : get_distance_code(d, False), [d for d in range(20 * 1000)]) string += concatenate(lambda d : get_distance_code(d, False), [d / 10 for d in range(20 * 1000)]) string += concatenate(lambda d : get_distance_code(d, False), [d / 100 for d in range(20 * 1000)]) - string += concatenate(lambda d : get_distance_code(d, True), [d / 100 for d in range( 100)]) + string += concatenate(lambda d : get_distance_code(d, True), [d / 100 for d in range(10 * 1000)]) # absorption encoding string += concatenate(get_absorption_code, [a / 100 for a in range(100 + 1)]) @@ -450,7 +450,7 @@ def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_re 2.6267e-08 ]) + '1' # hasEarlyReflections - + concatenate(lambda d : get_distance_code(d, False), + + concatenate(lambda d : get_distance_code(d, True), [ 3.0, 4.0, 2.5 ]) # room dimensions + get_count_or_index_code(0) # FreqGridID @@ -461,7 +461,7 @@ def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_re , endian='big') - file = open('rend_config_renderer.dat', 'wb') + file = open('rend_config_renderer_cfg_plus_early_reflections_no_listener_origin.dat', 'wb') data.tofile(file) file.close() @@ -507,7 +507,7 @@ def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_re 2.6267e-08 ]) + '1' # hasEarlyReflections - + concatenate(lambda code : get_distance_code(code, False), + + concatenate(lambda code : get_distance_code(code, True), [ 3.0, 4.0, 2.5 ]) # room dimensions + get_count_or_index_code(0) # FreqGridID @@ -515,14 +515,14 @@ def generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_re [ 0.8, 0.8, 0.8, 0.8, 0.2, 0.6 ]) + '1' # listener origin flag - + '1' # positive x origin - + '0' # negative y origin - + concatenate(lambda d : get_distance_code(d, False), + + '1' # is possitive x + + '0' # is possitive y + + concatenate(lambda d : get_distance_code(d, True), [ 0.5, 0.5, 1.5 ]) # listener origin (x, y, z) , endian='big') - file = open('rend_config_renderer.dat', 'wb') + file = open('rend_config_renderer_cfg_plus_early_reflections_listener_origin.dat', 'wb') data.tofile(file) file.close() @@ -616,5 +616,5 @@ generate_reverb_payload_equivalent_to_rend_config_renderer_cfg() generate_reverb_payload_equivalent_to_rend_config_hospital_patientroom_cfg() generate_reverb_payload_equivalent_to_rend_config_recreation_cfg() -#generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_reflections_no_listener_origin() #generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_reflections_listener_origin() +#generate_reverb_payload_equivalent_to_rend_config_renderer_cfg_plus_early_reflections_no_listener_origin() -- GitLab