From 02aa6faa6d1e0fee3186650d73ca3043ad6bb31a Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Mon, 17 Jul 2023 14:01:49 +0200 Subject: [PATCH 01/46] Support for multiple acoustic environments plus early reflections in text-based configuration (prototype) --- Workspace_msvc/render_config_reader_bin.c | 829 ++++++++++++++++++ lib_util/render_config_reader.c | 693 ++++++++++++--- .../acoustic_environment_recreation.cfg | 3 + scripts/testv/rend_config_renderer.cfg | 30 +- 4 files changed, 1431 insertions(+), 124 deletions(-) create mode 100644 Workspace_msvc/render_config_reader_bin.c diff --git a/Workspace_msvc/render_config_reader_bin.c b/Workspace_msvc/render_config_reader_bin.c new file mode 100644 index 0000000000..7c972460a5 --- /dev/null +++ b/Workspace_msvc/render_config_reader_bin.c @@ -0,0 +1,829 @@ +/****************************************************************************************************** + + (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "render_config_reader.h" +#include "prot.h" + +#ifdef CONTROL_METADATA_REVERB + +typedef enum _RC_LUT +{ + RC_LUT_INVALID = 0x00, + RC_LUT_COUNT_IDX_LO, + RC_LUT_COUNT_IDX_HI, + RC_LUT_DECI_SEC, + RC_LUT_SEC, + RC_LUT_MILLI_SEC, + RC_LUT_MICRO_SEC, + 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; + +/*------------------------------------------------------------------------------------------* + * Lookup tables + *------------------------------------------------------------------------------------------*/ + +const float lutCountIdxLo_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 +}; +const uint16_t lutCountIdxLo_Code[] = { + 7, 4, 12, 13, 10, 11, 8, 9, 15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, 5, 4, 3, 2, 1, 0, 63, 62, 61, 60, 59, 58, 57, 56, + 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97, 96, + 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80 +}; +const uint8_t lutCountIdxLo_Len[] = { + 4, 3, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 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 +}; + +const float lutCountIdxHi_Value[] = { 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 }; +const uint16_t lutCountIdxHi_Code[] = { 1, 0, 6, 5, 4, 7, 5, 15, 14, 13, 9, 8, 25, 49, 48 }; +const uint8_t lutCountIdxHi_Len[] = { 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 7, 7 }; + +const float lutDeciSec_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 lutDeciSec_Code[] = { 6, 4, 5, 6, 7, 7, 4, 5, 2, 3, 0 }; +const uint8_t lutDeciSec_Len[] = { 3, 3, 3, 4, 4, 3, 4, 4, 4, 4, 3 }; + +const float lutSec_Value[] = { + 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 +}; +const uint16_t lutSec_Code[] = { 3, 1, 0, 15, 13, 12, 11, 9, 8, 14, 13, 12, 11, 9, 8, 5, 29, 28, 21, 31, 30, 21, 9, 8, 41, 41, 40, 81, 161, 160 }; +const uint8_t lutSec_Len[] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 8, 8 }; + +const float lutMilliSec_Value[] = { + 0.00f, 0.001f, 0.002f, 0.003f, 0.004f, 0.005f, 0.006f, 0.007f, 0.008f, 0.009f, + 0.01f, 0.011f, 0.012f, 0.013f, 0.014f, 0.015f, 0.016f, 0.017f, 0.018f, 0.019f, + 0.02f, 0.021f, 0.022f, 0.023f, 0.024f, 0.025f, 0.026f, 0.027f, 0.028f, 0.029f, + 0.03f, 0.031f, 0.032f, 0.033f, 0.034f, 0.035f, 0.036f, 0.037f, 0.038f, 0.039f, + 0.04f, 0.041f, 0.042f, 0.043f, 0.044f, 0.045f, 0.046f, 0.047f, 0.048f, 0.049f, + 0.05f, 0.051f, 0.052f, 0.053f, 0.054f, 0.055f, 0.056f, 0.057f, 0.058f, 0.059f, + 0.06f, 0.061f, 0.062f, 0.063f, 0.064f, 0.065f, 0.066f, 0.067f, 0.068f, 0.069f, + 0.07f, 0.071f, 0.072f, 0.073f, 0.074f, 0.075f, 0.076f, 0.077f, 0.078f, 0.079f, + 0.08f, 0.081f, 0.082f, 0.083f, 0.084f, 0.085f, 0.086f, 0.087f, 0.088f, 0.089f, + 0.09f, 0.091f, 0.092f, 0.093f, 0.094f, 0.095f, 0.096f, 0.097f, 0.098f, 0.099f +}; +const uint16_t lutMilliSec_Code[] = { + 122, 123, 120, 121, 126, 127, 124, 125, 114, 115, 25, 112, 113, 118, 119, 116, 117, 42, 43, 40, + 18, 41, 46, 47, 44, 45, 34, 35, 32, 33, 19, 38, 39, 36, 37, 58, 59, 56, 57, 62, + 16, 63, 60, 61, 50, 51, 48, 49, 54, 55, 17, 52, 53, 10, 11, 8, 9, 14, 15, 12, + 22, 13, 2, 3, 0, 1, 6, 7, 4, 5, 23, 26, 27, 24, 25, 30, 31, 28, 29, 18, + 20, 19, 16, 17, 22, 23, 20, 21, 106, 107, 21, 104, 105, 110, 111, 108, 109, 98, 99, 48 +}; +const uint8_t lutMilliSec_Len[] = { + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 7, 7, 7, 7, 7, 7, 7, 7, 6 +}; + +const float lutMicroSec_Value[] = { + 0.00001f, 0.00002f, 0.00003f, 0.00004f, 0.00005f, 0.00006f, 0.00007f, 0.00008f, 0.00009f, 0.0001f, + 0.00011f, 0.00012f, 0.00013f, 0.00014f, 0.00015f, 0.00016f, 0.00017f, 0.00018f, 0.00019f, 0.0002f, + 0.00021f, 0.00022f, 0.00023f, 0.00024f, 0.00025f, 0.00026f, 0.00027f, 0.00028f, 0.00029f, 0.0003f, + 0.00031f, 0.00032f, 0.00033f, 0.00034f, 0.00035f, 0.00036f, 0.00037f, 0.00038f, 0.00039f, 0.0004f, + 0.00041f, 0.00042f, 0.00043f, 0.00044f, 0.00045f, 0.00046f, 0.00047f, 0.00048f, 0.00049f, 0.0005f, + 0.00051f, 0.00052f, 0.00053f, 0.00054f, 0.00055f, 0.00056f, 0.00057f, 0.00058f, 0.00059f, 0.0006f, + 0.00061f, 0.00062f, 0.00063f, 0.00064f, 0.00065f, 0.00066f, 0.00067f, 0.00068f, 0.00069f, 0.0007f, + 0.00071f, 0.00072f, 0.00073f, 0.00074f, 0.00075f, 0.00076f, 0.00077f, 0.00078f, 0.00079f, 0.0008f, + 0.00081f, 0.00082f, 0.00083f, 0.00084f, 0.00085f, 0.00086f, 0.00087f, 0.00088f, 0.00089f, 0.0009f, + 0.00091f, 0.00092f, 0.00093f, 0.00094f, 0.00095f, 0.00096f, 0.00097f, 0.00098f, 0.00099f +}; +const uint16_t lutMicroSec_Code[] = { + 444, 18, 445, 19, 894, 16, 895, 17, 892, 22, 893, 23, 434, 20, 435, 21, 432, 10, 433, 11, + 438, 8, 439, 9, 436, 14, 437, 15, 410, 12, 411, 13, 408, 2, 409, 3, 414, 0, 415, 1, + 412, 6, 413, 7, 402, 4, 403, 5, 400, 26, 401, 27, 406, 24, 407, 25, 404, 30, 405, 31, + 426, 28, 427, 29, 424, 18, 425, 19, 430, 16, 431, 17, 428, 22, 429, 23, 418, 20, 419, 21, + 416, 58, 417, 59, 422, 56, 423, 57, 420, 62, 421, 63, 442, 60, 443, 61, 440, 24, 441 +}; +const uint8_t lutMicroSec_Len[] = { + 9, 5, 9, 5, 10, 5, 10, 5, 10, 5, 10, 5, 9, 5, 9, 5, 9, 6, 9, 6, + 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, + 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, + 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, + 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 6, 9, 5, 9 +}; + +const float lutFreq_Value[] = { + 16.0f, 20.0f, 25.0f, 31.5f, 40.0f, 50.0f, 63.0f, 80.0f, 100.0f, 125.0f, + 160.0f, 200.0f, 250.0f, 315.0f, 400.0f, 500.0f, 630.0f, 800.0f, 1000.0f, 1250.0f, + 1600.0f, 2000.0f, 2500.0f, 3150.0f, 4000.0f, 5000.0f, 6300.0f, 8000.0f, 10000.0f, 12500.0f, + 16000.0f, 20000.0f, 25000.0f, 31500.0f, 40000.0f +}; +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.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, + -140.0f, -139.0f, -138.0f, -137.0f, -136.0f, -135.0f, -134.0f, -133.0f, -132.0f, -131.0f, + -130.0f, -129.0f, -128.0f, -127.0f, -126.0f, -125.0f, -124.0f, -123.0f, -122.0f, -121.0f, + -120.0f, -119.0f, -118.0f, -117.0f, -116.0f, -115.0f, -114.0f, -113.0f, -112.0f, -111.0f, + -110.0f, -109.0f, -108.0f, -107.0f, -106.0f, -105.0f, -104.0f, -103.0f, -102.0f, -101.0f, + -100.0f, -99.0f, -98.0f, -97.0f, -96.0f, -95.0f, -94.0f, -93.0f, -92.0f, -91.0f, + -90.0f, -89.0f, -88.0f, -87.0f, -86.0f, -85.0f, -84.0f, -83.0f, -82.0f, -81.0f, + -80.0f, -79.0f, -78.0f, -77.0f, -76.0f, -75.0f, -74.0f, -73.0f, -72.0f, -71.0f, + -70.0f, -69.0f, -68.0f, -67.0f, -66.0f, -65.0f, -64.0f, -63.0f, -62.0f, -61.0f, + -60.0f, -59.0f, -58.0f, -57.0f, -56.0f, -55.0f, -54.0f, -53.0f, -52.0f, -51.0f, + -50.0f, -49.0f, -48.0f, -47.0f, -46.0f, -45.0f, -44.0f, -43.0f, -42.0f, -41.0f, + -40.0f, -39.0f, -38.0f, -37.0f, -36.0f, -35.0f, -34.0f, -33.0f, -32.0f, -31.0f, + -30.0f, -29.0f, -28.0f, -27.0f, -26.0f, -25.0f, -24.0f, -23.0f, -22.0f, -21.0f, + -20.0f, -19.0f, -18.0f, -17.0f, -16.0f, -15.0f, -14.0f, -13.0f, -12.0f, -11.0f, + -10.0f +}; +const uint16_t lutDsr_Code[] = { + 140, 141, 286, 287, 284, 285, 130, 131, 128, 129, 134, 135, 132, 133, 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, 246, 247, 244, 245, 202, 203, 200, 201, 206, 207, 204, 205, 194, 195, 192, 193, 198, 199, + 196, 197, 218, 219, 216, 217, 222, 223, 220, 221, 20, 21, 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, 42, 43, 40, 41, 46, 47, 44, 45, 18, 19, 16, 17, + 22, 210, 211, 208, 209, 214, 215, 212, 213, 186, 187, 184, 185, 190, 191, 188, 189, 138, 139, 136, + 137 +}; +const uint8_t lutDsr_Len[] = { + 8, 8, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 6, + 6, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, + 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 + *------------------------------------------------------------------------------------------*/ + +const float defaultFrequencyGrid_0[] = { 31.5f, 63.0f, 125.0f, 250.0f, 500.0f, 1000.0f, 2000.0f, 4000.0f, 8000.0f, 16000.0f }; +const float defaultFrequencyGrid_1[] = { 25.0f, 50.0f, 100.0f, 200.0f, 400.0f, 800.0f, 1600.0f, 3150.0f, 6300.0f, 12500.0f }; +const float defaultFrequencyGrid_2[] = { + 20.0f, 25.0f, 31.5f, 40.0f, 50.0f, 63.0f, 80.0f, 100.0f, 125.0f, 160.0f, + 200.0f, 250.0f, 315.0f, 400.0f, 500.0f, 630.0f, 800.0f, 1000.0f, 1250.0f, 1600.0f, + 2000.0f, 2500.0f, 3150.0f, 4000.0f, 5000.0f, 6300.0f, 8000.0f, 10000.0f, 12500.0f, 16000.0f, 20000.0f +}; +const float defaultFrequencyGrid_3[] = { 25.0f, 100.0f, 400.0f, 1600.0f, 6300.0f }; +const float defaultFrequencyGrid_4[] = { 125.0f, 250.0f, 500.0f, 1000.0f, 2000.0f, 4000.0f }; +const float defaultFrequencyGrid_5[] = { 25.0f, 250.0f, 2500.0f }; +const float defaultFrequencyGrid_6[] = { + 27.0f, 56.0f, 89.0f, 126.0f, 168.0f, 214.0f, 265.0f, 323.0f, 387.0f, 459.0f, + 539.0f, 628.0f, 727.0f, 839.0f, 963.0f, 1101.0f, 1256.0f, 1429.0f, 1621.0f, 1836.0f, + 2077.0f, 2345.0f, 2644.0f, 2978.0f, 3351.0f, 3767.0f, 4232.0f, 4750.0f, 5329.0f, 5975.0f, + 6697.0f, 7502.0f, 8401.0f, 9405.0f, 10525.0f, 11775.0f, 13171.0f, 14729.0f, 16468.0f, 18410.0f, 20577.0f +}; +const float defaultFrequencyGrid_7[] = { + 27.0f, 89.0f, 168.0f, 265.0f, 387.0f, 539.0f, 727.0f, 963.0f, 1256.0f, 1621.0f, + 2077.0f, 2644.0f, 3351.0f, 4232.0f, 5329.0f, 6697.0f, 8401.0f, 10525.0f, 13171.0f, 16468.0f, 20577.0f +}; +const float defaultFrequencyGrid_8[] = { + 50.0f, 150.0f, 250.0f, 350.0f, 450.0f, 570.0f, 700.0f, 840.0f, 1000.0f, 1170.0f, + 1370.0f, 1600.0f, 1850.0f, 2150.0f, 2150.0f, 2500.0f, 2900.0f, 3400.0f, 4000.0f, 4800.0f, + 5800.0f, 7000.0f, 8500.0f, 10500.0f, 13500.0f +}; + +/*-----------------------------------------------------------------------------------------* + * Function read_bits() + * Reads a given number of bits from the bitstream + *-----------------------------------------------------------------------------------------*/ +static ivas_error read_bits( + RenderConfigReader *this, /* i/o : Renderer config reader handle */ + uint32_t *pTarget, /* o : Target read data pointer */ + const size_t nBits /* i : Number of bits to read */ +) +{ + uint8_t n; + uint32_t nByte; + uint8_t bit; + + if ( this == NULL || this->pBitstream == NULL || pTarget == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( this->readOffset + nBits > this->length * 8 ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + + *pTarget = 0; + for ( n = 0; n < nBits; n++ ) + { + nByte = ( this->readOffset + n ) >> 3; + bit = this->pBitstream[nByte] >> ( 7 - ( ( this->readOffset + n ) % 8 ) ) & 1; + *pTarget = ( *pTarget << 1 ) + bit; + } + + this->readOffset += nBits; + + return IVAS_ERR_OK; +} + +/*-----------------------------------------------------------------------------------------* + * Function read_bool_bin() + * Reads a boolean value from a bitstream + *-----------------------------------------------------------------------------------------*/ +static ivas_error read_bool_bin( + RenderConfigReader *this, /* i/o : Renderer config reader handle */ + uint32_t *pResult /* o : Target read data pointer */ +) +{ + return read_bits( this, pResult, 1 ); +} + +/*-----------------------------------------------------------------------------------------* + * Function get_id_bin() + * Reads an ID from a bitstream + *-----------------------------------------------------------------------------------------*/ +static ivas_error get_id_bin( + RenderConfigReader *this, /* i/o : Renderer config reader handle */ + uint32_t *pResult /* o : Target read data pointer */ +) +{ + ivas_error error; + uint32_t id; + uint32_t cont; + + *pResult = 0; + id = 0; + cont = true; + + if ( pResult == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + while ( cont ) + { + if ( ( error = read_bits( this, &id, 7 ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult = ( *pResult << 7 ) | id; + + if ( ( error = read_bool_bin( this, &cont ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + return IVAS_ERR_OK; +} + +/*-----------------------------------------------------------------------------------------* + * Function read_code_word() + * Reads a code word from a LUT + *-----------------------------------------------------------------------------------------*/ +static ivas_error read_code_word( + RenderConfigReader *this, /* i/o : Renderer config reader handle */ + const RC_LUT table, /* i : Table enum */ + float *pResult /* o : Code value */ +) +{ + ivas_error error; + const float *pValues; + const uint16_t *pCodes; + const uint8_t *pLengths; + uint8_t minLen; + uint8_t maxLen; + 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 ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + /* Select the right tables */ + switch ( table ) + { + case RC_LUT_COUNT_IDX_LO: + pValues = lutCountIdxLo_Value; + pCodes = lutCountIdxLo_Code; + pLengths = lutCountIdxLo_Len; + size = sizeof lutCountIdxLo_Len / sizeof( uint8_t ); + break; + case RC_LUT_COUNT_IDX_HI: + pValues = lutCountIdxHi_Value; + pCodes = lutCountIdxHi_Code; + pLengths = lutCountIdxHi_Len; + size = sizeof lutCountIdxHi_Len / sizeof( uint8_t ); + break; + case RC_LUT_DECI_SEC: + pValues = lutDeciSec_Value; + pCodes = lutDeciSec_Code; + pLengths = lutDeciSec_Len; + size = sizeof lutDeciSec_Len / sizeof( uint8_t ); + break; + case RC_LUT_SEC: + pValues = lutSec_Value; + pCodes = lutSec_Code; + pLengths = lutSec_Len; + size = sizeof lutSec_Len / sizeof( uint8_t ); + break; + case RC_LUT_MILLI_SEC: + pValues = lutMilliSec_Value; + pCodes = lutMilliSec_Code; + pLengths = lutMilliSec_Len; + size = sizeof lutMilliSec_Len / sizeof( uint8_t ); + break; + case RC_LUT_MICRO_SEC: + pValues = lutMicroSec_Value; + pCodes = lutMicroSec_Code; + pLengths = lutMicroSec_Len; + size = sizeof lutMicroSec_Len / sizeof( uint8_t ); + break; + case RC_LUT_FREQ: + pValues = lutFreq_Value; + pCodes = lutFreq_Code; + pLengths = lutFreq_Len; + size = sizeof lutFreq_Len / sizeof( uint8_t ); + break; + case RC_LUT_FREQ_HOP: + pValues = lutFreqHop_Value; + pCodes = lutFreqHop_Code; + pLengths = lutFreqHop_Len; + size = sizeof lutFreqHop_Len / sizeof( uint8_t ); + break; + case RC_LUT_DSR: + pValues = lutDsr_Value; + pCodes = lutDsr_Code; + 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++ ) + { + minLen = min( minLen, pLengths[n] ); + maxLen = max( maxLen, pLengths[n] ); + } + for ( len = minLen; len <= maxLen; len++ ) + { + 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] ) + { + *pResult = pValues[n]; + return IVAS_ERR_OK; + } + } + } + return IVAS_ERR_INVALID_RENDER_CONFIG; +} + +/*-----------------------------------------------------------------------------------------* + * Function get_count_or_index() + * Gets a count or index from a bitstream + *-----------------------------------------------------------------------------------------*/ +static ivas_error get_count_or_index( + RenderConfigReader *this, /* i/o : Renderer config reader handle */ + uint32_t *pResult /* o : Count or index value */ +) +{ + ivas_error error; + float value; + uint32_t isLarge; + + if ( pResult == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( ( error = read_code_word( this, RC_LUT_COUNT_IDX_LO, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult = (uint32_t) value; + + if ( ( error = read_bool_bin( this, &isLarge ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( isLarge ) + { + if ( ( error = read_code_word( this, RC_LUT_COUNT_IDX_HI, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult += (uint32_t) value << 6; + } + + return IVAS_ERR_OK; +} + +/*-----------------------------------------------------------------------------------------* + * Function get_duration() + * Gets a duration value + *-----------------------------------------------------------------------------------------*/ +static ivas_error get_duration( + RenderConfigReader *this, /* i/o : Renderer config reader handle */ + float *pResult /* o : Duration value */ +) +{ + ivas_error error; + float value; + uint32_t addFlag; + + /* Deciseconds */ + if ( ( error = read_code_word( this, RC_LUT_DECI_SEC, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult = value; + + /* Milliseconds */ + if ( ( error = read_bool_bin( this, &addFlag ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( addFlag ) + { + if ( ( error = read_code_word( this, RC_LUT_MILLI_SEC, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult += value; + + /* Microseconds */ + if ( ( error = read_bool_bin( this, &addFlag ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( addFlag ) + { + if ( ( error = read_code_word( this, RC_LUT_MICRO_SEC, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult += value; + } + } + + /* Seconds */ + if ( ( error = read_bool_bin( this, &addFlag ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( addFlag ) + { + if ( ( error = read_code_word( this, RC_LUT_SEC, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult += value; + } + + /* Correct rounding errors due to multiple additions: */ + *pResult = roundf( *pResult * 100000.0f ) / 100000.0f; + + return IVAS_ERR_OK; +} + +/*-----------------------------------------------------------------------------------------* + * Function get_frequency() + * Gets a frequency value + *-----------------------------------------------------------------------------------------*/ +static ivas_error get_frequency( + RenderConfigReader *this, /* i/o : Renderer config reader handle */ + float *pResult /* o : Frequency value */ +) +{ + ivas_error error; + uint32_t hiRes; + uint32_t refine; + + hiRes = 0; + refine = 0; + + if ( ( error = read_code_word( this, RC_LUT_FREQ, pResult ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( ( error = read_bool_bin( this, &hiRes ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( hiRes ) + { + if ( ( error = read_bits( this, &refine, 4 ) ) != IVAS_ERR_OK ) + { + return error; + } + + *pResult *= powf( 2.0f, ( (float) refine + 1.0f ) / 51.0f ); + } + return IVAS_ERR_OK; +} + +/*-----------------------------------------------------------------------------------------* + * Function get_dsr() + * Gets a DSR value + *-----------------------------------------------------------------------------------------*/ +static ivas_error get_dsr( + RenderConfigReader *this, /* i/o : Renderer config reader handle */ + float *pResult /* o : DSR value */ +) +{ + ivas_error error; + float value; + + if ( ( error = read_code_word( this, RC_LUT_DSR, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + *pResult = powf( 10.0f, value / 10.0f ); + + 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_bool_bin( this, &flag ) ) != 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_bool_bin( this, &flag ) ) != 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_bool_bin( this, &flag ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + } + + /* addCentimeters flag */ + if ( ( error = read_bool_bin( 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; + } + *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; +} + +#endif \ No newline at end of file diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index fc20ed0002..8d5a60f689 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -47,10 +47,10 @@ #define MAX_LINE_LENGTH ( 1024 ) #endif #define MAX_ITEM_LENGTH ( 64 ) -#ifndef CONTROL_METADATA_REVERB -#define N_REVERB_VECTORS ( 3 ) -#else +#ifdef CONTROL_METADATA_REVERB #define N_ABS_COEFFS ( 6 ) +#else +#define N_REVERB_VECTORS ( 3 ) #endif #define SHORTEST_REV_DEL_LINE ( 0.015f ) @@ -80,20 +80,22 @@ typedef struct float *pFc; /* Center frequencies */ } FrequencyGrid; +#ifdef CONTROL_METADATA_REVERB typedef enum _FREQ_GRID_MODE { + FREQ_GRID_MODE_UNKNOWN = -1, FREQ_GRID_MODE_INDIVIDUAL_FREQUENCIES = 0, FREQ_GRID_MODE_START_HOP_AMOUNT = 1, FREQ_GRID_MODE_DEFAULT_BANDING = 2 } FREQ_GRID_MODE; +#endif #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 */ + IVAS_VECTOR3 dimensions; /* Room dimensions [m] */ + float pAbsCoeff[N_ABS_COEFFS]; /* Absorption coeffs table */ + IVAS_VECTOR3 *pListenerOrigin; /* Listener origin */ } EarlyReflectionsConfig; #endif @@ -407,10 +409,10 @@ const float defaultFrequencyGrid_8[] = { }; /*-----------------------------------------------------------------------------------------* - * Function read_bits() + * Function read_bin_bits() * Reads a given number of bits from the bitstream *-----------------------------------------------------------------------------------------*/ -static ivas_error read_bits( +static ivas_error read_bin_bits( RenderConfigReader *this, /* i/o : Renderer config reader handle */ uint32_t *pTarget, /* o : Target read data pointer */ const size_t nBits /* i : Number of bits to read */ @@ -444,22 +446,22 @@ static ivas_error read_bits( } /*-----------------------------------------------------------------------------------------* - * Function read_bool() + * Function read_bin_bool() * Reads a boolean value from a bitstream *-----------------------------------------------------------------------------------------*/ -static ivas_error read_bool( +static ivas_error read_bin_bool( RenderConfigReader *this, /* i/o : Renderer config reader handle */ uint32_t *pResult /* o : Target read data pointer */ ) { - return read_bits( this, pResult, 1 ); + return read_bin_bits( this, pResult, 1 ); } /*-----------------------------------------------------------------------------------------* - * Function get_id() + * Function get_bin_id() * Reads an ID from a bitstream *-----------------------------------------------------------------------------------------*/ -static ivas_error get_id( +static ivas_error get_bin_id( RenderConfigReader *this, /* i/o : Renderer config reader handle */ uint32_t *pResult /* o : Target read data pointer */ ) @@ -479,13 +481,13 @@ static ivas_error get_id( while ( cont ) { - if ( ( error = read_bits( this, &id, 7 ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_bits( this, &id, 7 ) ) != IVAS_ERR_OK ) { return error; } *pResult = ( *pResult << 7 ) | id; - if ( ( error = read_bool( this, &cont ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_bool( this, &cont ) ) != IVAS_ERR_OK ) { return error; } @@ -495,10 +497,10 @@ static ivas_error get_id( } /*-----------------------------------------------------------------------------------------* - * Function read_code_word() + * Function read_bin_code_word() * Reads a code word from a LUT *-----------------------------------------------------------------------------------------*/ -static ivas_error read_code_word( +static ivas_error read_bin_code_word( RenderConfigReader *this, /* i/o : Renderer config reader handle */ const RC_LUT table, /* i : Table enum */ float *pResult /* o : Code value */ @@ -629,7 +631,7 @@ static ivas_error read_code_word( for ( len = minLen; len <= maxLen; len++ ) { nr_bits = ( len == minLen ) ? minLen : 1; - if ( ( error = read_bits( this, &bits, nr_bits ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_bits( this, &bits, nr_bits ) ) != IVAS_ERR_OK ) { return error; } @@ -647,10 +649,10 @@ static ivas_error read_code_word( } /*-----------------------------------------------------------------------------------------* - * Function get_count_or_index() + * Function get_bin_count_or_index() * Gets a count or index *-----------------------------------------------------------------------------------------*/ -static ivas_error get_count_or_index( +static ivas_error get_bin_count_or_index( RenderConfigReader *this, /* i/o : Renderer config reader handle */ uint32_t *pResult /* o : Count or index value */ ) @@ -664,20 +666,20 @@ static ivas_error get_count_or_index( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - if ( ( error = read_code_word( this, RC_LUT_COUNT_IDX_LO, &value ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_code_word( this, RC_LUT_COUNT_IDX_LO, &value ) ) != IVAS_ERR_OK ) { return error; } *pResult = (uint32_t) value; - if ( ( error = read_bool( this, &isLarge ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_bool( this, &isLarge ) ) != IVAS_ERR_OK ) { return error; } if ( isLarge ) { - if ( ( error = read_code_word( this, RC_LUT_COUNT_IDX_HI, &value ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_code_word( this, RC_LUT_COUNT_IDX_HI, &value ) ) != IVAS_ERR_OK ) { return error; } @@ -688,10 +690,10 @@ static ivas_error get_count_or_index( } /*-----------------------------------------------------------------------------------------* - * Function get_duration() + * Function get_bin_duration() * Gets a duration value *-----------------------------------------------------------------------------------------*/ -static ivas_error get_duration( +static ivas_error get_bin_duration( RenderConfigReader *this, /* i/o : Renderer config reader handle */ float *pResult /* o : Duration value */ ) @@ -701,35 +703,35 @@ static ivas_error get_duration( uint32_t addFlag; /* Deciseconds */ - if ( ( error = read_code_word( this, RC_LUT_DECI_SEC, &value ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_code_word( this, RC_LUT_DECI_SEC, &value ) ) != IVAS_ERR_OK ) { return error; } *pResult = value; /* Milliseconds */ - if ( ( error = read_bool( this, &addFlag ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_bool( this, &addFlag ) ) != IVAS_ERR_OK ) { return error; } if ( addFlag ) { - if ( ( error = read_code_word( this, RC_LUT_MILLI_SEC, &value ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_code_word( this, RC_LUT_MILLI_SEC, &value ) ) != IVAS_ERR_OK ) { return error; } *pResult += value; /* Microseconds */ - if ( ( error = read_bool( this, &addFlag ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_bool( this, &addFlag ) ) != IVAS_ERR_OK ) { return error; } if ( addFlag ) { - if ( ( error = read_code_word( this, RC_LUT_MICRO_SEC, &value ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_code_word( this, RC_LUT_MICRO_SEC, &value ) ) != IVAS_ERR_OK ) { return error; } @@ -738,14 +740,14 @@ static ivas_error get_duration( } /* Seconds */ - if ( ( error = read_bool( this, &addFlag ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_bool( this, &addFlag ) ) != IVAS_ERR_OK ) { return error; } if ( addFlag ) { - if ( ( error = read_code_word( this, RC_LUT_SEC, &value ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_code_word( this, RC_LUT_SEC, &value ) ) != IVAS_ERR_OK ) { return error; } @@ -759,10 +761,10 @@ static ivas_error get_duration( } /*-----------------------------------------------------------------------------------------* - * Function get_frequency() + * Function get_bin_frequency() * Gets a frequency value *-----------------------------------------------------------------------------------------*/ -static ivas_error get_frequency( +static ivas_error get_bin_frequency( RenderConfigReader *this, /* i/o : Renderer config reader handle */ float *pResult /* o : Frequency value */ ) @@ -774,19 +776,19 @@ static ivas_error get_frequency( hiRes = 0; refine = 0; - if ( ( error = read_code_word( this, RC_LUT_FREQ, pResult ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_code_word( this, RC_LUT_FREQ, pResult ) ) != IVAS_ERR_OK ) { return error; } - if ( ( error = read_bool( this, &hiRes ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_bool( this, &hiRes ) ) != IVAS_ERR_OK ) { return error; } if ( hiRes ) { - if ( ( error = read_bits( this, &refine, 4 ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_bits( this, &refine, 4 ) ) != IVAS_ERR_OK ) { return error; } @@ -797,10 +799,10 @@ static ivas_error get_frequency( } /*-----------------------------------------------------------------------------------------* - * Function get_dsr() + * Function get_bin_dsr() * Gets a DSR value *-----------------------------------------------------------------------------------------*/ -static ivas_error get_dsr( +static ivas_error get_bin_dsr( RenderConfigReader *this, /* i/o : Renderer config reader handle */ float *pResult /* o : DSR value */ ) @@ -808,7 +810,7 @@ static ivas_error get_dsr( ivas_error error; float value; - if ( ( error = read_code_word( this, RC_LUT_DSR, &value ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_code_word( this, RC_LUT_DSR, &value ) ) != IVAS_ERR_OK ) { return error; } @@ -818,11 +820,11 @@ static ivas_error get_dsr( } /*-----------------------------------------------------------------------------------------* - * Function get_distance() + * Function get_bin_distance() * Gets a distance value (in meters) *-----------------------------------------------------------------------------------------*/ -static ivas_error get_distance( +static ivas_error get_bin_distance( RenderConfigReader *this, /* i/o : Render config reader handle */ uint16_t isSmall, /* i : Flag indicating a small distance */ float *pResult /* o : Distance value */ @@ -832,7 +834,7 @@ static ivas_error get_distance( float value; uint32_t flag; - if ( ( error = read_code_word( this, RC_LUT_METERS, pResult ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_code_word( this, RC_LUT_METERS, pResult ) ) != IVAS_ERR_OK ) { return error; } @@ -840,7 +842,7 @@ static ivas_error get_distance( if ( isSmall == false ) { /* addHectometers flag */ - if ( ( error = read_bool( this, &flag ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_bool( this, &flag ) ) != IVAS_ERR_OK ) { return error; } @@ -848,14 +850,14 @@ static ivas_error get_distance( if ( flag == true ) { /* Hectometers */ - if ( ( error = read_code_word( this, RC_LUT_HECTOMETERS, &value ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_code_word( this, RC_LUT_HECTOMETERS, &value ) ) != IVAS_ERR_OK ) { return error; } *pResult += value * 100.0f; /* addKilometers flag */ - if ( ( error = read_bool( this, &flag ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_bool( this, &flag ) ) != IVAS_ERR_OK ) { return error; } @@ -863,14 +865,14 @@ static ivas_error get_distance( while ( flag == true ) { /* Kilometers */ - if ( ( error = read_code_word( this, RC_LUT_KILOMETERS, &value ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_code_word( this, RC_LUT_KILOMETERS, &value ) ) != IVAS_ERR_OK ) { return error; } *pResult += value * 1000.0f; /* addKilometers flag */ - if ( ( error = read_bool( this, &flag ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_bool( this, &flag ) ) != IVAS_ERR_OK ) { return error; } @@ -879,14 +881,14 @@ static ivas_error get_distance( } /* addCentimeters flag */ - if ( ( error = read_bool( this, &flag ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_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 ) + if ( ( error = read_bin_code_word( this, RC_LUT_CENTIMETERS, &value ) ) != IVAS_ERR_OK ) { return error; } @@ -897,18 +899,18 @@ static ivas_error get_distance( } /*-----------------------------------------------------------------------------------------* - * Function get_absorption() + * Function get_bin_absorption() * Gets an absorption value *-----------------------------------------------------------------------------------------*/ -static ivas_error get_absorption( +static ivas_error get_bin_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 ) + if ( ( error = read_bin_code_word( this, RC_LUT_ABSORPTION, pResult ) ) != IVAS_ERR_OK ) { return error; } @@ -916,6 +918,34 @@ static ivas_error get_absorption( return IVAS_ERR_OK; } +/*-----------------------------------------------------------------------------------------* + * Function read_txt_bool() + * Reads a boolean value from a line + *-----------------------------------------------------------------------------------------*/ +static ivas_error read_txt_bool( + const char *pLine, /* i : String to read from */ + uint32_t *pTarget /* o : Output pointer */ +) +{ + char value[8]; + + if ( sscanf( pLine, "%8s", (char *) &value ) != 1 ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + + if ( strcmp( value, "TRUE" ) == 0 ) + { + *pTarget = TRUE; + return IVAS_ERR_OK; + } + if ( strcmp( value, "FALSE" ) == 0 ) + { + *pTarget = FALSE; + return IVAS_ERR_OK; + } + return IVAS_ERR_INVALID_RENDER_CONFIG; +} #else /*-----------------------------------------------------------------------------------------* * Function read_bool() @@ -950,6 +980,60 @@ static int16_t read_bool( } #endif +#ifdef CONTROL_METADATA_REVERB +/*-----------------------------------------------------------------------------------------* + * Function read_txt_vector() + * + * Reads a vector value from a line + *-----------------------------------------------------------------------------------------*/ + +static int16_t read_txt_vector( + char *pLine, /* i : String to read from */ + const uint32_t length, /* i : Number of expected vector elements */ + float *pTarget /* o : Output vector pointer */ +) +{ + char *tmp; + uint16_t n; + uint16_t count; + + n = (int16_t) sscanf( pLine, "[%s", pLine ); + if ( n == 0 ) + { + return true; + } + + /* Additional comma to make parsing easier */ + pLine[strlen( pLine ) - 1] = ','; + + tmp = pLine; + /* Count # of commas to determine vector length */ + for ( n = 0; tmp[n]; tmp[n] == ',' ? n++ : *tmp++ ) + ; + + count = n; + + tmp = pLine; + + /* Check for maximum vector length */ + if ( n != length ) + { + return true; + } + + for ( n = 0; n < count; n++ ) + { + if ( (int16_t) sscanf( tmp, "%f,", &pTarget[n] ) != 1 ) + { + return true; + } + + tmp = strchr( tmp, ',' ) + 1; + } + + return false; +} +#else /*-----------------------------------------------------------------------------------------* * Function read_vector() * @@ -958,7 +1042,7 @@ static int16_t read_bool( static int16_t read_vector( char *pLine, /* i : String to read from */ - const int16_t length, /* i : Number of expected vector elements */ + const int32_t length, /* i : Number of expected vector elements */ float *pTarget /* o : Output vector pointer */ ) { @@ -1002,7 +1086,7 @@ static int16_t read_vector( return false; } - +#endif /*-----------------------------------------------------------------------------------------* * Function strip_spaces_upper() @@ -1189,6 +1273,8 @@ ivas_error RenderConfigReader_open( pSelf = calloc( sizeof( RenderConfigReader ), 1 ); pSelf->pConfigFile = pConfigFile; + pSelf->pFG = NULL; + pSelf->pAE = NULL; *ppRenderConfigReader = pSelf; return IVAS_ERR_OK; @@ -1196,13 +1282,13 @@ ivas_error RenderConfigReader_open( /*------------------------------------------------------------------------------------------* - * RenderConfigReader_readReverb() + * RenderConfigReader_readBinReverb() * * Reads the binary reverb configuration from a file *------------------------------------------------------------------------------------------*/ #ifdef CONTROL_METADATA_REVERB -static ivas_error RenderConfigReader_readReverb( +static ivas_error RenderConfigReader_readBinReverb( const char *pReverbConfigPath, /* i : Reverb configuration file path */ RenderConfigReader *pRenderConfigReader /* i/o : RenderConfigReader handle */ ) @@ -1245,7 +1331,7 @@ static ivas_error RenderConfigReader_readReverb( /****************************/ /* Read the presence flag */ /****************************/ - if ( ( error = read_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) { return error; } @@ -1261,7 +1347,7 @@ static ivas_error RenderConfigReader_readReverb( /****************************/ /* Number of frequency grids */ - if ( ( error = get_count_or_index( pRenderConfigReader, &pRenderConfigReader->nFG ) ) != IVAS_ERR_OK ) + if ( ( error = get_bin_count_or_index( pRenderConfigReader, &pRenderConfigReader->nFG ) ) != IVAS_ERR_OK ) { return error; } @@ -1275,14 +1361,14 @@ static ivas_error RenderConfigReader_readReverb( /* Initialize memory pointers to allow safe freeing ico errors */ for ( n = 0; n < pRenderConfigReader->nFG; n++ ) { - pRenderConfigReader->pFG[n].pFc = 0; + pRenderConfigReader->pFG[n].pFc = NULL; } for ( n = 0; n < pRenderConfigReader->nFG; n++ ) { /* Read the representation method */ value = 0; - if ( ( error = read_bits( pRenderConfigReader, &value, 2 ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_bits( pRenderConfigReader, &value, 2 ) ) != IVAS_ERR_OK ) { return error; } @@ -1291,7 +1377,7 @@ static ivas_error RenderConfigReader_readReverb( switch ( value ) { case FREQ_GRID_MODE_INDIVIDUAL_FREQUENCIES: - if ( ( error = get_count_or_index( pRenderConfigReader, &pRenderConfigReader->pFG[n].nrBands ) ) != IVAS_ERR_OK ) + if ( ( error = get_bin_count_or_index( pRenderConfigReader, &pRenderConfigReader->pFG[n].nrBands ) ) != IVAS_ERR_OK ) { return error; } @@ -1303,14 +1389,14 @@ static ivas_error RenderConfigReader_readReverb( /* Read the individual frequencies */ for ( m = 0; m < pRenderConfigReader->pFG[n].nrBands; m++ ) { - if ( ( error = get_frequency( pRenderConfigReader, &pRenderConfigReader->pFG[n].pFc[m] ) ) != IVAS_ERR_OK ) + if ( ( error = get_bin_frequency( pRenderConfigReader, &pRenderConfigReader->pFG[n].pFc[m] ) ) != IVAS_ERR_OK ) { return error; } } break; case FREQ_GRID_MODE_START_HOP_AMOUNT: - if ( ( error = get_count_or_index( pRenderConfigReader, &pRenderConfigReader->pFG[n].nrBands ) ) != IVAS_ERR_OK ) + if ( ( error = get_bin_count_or_index( pRenderConfigReader, &pRenderConfigReader->pFG[n].nrBands ) ) != IVAS_ERR_OK ) { return error; } @@ -1320,12 +1406,12 @@ static ivas_error RenderConfigReader_readReverb( return IVAS_ERR_FAILED_ALLOC; } /* Read the first frequency */ - if ( ( error = get_frequency( pRenderConfigReader, &pRenderConfigReader->pFG[n].pFc[0] ) ) != IVAS_ERR_OK ) + if ( ( error = get_bin_frequency( pRenderConfigReader, &pRenderConfigReader->pFG[n].pFc[0] ) ) != IVAS_ERR_OK ) { return error; } /* Read frequency hop from LUT */ - if ( ( error = read_code_word( pRenderConfigReader, RC_LUT_FREQ_HOP, &freqHop ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_code_word( pRenderConfigReader, RC_LUT_FREQ_HOP, &freqHop ) ) != IVAS_ERR_OK ) { return error; } @@ -1338,7 +1424,7 @@ static ivas_error RenderConfigReader_readReverb( case FREQ_GRID_MODE_DEFAULT_BANDING: /* Read the default grid ID */ value = 0; - if ( ( error = read_bits( pRenderConfigReader, &value, 4 ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_bits( pRenderConfigReader, &value, 4 ) ) != IVAS_ERR_OK ) { return error; } @@ -1386,21 +1472,21 @@ static ivas_error RenderConfigReader_readReverb( m = 0; /* Read sub-grid flag */ - if ( ( error = read_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) { return error; } if ( value != false ) { /* Read the sub-grid offset */ - if ( ( error = read_bits( pRenderConfigReader, &m, 3 ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_bits( pRenderConfigReader, &m, 3 ) ) != IVAS_ERR_OK ) { return error; } /* Read the sub-grid length */ subGridLen = 0; - if ( ( error = read_bits( pRenderConfigReader, &subGridLen, 6 ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_bits( pRenderConfigReader, &subGridLen, 6 ) ) != IVAS_ERR_OK ) { return error; } @@ -1434,7 +1520,7 @@ static ivas_error RenderConfigReader_readReverb( /**********************************/ /* Number of acoustic environments */ - if ( ( error = get_count_or_index( pRenderConfigReader, &pRenderConfigReader->nAE ) ) != IVAS_ERR_OK ) + if ( ( error = get_bin_count_or_index( pRenderConfigReader, &pRenderConfigReader->nAE ) ) != IVAS_ERR_OK ) { return IVAS_ERR_INVALID_RENDER_CONFIG; } @@ -1448,23 +1534,23 @@ static ivas_error RenderConfigReader_readReverb( /* Initialize memory pointers to allow safe freeing ico errors */ for ( n = 0; n < pRenderConfigReader->nAE; n++ ) { - pRenderConfigReader->pAE[n].pRT60 = 0; - pRenderConfigReader->pAE[n].pDSR = 0; + pRenderConfigReader->pAE[n].pRT60 = NULL; + pRenderConfigReader->pAE[n].pDSR = NULL; #ifdef CONTROL_METADATA_EARLY_REFLECTIONS - pRenderConfigReader->pAE[n].pEarlyReflections = 0; + pRenderConfigReader->pAE[n].pEarlyReflections = NULL; #endif } for ( n = 0; n < pRenderConfigReader->nAE; n++ ) { /* Read the AE ID */ - if ( ( error = get_id( pRenderConfigReader, &pRenderConfigReader->pAE[n].id ) ) != IVAS_ERR_OK ) + if ( ( error = get_bin_id( pRenderConfigReader, &pRenderConfigReader->pAE[n].id ) ) != IVAS_ERR_OK ) { return error; } /* Read the frequency grid ID */ - if ( ( error = get_count_or_index( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) + if ( ( error = get_bin_count_or_index( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) { return error; } @@ -1489,21 +1575,21 @@ static ivas_error RenderConfigReader_readReverb( } /* Read the values */ - if ( ( error = get_duration( pRenderConfigReader, &pRenderConfigReader->pAE[n].preDelay ) ) != IVAS_ERR_OK ) + if ( ( error = get_bin_duration( pRenderConfigReader, &pRenderConfigReader->pAE[n].preDelay ) ) != IVAS_ERR_OK ) { return error; } for ( m = 0; m < pRenderConfigReader->pAE[n].pFG->nrBands; m++ ) { - if ( ( error = get_duration( pRenderConfigReader, &pRenderConfigReader->pAE[n].pRT60[m] ) ) != IVAS_ERR_OK ) + if ( ( error = get_bin_duration( pRenderConfigReader, &pRenderConfigReader->pAE[n].pRT60[m] ) ) != IVAS_ERR_OK ) { return IVAS_ERR_INVALID_RENDER_CONFIG; } } for ( m = 0; m < pRenderConfigReader->pAE[n].pFG->nrBands; m++ ) { - if ( ( error = get_dsr( pRenderConfigReader, &pRenderConfigReader->pAE[n].pDSR[m] ) ) != IVAS_ERR_OK ) + if ( ( error = get_bin_dsr( pRenderConfigReader, &pRenderConfigReader->pAE[n].pDSR[m] ) ) != IVAS_ERR_OK ) { return IVAS_ERR_INVALID_RENDER_CONFIG; } @@ -1511,7 +1597,7 @@ static ivas_error RenderConfigReader_readReverb( #ifdef CONTROL_METADATA_EARLY_REFLECTIONS /* Has early reflections */ - if ( ( error = read_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) { return error; } @@ -1523,45 +1609,35 @@ static ivas_error RenderConfigReader_readReverb( } /* Room sizes */ - if ( ( error = get_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.x ) ) != IVAS_ERR_OK ) + if ( ( error = get_bin_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 ) + if ( ( error = get_bin_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 ) + if ( ( error = get_bin_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 ) + if ( ( error = get_bin_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 ) + for ( k = 0; k < N_ABS_COEFFS; k++ ) { - 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_bin_absorption( pRenderConfigReader, &pRenderConfigReader->pAE[n].pEarlyReflections->pAbsCoeff[k] ) ) != IVAS_ERR_OK ) { - if ( ( error = get_absorption( pRenderConfigReader, &pRenderConfigReader->pAE[n].pEarlyReflections->pAbsCoeff[m][k] ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } } /* Has listener origin */ - if ( ( error = read_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) { return error; } @@ -1573,15 +1649,15 @@ static ivas_error RenderConfigReader_readReverb( return IVAS_ERR_FAILED_ALLOC; } - if ( ( error = read_bits( pRenderConfigReader, &signx, 1 ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_bits( pRenderConfigReader, &signx, 1 ) ) != IVAS_ERR_OK ) { return error; } - if ( ( error = read_bits( pRenderConfigReader, &signy, 1 ) ) != IVAS_ERR_OK ) + if ( ( error = read_bin_bits( pRenderConfigReader, &signy, 1 ) ) != IVAS_ERR_OK ) { return error; } - if ( ( error = get_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->x ) ) != IVAS_ERR_OK ) + if ( ( error = get_bin_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->x ) ) != IVAS_ERR_OK ) { return error; } @@ -1589,7 +1665,7 @@ static ivas_error RenderConfigReader_readReverb( { pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->x *= -1.0f; } - if ( ( error = get_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y ) ) != IVAS_ERR_OK ) + if ( ( error = get_bin_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->y ) ) != IVAS_ERR_OK ) { return error; } @@ -1597,7 +1673,7 @@ 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 ) + if ( ( error = get_bin_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin->z ) ) != IVAS_ERR_OK ) { return error; } @@ -1639,6 +1715,15 @@ ivas_error RenderConfigReader_read( ivas_error error; int32_t params_length; int32_t length; + uint32_t i, idx; + char *pToken; + FREQ_GRID_MODE fgMode; + float freqHop; + uint32_t acIdx; + uint32_t defGridId, defGridLen, defGridSubGrid, defGridOffset, defGridNrBands; + const float *pDefGrid; + uint32_t hasER; + float erTemp[N_ABS_COEFFS]; #else int16_t nBandsInput; int16_t nVectorsMissing; @@ -1650,7 +1735,9 @@ ivas_error RenderConfigReader_read( pConfig_str = (char *) calloc( file_size + 1, sizeof( char ) ); pParams = (char *) calloc( file_size + 1, sizeof( char ) ); pTemp = (char *) calloc( file_size + 1, sizeof( char ) ); -#ifndef CONTROL_METADATA_REVERB +#ifdef CONTROL_METADATA_REVERB + acIdx = 0; +#else nBandsInput = hRenderConfig->room_acoustics.nBands; nVectorsMissing = N_REVERB_VECTORS; #endif @@ -1684,9 +1771,393 @@ ivas_error RenderConfigReader_read( strip_spaces_upper( pParams ); to_upper( chapter ); + pToken = strtok( chapter, ":" ); /* interpret params */ -#ifndef CONTROL_METADATA_REVERB +#ifdef CONTROL_METADATA_REVERB + if ( strcmp( chapter, "ROOMACOUSTICS" ) == 0 ) + { + params_idx = 0; + pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); + hRenderConfig->room_acoustics.override = TRUE; + + while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) + { + params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); +#ifdef DEBUGGING + fprintf( stderr, " PARAM: %s -> %s\n", item, pValue ); +#endif + if ( strcmp( item, "FREQUENCYGRIDCOUNT" ) == 0 ) + { + /* Read the number of frequency grids */ + if ( !sscanf( pValue, "%d", &pRenderConfigReader->nFG ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + /* Allocate memory for the frequency grids */ + if ( ( pRenderConfigReader->pFG = (FrequencyGrid *) malloc( pRenderConfigReader->nFG * sizeof( FrequencyGrid ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + } + else if ( strcmp( item, "ACOUSTICENVIRONMENTCOUNT" ) == 0 ) + { + /* Read the number of acoustic environments */ + if ( !sscanf( pValue, "%d", &pRenderConfigReader->nAE ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + /* Allocate memory for the acoustic environments array */ + if ( ( pRenderConfigReader->pAE = (AcousticEnv *) malloc( pRenderConfigReader->nAE * sizeof( AcousticEnv ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + /* Initialize memory pointers to allow for safe freeing */ + for ( acIdx = 0; acIdx < pRenderConfigReader->nAE; acIdx++ ) + { + pRenderConfigReader->pAE[acIdx].pRT60 = NULL; + pRenderConfigReader->pAE[acIdx].pDSR = NULL; +#ifdef CONTROL_METADATA_EARLY_REFLECTIONS + pRenderConfigReader->pAE[acIdx].pEarlyReflections = NULL; +#endif + } + acIdx = 0; + } + } + free( pValue ); + } + if ( strcmp( pToken, "FREQUENCYGRID" ) == 0 ) + { + if ( pRenderConfigReader->pFG == NULL ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + + idx = strtol( strtok( NULL, ":" ), NULL, 0 ); + if ( idx >= pRenderConfigReader->nFG ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + + fgMode = FREQ_GRID_MODE_UNKNOWN; + params_idx = 0; + 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 ); +#ifdef DEBUGGING + fprintf( stderr, " PARAM: %s -> %s\n", item, pValue ); +#endif + if ( strcmp( item, "METHOD" ) == 0 ) + { + if ( strcmp( pValue, "INDIVIDUALFREQUENCIES" ) == 0 ) + { + fgMode = FREQ_GRID_MODE_INDIVIDUAL_FREQUENCIES; + } + else if ( strcmp( pValue, "INDIVIDUALFREQUENCIES" ) == 0 ) + { + fgMode = FREQ_GRID_MODE_START_HOP_AMOUNT; + } + else if ( strcmp( pValue, "DEFAULTBANDING" ) == 0 ) + { + fgMode = FREQ_GRID_MODE_DEFAULT_BANDING; + } + } + /* Read number of bands for individual frequency, start-hop-amount mode */ + else if ( strcmp( item, "NBANDS" ) == 0 ) + { + if ( fgMode != FREQ_GRID_MODE_INDIVIDUAL_FREQUENCIES && fgMode != FREQ_GRID_MODE_START_HOP_AMOUNT ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + if ( !sscanf( pValue, "%d", &pRenderConfigReader->pFG[idx].nrBands ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + /* Allocate memory for the center frequency array */ + if ( ( pRenderConfigReader->pFG[idx].pFc = (float *) malloc( pRenderConfigReader->pFG[idx].nrBands * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + } + else if ( strcmp( item, "FREQUENCIES" ) == 0 ) + { + if ( fgMode != FREQ_GRID_MODE_INDIVIDUAL_FREQUENCIES || pRenderConfigReader->pFG[idx].nrBands == 0 || pRenderConfigReader->pFG[idx].pFc == NULL ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + /* Read the individual frequencies */ + if ( read_txt_vector( pValue, pRenderConfigReader->pFG[idx].nrBands, pRenderConfigReader->pFG[idx].pFc ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } + else if ( strcmp( item, "STARTFREQUENCY" ) == 0 ) + { + if ( fgMode != FREQ_GRID_MODE_START_HOP_AMOUNT || pRenderConfigReader->pFG[idx].nrBands == 0 || pRenderConfigReader->pFG[idx].pFc == NULL ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + if ( !sscanf( pValue, "%f", &pRenderConfigReader->pFG[idx].pFc[0] ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } + else if ( strcmp( item, "FREQUENCYHOP" ) == 0 ) + { + if ( fgMode != FREQ_GRID_MODE_START_HOP_AMOUNT || pRenderConfigReader->pFG[idx].nrBands == 0 || pRenderConfigReader->pFG[idx].pFc == NULL || pRenderConfigReader->pFG[idx].pFc[0] == 0.0f ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + if ( !sscanf( pValue, "%f", &freqHop ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + /* Fill up the center frequency array */ + for ( i = 1; i < pRenderConfigReader->pFG[idx].nrBands; i++ ) + { + pRenderConfigReader->pFG[idx].pFc[i] = pRenderConfigReader->pFG[idx].pFc[i - 1] * freqHop; + } + } + /* Handle default grids, with optional sub-grids */ + else if ( strcmp( item, "DEFAULTGRID" ) == 0 ) + { + if ( !sscanf( pValue, "%d", &defGridId ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + + switch ( defGridId ) + { + case 0: + defGridLen = sizeof( defaultFrequencyGrid_0 ) / sizeof( defaultFrequencyGrid_0[0] ); + pDefGrid = defaultFrequencyGrid_0; + break; + case 1: + defGridLen = sizeof( defaultFrequencyGrid_1 ) / sizeof( defaultFrequencyGrid_1[0] ); + pDefGrid = defaultFrequencyGrid_1; + break; + case 2: + defGridLen = sizeof( defaultFrequencyGrid_2 ) / sizeof( defaultFrequencyGrid_2[0] ); + pDefGrid = defaultFrequencyGrid_2; + break; + case 3: + defGridLen = sizeof( defaultFrequencyGrid_3 ) / sizeof( defaultFrequencyGrid_3[0] ); + pDefGrid = defaultFrequencyGrid_3; + break; + case 4: + defGridLen = sizeof( defaultFrequencyGrid_4 ) / sizeof( defaultFrequencyGrid_4[0] ); + pDefGrid = defaultFrequencyGrid_4; + break; + case 5: + defGridLen = sizeof( defaultFrequencyGrid_5 ) / sizeof( defaultFrequencyGrid_5[0] ); + pDefGrid = defaultFrequencyGrid_5; + break; + case 6: + defGridLen = sizeof( defaultFrequencyGrid_6 ) / sizeof( defaultFrequencyGrid_6[0] ); + pDefGrid = defaultFrequencyGrid_6; + break; + case 7: + defGridLen = sizeof( defaultFrequencyGrid_7 ) / sizeof( defaultFrequencyGrid_7[0] ); + pDefGrid = defaultFrequencyGrid_7; + break; + case 8: + defGridLen = sizeof( defaultFrequencyGrid_8 ) / sizeof( defaultFrequencyGrid_8[0] ); + pDefGrid = defaultFrequencyGrid_8; + break; + default: + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + /* Handle sub-grids */ + defGridSubGrid = FALSE; + defGridOffset = 0; + defGridNrBands = defGridLen; + + + while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) + { + if ( strcmp( item, "DEFAULTGRIDOFFSET" ) == 0 ) + { + defGridSubGrid = TRUE; + if ( !sscanf( pValue, "%d", &defGridOffset ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } + else if ( strcmp( item, "DEFAULTGRIDNRBANDS" ) == 0 ) + { + defGridSubGrid = TRUE; + if ( !sscanf( pValue, "%d", &defGridNrBands ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } + else + { + break; + } + params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); + } + + if ( defGridSubGrid == TRUE && defGridOffset + defGridNrBands > defGridLen ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + pRenderConfigReader->pFG[idx].nrBands = defGridNrBands; + + /* Allocate memory for the center frequency array */ + if ( ( pRenderConfigReader->pFG[idx].pFc = (float *) malloc( defGridNrBands * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + + /* Copy the ROM content to the frequency grid*/ + for ( i = 0; i < defGridNrBands; i++ ) + { + pRenderConfigReader->pFG[idx].pFc[i] = pDefGrid[defGridOffset + i]; + } + } +#ifdef DEBUGGING + else + { + fprintf( stderr, "Unsupported configuration property %s\n", item ); + } +#endif + } + free( pValue ); + } + /* Handle multiple acoustic environments */ + if ( strcmp( pToken, "ACOUSTICENVIRONMENT" ) == 0 ) + { + if ( pRenderConfigReader->pAE == NULL || acIdx >= pRenderConfigReader->nAE ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + idx = strtol( strtok( NULL, ":" ), NULL, 0 ); + pRenderConfigReader->pAE->id = idx; + + params_idx = 0; + 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 ); +#ifdef DEBUGGING + fprintf( stderr, " PARAM: %s -> %s\n", item, pValue ); +#endif + /* Frequency grid index */ + if ( strcmp( item, "FREQUENCYGRIDINDEX" ) == 0 ) + { + if ( !sscanf( pValue, "%d", &i ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + if ( i > pRenderConfigReader->nFG || &pRenderConfigReader->pFG[i] == NULL ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + pRenderConfigReader->pAE[acIdx].pFG = &pRenderConfigReader->pFG[i]; + + /* Allocate memory for RT60 and DSR arrays */ + if ( ( pRenderConfigReader->pAE[acIdx].pRT60 = (float *) malloc( pRenderConfigReader->pAE[acIdx].pFG->nrBands * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + + if ( ( pRenderConfigReader->pAE[acIdx].pDSR = (float *) malloc( pRenderConfigReader->pAE[acIdx].pFG->nrBands * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + + } + /* Pre-delay */ + if ( strcmp( item, "PREDELAY" ) == 0 ) + { + if ( !sscanf( pValue, "%f", &pRenderConfigReader->pAE[acIdx].preDelay ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } + /* RT60 */ + if ( strcmp( item, "RT60" ) == 0 ) + { + if ( read_txt_vector( pValue, pRenderConfigReader->pFG[idx].nrBands, pRenderConfigReader->pAE[acIdx].pRT60 ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } + /* DSR */ + if ( strcmp( item, "DSR" ) == 0 ) + { + if ( read_txt_vector( pValue, pRenderConfigReader->pFG[idx].nrBands, pRenderConfigReader->pAE[acIdx].pDSR ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } +#ifdef CONTROL_METADATA_EARLY_REFLECTIONS + if ( strcmp( item, "HASEARLYREFLECTIONS" ) == 0 ) + { + if ( read_txt_bool( pValue, &hasER ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + if ( hasER == TRUE ) + { + if ( ( pRenderConfigReader->pAE[acIdx].pEarlyReflections = (EarlyReflectionsConfig *) malloc( sizeof( EarlyReflectionsConfig ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) + { + if ( strcmp( item, "EARLYREFLECTIONSSIZE" ) == 0 ) + { + if ( read_txt_vector( pValue, 3, erTemp ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + pRenderConfigReader->pAE[acIdx].pEarlyReflections->dimensions.x = erTemp[0]; + pRenderConfigReader->pAE[acIdx].pEarlyReflections->dimensions.y = erTemp[1]; + pRenderConfigReader->pAE[acIdx].pEarlyReflections->dimensions.z = erTemp[2]; + } + else if ( strcmp( item, "ABSORPTIONCOEFFS" ) == 0 ) + { + if ( read_txt_vector( pValue, N_ABS_COEFFS, erTemp ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + + for ( i = 0; i < N_ABS_COEFFS; i++ ) + { + pRenderConfigReader->pAE[acIdx].pEarlyReflections->pAbsCoeff[i] = erTemp[i]; + } + } + else if ( strcmp( item, "LISTENERORIGIN" ) ) + { + if ( read_txt_vector( pValue, 3, erTemp ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + if ( ( pRenderConfigReader->pAE[acIdx].pEarlyReflections->pListenerOrigin = malloc( sizeof( IVAS_VECTOR3 ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + pRenderConfigReader->pAE[acIdx].pEarlyReflections->pListenerOrigin->x = erTemp[0]; + pRenderConfigReader->pAE[acIdx].pEarlyReflections->pListenerOrigin->y = erTemp[1]; + pRenderConfigReader->pAE[acIdx].pEarlyReflections->pListenerOrigin->z = erTemp[2]; + } + else + { + break; + } + params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); + } + } + } +#endif + } + free( pValue ); + acIdx++; + } +#else if ( strcmp( chapter, "ROOMACOUSTICS" ) == 0 ) { params_idx = 0; @@ -1760,10 +2231,8 @@ ivas_error RenderConfigReader_read( fprintf( stderr, "Reverb config: number of bands changed but configuration vectors missing\n" ); } } - else if ( strcmp( chapter, "GENERAL" ) == 0 && strlen( pParams ) != 0 ) -#else - if ( strcmp( chapter, "GENERAL" ) == 0 && strlen( pParams ) != 0 ) #endif + else if ( strcmp( chapter, "GENERAL" ) == 0 && strlen( pParams ) != 0 ) { params_idx = 0; pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); @@ -1796,7 +2265,7 @@ ivas_error RenderConfigReader_read( strncpy( pCombinedName, pRenderConfigPath, length ); strcpy( pCombinedName + length, pValue ); - if ( ( error = RenderConfigReader_readReverb( pCombinedName, pRenderConfigReader ) ) != IVAS_ERR_OK ) + if ( ( error = RenderConfigReader_readBinReverb( pCombinedName, pRenderConfigReader ) ) != IVAS_ERR_OK ) { errorHandler( item, ERROR_VALUE_INVALID ); } @@ -1824,7 +2293,11 @@ ivas_error RenderConfigReader_read( } else if ( strcmp( item, "DIRECTIVITY" ) == 0 ) { +#ifdef CONTROL_METADATA_REVERB + if ( read_txt_vector( pValue, 3, hRenderConfig->directivity ) ) +#else if ( read_vector( pValue, 3, hRenderConfig->directivity ) ) +#endif { errorHandler( item, ERROR_VALUE_INVALID ); } diff --git a/scripts/reverb/acoustic_environment_recreation.cfg b/scripts/reverb/acoustic_environment_recreation.cfg index 02a9c722e7..fed625c878 100644 --- a/scripts/reverb/acoustic_environment_recreation.cfg +++ b/scripts/reverb/acoustic_environment_recreation.cfg @@ -1,3 +1,6 @@ +[roomAcoustics] +frequencyGridCount = 1 +acousticEnvironmentCount = 1 [frequencyGrid:0] nBands = 31 method = individualFrequencies diff --git a/scripts/testv/rend_config_renderer.cfg b/scripts/testv/rend_config_renderer.cfg index 3cd52373da..a4576eb70d 100644 --- a/scripts/testv/rend_config_renderer.cfg +++ b/scripts/testv/rend_config_renderer.cfg @@ -1,15 +1,22 @@ [roomAcoustics] -nBands = 31; +frequencyGridCount = 1; +acousticEnvironmentCount = 1; -fc = [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]; +[frequencyGrid:0] +method = individualFrequencies; +nBands = 31; +frequencies = [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]; +[acousticEnvironment:0] +frequencyGridIndex = 0; +predelay = 0.1; 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, @@ -24,8 +31,3 @@ dsr = [1.9952632e-08, 1.9952632e-08, 1.2589251e-08, 1.5848926e-08, 1.2589251e-0 5.01187e-07, 6.3095763e-07, 6.3095763e-07, 6.3095763e-07, 5.01187e-07, 2.511887e-07, 1.2589251e-07, 1e-07, 6.309576e-08, 3.1622776e-08, 2.511887e-08]; -acousticPreDelay = 0.016; -inputPreDelay = 0.1; - -[general] -reverbFile = rend_config_renderer.dat; -- GitLab From 7af197198a137afd9b2f77f3ffefc52ab4647cff Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Mon, 17 Jul 2023 15:36:41 +0200 Subject: [PATCH 02/46] Support for multiple acoustic environments plus early reflections in text-based configuration (prototype) --- lib_util/render_config_reader.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 8d5a60f689..4e87b7ab86 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -1826,7 +1826,7 @@ ivas_error RenderConfigReader_read( } free( pValue ); } - if ( strcmp( pToken, "FREQUENCYGRID" ) == 0 ) + else if ( strcmp( pToken, "FREQUENCYGRID" ) == 0 ) { if ( pRenderConfigReader->pFG == NULL ) { @@ -1836,6 +1836,9 @@ ivas_error RenderConfigReader_read( idx = strtol( strtok( NULL, ":" ), NULL, 0 ); if ( idx >= pRenderConfigReader->nFG ) { +#ifdef DEBUGGING + fprintf( stderr, "Frequency grid with index %d does not fit into the frequency grid array of %d elements.\n", idx, pRenderConfigReader->nFG ); +#endif return IVAS_ERR_INVALID_RENDER_CONFIG; } @@ -1854,7 +1857,7 @@ ivas_error RenderConfigReader_read( { fgMode = FREQ_GRID_MODE_INDIVIDUAL_FREQUENCIES; } - else if ( strcmp( pValue, "INDIVIDUALFREQUENCIES" ) == 0 ) + else if ( strcmp( pValue, "STARTHOPAMOUNT" ) == 0 ) { fgMode = FREQ_GRID_MODE_START_HOP_AMOUNT; } @@ -2027,7 +2030,7 @@ ivas_error RenderConfigReader_read( free( pValue ); } /* Handle multiple acoustic environments */ - if ( strcmp( pToken, "ACOUSTICENVIRONMENT" ) == 0 ) + else if ( strcmp( pToken, "ACOUSTICENVIRONMENT" ) == 0 ) { if ( pRenderConfigReader->pAE == NULL || acIdx >= pRenderConfigReader->nAE ) { -- GitLab From 181ba0cc443d5502e44583b68635c67227cfbfdf Mon Sep 17 00:00:00 2001 From: Jan Brouwer Date: Mon, 17 Jul 2023 15:57:22 +0200 Subject: [PATCH 03/46] add missing RenderConfigReader_getAcousticEnvironment() in renderer --- apps/decoder.c | 23 ++++++++++++++--------- apps/renderer.c | 15 +++++++++++++++ lib_util/render_config_reader.c | 4 +++- 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index cb70713e59..5ecc575d4d 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -570,21 +570,26 @@ int main( } #ifdef CONTROL_METADATA_REVERB - if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, ACOUSTIC_ENVIRONMENT_ID, &renderConfig.room_acoustics ) ) == IVAS_ERR_OK ) + if ( arg.outputFormat == IVAS_DEC_OUTPUT_BINAURAL_ROOM_REVERB ) { - if ( RenderConfigReader_checkValues( &renderConfig ) != IVAS_ERR_OK ) + if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, ACOUSTIC_ENVIRONMENT_ID, &renderConfig.room_acoustics ) ) == IVAS_ERR_OK ) { - fprintf( stderr, "Invalid reverberation configuration parameters\n\n" ); + if ( RenderConfigReader_checkValues( &renderConfig ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Invalid reverberation configuration parameters\n\n" ); + goto cleanup; + } + } + else if ( error != IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING ) + { + fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", ACOUSTIC_ENVIRONMENT_ID ); goto cleanup; } + renderConfig.room_acoustics.override = true; } - else if ( error != IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING ) - { - fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", ACOUSTIC_ENVIRONMENT_ID ); - goto cleanup; - } -#endif +#else renderConfig.room_acoustics.override = true; +#endif if ( ( error = IVAS_DEC_FeedRenderConfig( hIvasDec, renderConfig ) ) != IVAS_ERR_OK ) { diff --git a/apps/renderer.c b/apps/renderer.c index 822aea634d..a6b9e3ff7a 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -786,6 +786,21 @@ int main( if ( args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { +#ifdef CONTROL_METADATA_REVERB + if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, ACOUSTIC_ENVIRONMENT_ID, &renderConfig.room_acoustics ) ) == IVAS_ERR_OK ) + { + if ( RenderConfigReader_checkValues( &renderConfig ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Invalid reverberation configuration parameters\n\n" ); + exit( -1 ); + } + } + else if ( error != IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING ) + { + fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", ACOUSTIC_ENVIRONMENT_ID ); + exit( -1 ); + } +#endif renderConfig.room_acoustics.override = TRUE; } diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 8d5a60f689..a22712c5a8 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -1273,8 +1273,10 @@ ivas_error RenderConfigReader_open( pSelf = calloc( sizeof( RenderConfigReader ), 1 ); pSelf->pConfigFile = pConfigFile; +#ifdef CONTROL_METADATA_REVERB pSelf->pFG = NULL; pSelf->pAE = NULL; +#endif *ppRenderConfigReader = pSelf; return IVAS_ERR_OK; @@ -1771,10 +1773,10 @@ ivas_error RenderConfigReader_read( strip_spaces_upper( pParams ); to_upper( chapter ); - pToken = strtok( chapter, ":" ); /* interpret params */ #ifdef CONTROL_METADATA_REVERB + pToken = strtok( chapter, ":" ); if ( strcmp( chapter, "ROOMACOUSTICS" ) == 0 ) { params_idx = 0; -- GitLab From 9bd470aa10dc1638c3ba27271c3f521e85a4671a Mon Sep 17 00:00:00 2001 From: Jan Brouwer Date: Mon, 17 Jul 2023 16:27:23 +0200 Subject: [PATCH 04/46] finish modification of pEarlyReflections->pAbsCoeff --- lib_util/render_config_reader.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 51152ead72..ac96e8e76e 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -1622,7 +1622,6 @@ static ivas_error RenderConfigReader_readBinReverb( return IVAS_ERR_FAILED_ALLOC; } /* Initialize memory pointers to allow safe freeing ico eg errors */ - pRenderConfigReader->pAE[n].pEarlyReflections->pAbsCoeff = 0; pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin = 0; /* Room sizes */ @@ -2444,7 +2443,6 @@ void RenderConfigReader_close( if ( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections != NULL ) { free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections->pListenerOrigin ); - free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections->pAbsCoeff ); free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections ); } #endif -- GitLab From 33920dcfaf64df71450c15641893b2d96ce22ae4 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Mon, 17 Jul 2023 17:10:41 +0200 Subject: [PATCH 05/46] Support for multiple acoustic environments plus early reflections in text-based configuration (prototype) --- lib_util/render_config_reader.c | 146 ++++++++++++++++++++++++++++---- 1 file changed, 128 insertions(+), 18 deletions(-) diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 41664819a6..34a268c289 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -1619,9 +1619,7 @@ static ivas_error RenderConfigReader_readBinReverb( { return IVAS_ERR_FAILED_ALLOC; } - /* Initialize memory pointers to allow safe freeing ico eg errors */ - pRenderConfigReader->pAE[n].pEarlyReflections->pAbsCoeff = 0; - pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin = 0; + pRenderConfigReader->pAE[n].pEarlyReflections->pListenerOrigin = NULL; /* Room sizes */ if ( ( error = get_bin_distance( pRenderConfigReader, true, &pRenderConfigReader->pAE[n].pEarlyReflections->dimensions.x ) ) != IVAS_ERR_OK ) @@ -1735,10 +1733,15 @@ ivas_error RenderConfigReader_read( FREQ_GRID_MODE fgMode; float freqHop; uint32_t acIdx; - uint32_t defGridId, defGridLen, defGridSubGrid, defGridOffset, defGridNrBands; + uint32_t defGridId, defGridLen, defGridOffset, defGridNrBands; const float *pDefGrid; - uint32_t hasER; float erTemp[N_ABS_COEFFS]; + uint32_t roomAcHasFgCount, roomAcHasAcEnvCount; + uint32_t fgHasMethod, fgHasNBands, fgHasFreqs, fgHasDefaultGrid, fgHasStartFreq, fgHasFreqHop; + uint32_t aeHasFgIdx, aeHasPredelay, aeHasRt60, aeHasDsr; +#ifdef CONTROL_METADATA_EARLY_REFLECTIONS + uint32_t aeHasER, aeHasERsize, aeHasERabs; +#endif #else int16_t nBandsInput; int16_t nVectorsMissing; @@ -1752,6 +1755,7 @@ ivas_error RenderConfigReader_read( pTemp = (char *) calloc( file_size + 1, sizeof( char ) ); #ifdef CONTROL_METADATA_REVERB acIdx = 0; + roomAcHasFgCount = roomAcHasAcEnvCount = FALSE; #else nBandsInput = hRenderConfig->room_acoustics.nBands; nVectorsMissing = N_REVERB_VECTORS; @@ -1814,12 +1818,14 @@ ivas_error RenderConfigReader_read( if ( !sscanf( pValue, "%d", &pRenderConfigReader->nFG ) ) { errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; } /* Allocate memory for the frequency grids */ if ( ( pRenderConfigReader->pFG = (FrequencyGrid *) malloc( pRenderConfigReader->nFG * sizeof( FrequencyGrid ) ) ) == NULL ) { return IVAS_ERR_FAILED_ALLOC; } + roomAcHasFgCount = TRUE; } else if ( strcmp( item, "ACOUSTICENVIRONMENTCOUNT" ) == 0 ) { @@ -1827,6 +1833,7 @@ ivas_error RenderConfigReader_read( if ( !sscanf( pValue, "%d", &pRenderConfigReader->nAE ) ) { errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; } /* Allocate memory for the acoustic environments array */ if ( ( pRenderConfigReader->pAE = (AcousticEnv *) malloc( pRenderConfigReader->nAE * sizeof( AcousticEnv ) ) ) == NULL ) @@ -1843,8 +1850,23 @@ ivas_error RenderConfigReader_read( #endif } acIdx = 0; + roomAcHasAcEnvCount = TRUE; } } +#ifdef DEBUGGING + if ( roomAcHasFgCount == FALSE ) + { + fprintf( stderr, "Renderer configuration: frequencyGridCount missing from 'roomAcoustics' chapter.\n\n" ); + } + if ( roomAcHasAcEnvCount == FALSE ) + { + fprintf( stderr, "Renderer configuration: acousticEnvironmentCount missing from 'roomAcoustics' chapter.\n\n" ); + } +#endif + if ( roomAcHasFgCount == FALSE || roomAcHasAcEnvCount == FALSE ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } free( pValue ); } else if ( strcmp( pToken, "FREQUENCYGRID" ) == 0 ) @@ -1863,6 +1885,7 @@ ivas_error RenderConfigReader_read( return IVAS_ERR_INVALID_RENDER_CONFIG; } + fgHasMethod = fgHasNBands = fgHasFreqs = fgHasDefaultGrid = fgHasStartFreq = fgHasFreqHop = FALSE; fgMode = FREQ_GRID_MODE_UNKNOWN; params_idx = 0; pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); @@ -1886,6 +1909,7 @@ ivas_error RenderConfigReader_read( { fgMode = FREQ_GRID_MODE_DEFAULT_BANDING; } + fgHasMethod = TRUE; } /* Read number of bands for individual frequency, start-hop-amount mode */ else if ( strcmp( item, "NBANDS" ) == 0 ) @@ -1897,12 +1921,14 @@ ivas_error RenderConfigReader_read( if ( !sscanf( pValue, "%d", &pRenderConfigReader->pFG[idx].nrBands ) ) { errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; } /* Allocate memory for the center frequency array */ if ( ( pRenderConfigReader->pFG[idx].pFc = (float *) malloc( pRenderConfigReader->pFG[idx].nrBands * sizeof( float ) ) ) == NULL ) { return IVAS_ERR_FAILED_ALLOC; } + fgHasNBands = TRUE; } else if ( strcmp( item, "FREQUENCIES" ) == 0 ) { @@ -1914,7 +1940,9 @@ ivas_error RenderConfigReader_read( if ( read_txt_vector( pValue, pRenderConfigReader->pFG[idx].nrBands, pRenderConfigReader->pFG[idx].pFc ) ) { errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; } + fgHasFreqs = TRUE; } else if ( strcmp( item, "STARTFREQUENCY" ) == 0 ) { @@ -1925,7 +1953,9 @@ ivas_error RenderConfigReader_read( if ( !sscanf( pValue, "%f", &pRenderConfigReader->pFG[idx].pFc[0] ) ) { errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; } + fgHasStartFreq = TRUE; } else if ( strcmp( item, "FREQUENCYHOP" ) == 0 ) { @@ -1936,12 +1966,14 @@ ivas_error RenderConfigReader_read( if ( !sscanf( pValue, "%f", &freqHop ) ) { errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; } /* Fill up the center frequency array */ for ( i = 1; i < pRenderConfigReader->pFG[idx].nrBands; i++ ) { pRenderConfigReader->pFG[idx].pFc[i] = pRenderConfigReader->pFG[idx].pFc[i - 1] * freqHop; } + fgHasFreqHop = TRUE; } /* Handle default grids, with optional sub-grids */ else if ( strcmp( item, "DEFAULTGRID" ) == 0 ) @@ -1949,6 +1981,7 @@ ivas_error RenderConfigReader_read( if ( !sscanf( pValue, "%d", &defGridId ) ) { errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; } switch ( defGridId ) @@ -1992,28 +2025,28 @@ ivas_error RenderConfigReader_read( default: return IVAS_ERR_INVALID_RENDER_CONFIG; } + fgHasDefaultGrid = TRUE; + /* Handle sub-grids */ - defGridSubGrid = FALSE; defGridOffset = 0; defGridNrBands = defGridLen; - while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) { if ( strcmp( item, "DEFAULTGRIDOFFSET" ) == 0 ) { - defGridSubGrid = TRUE; if ( !sscanf( pValue, "%d", &defGridOffset ) ) { errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; } } else if ( strcmp( item, "DEFAULTGRIDNRBANDS" ) == 0 ) { - defGridSubGrid = TRUE; if ( !sscanf( pValue, "%d", &defGridNrBands ) ) { errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; } } else @@ -2023,8 +2056,11 @@ ivas_error RenderConfigReader_read( params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); } - if ( defGridSubGrid == TRUE && defGridOffset + defGridNrBands > defGridLen ) + if ( defGridOffset + defGridNrBands > defGridLen ) { +#ifdef DEBUGGING + fprintf( stderr, "Rendering configuration: Invalid default banding selection.\n\n" ); +#endif return IVAS_ERR_INVALID_RENDER_CONFIG; } pRenderConfigReader->pFG[idx].nrBands = defGridNrBands; @@ -2048,6 +2084,16 @@ ivas_error RenderConfigReader_read( } #endif } + if ( fgHasMethod == FALSE || + ( fgMode == FREQ_GRID_MODE_INDIVIDUAL_FREQUENCIES && ( fgHasFreqs == FALSE || fgHasNBands == FALSE ) ) || + ( fgMode == FREQ_GRID_MODE_DEFAULT_BANDING && fgHasDefaultGrid == FALSE ) || + ( fgMode == FREQ_GRID_MODE_START_HOP_AMOUNT && ( fgHasStartFreq == FALSE || fgHasFreqHop == FALSE || fgHasNBands == FALSE ) ) ) + { +#ifdef DEBUGGING + fprintf( stderr, "Rendering configuration: inconsistent default frequency band configuration.\n\n" ); +#endif + return IVAS_ERR_INVALID_RENDER_CONFIG; + } free( pValue ); } /* Handle multiple acoustic environments */ @@ -2060,6 +2106,10 @@ ivas_error RenderConfigReader_read( idx = strtol( strtok( NULL, ":" ), NULL, 0 ); pRenderConfigReader->pAE->id = idx; + aeHasFgIdx = aeHasPredelay = aeHasRt60 = aeHasDsr = FALSE; +#ifdef CONTROL_METADATA_EARLY_REFLECTIONS + aeHasER = aeHasERsize = aeHasERabs = FALSE; +#endif params_idx = 0; pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) @@ -2074,6 +2124,7 @@ ivas_error RenderConfigReader_read( if ( !sscanf( pValue, "%d", &i ) ) { errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; } if ( i > pRenderConfigReader->nFG || &pRenderConfigReader->pFG[i] == NULL ) { @@ -2091,45 +2142,53 @@ ivas_error RenderConfigReader_read( { return IVAS_ERR_FAILED_ALLOC; } - + aeHasFgIdx = TRUE; } /* Pre-delay */ - if ( strcmp( item, "PREDELAY" ) == 0 ) + else if ( strcmp( item, "PREDELAY" ) == 0 ) { if ( !sscanf( pValue, "%f", &pRenderConfigReader->pAE[acIdx].preDelay ) ) { errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; } + aeHasPredelay = TRUE; } /* RT60 */ - if ( strcmp( item, "RT60" ) == 0 ) + else if ( strcmp( item, "RT60" ) == 0 ) { if ( read_txt_vector( pValue, pRenderConfigReader->pFG[idx].nrBands, pRenderConfigReader->pAE[acIdx].pRT60 ) ) { errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; } + aeHasRt60 = TRUE; } /* DSR */ - if ( strcmp( item, "DSR" ) == 0 ) + else if ( strcmp( item, "DSR" ) == 0 ) { if ( read_txt_vector( pValue, pRenderConfigReader->pFG[idx].nrBands, pRenderConfigReader->pAE[acIdx].pDSR ) ) { errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; } + aeHasDsr = TRUE; } #ifdef CONTROL_METADATA_EARLY_REFLECTIONS - if ( strcmp( item, "HASEARLYREFLECTIONS" ) == 0 ) + else if ( strcmp( item, "HASEARLYREFLECTIONS" ) == 0 ) { - if ( read_txt_bool( pValue, &hasER ) ) + if ( read_txt_bool( pValue, &aeHasER ) ) { errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; } - if ( hasER == TRUE ) + if ( aeHasER == TRUE ) { if ( ( pRenderConfigReader->pAE[acIdx].pEarlyReflections = (EarlyReflectionsConfig *) malloc( sizeof( EarlyReflectionsConfig ) ) ) == NULL ) { return IVAS_ERR_FAILED_ALLOC; } + aeHasERsize = aeHasERabs = FALSE; while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) { if ( strcmp( item, "EARLYREFLECTIONSSIZE" ) == 0 ) @@ -2137,28 +2196,33 @@ ivas_error RenderConfigReader_read( if ( read_txt_vector( pValue, 3, erTemp ) ) { errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; } pRenderConfigReader->pAE[acIdx].pEarlyReflections->dimensions.x = erTemp[0]; pRenderConfigReader->pAE[acIdx].pEarlyReflections->dimensions.y = erTemp[1]; pRenderConfigReader->pAE[acIdx].pEarlyReflections->dimensions.z = erTemp[2]; + aeHasERsize = TRUE; } else if ( strcmp( item, "ABSORPTIONCOEFFS" ) == 0 ) { if ( read_txt_vector( pValue, N_ABS_COEFFS, erTemp ) ) { errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; } for ( i = 0; i < N_ABS_COEFFS; i++ ) { pRenderConfigReader->pAE[acIdx].pEarlyReflections->pAbsCoeff[i] = erTemp[i]; } + aeHasERabs = TRUE; } else if ( strcmp( item, "LISTENERORIGIN" ) ) { if ( read_txt_vector( pValue, 3, erTemp ) ) { errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; } if ( ( pRenderConfigReader->pAE[acIdx].pEarlyReflections->pListenerOrigin = malloc( sizeof( IVAS_VECTOR3 ) ) ) == NULL ) { @@ -2177,7 +2241,52 @@ ivas_error RenderConfigReader_read( } } #endif +#ifdef DEBUGGING + else + { + fprintf( stderr, "Unsupported configuration property %s\n", item ); + } +#endif + } +#ifdef DEBUGGING + if ( aeHasFgIdx == FALSE ) + { + fprintf( stderr, "Renderer configuration: frequencyGridIndex missing from 'acousticEnvironment' %d.\n\n", acIdx ); } + if ( aeHasPredelay == FALSE ) + { + fprintf( stderr, "Renderer configuration: predelay missing from 'acousticEnvironment' %d.\n\n", acIdx ); + } + if ( aeHasRt60 == FALSE ) + { + fprintf( stderr, "Renderer configuration: RT60 missing from 'acousticEnvironment' %d.\n\n", acIdx ); + } + if ( aeHasDsr == FALSE ) + { + fprintf( stderr, "Renderer configuration: DSR missing from 'acousticEnvironment' %d.\n\n", acIdx ); + } +#ifdef CONTROL_METADATA_EARLY_REFLECTIONS + if ( aeHasER == TRUE && aeHasERsize == FALSE ) + { + fprintf( stderr, "Renderer configuration: early reflections room size missing from 'acousticEnvironment' %d.\n\n", acIdx ); + } + if ( aeHasER == TRUE && aeHasERabs == FALSE ) + { + fprintf( stderr, "Renderer configuration: early reflections absorption coeffs missing from 'acousticEnvironment' %d.\n\n", acIdx ); + } +#endif +#endif + if ( aeHasFgIdx == FALSE || aeHasPredelay == FALSE || aeHasRt60 == FALSE || aeHasDsr == FALSE ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } +#ifdef CONTROL_METADATA_EARLY_REFLECTIONS + if ( aeHasER && ( aeHasERsize == FALSE || aeHasERabs == FALSE ) ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } +#endif + free( pValue ); acIdx++; } @@ -2297,6 +2406,7 @@ ivas_error RenderConfigReader_read( if ( ( error = RenderConfigReader_readBinReverb( pCombinedName, pRenderConfigReader ) ) != IVAS_ERR_OK ) { errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; } free( pCombinedName ); } @@ -2318,6 +2428,7 @@ ivas_error RenderConfigReader_read( else { errorHandler( pValue, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; } } else if ( strcmp( item, "DIRECTIVITY" ) == 0 ) @@ -2442,7 +2553,6 @@ void RenderConfigReader_close( if ( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections != NULL ) { free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections->pListenerOrigin ); - free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections->pAbsCoeff ); free( ( *ppRenderConfigReader )->pAE[n].pEarlyReflections ); } #endif -- GitLab From 63246d1afb0d08eea51a605e90ceae70898c9ee9 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Mon, 17 Jul 2023 17:37:46 +0200 Subject: [PATCH 06/46] Support for multiple acoustic environments plus early reflections in text-based configuration (prototype) --- lib_util/render_config_reader.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 4a9eb93bd2..3093aef320 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -96,6 +96,7 @@ typedef struct IVAS_VECTOR3 dimensions; /* Room dimensions [m] */ float pAbsCoeff[N_ABS_COEFFS]; /* Absorption coeffs table */ IVAS_VECTOR3 *pListenerOrigin; /* Listener origin */ + uint32_t lowComplexity; /* Low complexity mode flag */ } EarlyReflectionsConfig; #endif @@ -1638,12 +1639,6 @@ static ivas_error RenderConfigReader_readBinReverb( return error; } - /* Frequency grid ID */ - if ( ( error = get_bin_count_or_index( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) - { - return error; - } - for ( k = 0; k < N_ABS_COEFFS; k++ ) { if ( ( error = get_bin_absorption( pRenderConfigReader, &pRenderConfigReader->pAE[n].pEarlyReflections->pAbsCoeff[k] ) ) != IVAS_ERR_OK ) @@ -1694,6 +1689,12 @@ static ivas_error RenderConfigReader_readBinReverb( return error; } } + + /* Low complexity mode */ + if ( ( error = read_bin_bool( pRenderConfigReader, &pRenderConfigReader->pAE[n].pEarlyReflections->lowComplexity ) ) != IVAS_ERR_OK ) + { + return error; + } } #endif } @@ -2191,6 +2192,8 @@ ivas_error RenderConfigReader_read( { return IVAS_ERR_FAILED_ALLOC; } + pRenderConfigReader->pAE[acIdx].pEarlyReflections->pListenerOrigin = NULL; + pRenderConfigReader->pAE[acIdx].pEarlyReflections->lowComplexity = FALSE; aeHasERsize = aeHasERabs = FALSE; while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) { @@ -2235,6 +2238,14 @@ ivas_error RenderConfigReader_read( pRenderConfigReader->pAE[acIdx].pEarlyReflections->pListenerOrigin->y = erTemp[1]; pRenderConfigReader->pAE[acIdx].pEarlyReflections->pListenerOrigin->z = erTemp[2]; } + else if ( strcmp( item, "LOWCOMPLEXITY") ) + { + if ( read_txt_bool( pValue, &pRenderConfigReader->pAE[acIdx].pEarlyReflections->lowComplexity ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + } else { break; -- GitLab From 0fff1f91a1d684d8d99590ff3ecd02cb07174745 Mon Sep 17 00:00:00 2001 From: Jan Brouwer Date: Mon, 17 Jul 2023 17:51:22 +0200 Subject: [PATCH 07/46] add acoustic environment ID command line options (-aeID) to decoder and renderer --- apps/decoder.c | 27 +++++++++++++++++++-------- apps/renderer.c | 35 ++++++++++++++++++++++++++++------- 2 files changed, 47 insertions(+), 15 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 5ecc575d4d..00fd397cd5 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -80,10 +80,6 @@ static #define IVAS_PUBLIC_ORIENT_TRK_REF_VEC ( 3 ) #define IVAS_PUBLIC_ORIENT_TRK_REF_VEC_LEV ( 4 ) -#ifdef CONTROL_METADATA_REVERB -#define ACOUSTIC_ENVIRONMENT_ID ( 0 ) -#endif - #ifdef VARIABLE_SPEED_DECODING #define VARIABLE_SPEED_FETCH_FRAMESIZE_MS 20 #endif @@ -146,6 +142,10 @@ typedef struct #endif #endif +#ifdef CONTROL_METADATA_REVERB + uint16_t acousticEnvironmentId; +#endif + } DecArguments; @@ -572,7 +572,7 @@ int main( #ifdef CONTROL_METADATA_REVERB if ( arg.outputFormat == IVAS_DEC_OUTPUT_BINAURAL_ROOM_REVERB ) { - if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, ACOUSTIC_ENVIRONMENT_ID, &renderConfig.room_acoustics ) ) == IVAS_ERR_OK ) + if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, arg.acousticEnvironmentId, &renderConfig.room_acoustics ) ) == IVAS_ERR_OK ) { if ( RenderConfigReader_checkValues( &renderConfig ) != IVAS_ERR_OK ) { @@ -580,9 +580,9 @@ int main( goto cleanup; } } - else if ( error != IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING ) + else { - fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", ACOUSTIC_ENVIRONMENT_ID ); + fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", arg.acousticEnvironmentId ); goto cleanup; } renderConfig.room_acoustics.override = true; @@ -928,6 +928,10 @@ static bool parseCmdlIVAS_dec( #endif #endif +#ifdef CONTROL_METADATA_REVERB + arg->acousticEnvironmentId = 0; +#endif + /*-----------------------------------------------------------------* * Initialization *-----------------------------------------------------------------*/ @@ -1275,7 +1279,13 @@ static bool parseCmdlIVAS_dec( fprintf( stdout, "Complexity levels 1 and 2 will be defined after characterisation - default to level 3 (full functionality).\n" ); } } - +#ifdef CONTROL_METADATA_REVERB + else if ( strcmp( argv_to_upper, "-AEID" ) == 0 ) + { + ++i; + arg->acousticEnvironmentId = (int16_t) atoi( argv[i++] ); + } +#endif /*-----------------------------------------------------------------* * Option not recognized *-----------------------------------------------------------------*/ @@ -1452,6 +1462,7 @@ static void usage_dec( void ) fprintf( stdout, " Currently, all values default to level 3 (full functionality).\n" ); #endif fprintf( stdout, "-exof File : External orientation file for external orientation trajectory\n" ); + fprintf( stdout, "-aeid ID : Acoustic environment ID (number >= 0) for BINAURAL_ROOM_REVERB output configuration\n" ); #ifdef DEBUG_MODE_INFO #ifdef DEBUG_MODE_INFO_TWEAK fprintf( stdout, "-info : specify subfolder name for debug output\n" ); diff --git a/apps/renderer.c b/apps/renderer.c index a6b9e3ff7a..b38c5e7b15 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -61,10 +61,6 @@ #define RENDERER_MAX_METADATA_LENGTH 8192 #define RENDERER_MAX_METADATA_LINE_LENGTH 1024 -#ifdef CONTROL_METADATA_REVERB -#define ACOUSTIC_ENVIRONMENT_ID 0 -#endif - #if !defined( DEBUGGING ) && !defined( WMOPS ) static #endif @@ -161,6 +157,9 @@ typedef struct float lfeConfigElevation; bool lfeCustomRoutingEnabled; char inLfePanningMatrixFile[RENDERER_MAX_CLI_ARG_LENGTH]; +#ifdef CONTROL_METADATA_REVERB + uint16_t acousticEnvironmentId; +#endif } CmdlnArgs; typedef enum @@ -185,6 +184,9 @@ typedef enum CmdLnOptionId_inputGain, CmdLnOptionId_referenceVectorFile, CmdLnOptionId_exteriorOrientationFile, +#ifdef CONTROL_METADATA_REVERB + CmdLnOptionId_acousticEnvironmentId +#endif } CmdLnOptionId; static const CmdLnParser_Option cliOptions[] = { @@ -306,6 +308,14 @@ static const CmdLnParser_Option cliOptions[] = { .matchShort = "exof", .description = "External orientation trajectory file for simulation of external orientations", }, +#ifdef CONTROL_METADATA_REVERB + { + .id = CmdLnOptionId_acousticEnvironmentId, + .match = "acoustic_environment_id", + .matchShort = "aeid", + .description = "Acoustic environment ID (number >= 0) for BINAURAL_ROOM_REVERB output configuration", + }, +#endif }; @@ -787,7 +797,7 @@ int main( if ( args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { #ifdef CONTROL_METADATA_REVERB - if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, ACOUSTIC_ENVIRONMENT_ID, &renderConfig.room_acoustics ) ) == IVAS_ERR_OK ) + if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, args.acousticEnvironmentId, &renderConfig.room_acoustics ) ) == IVAS_ERR_OK ) { if ( RenderConfigReader_checkValues( &renderConfig ) != IVAS_ERR_OK ) { @@ -795,9 +805,9 @@ int main( exit( -1 ); } } - else if ( error != IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING ) + else { - fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", ACOUSTIC_ENVIRONMENT_ID ); + fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", args.acousticEnvironmentId ); exit( -1 ); } #endif @@ -1923,6 +1933,11 @@ static CmdlnArgs defaultArgs( args.lfeCustomRoutingEnabled = false; clearString( args.inLfePanningMatrixFile ); + +#ifdef CONTROL_METADATA_REVERB + args.acousticEnvironmentId = 0; +#endif + return args; } @@ -2052,6 +2067,12 @@ static void parseOption( exit( -1 ); } break; +#ifdef CONTROL_METADATA_REVERB + case CmdLnOptionId_acousticEnvironmentId: + assert( numOptionValues == 1 ); + args->acousticEnvironmentId = (int16_t) strtol( optionValues[0], NULL, 10 ); + break; +#endif default: assert( 0 && "This should be unreachable - all command line options should be explicitly handled." ); break; -- GitLab From 17a2a7a0aa4f500b9d2f7dc7db4ab282268d92e1 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Tue, 18 Jul 2023 08:54:51 +0200 Subject: [PATCH 08/46] Support for multiple acoustic environments plus early reflections in text-based configuration (prototype) --- lib_util/render_config_reader.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 3093aef320..5dcd17705c 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -1856,6 +1856,12 @@ ivas_error RenderConfigReader_read( acIdx = 0; roomAcHasAcEnvCount = TRUE; } +#ifdef DEBUGGING + else + { + fprintf( stderr, "Rendering configuration: unsupported property %s\n", item ); + } +#endif } #ifdef DEBUGGING if ( roomAcHasFgCount == FALSE ) @@ -1884,7 +1890,7 @@ ivas_error RenderConfigReader_read( if ( idx >= pRenderConfigReader->nFG ) { #ifdef DEBUGGING - fprintf( stderr, "Frequency grid with index %d does not fit into the frequency grid array of %d elements.\n", idx, pRenderConfigReader->nFG ); + fprintf( stderr, "Rendering configuration: frequency grid with index %d does not fit into the frequency grid array of %d elements.\n", idx, pRenderConfigReader->nFG ); #endif return IVAS_ERR_INVALID_RENDER_CONFIG; } @@ -2055,6 +2061,9 @@ ivas_error RenderConfigReader_read( } else { +#ifdef DEBUGGING + fprintf( stderr, "Rendering configuration: unsupported property %s\n", item ); +#endif break; } params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); @@ -2063,7 +2072,7 @@ ivas_error RenderConfigReader_read( if ( defGridOffset + defGridNrBands > defGridLen ) { #ifdef DEBUGGING - fprintf( stderr, "Rendering configuration: Invalid default banding selection.\n\n" ); + fprintf( stderr, "Rendering configuration: invalid default banding selection.\n\n" ); #endif return IVAS_ERR_INVALID_RENDER_CONFIG; } @@ -2084,7 +2093,7 @@ ivas_error RenderConfigReader_read( #ifdef DEBUGGING else { - fprintf( stderr, "Unsupported configuration property %s\n", item ); + fprintf( stderr, "Rendering configuration: unsupported configuration property %s\n", item ); } #endif } @@ -2248,6 +2257,9 @@ ivas_error RenderConfigReader_read( } else { +#ifdef DEBUGGING + fprintf( stderr, "Rendering configuration: unsupported property %s\n", item ); +#endif break; } params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); @@ -2258,7 +2270,7 @@ ivas_error RenderConfigReader_read( #ifdef DEBUGGING else { - fprintf( stderr, "Unsupported configuration property %s\n", item ); + fprintf( stderr, "Rendering configuration: unsupported configuration property %s\n", item ); } #endif } @@ -2286,7 +2298,7 @@ ivas_error RenderConfigReader_read( } if ( aeHasER == TRUE && aeHasERabs == FALSE ) { - fprintf( stderr, "Renderer configuration: early reflections absorption coeffs missing from 'acousticEnvironment' %d.\n\n", acIdx ); + fprintf( stderr, "Renderer configuration: early reflections absorption coefficients missing from 'acousticEnvironment' %d.\n\n", acIdx ); } #endif #endif -- GitLab From 25132b7cb2d243e3a26bd23e2fc3564787a4493a Mon Sep 17 00:00:00 2001 From: Jan Brouwer Date: Tue, 18 Jul 2023 10:08:15 +0200 Subject: [PATCH 09/46] update remaining render configuration files to new format --- .../rend_config_hospital_patientroom.cfg | 31 ++++++++++--------- scripts/testv/rend_config_recreation.cfg | 31 ++++++++++--------- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/scripts/testv/rend_config_hospital_patientroom.cfg b/scripts/testv/rend_config_hospital_patientroom.cfg index 07b8614d5d..cb24dc7615 100644 --- a/scripts/testv/rend_config_hospital_patientroom.cfg +++ b/scripts/testv/rend_config_hospital_patientroom.cfg @@ -1,15 +1,22 @@ -[roomAcoustics] -nBands = 31; +[roomAcoustics] +frequencyGridCount = 1; +acousticEnvironmentCount = 1; -fc = [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]; +[frequencyGrid:0] +method = individualFrequencies; +nBands = 31; +frequencies = [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]; +[acousticEnvironment:0] +frequencyGridIndex = 0; +predelay = 0.08163; rt60 = [0.81275, 0.61888, 0.45111, 0.34672, 0.46683, 0.53987, 0.61874, 0.70291, 0.66657, 0.73037, 0.75090, 0.72470, 0.75486, 0.75857, 0.76844, 0.74999, 0.77622, 0.78227, 0.77441, 0.74688, 0.73521, 0.73782, 0.71928, 0.71708, 0.71465, 0.60592, 0.52031, 0.51768, 0.52102, 0.37956, @@ -20,9 +27,5 @@ dsr = [0.00019952621, 0.00019952621, 7.9432844e-05, 5.0118702e-05, 7.943284e-06 6.3095763e-06, 6.3095763e-06, 6.3095763e-06, 6.3095763e-06, 6.3095763e-06, 3.1622776e-06, 3.1622776e-06, 3.1622776e-06, 6.3095763e-07, 3.1622776e-07, 3.1622776e-07]; - -acousticPreDelay = 0.016; -inputPreDelay = 0.08163; - [general] reverbFile = rend_config_hospital_patientroom.dat; diff --git a/scripts/testv/rend_config_recreation.cfg b/scripts/testv/rend_config_recreation.cfg index 43c060eab6..2806b3f791 100644 --- a/scripts/testv/rend_config_recreation.cfg +++ b/scripts/testv/rend_config_recreation.cfg @@ -1,15 +1,22 @@ -[roomAcoustics] -nBands = 31; +[roomAcoustics] +frequencyGridCount = 1; +acousticEnvironmentCount = 1; -fc = [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]; +[frequencyGrid:0] +method = individualFrequencies; +nBands = 31; +frequencies = [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]; +[acousticEnvironment:0] +frequencyGridIndex = 0; +predelay = 0.43031; rt60 = [4.51916, 4.89553, 4.83276, 5.00198, 5.34468, 5.76026, 6.36818, 6.95503, 7.27557, 7.62559, 8.08892, 8.16002, 8.13900, 8.17919, 8.16280, 8.46226, 9.61806, 9.93048, 9.81353, 8.59340, 8.38885, 8.36823, 6.51845, 3.76089, 3.75374, 3.57451, 1.28724, 1.22174, 1.22448, 1.71631, @@ -20,9 +27,5 @@ dsr = [1e-06, 7.943284e-07, 1e-06, 1e-06, 1.5848925e-06, 1.9952631e-06, 3.16227 3.1622776e-06, 2.511887e-06, 7.943284e-07, 6.3095763e-07, 6.3095763e-07, 5.01187e-08, 1.2589251e-08, 1.2589251e-08, 1.2589265e-09, 1.2589266e-11, 3.981075e-12]; - -acousticPreDelay = 0.016; -inputPreDelay = 0.43031; - [general] reverbFile = rend_config_recreation.dat; -- GitLab From 843d4f4fcf5c62570c407444e082eeca64e81695 Mon Sep 17 00:00:00 2001 From: Jan Brouwer Date: Tue, 18 Jul 2023 11:24:19 +0200 Subject: [PATCH 10/46] rename render configuration file option "reverbFile" to "binaryConfig" --- lib_util/render_config_reader.c | 4 ++-- scripts/testv/rend_config_hospital_patientroom.cfg | 2 +- scripts/testv/rend_config_recreation.cfg | 2 +- scripts/testv/rend_config_renderer.cfg | 2 ++ 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 5dcd17705c..26ae5cf9ef 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -2391,7 +2391,7 @@ ivas_error RenderConfigReader_read( } } #endif - else if ( strcmp( chapter, "GENERAL" ) == 0 && strlen( pParams ) != 0 ) + else if ( strcmp( chapter, "GENERAL" ) == 0 ) { params_idx = 0; pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); @@ -2406,7 +2406,7 @@ ivas_error RenderConfigReader_read( fprintf( stderr, " PARAM: %s -> %s\n", item, pValue ); #endif #ifdef CONTROL_METADATA_REVERB - if ( strcmp( item, "REVERBFILE" ) == 0 ) + if ( strcmp( item, "BINARYCONFIG" ) == 0 ) { /* get correct case reverb configuration file path */ sscanf( pTemp + params_idx, "%*[^=] = %[^;];", pValue ); diff --git a/scripts/testv/rend_config_hospital_patientroom.cfg b/scripts/testv/rend_config_hospital_patientroom.cfg index cb24dc7615..9ec11a318d 100644 --- a/scripts/testv/rend_config_hospital_patientroom.cfg +++ b/scripts/testv/rend_config_hospital_patientroom.cfg @@ -28,4 +28,4 @@ dsr = [0.00019952621, 0.00019952621, 7.9432844e-05, 5.0118702e-05, 7.943284e-06 3.1622776e-07]; [general] -reverbFile = rend_config_hospital_patientroom.dat; +binaryConfig = rend_config_hospital_patientroom.dat; diff --git a/scripts/testv/rend_config_recreation.cfg b/scripts/testv/rend_config_recreation.cfg index 2806b3f791..e39a4b3fc7 100644 --- a/scripts/testv/rend_config_recreation.cfg +++ b/scripts/testv/rend_config_recreation.cfg @@ -28,4 +28,4 @@ dsr = [1e-06, 7.943284e-07, 1e-06, 1e-06, 1.5848925e-06, 1.9952631e-06, 3.16227 3.981075e-12]; [general] -reverbFile = rend_config_recreation.dat; +binaryConfig = rend_config_recreation.dat; diff --git a/scripts/testv/rend_config_renderer.cfg b/scripts/testv/rend_config_renderer.cfg index a4576eb70d..af52833136 100644 --- a/scripts/testv/rend_config_renderer.cfg +++ b/scripts/testv/rend_config_renderer.cfg @@ -31,3 +31,5 @@ dsr = [1.9952632e-08, 1.9952632e-08, 1.2589251e-08, 1.5848926e-08, 1.2589251e-0 5.01187e-07, 6.3095763e-07, 6.3095763e-07, 6.3095763e-07, 5.01187e-07, 2.511887e-07, 1.2589251e-07, 1e-07, 6.309576e-08, 3.1622776e-08, 2.511887e-08]; +[general] +binaryConfig = rend_config_renderer.dat; -- GitLab From 5f50e3315cc0fcae4f000de6cf485e1f899ae3a3 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Tue, 18 Jul 2023 16:28:46 +0200 Subject: [PATCH 11/46] Merge from philips/contribution-38-control-metadata-reverb with Ericsson directivity updates --- Workspace_msvc/render_config_reader_bin.h | 41 +++++++++++++++++++++++ lib_util/render_config_reader.h | 1 - scripts/reverb/text_to_binary_payload.py | 14 +++++--- 3 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 Workspace_msvc/render_config_reader_bin.h diff --git a/Workspace_msvc/render_config_reader_bin.h b/Workspace_msvc/render_config_reader_bin.h new file mode 100644 index 0000000000..3ceee1ac5e --- /dev/null +++ b/Workspace_msvc/render_config_reader_bin.h @@ -0,0 +1,41 @@ +/****************************************************************************************************** + + (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef RENDER_CONFIG_READER_H +#define RENDER_CONFIG_READER_H + +#ifdef CONTROL_METADATA_REVERB + +#include "common_api_types.h" + +#endif +#endif \ No newline at end of file diff --git a/lib_util/render_config_reader.h b/lib_util/render_config_reader.h index 252338526e..2f3fdf3265 100644 --- a/lib_util/render_config_reader.h +++ b/lib_util/render_config_reader.h @@ -65,7 +65,6 @@ ivas_error RenderConfigReader_checkValues( #ifdef CONTROL_METADATA_DIRECTIVITY ivas_error RenderConfigReader_getDirectivity( RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ - uint16_t id, /* i : Acoustic environment ID */ float *directivity /* o : directivity */ ); #endif diff --git a/scripts/reverb/text_to_binary_payload.py b/scripts/reverb/text_to_binary_payload.py index 00a10ede85..a67bff20b9 100644 --- a/scripts/reverb/text_to_binary_payload.py +++ b/scripts/reverb/text_to_binary_payload.py @@ -74,11 +74,17 @@ def parse_reverb_text_configuration_and_generate_binary_payload(file): assert len(files_parsed) == 1, 'file {} not successfully parsed'.format(file) # collect dicts of frequency grid, acoustic environment and directivity sections - sections = { key : {} for key in ['frequencyGrid', 'acousticEnvironment', 'directivity' ] } + sections = { key : {} for key in ['roomAcoustics', 'frequencyGrid', 'acousticEnvironment', 'directivity' ] } for section_name in config.sections(): - section, index = section_name.split(':') + if ':' in section_name: + assert section in ['frequencyGrid', 'acousticEnvironment'] + section, index = section_name.split(':') + sections[section][index] = config[section_name] + else: + assert section in ['roomAcoustics', 'directivity'] + sections[section] = config[section_name] assert section in sections, 'unknown section name' - sections[section][index] = config[section_name] + # parse frequency grids nr_bands = [] @@ -146,7 +152,7 @@ def parse_reverb_text_configuration_and_generate_binary_payload(file): if hasDirectivity: for _, dir in sections['directivity'].items(): dir_values = eval_option(dir['directivity']) - data += bitarray(get_angle_code(dir_values[0]) # Directivity inner angle + data += bitarray(get_angle_code(dir_values[0]) # Directivity inner angle + get_angle_code(dir_values[1]) # Directivity outer angle + get_outer_attenuation_code(dir_values[2])) # Directivity outer attenuation -- GitLab From 160e313da35e72a4ffd5e4913108543ec0db4558 Mon Sep 17 00:00:00 2001 From: Marek Szczerba Date: Tue, 18 Jul 2023 16:46:07 +0200 Subject: [PATCH 12/46] Merge from philips/contribution-38-control-metadata-reverb with Ericsson directivity updates --- apps/decoder.c | 4 ++++ apps/renderer.c | 6 +++++- lib_util/render_config_reader.c | 8 +++++--- lib_util/render_config_reader.h | 5 ++++- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 040f7daec8..fc06266475 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -560,7 +560,11 @@ int main( } #ifdef CONTROL_METADATA_REVERB +#ifdef DEBUGGING if ( RenderConfigReader_read( renderConfigReader, arg.renderConfigFilename, &renderConfig ) != IVAS_ERR_OK ) +#else + if ( RenderConfigReader_read( renderConfigReader, arg.renderConfigFilename ) != IVAS_ERR_OK ) +#endif #else if ( RenderConfigReader_read( renderConfigReader, &renderConfig ) != IVAS_ERR_OK ) #endif diff --git a/apps/renderer.c b/apps/renderer.c index b38c5e7b15..9c460a9bec 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -785,7 +785,11 @@ int main( } #ifdef CONTROL_METADATA_REVERB +#ifdef DEBUGGING if ( RenderConfigReader_read( renderConfigReader, args.renderConfigFilePath, &renderConfig ) != IVAS_ERR_OK ) +#else + if ( RenderConfigReader_read( renderConfigReader, args.renderConfigFilePath ) != IVAS_ERR_OK ) +#endif #else if ( RenderConfigReader_read( renderConfigReader, &renderConfig ) != IVAS_ERR_OK ) #endif @@ -801,7 +805,7 @@ int main( { if ( RenderConfigReader_checkValues( &renderConfig ) != IVAS_ERR_OK ) { - fprintf( stderr, "Invalid reverberation configuration parameters\n\n" ); + fprintf( stderr, "Invalid room acoustics configuration parameters\n\n" ); exit( -1 ); } } diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 63aec5b599..8105ce6f8a 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -1794,8 +1794,11 @@ static ivas_error RenderConfigReader_readBinReverb( ivas_error RenderConfigReader_read( #ifdef CONTROL_METADATA_REVERB RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ - const char *pRenderConfigPath, /* i : Renderer configuration file path */ + const char *pRenderConfigPath /* i : Renderer configuration file path */ +#ifdef DEBUGGING + , IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ +#endif #else RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ @@ -1891,7 +1894,6 @@ ivas_error RenderConfigReader_read( { params_idx = 0; pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); - hRenderConfig->room_acoustics.override = TRUE; while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) { @@ -2543,7 +2545,7 @@ ivas_error RenderConfigReader_read( else if ( strcmp( item, "DIRECTIVITY" ) == 0 ) { #ifdef CONTROL_METADATA_REVERB - if ( read_txt_vector( pValue, 3, hRenderConfig->directivity ) ) + if ( read_txt_vector( pValue, 3, pRenderConfigReader->directivity ) ) #else if ( read_vector( pValue, 3, hRenderConfig->directivity ) ) #endif diff --git a/lib_util/render_config_reader.h b/lib_util/render_config_reader.h index 2f3fdf3265..af791ce1a6 100644 --- a/lib_util/render_config_reader.h +++ b/lib_util/render_config_reader.h @@ -74,8 +74,11 @@ ivas_error RenderConfigReader_getDirectivity( ivas_error RenderConfigReader_read( #ifdef CONTROL_METADATA_REVERB RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ - const char *pRenderConfigPath, /* i : Renderer configuration file path */ + const char *pRenderConfigPath /* i : Renderer configuration file path */ +#ifdef DEBUGGING + , IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ +#endif #else RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ -- GitLab From 9653165eff251bf2e218666796dfdc88e52bd735 Mon Sep 17 00:00:00 2001 From: Jan Brouwer Date: Tue, 18 Jul 2023 18:03:42 +0200 Subject: [PATCH 13/46] update text_to_binary_payload.py to make input format more compatible with render configuration files --- ...ustic_environment_hospital_patientroom.cfg | 18 ++++--- .../acoustic_environment_recreation.cfg | 21 ++++---- .../reverb/acoustic_environment_renderer.cfg | 18 ++++--- ...ustic_environment_renderer_directivity.cfg | 22 ++++---- scripts/reverb/text_to_binary_payload.py | 51 +++++++++++-------- 5 files changed, 76 insertions(+), 54 deletions(-) diff --git a/scripts/reverb/acoustic_environment_hospital_patientroom.cfg b/scripts/reverb/acoustic_environment_hospital_patientroom.cfg index 62a4462477..cc7747cd1b 100644 --- a/scripts/reverb/acoustic_environment_hospital_patientroom.cfg +++ b/scripts/reverb/acoustic_environment_hospital_patientroom.cfg @@ -1,5 +1,9 @@ +[roomAcoustics] +frequencyGridCount = 1; +acousticEnvironmentCount = 1; + [frequencyGrid:0] -method = individualFrequencies +method = individualFrequencies; frequencies = [ 20.0, 25.0, 31.5, 40.0, 50.0, 63.0, 80.0, 100.0, @@ -8,21 +12,21 @@ frequencies = [ 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] + 12500.0, 16000.0, 20000.0]; [acousticEnvironment:0] -id = 0 -frequencyGridIndex = 0 -predelay = 0.08163 +id = 0; +frequencyGridIndex = 0; +predelay = 0.08163; rt60 = [ 0.81275, 0.61888, 0.45111, 0.34672, 0.46683, 0.53987, 0.61874, 0.70291, 0.66657, 0.73037, 0.75090, 0.72470, 0.75486, 0.75857, 0.76844, 0.74999, 0.77622, 0.78227, 0.77441, 0.74688, 0.73521, 0.73782, 0.71928, 0.71708, 0.71465, 0.60592, 0.52031, 0.51768, 0.52102, 0.37956, - 0.30786] + 0.30786]; dsr = [ 0.00019952621, 0.00019952621, 7.9432844e-05, 5.0118702e-05, 7.943284e-06, 6.3095763e-06, 6.3095763e-06, 7.943284e-06, 1e-05, 1e-05, 7.943284e-06, 1e-05, 1e-05, 1e-05, 7.943284e-06, 1e-05, 1e-05, 7.943284e-06, 7.943284e-06, 6.3095763e-06, 6.3095763e-06, 6.3095763e-06, 6.3095763e-06, 6.3095763e-06, 6.3095763e-06, 3.1622776e-06, 3.1622776e-06, 3.1622776e-06, 6.3095763e-07, 3.1622776e-07, - 3.1622776e-07] + 3.1622776e-07]; diff --git a/scripts/reverb/acoustic_environment_recreation.cfg b/scripts/reverb/acoustic_environment_recreation.cfg index fed625c878..ec1ee14b7a 100644 --- a/scripts/reverb/acoustic_environment_recreation.cfg +++ b/scripts/reverb/acoustic_environment_recreation.cfg @@ -1,9 +1,10 @@ [roomAcoustics] -frequencyGridCount = 1 -acousticEnvironmentCount = 1 +frequencyGridCount = 1; +acousticEnvironmentCount = 1; + [frequencyGrid:0] -nBands = 31 -method = individualFrequencies +nBands = 31; +method = individualFrequencies; frequencies = [ 20.0, 25.0, 31.5, 40.0, 50.0, 63.0, 80.0, 100.0, @@ -12,20 +13,20 @@ frequencies = [ 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] + 12500.0, 16000.0, 20000.0]; [acousticEnvironment:0] -id = 0 -frequencyGridIndex = 0 -predelay = 0.43031 +id = 0; +frequencyGridIndex = 0; +predelay = 0.43031; rt60 = [ 4.51916, 4.89553, 4.83276, 5.00198, 5.34468, 5.76026, 6.36818, 6.95503, 7.27557, 7.62559, 8.08892, 8.16002, 8.13900, 8.17919, 8.16280, 8.46226, 9.61806, 9.93048, 9.81353, 8.59340, 8.38885, 8.36823, 6.51845, 3.76089, 3.75374, 3.57451, 1.28724, 1.22174, 1.22448, 1.71631, - 2.14343] + 2.14343]; dsr = [ 1e-06, 7.943284e-07, 1e-06, 1e-06, 1.5848925e-06, 1.9952631e-06, 3.1622776e-06, 3.9810707e-06, 6.3095763e-06, 7.943284e-06, 1e-05, 7.943284e-06, 7.943284e-06, 7.943284e-06, 7.943284e-06, 7.943284e-06, 5.01187e-06, 5.01187e-06, 3.9810707e-06, 3.1622776e-06, 3.1622776e-06, 2.511887e-06, 7.943284e-07, 6.3095763e-07, 6.3095763e-07, 5.01187e-08, 1.2589251e-08, 1.2589251e-08, 1.2589265e-09, 1.2589266e-11, - 3.981075e-12] + 3.981075e-12]; diff --git a/scripts/reverb/acoustic_environment_renderer.cfg b/scripts/reverb/acoustic_environment_renderer.cfg index e56f1bd9a8..fffa8d0f26 100644 --- a/scripts/reverb/acoustic_environment_renderer.cfg +++ b/scripts/reverb/acoustic_environment_renderer.cfg @@ -1,5 +1,9 @@ +[roomAcoustics] +frequencyGridCount = 1; +acousticEnvironmentCount = 1; + [frequencyGrid:0] -method = individualFrequencies +method = individualFrequencies; frequencies = [ 20.0, 25.0, 31.5, 40.0, 50.0, 63.0, 80.0, 100.0, @@ -8,12 +12,12 @@ frequencies = [ 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] + 12500.0, 16000.0, 20000.0]; [acousticEnvironment:0] -id = 0 -frequencyGridIndex = 0 -predelay = 0.1 +id = 0; +frequencyGridIndex = 0; +predelay = 0.1; rt60 = [ 1.3622, 1.4486, 1.3168, 1.5787, 1.4766, 1.3954, 1.2889, 1.3462, @@ -22,12 +26,12 @@ rt60 = [ 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] + 0.71945, 0.61682, 0.60031]; dsr = [ 1.9952632e-08, 1.9952632e-08, 1.2589251e-08, 1.5848926e-08, 1.2589251e-08, 1.9952632e-08, 2.511887e-08, 3.9810708e-08, 1e-07, 1.9952633e-07, 3.981071e-07, 6.3095763e-07, 7.943284e-07, 6.3095763e-07, 5.01187e-07, 5.01187e-07, 6.3095763e-07, 6.3095763e-07, 7.943284e-07, 6.3095763e-07, 5.01187e-07, 6.3095763e-07, 6.3095763e-07, 6.3095763e-07, 5.01187e-07, 2.511887e-07, 1.2589251e-07, 1e-07, 6.309576e-08, 3.1622776e-08, - 2.511887e-08] + 2.511887e-08]; diff --git a/scripts/reverb/acoustic_environment_renderer_directivity.cfg b/scripts/reverb/acoustic_environment_renderer_directivity.cfg index 04b99f7f3c..9d15adb547 100644 --- a/scripts/reverb/acoustic_environment_renderer_directivity.cfg +++ b/scripts/reverb/acoustic_environment_renderer_directivity.cfg @@ -1,5 +1,9 @@ +[roomAcoustics] +frequencyGridCount = 1; +acousticEnvironmentCount = 1; + [frequencyGrid:0] -method = individualFrequencies +method = individualFrequencies; frequencies = [ 20.0, 25.0, 31.5, 40.0, 50.0, 63.0, 80.0, 100.0, @@ -8,12 +12,12 @@ frequencies = [ 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] + 12500.0, 16000.0, 20000.0]; [acousticEnvironment:0] -id = 0 -frequencyGridIndex = 0 -predelay = 0.1 +id = 0; +frequencyGridIndex = 0; +predelay = 0.1; rt60 = [ 1.3622, 1.4486, 1.3168, 1.5787, 1.4766, 1.3954, 1.2889, 1.3462, @@ -22,13 +26,13 @@ rt60 = [ 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] + 0.71945, 0.61682, 0.60031]; dsr = [ 1.9952632e-08, 1.9952632e-08, 1.2589251e-08, 1.5848926e-08, 1.2589251e-08, 1.9952632e-08, 2.511887e-08, 3.9810708e-08, 1e-07, 1.9952633e-07, 3.981071e-07, 6.3095763e-07, 7.943284e-07, 6.3095763e-07, 5.01187e-07, 5.01187e-07, 6.3095763e-07, 6.3095763e-07, 7.943284e-07, 6.3095763e-07, 5.01187e-07, 6.3095763e-07, 6.3095763e-07, 6.3095763e-07, 5.01187e-07, 2.511887e-07, 1.2589251e-07, 1e-07, 6.309576e-08, 3.1622776e-08, - 2.511887e-08] + 2.511887e-08]; -[directivity:0] -directivity = [0.0, 360.0, 0.2512] +[directivity] +directivity = [0.0, 360.0, 0.2512]; diff --git a/scripts/reverb/text_to_binary_payload.py b/scripts/reverb/text_to_binary_payload.py index a67bff20b9..015707a56f 100644 --- a/scripts/reverb/text_to_binary_payload.py +++ b/scripts/reverb/text_to_binary_payload.py @@ -40,9 +40,9 @@ #