Skip to content
......@@ -141,6 +141,11 @@ class IvasScriptArgParser(argparse.ArgumentParser):
default=multiprocessing.cpu_count(),
type=int,
)
self.add_argument(
"--timeout",
help="Timeout duration for an individual encoder/decoder run",
default=None,
)
if not minimal:
self.add_argument(
"-C",
......@@ -339,6 +344,15 @@ class IvasScriptArgParser(argparse.ArgumentParser):
args["error"] = 1
args["exit"] = 1
if args["timeout"] is not None:
try:
timeout = float(args["timeout"])
args["timeout"] = timeout
except ValueError:
print(f"Given timeout value {args['timeout']} is not a valid number.")
args["error"] = 1
args["exit"] = 1
if not self.minimal:
format_dict = self.get_format_dict(args["format_file"])
if format_dict == -1:
......@@ -690,6 +704,9 @@ def runner_setup(runner, args):
if args["filter_regex"]:
runner.filter = args["filter_regex"]
if args["timeout"] is not None:
runner.timeout = args["timeout"]
def analyzer_setup(analyzer, args):
bs_proc_chain = {}
......
......@@ -763,6 +763,7 @@ class IvasBuilderAndRunner(IvasBaseClass):
self,
cfg_name,
run_tool="",
run_env={},
make_options=[],
defines_to_enable=[],
defines_to_disable=[],
......@@ -774,6 +775,7 @@ class IvasBuilderAndRunner(IvasBaseClass):
formats_dict={},
formats_fname="",
max_workers=1,
timeout=None,
):
"""
......@@ -829,6 +831,7 @@ class IvasBuilderAndRunner(IvasBaseClass):
dir_name=run_dir,
bin_suffix=self.builder.binary_ext,
test_tool=run_tool,
run_env=run_env,
site_config=self.site_config,
sample_rate_enc_in=sample_rate_enc_in,
formats_fname=formats_fname,
......@@ -838,6 +841,7 @@ class IvasBuilderAndRunner(IvasBaseClass):
enable_logging=True,
logger_name="{}.{}runner".format(self.logger.name, cfg_name),
log_level=self.logger.level,
timeout=timeout,
)
if format_select_list:
newRunner.set_format_select_list(format_select_list)
......@@ -1110,9 +1114,14 @@ class IvasBuilderAndRunner(IvasBaseClass):
self.build_and_run_dict[cfg_name]["runner"].dir_name = run_dir
self.build_and_run_dict[cfg_name]["analyzer"].dir = run_dir
self.build_and_run_dict[cfg_name]["runner"].run()
ret_val = 0
if self.build_and_run_dict[cfg_name]["analyzer"].get_errors:
failed_modes = self.build_and_run_dict[cfg_name]["runner"].failed_modes
self.build_and_run_dict[cfg_name]["analyzer"].get_errors(failed_modes)
_, n_runtime_err = self.build_and_run_dict[cfg_name]["analyzer"].get_errors(failed_modes)
ret_val = int(n_runtime_err > 0)
return ret_val
def get_run_errors(self, cfg_name):
"""
......@@ -1175,12 +1184,14 @@ class IvasBuilderAndRunner(IvasBaseClass):
defines_to_disable=None,
formats_fname="",
max_workers=1,
usan_supp_file=None,
):
n_cpus = cpu_count()
# do not use all cores to avoid weird getting-stuck issues observed on Mac...
make_options = ["-j" ,f"{n_cpus - 2}"]
run_tool = ""
run_env = dict()
if defines_to_enable is None:
defines_to_enable_check = []
else:
......@@ -1190,8 +1201,14 @@ class IvasBuilderAndRunner(IvasBaseClass):
else:
defines_to_disable_check = defines_to_disable.copy()
if check.startswith("CLANG"):
make_options.append("CLANG=" + check[-1])
clang_n = check[-1]
make_options.append("CLANG=" + clang_n)
defines_to_disable_check.extend(["RAM_COUNTING_TOOL"])
# for undefined behaviou sanitizer, pass suppression file if given
if clang_n == "3" and usan_supp_file is not None:
run_env["UBSAN_OPTIONS"] = f"suppressions={usan_supp_file},report_error_type=1"
elif check == "VALGRIND":
defines_to_disable_check.extend(["RAM_COUNTING_TOOL"])
run_tool = [
......@@ -1206,6 +1223,7 @@ class IvasBuilderAndRunner(IvasBaseClass):
self.add_build_and_run_config(
check,
run_tool=run_tool,
run_env=run_env,
make_options=make_options,
format_select_list=format_select_list,
mode_select_list=mode_select_list,
......
......@@ -133,6 +133,7 @@ class RunIvasCodec(IvasScriptsCommon.IvasScript):
sample_rate_dec_out=self.args["srout"],
enable_logging=True,
logger_name="{}.runner".format(self.logger.name),
timeout=self.args["timeout"],
)
IvasScriptsCommon.runner_setup(runner, self.args)
......
......@@ -145,10 +145,7 @@ if dataSpec.genRomFile
username = getenv('username');
end
fprintf(fileID_c, '/*\n');
fprintf(fileID_c, ' * Generated on %s with Matlab version %s by %s on %s\n', datetime("today"), version, username, computer);
fprintf(fileID_c, [' * Binaural rendering data set based on BRIRs\n']);
fprintf(fileID_c, [' * Tables derived from Mozart IIS BRIRs.*/']);
fprintf(fileID_c, '/* Generated on %s with Matlab version %s by %s on %s */\n', datetime("today"), version, username, computer);
fprintf(fileID_c, '\n\n');
c_file_content = string(join({
......@@ -580,8 +577,8 @@ for fs = [48000 32000 16000]
K = size(mod_hrf.WL{1}, 2);
sec_length = int32(floor(K / HRTF_MODEL_N_SECTIONS));
iSecFirst = zeros(HRTF_MODEL_N_SECTIONS,1,"int32");
iSecLast = zeros(HRTF_MODEL_N_SECTIONS,1,"int32");
iSecFirst = zeros(HRTF_MODEL_N_SECTIONS,1,'int32');
iSecLast = zeros(HRTF_MODEL_N_SECTIONS,1,'int32');
for i = 1:HRTF_MODEL_N_SECTIONS
iSecFirst(i) = (i -1) * sec_length;
end
......@@ -590,8 +587,8 @@ for fs = [48000 32000 16000]
end
iSecLast(HRTF_MODEL_N_SECTIONS) = K - 1;
EL = zeros( HRTF_MODEL_N_SECTIONS * AlphaN, 1, "single");
ER = zeros( HRTF_MODEL_N_SECTIONS * AlphaN, 1, "single");
EL = zeros( HRTF_MODEL_N_SECTIONS * AlphaN, 1, 'single');
ER = zeros( HRTF_MODEL_N_SECTIONS * AlphaN, 1, 'single');
ind = 1;
for i = 1:HRTF_MODEL_N_SECTIONS
for j = 1:AlphaN
......
......@@ -422,7 +422,7 @@ class DecoderFrontend:
system = platform.system()
if system == "Windows":
eid_path = "./scripts/tools/Windows/eid-xor.exe"
eid_path = "./scripts/tools/Win32/eid-xor.exe"
elif system == "Linux":
eid_path = "./scripts/tools/Linux/eid-xor"
elif system == "Darwin":
......
#!/usr/bin/env python3
"""
(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.
"""
#!/usr/bin/env python3
"""
(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.
"""
def pytest_addoption(parser):
parser.addoption(
"--create_ref",
action="store_true",
default=False,
)
parser.addoption(
"--create_cut",
action="store_true",
default=False,
)
#!/usr/bin/env python3
"""
(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.
"""
import re
from pathlib import Path
from tests.renderer.constants import (
OUTPUT_FORMATS_BINAURAL,
SCRIPTS_DIR,
TESTV_DIR,
)
TESTS_DIR = Path(__file__).parent
BITSTREAM_DIR = TESTS_DIR.joinpath("bitstream")
DEC_ROM_DIR = TESTS_DIR.joinpath("dec_out_rom")
HRTF_BINARY_DIR = SCRIPTS_DIR.joinpath(
"binauralRenderer_interface", "binaural_renderers_hrtf_data"
)
DEC_BINARY_DIR = TESTS_DIR.joinpath("dec_out_bin")
ENCODER_CMD = [str(TESTS_DIR.parent.parent.joinpath("IVAS_cod"))]
DECODER_CMD = [str(TESTS_DIR.parent.parent.joinpath("IVAS_dec"))]
RENDERER_CMD = [str(TESTS_DIR.parent.parent.joinpath("IVAS_rend"))]
HRTF_BINARY_FILE = "ivas_binaural_{}kHz.bin"
SAMPLE_RATE = ["16", "32", "48"]
INPUT_FORMATS_MC = ["5_1", "5_1_2", "5_1_4", "7_1", "7_1_4"] # "MONO", "STEREO",
INPUT_FORMATS_SBA = ["1", "2", "3"]
INPUT_FORMATS_ISM = ["1", "2", "3", "4"]
INPUT_FORMATS_MASA = {"tc": ["1", "2"], "dir": ["1", "2"]}
INPUT_FORMATS_MASA_RENDERER = ["MASA1", "MASA2"]
FORMAT_TO_FILE_MC_WOEXT = {
"5_1": "stv51MC{}c",
"7_1": "stv71MC{}c",
"5_1_2": "stv512MC{}c",
"5_1_4": "stv514MC{}c",
"7_1_4": "stv714MC{}c",
}
FORMAT_TO_FILE_SBA_WOEXT = {
"1": "stvFOA{}c",
"2": "stv2OA{}c",
"3": "stv3OA{}c",
}
FORMAT_TO_FILE_ISM_WOEXT = "stv{}ISM{}s"
FORMAT_TO_FILE_MASA_WOEXT = "stv{}MASA{}TC{}c"
BITRATE_ISM = {
"1": 96000,
"2": 160000,
"3": 384000,
"4": 512000,
}
FORMAT_TO_METADATA_FILES = {"MASA": "stv{}MASA{}TC{}c.met", "ISM": "stvISM{}.csv"}
FORMAT_TO_METADATA_FILES_RENDERER = {
"ISM1": [str(TESTV_DIR.joinpath("stvISM1.csv"))],
"ISM2": [
str(TESTV_DIR.joinpath("stvISM1.csv")),
str(TESTV_DIR.joinpath("stvISM2.csv")),
],
"ISM3": [
str(TESTV_DIR.joinpath("stvISM1.csv")),
str(TESTV_DIR.joinpath("stvISM2.csv")),
str(TESTV_DIR.joinpath("stvISM3.csv")),
],
"ISM4": [
str(TESTV_DIR.joinpath("stvISM1.csv")),
str(TESTV_DIR.joinpath("stvISM2.csv")),
str(TESTV_DIR.joinpath("stvISM3.csv")),
str(TESTV_DIR.joinpath("stvISM4.csv")),
],
"NDP_ISM4": [
str(TESTV_DIR.joinpath("stvISM1.csv")),
str(TESTV_DIR.joinpath("stvISM2_non-diegetic-pan.csv")),
str(TESTV_DIR.joinpath("stvISM3.csv")),
str(TESTV_DIR.joinpath("stvISM4.csv")),
],
"MASA1": [str(TESTV_DIR.joinpath("stv1MASA1TC48c.met"))],
"MASA2": [str(TESTV_DIR.joinpath("stv2MASA2TC48c.met"))],
}
HR_TRAJECTORIES_TO_TEST = ["headrot_case00_3000_q", "headrot"]
HR_TRAJECTORIES_TO_TEST_RENDERER = ["full_circle_in_15s"]
with open(
str(TESTS_DIR.parent.parent.joinpath("lib_com")) + "/ivas_cnst.h", "r"
) as ivas_cnst_file:
ivas_cnst = ivas_cnst_file.read()
# Declare renderer_types
rtid = ivas_cnst.find("RENDERER_TYPE;")
rte_c = ivas_cnst[ivas_cnst[:rtid].rfind("{") : ivas_cnst[:rtid].rfind("}")]
enumid = 0
for rtid1 in [m.start() for m in re.finditer("RENDERER_", rte_c)]:
rtid2 = rte_c[rtid1:].find(",")
if rtid2 == -1:
rtid2 = rte_c[rtid1:].find(" ")
globals()[rte_c[rtid1 : rtid1 + rtid2]] = enumid
enumid += 1
# Declare binaural_input_audio_config
biacid = ivas_cnst.find("BINAURAL_INPUT_AUDIO_CONFIG;")
biace_c = ivas_cnst[ivas_cnst[:biacid].rfind("{") : ivas_cnst[:biacid].rfind("}")]
enumid = 0
for biacid1 in [
m.start() for m in re.finditer("BINAURAL_INPUT_AUDIO_CONFIG_", biace_c)
]:
biacid2 = biace_c[biacid1:].find(",")
if biacid2 == -1:
biacid2 = biace_c[biacid1:].find(" ")
globals()[biace_c[biacid1 : biacid1 + biacid2]] = enumid
enumid += 1
HRTF_READER_RENDERER_BINAURAL_INVALID = 0
HRTF_READER_RENDERER_BINAURAL_FASTCONV = 1
HRTF_READER_RENDERER_BINAURAL_FASTCONV_ROOM = 2
HRTF_READER_RENDERER_BINAURAL_PARAMETRIC = 3
HRTF_READER_RENDERER_BINAURAL_PARAMETRIC_ROOM = 4
HRTF_READER_RENDERER_BINAURAL_OBJECTS_TD = 5
HRTF_READER_RENDERER_BINAURAL_MIXER_CONV = 6
HRTF_READER_RENDERER_BINAURAL_MIXER_CONV_ROOM = 7
HRTF_READER_RENDERER_BINAURAL_REVERB_ALL = 8
BINAURAL_INPUT_AUDIO_CONFIG_INVALID = 0
BINAURAL_INPUT_AUDIO_CONFIG_COMBINED = 1
BINAURAL_INPUT_AUDIO_CONFIG_HOA3 = 2
BINAURAL_INPUT_AUDIO_CONFIG_HOA2 = 3
BINAURAL_INPUT_AUDIO_CONFIG_FOA = 4
BINAURAL_INPUT_AUDIO_CONFIG_UNDEFINED = 5
REQ_HRTF_CONFIG = [
{
"renderer_type": HRTF_READER_RENDERER_BINAURAL_FASTCONV,
"input_configuration": BINAURAL_INPUT_AUDIO_CONFIG_COMBINED,
"sampling_frequency": 48000,
},
{
"renderer_type": HRTF_READER_RENDERER_BINAURAL_FASTCONV,
"input_configuration": BINAURAL_INPUT_AUDIO_CONFIG_HOA3,
"sampling_frequency": 48000,
},
{
"renderer_type": HRTF_READER_RENDERER_BINAURAL_FASTCONV,
"input_configuration": BINAURAL_INPUT_AUDIO_CONFIG_HOA2,
"sampling_frequency": 48000,
},
{
"renderer_type": HRTF_READER_RENDERER_BINAURAL_FASTCONV,
"input_configuration": BINAURAL_INPUT_AUDIO_CONFIG_FOA,
"sampling_frequency": 48000,
},
{
"renderer_type": HRTF_READER_RENDERER_BINAURAL_FASTCONV_ROOM,
"input_configuration": BINAURAL_INPUT_AUDIO_CONFIG_COMBINED,
"sampling_frequency": 48000,
},
{
"renderer_type": HRTF_READER_RENDERER_BINAURAL_PARAMETRIC_ROOM,
"input_configuration": BINAURAL_INPUT_AUDIO_CONFIG_UNDEFINED,
"sampling_frequency": 48000,
},
{
"renderer_type": HRTF_READER_RENDERER_BINAURAL_OBJECTS_TD,
"input_configuration": BINAURAL_INPUT_AUDIO_CONFIG_UNDEFINED,
"sampling_frequency": -1,
},
{
"renderer_type": HRTF_READER_RENDERER_BINAURAL_MIXER_CONV,
"input_configuration": BINAURAL_INPUT_AUDIO_CONFIG_COMBINED,
"sampling_frequency": -1,
},
{
"renderer_type": HRTF_READER_RENDERER_BINAURAL_MIXER_CONV,
"input_configuration": BINAURAL_INPUT_AUDIO_CONFIG_HOA3,
"sampling_frequency": -1,
},
{
"renderer_type": HRTF_READER_RENDERER_BINAURAL_MIXER_CONV,
"input_configuration": BINAURAL_INPUT_AUDIO_CONFIG_HOA2,
"sampling_frequency": -1,
},
{
"renderer_type": HRTF_READER_RENDERER_BINAURAL_MIXER_CONV,
"input_configuration": BINAURAL_INPUT_AUDIO_CONFIG_FOA,
"sampling_frequency": -1,
},
{
"renderer_type": HRTF_READER_RENDERER_BINAURAL_MIXER_CONV_ROOM,
"input_configuration": BINAURAL_INPUT_AUDIO_CONFIG_COMBINED,
"sampling_frequency": -1,
},
{
"renderer_type": HRTF_READER_RENDERER_BINAURAL_REVERB_ALL,
"input_configuration": BINAURAL_INPUT_AUDIO_CONFIG_UNDEFINED,
"sampling_frequency": -1,
},
]
#!/usr/bin/env python3
"""
(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.
"""
import pytest
from tests.hrtf_binary_loading.utils import *
""" Binary file """
@pytest.mark.parametrize("out_fs", SAMPLE_RATE)
def test_binary_file(test_info, out_fs):
check_binary_file(out_fs)
""" Multichannel """
@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL[:-1])
@pytest.mark.parametrize("out_fs", SAMPLE_RATE)
@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC)
def test_multichannel_binaural_static(test_info, in_fmt, out_fmt, out_fs):
# if in_fmt in ["MONO", "STEREO"]:
# pytest.skip("MONO or STEREO to Binaural rendering unsupported")
# -mc InputConf : Multi-channel format
# where InputConf specifies the channel configuration (5_1, 7_1, 5_1_2, 5_1_4, 7_1_4)
bitrate = 512000
in_fs = 48
option_list = ["-mc", in_fmt]
in_file = FORMAT_TO_FILE_MC_WOEXT[in_fmt].format(in_fs)
compare_rom_vs_binary(
test_info,
option_list,
bitrate,
in_file,
in_fs,
out_fmt,
out_fs,
)
@pytest.mark.parametrize("trj_file", [HR_TRAJECTORIES_TO_TEST[0]])
@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL[:-1])
@pytest.mark.parametrize("out_fs", SAMPLE_RATE)
@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC)
def test_multichannel_binaural_headrotation(
test_info, in_fmt, out_fmt, out_fs, trj_file
):
# if in_fmt in ["MONO", "STEREO"]:
# pytest.skip("MONO or STEREO to Binaural rendering unsupported")
# -mc InputConf : Multi-channel format
# where InputConf specifies the channel configuration (5_1, 7_1, 5_1_2, 5_1_4, 7_1_4)
bitrate = 512000
in_fs = 48
option_list = ["-mc", in_fmt]
in_file = FORMAT_TO_FILE_MC_WOEXT[in_fmt].format(in_fs)
compare_rom_vs_binary(
test_info,
option_list,
bitrate,
in_file,
in_fs,
out_fmt,
out_fs,
trj_file=str(TESTV_DIR.joinpath(f"{trj_file}.csv")),
)
""" Ambisonics """
@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL[:-1])
@pytest.mark.parametrize("fs", SAMPLE_RATE[1:])
@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_SBA)
def test_sba_binaural_static(test_info, in_fmt, fs, out_fmt):
# -sba +/-Order : Scene Based Audio input format (Ambisonics ACN/SN3D)
# where Order specifies the Ambisionics order (1-3)
bitrate = 256000
option_list = ["-sba", in_fmt]
in_file = FORMAT_TO_FILE_SBA_WOEXT[in_fmt].format(fs)
compare_rom_vs_binary(
test_info,
option_list,
bitrate,
in_file,
fs,
out_fmt,
fs,
)
@pytest.mark.parametrize("trj_file", [HR_TRAJECTORIES_TO_TEST[0]])
@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL[:-1])
@pytest.mark.parametrize("fs", SAMPLE_RATE[1:])
@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_SBA)
def test_sba_binaural_headrotation(test_info, in_fmt, fs, out_fmt, trj_file):
# -sba +/-Order : Scene Based Audio input format (Ambisonics ACN/SN3D)
# where Order specifies the Ambisionics order (1-3)
bitrate = 256000
option_list = ["-sba", in_fmt]
in_file = FORMAT_TO_FILE_SBA_WOEXT[in_fmt].format(fs)
compare_rom_vs_binary(
test_info,
option_list,
bitrate,
in_file,
fs,
out_fmt,
fs,
trj_file=str(TESTV_DIR.joinpath(f"{trj_file}.csv")),
)
""" MASA """
@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL[:-1])
@pytest.mark.parametrize("fs", SAMPLE_RATE[-1:])
@pytest.mark.parametrize("in_dir", INPUT_FORMATS_MASA["dir"])
@pytest.mark.parametrize("in_tc", INPUT_FORMATS_MASA["tc"])
def test_masa_binaural_static(test_info, in_tc, in_dir, fs, out_fmt):
# -masa Ch File : MASA format
# where Ch specifies the number of MASA input/transport channels (1 or 2)
# and File specifies input file containing parametric MASA metadata
bitrate = 256000
metadata_file = str(
TESTV_DIR.joinpath(FORMAT_TO_METADATA_FILES["MASA"].format(in_dir, in_tc, fs))
)
option_list = ["-masa", in_tc, metadata_file]
in_file = FORMAT_TO_FILE_MASA_WOEXT.format(in_dir, in_tc, fs)
compare_rom_vs_binary(
test_info,
option_list,
bitrate,
in_file,
fs,
out_fmt,
fs,
)
@pytest.mark.parametrize("trj_file", [HR_TRAJECTORIES_TO_TEST[1]])
@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL[:-1])
@pytest.mark.parametrize("fs", SAMPLE_RATE[-1:])
@pytest.mark.parametrize("in_dir", INPUT_FORMATS_MASA["dir"])
@pytest.mark.parametrize("in_tc", INPUT_FORMATS_MASA["tc"])
def test_masa_binaural_headrotation(test_info, in_tc, in_dir, fs, out_fmt, trj_file):
# -masa Ch File : MASA format
# where Ch specifies the number of MASA input/transport channels (1 or 2)
# and File specifies input file containing parametric MASA metadata
bitrate = 256000
metadata_file = str(
TESTV_DIR.joinpath(FORMAT_TO_METADATA_FILES["MASA"].format(in_dir, in_tc, fs))
)
option_list = ["-masa", in_tc, metadata_file]
in_file = FORMAT_TO_FILE_MASA_WOEXT.format(in_dir, in_tc, fs)
compare_rom_vs_binary(
test_info,
option_list,
bitrate,
in_file,
fs,
out_fmt,
fs,
trj_file=str(TESTV_DIR.joinpath(f"{trj_file}.csv")),
)
""" ISM """
@pytest.mark.parametrize("out_fmt", [OUTPUT_FORMATS_BINAURAL[0]])
@pytest.mark.parametrize("out_fs", SAMPLE_RATE)
@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM)
def test_ism_binaural_static(test_info, in_fmt, out_fs, out_fmt):
# -ism [+]Ch Files : ISM format
# where Ch specifies the number of ISMs (1-4)
# and Files specify input files containing metadata, one file per object
in_fs = 48
bitrate = BITRATE_ISM[in_fmt]
option_list = ["-ism", in_fmt]
metadata_file_list = []
for n in range(int(in_fmt)):
test = str(
TESTV_DIR.joinpath(FORMAT_TO_METADATA_FILES["ISM"].format(n + 1, in_fs))
)
metadata_file_list.append(test)
option_list.extend(metadata_file_list)
in_file = FORMAT_TO_FILE_ISM_WOEXT.format(in_fmt, in_fs)
compare_rom_vs_binary(
test_info,
option_list,
bitrate,
in_file,
in_fs,
out_fmt,
out_fs,
)
@pytest.mark.parametrize("trj_file", [HR_TRAJECTORIES_TO_TEST[0]])
@pytest.mark.parametrize("out_fmt", [OUTPUT_FORMATS_BINAURAL[0]])
@pytest.mark.parametrize("out_fs", SAMPLE_RATE)
@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM)
def test_ism_binaural_headrotation(test_info, in_fmt, out_fs, out_fmt, trj_file):
# -ism [+]Ch Files : ISM format
# where Ch specifies the number of ISMs (1-4)
# and Files specify input files containing metadata, one file per object
in_fs = 48
bitrate = BITRATE_ISM[in_fmt]
option_list = ["-ism", in_fmt]
metadata_file_list = []
for n in range(int(in_fmt)):
test = str(
TESTV_DIR.joinpath(FORMAT_TO_METADATA_FILES["ISM"].format(n + 1, in_fs))
)
metadata_file_list.append(test)
option_list.extend(metadata_file_list)
in_file = FORMAT_TO_FILE_ISM_WOEXT.format(in_fmt, in_fs)
compare_rom_vs_binary(
test_info,
option_list,
bitrate,
in_file,
in_fs,
out_fmt,
out_fs,
trj_file=str(TESTV_DIR.joinpath(f"{trj_file}.csv")),
)
""" ISM - Room Reverb """
@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL[-1:])
@pytest.mark.parametrize("out_fs", SAMPLE_RATE)
@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM)
def test_ism_binaural_roomreverb_static(test_info, in_fmt, out_fs, out_fmt):
# -ism [+]Ch Files : ISM format
# where Ch specifies the number of ISMs (1-4)
# and Files specify input files containing metadata, one file per object
in_fs = 48
bitrate = BITRATE_ISM[in_fmt]
option_list = ["-ism", in_fmt]
metadata_file_list = []
for n in range(int(in_fmt)):
test = str(
TESTV_DIR.joinpath(FORMAT_TO_METADATA_FILES["ISM"].format(n + 1, in_fs))
)
metadata_file_list.append(test)
option_list.extend(metadata_file_list)
in_file = FORMAT_TO_FILE_ISM_WOEXT.format(in_fmt, in_fs)
compare_rom_vs_binary(
test_info,
option_list,
bitrate,
in_file,
in_fs,
out_fmt,
out_fs,
)
@pytest.mark.parametrize("trj_file", [HR_TRAJECTORIES_TO_TEST[0]])
@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL[-1:])
@pytest.mark.parametrize("out_fs", SAMPLE_RATE)
@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM)
def test_ism_binaural_roomreverb_headrotation(
test_info, in_fmt, out_fs, out_fmt, trj_file
):
# -ism [+]Ch Files : ISM format
# where Ch specifies the number of ISMs (1-4)
# and Files specify input files containing metadata, one file per object
in_fs = 48
bitrate = BITRATE_ISM[in_fmt]
option_list = ["-ism", in_fmt]
metadata_file_list = []
for n in range(int(in_fmt)):
test = str(
TESTV_DIR.joinpath(FORMAT_TO_METADATA_FILES["ISM"].format(n + 1, in_fs))
)
metadata_file_list.append(test)
option_list.extend(metadata_file_list)
in_file = FORMAT_TO_FILE_ISM_WOEXT.format(in_fmt, in_fs)
compare_rom_vs_binary(
test_info,
option_list,
bitrate,
in_file,
in_fs,
out_fmt,
out_fs,
trj_file=str(TESTV_DIR.joinpath(f"{trj_file}.csv")),
)
#!/usr/bin/env python3
"""
(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.
"""
import pytest
from tests.hrtf_binary_loading.utils import *
from tests.renderer.constants import (
INPUT_FORMATS_AMBI,
INPUT_FORMATS_ISM,
INPUT_FORMATS_MC,
CUSTOM_LS_TO_TEST,
CUSTOM_LAYOUT_DIR,
FRAMING_TO_TEST,
HR_TRAJECTORY_DIR,
)
""" Ambisonics """
@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL)
@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI)
@pytest.mark.parametrize("frame_size", FRAMING_TO_TEST)
def test_ambisonics_binaural_static_with_binary_hrir(
test_info, in_fmt, out_fmt, frame_size
):
compare_renderer_vs_renderer_with_binary_hrir(
test_info, in_fmt, out_fmt, frame_size=frame_size
)
@pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST_RENDERER)
@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL)
@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI)
@pytest.mark.parametrize("frame_size", FRAMING_TO_TEST)
def test_ambisonics_binaural_headrotation_with_binary_hrir(
test_info, in_fmt, out_fmt, trj_file, frame_size
):
compare_renderer_vs_renderer_with_binary_hrir(
test_info,
in_fmt,
out_fmt,
trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"),
frame_size=frame_size,
)
""" Multichannel """
@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL)
@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC)
@pytest.mark.parametrize("frame_size", FRAMING_TO_TEST)
def test_multichannel_binaural_static_with_binary_hrir(
test_info, in_fmt, out_fmt, frame_size
):
if in_fmt in ["MONO", "STEREO"]:
pytest.skip("MONO or STEREO to Binaural rendering unsupported")
compare_renderer_vs_renderer_with_binary_hrir(
test_info, in_fmt, out_fmt, frame_size=frame_size
)
@pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST_RENDERER)
@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL)
@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC)
@pytest.mark.parametrize("frame_size", FRAMING_TO_TEST)
def test_multichannel_binaural_headrotation_with_binary_hrir(
test_info, in_fmt, out_fmt, trj_file, frame_size
):
if in_fmt in ["MONO", "STEREO"]:
pytest.skip("MONO or STEREO to Binaural rendering unsupported")
compare_renderer_vs_renderer_with_binary_hrir(
test_info,
in_fmt,
out_fmt,
trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"),
frame_size=frame_size,
)
""" ISM """
@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL)
@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM)
@pytest.mark.parametrize("frame_size", FRAMING_TO_TEST)
def test_ism_binaural_static_with_binary_hrir(test_info, in_fmt, out_fmt, frame_size):
try:
in_meta_files = FORMAT_TO_METADATA_FILES_RENDERER[in_fmt]
except:
in_meta_files = None
compare_renderer_vs_renderer_with_binary_hrir(
test_info, in_fmt, out_fmt, in_meta_files=in_meta_files, frame_size=frame_size
)
@pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST_RENDERER)
@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL)
@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM)
@pytest.mark.parametrize("frame_size", FRAMING_TO_TEST)
def test_ism_binaural_headrotation_with_binary_hrir(
test_info, in_fmt, out_fmt, trj_file, frame_size
):
try:
in_meta_files = FORMAT_TO_METADATA_FILES_RENDERER[in_fmt]
except:
in_meta_files = None
compare_renderer_vs_renderer_with_binary_hrir(
test_info,
in_fmt,
out_fmt,
trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"),
in_meta_files=in_meta_files,
frame_size=frame_size,
)
""" MASA """
@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL)
@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MASA_RENDERER)
@pytest.mark.parametrize("frame_size", FRAMING_TO_TEST)
def test_masa_binaural_static_with_binary_hrir(test_info, in_fmt, out_fmt, frame_size):
if out_fmt in ["BINAURAL_ROOM_IR", "BINAURAL_ROOM_REVERB"]:
pytest.skip("Skipping binaural room outputs for MASA as unimplemented.")
compare_renderer_vs_renderer_with_binary_hrir(
test_info,
in_fmt,
out_fmt,
in_meta_files=FORMAT_TO_METADATA_FILES_RENDERER[in_fmt],
)
@pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST_RENDERER)
@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL)
@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MASA_RENDERER)
@pytest.mark.parametrize("frame_size", FRAMING_TO_TEST)
def test_masa_binaural_headrotation_with_binary_hrir(
test_info, in_fmt, out_fmt, trj_file, frame_size
):
if out_fmt in ["BINAURAL_ROOM_IR", "BINAURAL_ROOM_REVERB"]:
pytest.skip("Skipping binaural room outputs for MASA as unimplemented.")
compare_renderer_vs_renderer_with_binary_hrir(
test_info,
in_fmt,
out_fmt,
trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"),
in_meta_files=FORMAT_TO_METADATA_FILES_RENDERER[in_fmt],
)
""" Custom loudspeaker layouts """
@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL)
@pytest.mark.parametrize("in_layout", CUSTOM_LS_TO_TEST)
@pytest.mark.parametrize("frame_size", FRAMING_TO_TEST)
def test_custom_ls_input_binaural_with_binary_hrir(
test_info, in_layout, out_fmt, frame_size
):
compare_renderer_vs_renderer_with_binary_hrir(
test_info,
CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"),
out_fmt,
frame_size=frame_size,
)
@pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST_RENDERER)
@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL)
@pytest.mark.parametrize("in_layout", CUSTOM_LS_TO_TEST)
@pytest.mark.parametrize("frame_size", FRAMING_TO_TEST)
def test_custom_ls_input_binaural_headrotation_with_binary_hrir(
test_info, in_layout, out_fmt, trj_file, frame_size
):
compare_renderer_vs_renderer_with_binary_hrir(
test_info,
CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"),
out_fmt,
trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"),
frame_size=frame_size,
)
#!/usr/bin/env python3
"""
(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.
"""
import os
import sys
import uuid
from typing import Dict, Optional
import pytest
from tests.renderer.compare_audio import compare_audio_arrays
from tests.renderer.utils import check_BE, run_cmd, test_info, run_renderer
from .constants import *
sys.path.append(SCRIPTS_DIR)
import pyaudio3dtools
def run_encoder(
bitrate: int,
sampling_rate: int,
input_file: str,
output_file: str,
sba_order: Optional[str] = None,
dtx_mode: Optional[bool] = False,
max_band: Optional[str] = None,
bypass_mode: Optional[int] = None,
quiet_mode: Optional[bool] = True,
add_option_list: Optional[list] = None,
):
cmd = ENCODER_CMD[:]
# add optional parameters
if sba_order is not None:
cmd.extend(["-sba", sba_order])
if dtx_mode:
cmd.extend(["-dtx"])
if max_band is not None:
cmd.extend(["-max_band", max_band])
if bypass_mode is not None:
cmd.extend(["-bypass", str(bypass_mode)])
if quiet_mode:
cmd.extend(["-q"])
if add_option_list is not None:
cmd.extend(add_option_list)
# add mandatory parameters
cmd += [
str(bitrate),
str(sampling_rate),
str(input_file),
str(output_file),
]
run_cmd(cmd)
def run_decoder(
output_config: str,
output_sampling_rate: int,
input_bitstream_path: Path,
output_path: Path,
quiet_mode: Optional[bool] = True,
plc_file: Optional[Path] = None,
add_option_list: Optional[list] = None,
):
cmd = DECODER_CMD[:]
# add optional parameters
if quiet_mode:
cmd.extend(["-q"])
if plc_file is not None:
cmd.extend(["-fec", str(plc_file)])
if add_option_list is not None:
cmd.extend(add_option_list)
# add mandatory parameters
# output_config is mandatory for IVAS; EVS does not have this parameter, indicated by ""
if output_config != "":
cmd += [output_config]
cmd += [
str(output_sampling_rate),
str(input_bitstream_path),
str(output_path),
]
run_cmd(cmd)
def get_option_list_str(option_list):
option_list_str = option_list.copy()
for i in range(len(option_list_str)):
if option_list_str[i][0] == "-":
option_list_str[i] = option_list_str[i][1:]
if os.path.isfile(option_list_str[i]):
option_list_str[i] = Path(option_list_str[i]).stem
return option_list_str
def check_binary_file(out_fs):
with open(
str(HRTF_BINARY_DIR.joinpath(HRTF_BINARY_FILE.format(out_fs))), "rb"
) as file:
binary_data = file.read()
# [Declaration of the binary file]
# File Identifier (8 bytes)
# Size of file in bytes (4 bytes)
# Number of HRTF (2 bytes)
# Max length of HRTF data (4 bytes)
binary_file_size = os.path.getsize(
str(HRTF_BINARY_DIR.joinpath(HRTF_BINARY_FILE.format(out_fs)))
)
if binary_file_size < 18:
pytest.fail("HRTF binary file not compliant (size of file header)")
file_header = binary_data[:18]
file_identifier = file_header[:8].decode()
if file_identifier != "IVASHRTF":
pytest.fail("Header of HRTF binary file not compliant (identifier)")
file_size = int.from_bytes(file_header[8:12], byteorder="little")
if file_size != binary_file_size:
pytest.fail("Header of HRTF binary file not compliant (file size)")
nb_hrtf = int.from_bytes(file_header[12:14], byteorder="little")
max_data_size = int.from_bytes(file_header[14:18], byteorder="little")
read_bid = 18
hrtf_cnt = 0
raw_data_size_max = 0
hrtf_config_file = []
while read_bid < file_size:
if read_bid + 16 > file_size:
pytest.fail("Reading of HRTF header failed")
# HRTF Header */
# Renderer type (4 bytes) : See "RENDERER_TYPE" */
# Input configuration (4 bytes) : See "BINAURAL_INPUT_AUDIO_CONFIG" */
# Sampling Frequency (4 bytes) */
# Raw data size (4 bytes) */
hrtf_header = binary_data[read_bid : read_bid + 16]
renderer_type = int.from_bytes(hrtf_header[:4], byteorder="little")
input_configuration = int.from_bytes(hrtf_header[4:8], byteorder="little")
sampling_frequency = int.from_bytes(hrtf_header[8:12], byteorder="little")
raw_data_size = int.from_bytes(hrtf_header[12:16], byteorder="little")
if (
(renderer_type != HRTF_READER_RENDERER_BINAURAL_MIXER_CONV)
and (renderer_type != HRTF_READER_RENDERER_BINAURAL_MIXER_CONV_ROOM)
and (renderer_type != HRTF_READER_RENDERER_BINAURAL_FASTCONV)
and (renderer_type != HRTF_READER_RENDERER_BINAURAL_FASTCONV_ROOM)
and (renderer_type != HRTF_READER_RENDERER_BINAURAL_PARAMETRIC)
and (renderer_type != HRTF_READER_RENDERER_BINAURAL_PARAMETRIC_ROOM)
and (renderer_type != HRTF_READER_RENDERER_BINAURAL_OBJECTS_TD)
and (renderer_type != HRTF_READER_RENDERER_BINAURAL_REVERB_ALL)
):
pytest.fail("Header of HRTF binary file not compliant (renderer type)")
if (
(input_configuration != BINAURAL_INPUT_AUDIO_CONFIG_COMBINED)
and (input_configuration != BINAURAL_INPUT_AUDIO_CONFIG_HOA3)
and (input_configuration != BINAURAL_INPUT_AUDIO_CONFIG_HOA2)
and (input_configuration != BINAURAL_INPUT_AUDIO_CONFIG_FOA)
and (input_configuration != BINAURAL_INPUT_AUDIO_CONFIG_UNDEFINED)
):
pytest.fail(
"Header of HRTF binary file not compliant (input configuration)"
)
if (
(sampling_frequency != 16000)
and (sampling_frequency != 32000)
and (sampling_frequency != 48000)
):
pytest.fail(
"Header of HRTF binary file not compliant (sampling frequency)"
)
if raw_data_size_max < raw_data_size:
raw_data_size_max = raw_data_size
hrtf_config_file.append(
{
"renderer_type": renderer_type,
"input_configuration": input_configuration,
"sampling_frequency": sampling_frequency,
}
)
# hrtf_raw_data => Tested in compare_rom_vs_binary
read_bid += 16 + raw_data_size
hrtf_cnt += 1
if read_bid != file_size:
pytest.fail("Inconsistent size of binary file")
if hrtf_cnt != nb_hrtf:
pytest.fail("Inconsistent number of HRTF in binary file")
if raw_data_size_max != max_data_size:
pytest.fail("Inconsistent max data size")
for hrtf_config in REQ_HRTF_CONFIG:
config = next(
(
cfg
for cfg in hrtf_config_file
if (cfg["renderer_type"] == hrtf_config["renderer_type"])
and (
cfg["input_configuration"] == hrtf_config["input_configuration"]
)
),
None,
)
if config == None:
pytest.fail(
f"Configuration (renderer_type : {hrtf_config['renderer_type']} - input_configuration : {hrtf_config['input_configuration']}) not found in binary file!"
)
if (
(hrtf_config["sampling_frequency"] == -1)
and (config["sampling_frequency"] != int(out_fs) * 1000)
) or (
(hrtf_config["sampling_frequency"] != -1)
and (config["sampling_frequency"] != hrtf_config["sampling_frequency"])
):
pytest.fail(
f"Bad sampling frequency for configuration (renderer_type : {hrtf_config['renderer_type']} - input_configuration : {hrtf_config['input_configuration']}) : {config['sampling_frequency']} instead of {int(out_fs)*1000}!"
)
def compare_rom_vs_binary(
test_info,
option_list_enc,
bitrate,
in_file,
in_fs,
out_fmt,
out_fs,
keep_file: Optional[bool] = False,
trj_file: Optional[str] = None,
):
option_str = "_".join(get_option_list_str(option_list_enc))
file_ext = f"_{option_str or ''}_{bitrate or ''}_{in_fs or ''}-{out_fs or ''}_{out_fmt or ''}-{uuid.uuid1()} "
# check_binary_file(out_fs)
input_path = TESTV_DIR.joinpath(in_file).with_suffix(".wav")
bitstream_path = BITSTREAM_DIR.joinpath(in_file + file_ext)
run_encoder(
bitrate, in_fs, input_path, bitstream_path, add_option_list=option_list_enc
)
if trj_file is not None:
option_list_dec = ["-t", trj_file]
file_ext += "_headrot"
else:
option_list_dec = None
out_rom_path = DEC_ROM_DIR.joinpath(in_file + file_ext).with_suffix(".wav")
run_decoder(
out_fmt, out_fs, bitstream_path, out_rom_path, add_option_list=option_list_dec
)
out_rom, out_rom_fs = pyaudio3dtools.audiofile.readfile(out_rom_path)
hrtf_file = HRTF_BINARY_FILE.format(out_fs)
if trj_file is not None:
option_list_dec.extend(["-hrtf", str(HRTF_BINARY_DIR.joinpath(hrtf_file))])
else:
option_list_dec = ["-hrtf", str(HRTF_BINARY_DIR.joinpath(hrtf_file))]
out_bin_path = DEC_BINARY_DIR.joinpath(in_file + file_ext).with_suffix(".wav")
run_decoder(
out_fmt, out_fs, bitstream_path, out_bin_path, add_option_list=option_list_dec
)
out_bin, out_bin_fs = pyaudio3dtools.audiofile.readfile(out_rom_path)
check_BE(test_info, out_rom, out_rom_fs, out_bin, out_bin_fs)
if keep_file == False:
os.remove(bitstream_path)
os.remove(out_rom_path)
os.remove(out_bin_path)
def compare_renderer_vs_renderer_with_binary_hrir(
test_info,
in_fmt,
out_fmt,
metadata_input: Optional[str] = None,
in_meta_files: Optional[list] = None,
trj_file: Optional[str] = None,
non_diegetic_pan: Optional[str] = None,
name_extension: Optional[str] = uuid.uuid1(),
refrot_file: Optional[str] = None,
refvec_file: Optional[str] = None,
refveclev_file: Optional[str] = None,
config_file: Optional[str] = None,
frame_size: Optional[str] = "20ms",
hrir_name="ivas_binaural_48kHz.bin",
keep_file=False,
):
hrtf_file_dir = SCRIPTS_DIR.joinpath(
"binauralRenderer_interface/binaural_renderers_hrtf_data"
)
hrtf_file_path = hrtf_file_dir.joinpath(hrir_name)
ref_out = run_renderer(
test_info,
in_fmt,
out_fmt,
metadata_input,
in_meta_files,
trj_file,
non_diegetic_pan,
name_extension,
refrot_file,
refvec_file,
refveclev_file,
config_file,
frame_size=frame_size,
)
cut_out = run_renderer(
test_info,
in_fmt,
out_fmt,
metadata_input,
in_meta_files,
trj_file,
non_diegetic_pan,
name_extension,
refrot_file,
refvec_file,
refveclev_file,
config_file,
hrtf_file=hrtf_file_path,
frame_size=frame_size,
)
ref, ref_fs = pyaudio3dtools.audiofile.readfile(ref_out)
cut, cut_fs = pyaudio3dtools.audiofile.readfile(cut_out)
check_BE(test_info, ref, ref_fs, cut, cut_fs)
if keep_file == False:
os.remove(ref_out)
os.remove(cut_out)
......@@ -108,6 +108,7 @@ def run_renderer(
config_file: Optional[str] = None,
binary_suffix: str = "",
frame_size: Optional[str] = "20ms",
hrtf_file: Optional[str] = None,
) -> str:
# prepare arguments and filepaths
if trj_file is not None:
......@@ -145,6 +146,11 @@ def run_renderer(
else:
out_name = out_fmt
if hrtf_file is not None:
hrtf_file_name = f"_{hrtf_file.stem}"
else:
hrtf_file_name = ""
if test_info.config.option.create_ref:
output_path_base = OUTPUT_PATH_REF
else:
......@@ -166,7 +172,7 @@ def run_renderer(
in_file = FORMAT_TO_FILE[in_fmt]
in_name = in_fmt
out_file_stem = f"{in_name}_to_{out_name}{trj_name}{non_diegetic_pan}{refrot_name}{refvec_name}{refveclev_name}{config_name}{framing_name}{name_extension}.wav"
out_file_stem = f"{in_name}_to_{out_name}{trj_name}{non_diegetic_pan}{refrot_name}{refvec_name}{refveclev_name}{config_name}{framing_name}{hrtf_file_name}{name_extension}.wav"
out_file = str(output_path_base.joinpath(out_file_stem))
......
__copyright__ = """
(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.
"""
__doc__ = """
Execute tests specified via a parameter file.
"""
import os
from pathlib import Path
import filecmp
import subprocess
import pytest
test_dict = {}
TEST_DIR = "evs_be_test"
scripts=["Readme_AMRWB_IO_dec.txt", "Readme_AMRWB_IO_enc.txt", "Readme_EVS_dec.txt","Readme_EVS_enc.txt", "Readme_JBM_dec.txt"]
for s in scripts:
with open(os.path.join(TEST_DIR, s), "r", encoding="UTF-8") as fp:
tag = ""
enc_opts = ""
dec_opts = ""
diff_opts = ""
for line in fp.readlines():
if line.startswith("$ENC_BIN"):
enc_opts = line
if line.startswith("$DEC_BIN"):
dec_opts = line
if line.startswith("$DIFF_BIN"):
diff_opts = line[9:]
tag = s + "--" + diff_opts.split()[1].split('/')[-1]
if tag in test_dict:
print("non-unique tag found - ignoring new entry")
continue
test_dict[tag] = (enc_opts, dec_opts, diff_opts)
tag = ""
enc_opts = ""
dec_opts = ""
diff_opts = ""
@pytest.mark.parametrize("test_tag", list(test_dict.keys()))
def test_evs_26444(test_tag):
enc_opts, dec_opts, diff_opts = test_dict[test_tag]
if enc_opts:
enc_opts = enc_opts.replace("./", TEST_DIR + "/")
subprocess.run(["./IVAS_cod","-q"] + enc_opts.split()[1:])
if dec_opts:
dec_opts = dec_opts.replace("./", TEST_DIR + "/")
subprocess.run(["./IVAS_dec","-q"] + dec_opts.split()[1:])
diff_opts = diff_opts.replace("./", TEST_DIR + "/")
if ';' in diff_opts:
cmd1, cmd2 = diff_opts.split(';')
cmd1 = cmd1.split()
cmd2 = cmd2.split()
result1 = filecmp.cmp(cmd1[0], cmd1[1])
result2 = filecmp.cmp(cmd2[2], cmd2[3])
else:
cmd1 = diff_opts.split()
result1 = filecmp.cmp(cmd1[0], cmd1[1])
result2 = True
if not (result1 and result2):
assert False, "Output differs"
\ No newline at end of file