diff --git a/ivas_processing_scripts/audiotools/binaural_datasets/binaural_dataset.py b/ivas_processing_scripts/audiotools/binaural_datasets/binaural_dataset.py index c51566eed2f6a33d240bd43149664062bf8fea6f..d33c4240de3a5543260a4e1cb762c661662ece0e 100755 --- a/ivas_processing_scripts/audiotools/binaural_datasets/binaural_dataset.py +++ b/ivas_processing_scripts/audiotools/binaural_datasets/binaural_dataset.py @@ -118,9 +118,10 @@ def load_ir( dataset_suffix = None if out_fmt.startswith("BINAURAL") and "ROOM" in out_fmt: - if "_IR" in out_fmt or "_REVERB" in out_fmt: - warn("For reference rendering _IR and _REVERB extensions of BINAURAL_ROOM are ignored") + warn( + "For reference rendering _IR and _REVERB extensions of BINAURAL_ROOM are ignored" + ) dataset_prefix = "BRIR" if dataset is None: diff --git a/ivas_processing_scripts/audiotools/convert/__init__.py b/ivas_processing_scripts/audiotools/convert/__init__.py index e26c8c6fc95a4c0182a719aeb40d59d41ce2ddce..845f00c69041d8766901c64e9d7041ee61f109fa 100755 --- a/ivas_processing_scripts/audiotools/convert/__init__.py +++ b/ivas_processing_scripts/audiotools/convert/__init__.py @@ -44,7 +44,7 @@ from ivas_processing_scripts.audiotools.convert.masa import convert_masa from ivas_processing_scripts.audiotools.convert.objectbased import convert_objectbased from ivas_processing_scripts.audiotools.convert.scenebased import convert_scenebased from ivas_processing_scripts.audiotools.wrappers.bs1770 import loudness_norm -from ivas_processing_scripts.audiotools.wrappers.esdru import esdru +from ivas_processing_scripts.audiotools.wrappers.esdru import esdru, spatial_distortion from ivas_processing_scripts.audiotools.wrappers.filter import ( lpfilter_itu, maskfilter_itu, @@ -169,6 +169,8 @@ def convert( limit: Optional[bool] = False, mnru_q: Optional[float] = None, esdru_alpha: Optional[float] = None, + spatial_distortion_amplitude: Optional[float] = None, + spatial_distortion_frequency: Optional[float] = None, logger: Optional[logging.Logger] = None, **kwargs, ) -> None: @@ -186,6 +188,8 @@ def convert( window=in_window, loudness=in_loudness, loudness_fmt=in_loudness_fmt, + spatial_distortion_amplitude=spatial_distortion_amplitude, + spatial_distortion_frequency=spatial_distortion_frequency, logger=logger, ) @@ -225,6 +229,8 @@ def process_audio( limit: Optional[bool] = False, mnru_q: Optional[float] = None, esdru_alpha: Optional[float] = None, + spatial_distortion_amplitude: Optional[float] = None, + spatial_distortion_frequency: Optional[float] = None, logger: Optional[logging.Logger] = None, ) -> None: """Perform (pre-/pos-) processing of audio""" @@ -287,6 +293,17 @@ def process_audio( logger.debug("Applying ESDRU Recommendation ITU-T P.811") x.audio = esdru(x, esdru_alpha) + """Spatial distortion""" + if ( + spatial_distortion_frequency is not None + and spatial_distortion_amplitude is not None + ): + if logger: + logger.debug("Applying spatial distortion") + x.audio = spatial_distortion( + x, spatial_distortion_amplitude, spatial_distortion_frequency + ) + """loudness normalization""" if loudness is not None: if logger: diff --git a/ivas_processing_scripts/audiotools/wrappers/dlyerr_2_errpat.py b/ivas_processing_scripts/audiotools/wrappers/dlyerr_2_errpat.py index 9ea3e2b0905a418045c054da65e0dc7b1f25ec57..cea1f6879959f9ac69a033e6647d616de3099802 100644 --- a/ivas_processing_scripts/audiotools/wrappers/dlyerr_2_errpat.py +++ b/ivas_processing_scripts/audiotools/wrappers/dlyerr_2_errpat.py @@ -30,17 +30,19 @@ # the United Nations Convention on Contracts on the International Sales of Goods. # -import os.path from pathlib import Path from typing import Optional, Union from warnings import warn -from ivas_processing_scripts.audiotools.wrappers.networkSimulator import LIST_JBM_PROFILES, ERROR_PATTERNS_DIR -from ivas_processing_scripts.constants import DEFAULT_CONFIG_BINARIES -from ivas_processing_scripts.utils import find_binary, run from ivas_processing_scripts.audiotools.wrappers.eid_xor import eid_xor +from ivas_processing_scripts.audiotools.wrappers.networkSimulator import ( + ERROR_PATTERNS_DIR, + LIST_JBM_PROFILES, + length_pattern, +) from ivas_processing_scripts.audiotools.wrappers.random_seed import random_seed -from ivas_processing_scripts.audiotools.wrappers.networkSimulator import length_pattern +from ivas_processing_scripts.constants import DEFAULT_CONFIG_BINARIES +from ivas_processing_scripts.utils import find_binary, run def dlyerr_2_errpat( @@ -87,7 +89,9 @@ def dlyerr_2_errpat( if "dlyerr_2_errpat" in DEFAULT_CONFIG_BINARIES["binary_paths"]: binary = find_binary( DEFAULT_CONFIG_BINARIES["binary_paths"]["dlyerr_2_errpat"].name, - binary_path=DEFAULT_CONFIG_BINARIES["binary_paths"]["dlyerr_2_errpat"].parent, + binary_path=DEFAULT_CONFIG_BINARIES["binary_paths"][ + "dlyerr_2_errpat" + ].parent, ) else: binary = find_binary("dlyerr_2_errpat") @@ -98,7 +102,9 @@ def dlyerr_2_errpat( f"Delay and error pattern file {dlyerr_pattern} for bitstream processing does not exist" ) if delay is not None and late_loss_rate is not None: - raise ValueError("Can't scpecify delay and late loss rate for dlyerr_2_err tool but only one of them") + raise ValueError( + "Can't scpecify delay and late loss rate for dlyerr_2_err tool but only one of them" + ) # set up command line cmd = [ @@ -132,8 +138,17 @@ def dlyerr_2_errpat( return -def evs_jbm(bitstream, bitstream_processed, error_profile, error_pattern, errpatt_late_loss_rate, errpatt_delay, errpatt_seed, errpatt_frames_packet, master_seed): - +def evs_jbm( + bitstream, + bitstream_processed, + error_profile, + error_pattern, + errpatt_late_loss_rate, + errpatt_delay, + errpatt_seed, + errpatt_frames_packet, + master_seed, +): # convert delay and error profile delay = None num_frames_packet = None @@ -257,9 +272,13 @@ def validate_evs_jbm( "JBM pattern and JBM profile number are specified for bitstream processing. Can't use both! Please check the configuration." ) if errpatt_late_loss_rate is not None and errpatt_delay is not None: - raise ValueError("For EVS JBM conditions with error pattern only late loss rate OR delay has to be specified, not both!") + raise ValueError( + "For EVS JBM conditions with error pattern only late loss rate OR delay has to be specified, not both!" + ) if errpatt_late_loss_rate is None and errpatt_delay is None: - raise ValueError("For EVS JBM conditions with error pattern either late loss rate or delay has to be specified!") + raise ValueError( + "For EVS JBM conditions with error pattern either late loss rate or delay has to be specified!" + ) if errpatt_seed is None: warn("No seed was specified for EVS JBM offset -> Use 0") elif error_profile is not None: @@ -272,4 +291,3 @@ def validate_evs_jbm( f"n_frames_per_paket is {n_frames_per_packet}. Should be 1 or 2. Please check your configuration." ) return - diff --git a/ivas_processing_scripts/audiotools/wrappers/esdru.py b/ivas_processing_scripts/audiotools/wrappers/esdru.py index 92c9a65353467ce08e44661dbcdb65d323675be1..0347e30b164630a49e5c334c9f04548dc87618bb 100755 --- a/ivas_processing_scripts/audiotools/wrappers/esdru.py +++ b/ivas_processing_scripts/audiotools/wrappers/esdru.py @@ -30,6 +30,7 @@ # the United Nations Convention on Contracts on the International Sales of Goods. # +from copy import deepcopy from pathlib import Path from tempfile import TemporaryDirectory from typing import Optional @@ -126,3 +127,32 @@ def esdru( tmp_output_signal, out_fs = read(tmp_output_file, 2, sf) return tmp_output_signal + + +def spatial_distortion( + input: audio.Audio, + amplitude, + frequency, +) -> np.ndarray: + if not isinstance(input, audio.SceneBasedAudio): + raise ValueError("Spatial distortion currently only implemented for SBA.") + + input_copy = deepcopy(input) + + # order channels WYZX + y = input_copy.audio[:, 1] + x = input_copy.audio[:, 3] + + # angle changes over time + amplitude = np.deg2rad(amplitude) + angle = amplitude * np.sin(np.arange(len(y)) * 2 * np.pi * frequency) + + # Y channel left-right + y_new = y * np.cos(angle) + x * np.sin(angle) + input_copy.audio[:, 1] = y_new + + # X channel front-back + x_new = -y * np.sin(angle) + x * np.cos(angle) + input_copy.audio[:, 3] = x_new + + return input_copy.audio diff --git a/ivas_processing_scripts/audiotools/wrappers/networkSimulator.py b/ivas_processing_scripts/audiotools/wrappers/networkSimulator.py index aff395992e80021ea7fa3764fa9f496a3a4ae8f2..86347f5273dbe55d0528f3e711db55b2627cd009 100644 --- a/ivas_processing_scripts/audiotools/wrappers/networkSimulator.py +++ b/ivas_processing_scripts/audiotools/wrappers/networkSimulator.py @@ -33,11 +33,10 @@ import logging from pathlib import Path from typing import Optional, Union -from warnings import warn +from ivas_processing_scripts.audiotools.wrappers.random_seed import random_seed from ivas_processing_scripts.constants import DEFAULT_CONFIG_BINARIES from ivas_processing_scripts.utils import find_binary, run -from ivas_processing_scripts.audiotools.wrappers.random_seed import random_seed LIST_JBM_PROFILES = range(11) ERROR_PATTERNS_DIR = Path(__file__).parent.parent.parent.joinpath("dly_error_profiles") @@ -84,8 +83,6 @@ def validate_network_simulator( raise ValueError( "JBM pattern and JBM profile number are specified for bitstream processing. Can't use both! Please check the configuration." ) - if errpatt_seed is None: - raise warn("No error pattern seed specified for JBM offset -> use 0") elif error_profile is not None: if error_profile not in LIST_JBM_PROFILES: raise ValueError( @@ -238,7 +235,7 @@ def apply_network_simulator( def length_pattern(path_pattern): - with open(path_pattern, 'r') as f: + with open(path_pattern, "r") as f: p = f.readlines() length = len(p) return length diff --git a/ivas_processing_scripts/constants.py b/ivas_processing_scripts/constants.py index b4cf5a280a1396a4cf39cdd974325cdc645c52aa..3d63dd10dd756dedb24b2418a472444cfad4362b 100755 --- a/ivas_processing_scripts/constants.py +++ b/ivas_processing_scripts/constants.py @@ -50,6 +50,7 @@ SUPPORTED_CONDITIONS = { "evs", "ivas", "mono_dmx", + "spatial_distortion", } DEFAULT_CONFIG = { diff --git a/ivas_processing_scripts/processing/chains.py b/ivas_processing_scripts/processing/chains.py index 3c35168c578501d4a0ba2eefaf5caa898e88d548..e52bc8c844f7391b357bb6a045286090469bd516 100755 --- a/ivas_processing_scripts/processing/chains.py +++ b/ivas_processing_scripts/processing/chains.py @@ -237,14 +237,22 @@ def get_processing_chain( tmp_lp_cutoff = post_cfg.get("lp_cutoff") tmp_mnru_q = None tmp_esdru_alpha = None + tmp_spatial_dist_amp = None + tmp_spatial_dist_freq = None tx_condition = False ivas_jbm = False + cond_fmt = [] # override / add values based on specific conditions cond_cfg = cfg.conditions_to_generate[condition] if cond_cfg["type"] == "ref": - pass # no configuration necessary + # allow list of output formats + if (ref_fmt := cond_cfg.get("fmt", None)) is not None: + if isinstance(ref_fmt, list): + cond_fmt.extend(ref_fmt) + else: + cond_fmt.append(ref_fmt) elif cond_cfg["type"] == "lp3k5": tmp_lp_cutoff = 3500 elif cond_cfg["type"] == "lp7k": @@ -253,6 +261,13 @@ def get_processing_chain( tmp_mnru_q = cond_cfg["q"] elif cond_cfg["type"] == "esdru": tmp_esdru_alpha = cond_cfg["alpha"] + elif cond_cfg["type"] == "spatial_distortion": + tmp_spatial_dist_amp = cond_cfg.get("amplitude", None) + tmp_spatial_dist_freq = cond_cfg.get("frequency", None) + if tmp_spatial_dist_amp is None or tmp_spatial_dist_freq is None: + raise ValueError( + "For spatial distortion amplitude and frequency values need to be given" + ) elif cond_cfg["type"] == "mono_dmx": # add another postprocessing from in_fmt to mono chain["processes"].append( @@ -302,7 +317,9 @@ def get_processing_chain( "error_pattern": get_abs_path( tx_cfg_tmp.get("error_pattern", None) ), - "errpatt_late_loss_rate": tx_cfg_tmp.get("errpatt_late_loss_rate", None), + "errpatt_late_loss_rate": tx_cfg_tmp.get( + "errpatt_late_loss_rate", None + ), "errpatt_delay": tx_cfg_tmp.get("errpatt_delay", None), "errpatt_seed": tx_cfg_tmp.get("errpatt_seed", None), "error_profile": tx_cfg_tmp.get("error_profile", None), @@ -364,6 +381,18 @@ def get_processing_chain( cod_cfg = cond_cfg["cod"] dec_cfg = cond_cfg["dec"] + # enable ESDRU and spatial distorition after IVAS condition + if cond_cfg.get("esdru_alpha", None) is not None: + tmp_esdru_alpha = cond_cfg.get("esdru_alpha", None) + + if (sd := cond_cfg.get("spatial_distortion", None)) is not None: + tmp_spatial_dist_amp = sd.get("amplitude", None) + tmp_spatial_dist_freq = sd.get("frequency", None) + if tmp_spatial_dist_amp is None or tmp_spatial_dist_freq is None: + raise ValueError( + "For spatial distortion amplitude and frequency values need to be given" + ) + # 9.6 kbit/s NB for EVS LFE coding only applies to EVS conditions evs_lfe_9k6bps_nb = cond_cfg.get("evs_lfe_9k6bps_nb", None) @@ -432,12 +461,18 @@ def get_processing_chain( ) tmp_in_fmt = cod_fmt + # allow list of output values for IVAS + tmp_out_fmt = dec_cfg.get("fmt", tmp_out_fmt) + if isinstance(tmp_out_fmt, list): + cond_fmt.extend(tmp_out_fmt) + tmp_out_fmt = tmp_out_fmt[0] + chain["processes"].append( IVAS( { "in_fmt": tmp_in_fmt, "in_fs": tmp_in_fs, - "out_fmt": dec_cfg.get("fmt", tmp_out_fmt), + "out_fmt": tmp_out_fmt, "out_fs": dec_cfg.get("fs", tmp_in_fs), "bitrate": bitrate, "cod_bin": get_abs_path(cod_cfg.get("bin", None)), @@ -454,7 +489,10 @@ def get_processing_chain( ) # update values to reflect decoder output tmp_in_fs = dec_cfg.get("fs", tmp_in_fs) - tmp_in_fmt = dec_cfg.get("fmt", tmp_out_fmt) + if isinstance(dec_cfg.get("fmt", tmp_out_fmt), list): + tmp_in_fmt = dec_cfg.get("fmt", tmp_out_fmt)[0] + else: + tmp_in_fmt = dec_cfg.get("fmt", tmp_out_fmt) else: raise SystemExit(f"Unknown condition {condition}!") @@ -479,7 +517,11 @@ def get_processing_chain( # add postprocessing step based on condition post_fmt = post_cfg.get("fmt") - if isinstance(post_fmt, list): + if isinstance(post_fmt, list) or len(cond_fmt) > 0: + if not isinstance(post_fmt, list): + post_fmt = [post_fmt] + cond_fmt.extend(post_fmt) + post_fmt = cond_fmt pre_fmts = post_fmt[:-1] post_fmt = post_fmt[-1] @@ -501,6 +543,10 @@ def get_processing_chain( ) tmp_in_fmt = fmt_out + # if LP filtering is defined in condition use that one + if cond_cfg.get("out_fc") is not None: + tmp_lp_cutoff = cond_cfg.get("out_fc") + chain["processes"].append( Postprocessing( { @@ -516,6 +562,8 @@ def get_processing_chain( "multiprocessing": cfg.multiprocessing, "mnru_q": tmp_mnru_q, "esdru_alpha": tmp_esdru_alpha, + "spatial_distortion_amplitude": tmp_spatial_dist_amp, + "spatial_distortion_frequency": tmp_spatial_dist_freq, "tx_condition": tx_condition, } ) diff --git a/ivas_processing_scripts/processing/config.py b/ivas_processing_scripts/processing/config.py index 1e6371a92526112d3d1b6f1f79ad8dea5d8ec61a..347cee8e862286e9f17418c29f4970ad11d4ca02 100755 --- a/ivas_processing_scripts/processing/config.py +++ b/ivas_processing_scripts/processing/config.py @@ -255,12 +255,14 @@ class TestConfig: f"The following key must be specified for ESDRU: {REQUIRED_KEYS_ESDRU}" ) - if cond_cfg.get("ivas_rend", -1) != -1: - merged_cfg = get_default_config_for_renderer("IVAS", codec_bin_extension) - merge_dicts(merged_cfg, cond_cfg) + if cfg["conditions_to_generate"][cond_name].get("ivas_rend", -1) != -1: + merged_cfg = get_default_config_for_renderer( + "IVAS", codec_bin_extension + ) + cond_cfg_rend = cfg["conditions_to_generate"][cond_name] + merge_dicts(merged_cfg, cond_cfg_rend) cfg["conditions_to_generate"][cond_name] = merged_cfg - def _validate_merged_config(self, cfg: dict): # if not on windows, but "use_windows_codec_binaries" is given, assure that wine is there if use_wine(cfg["use_windows_codec_binaries"]) and find_binary("wine") is None: diff --git a/ivas_processing_scripts/processing/evs.py b/ivas_processing_scripts/processing/evs.py index 791ff91f66fc3989be5953a902ddfed0ce248abf..2440eadb992cfd3aa8894e556edc6ebc6c3e8fd4 100755 --- a/ivas_processing_scripts/processing/evs.py +++ b/ivas_processing_scripts/processing/evs.py @@ -36,7 +36,7 @@ import platform from itertools import repeat from pathlib import Path from shutil import copyfile -from typing import Optional, Tuple, Union +from typing import Optional, Union from ivas_processing_scripts.audiotools import audio from ivas_processing_scripts.audiotools.audiofile import ( @@ -46,12 +46,14 @@ from ivas_processing_scripts.audiotools.audiofile import ( split_channels, ) from ivas_processing_scripts.audiotools.constants import IVAS_FRAME_LEN_MS +from ivas_processing_scripts.audiotools.wrappers.dlyerr_2_errpat import ( + evs_jbm, + validate_evs_jbm, +) from ivas_processing_scripts.audiotools.wrappers.eid_xor import ( create_and_apply_error_pattern, validate_error_pattern_application, ) -from ivas_processing_scripts.audiotools.wrappers.dlyerr_2_errpat import validate_evs_jbm -from ivas_processing_scripts.audiotools.wrappers.dlyerr_2_errpat import evs_jbm from ivas_processing_scripts.processing.processing import Processing from ivas_processing_scripts.utils import apply_func_parallel, run, use_wine diff --git a/ivas_processing_scripts/processing/ivas.py b/ivas_processing_scripts/processing/ivas.py index 7a68f4ea5ae996d31704529d1836655c845175d7..b9d5b339c5dd5ac02ddf48ee45e9ce5d7cb9bcd8 100755 --- a/ivas_processing_scripts/processing/ivas.py +++ b/ivas_processing_scripts/processing/ivas.py @@ -108,7 +108,9 @@ class IVAS(Processing): # set defaults in case input and output sampling rates were not specified if not self.in_fs: if in_file.suffix in [".pcm", ".raw"]: - raise ValueError("Sampling rate has to be specified for headerless files!") + raise ValueError( + "Sampling rate has to be specified for headerless files!" + ) elif in_file.suffix == ".txt": raise NotImplementedError(".txt file support is WIP!") else: @@ -291,7 +293,9 @@ class IVAS(Processing): # add -voip cmdline option to the decoder if voip: - cmd.extend(["-voip", "-Tracefile", f"{str(out_file).split('.')[0]}.tracefile.csv"]) + cmd.extend( + ["-voip", "-Tracefile", f"{str(out_file).split('.')[0]}.tracefile.csv"] + ) if self.dec_opts: cmd.extend(self.dec_opts) @@ -368,16 +372,16 @@ class IVAS_rend(Processing): if not hasattr(self, "opts"): self.dec_opts = None self._use_wine = ( - platform.system() == "Linux" and self.use_windows_codec_binaries + platform.system() == "Linux" and self.use_windows_codec_binaries ) def _validate(self): need_exe_suffix = ( - platform.system() == "Windows" or self.use_windows_codec_binaries + platform.system() == "Windows" or self.use_windows_codec_binaries ) if not Path(self.bin).exists(): if need_exe_suffix and ( - self.bin and Path(self.bin).with_suffix(".exe").exists() + self.bin and Path(self.bin).with_suffix(".exe").exists() ): self.bin = Path(self.bin).with_suffix(".exe") else: @@ -398,7 +402,9 @@ class IVAS_rend(Processing): # set defaults in case input sampling rate is not specified if not self.in_fs: if in_file.suffix in [".pcm", ".raw"]: - raise ValueError("Sampling rate has to be specified for headerless files!") + raise ValueError( + "Sampling rate has to be specified for headerless files!" + ) elif in_file.suffix == ".txt": raise NotImplementedError(".txt file support is WIP!") else: @@ -411,11 +417,16 @@ class IVAS_rend(Processing): cmd.extend( [ - "-fs", str(self.in_fs // 1000), - "-i", str(in_file), - "-if", self.in_fmt.name, - "-o", str(out_file), - "-of", self.out_fmt.name, + "-fs", + str(self.in_fs // 1000), + "-i", + str(in_file), + "-if", + self.in_fmt.name, + "-o", + str(out_file), + "-of", + self.out_fmt.name, ] ) diff --git a/ivas_processing_scripts/processing/processing.py b/ivas_processing_scripts/processing/processing.py index b8fda56bd9c3230ad1142c185ef0b3ab2fe7fd9a..db63c8fd787a329b64dc4819c4a5fa3c51a3de56 100755 --- a/ivas_processing_scripts/processing/processing.py +++ b/ivas_processing_scripts/processing/processing.py @@ -40,6 +40,7 @@ from shutil import copyfile from time import sleep from typing import Iterable, Union from warnings import warn + import numpy as np from ivas_processing_scripts.audiotools import audio @@ -174,14 +175,20 @@ def concat_setup(cfg: TestConfig, chain, logger: logging.Logger): logger.info(f"Splits written to file {splits_info_file}") -def concat_teardown(x, splits, out_fmt, fs, in_fs, meta, tracefile, ivas_jbm, logger: logging.Logger): +def concat_teardown( + x, splits, out_fmt, fs, in_fs, meta, tracefile, ivas_jbm, logger: logging.Logger +): if splits is None: raise ValueError("Splitting not possible without split marker") if ivas_jbm and tracefile is None: - raise ValueError("Splitting for IVAS JBM conditions not possible without tracefile") + raise ValueError( + "Splitting for IVAS JBM conditions not possible without tracefile" + ) if (out_fmt.startswith("ISM") or out_fmt.startswith("MASA")) and ivas_jbm: - raise ValueError("Splitting with JBM compensation not supportet for formats with metadata (e.g. MASA, ISM)") + raise ValueError( + "Splitting with JBM compensation not supportet for formats with metadata (e.g. MASA, ISM)" + ) if logger and ivas_jbm: logger.debug("Split files with JBM compensation") @@ -221,7 +228,9 @@ def concat_teardown(x, splits, out_fmt, fs, in_fs, meta, tracefile, ivas_jbm, lo if (num := entry[1] / rtpTimeScale - split_start) == 0: rtpTsRelErr = num else: - rtpTsRelErr = num / (((entry[1] - lastRtpTs) / rtpTimeScale) + sys.float_info.epsilon) + rtpTsRelErr = num / ( + ((entry[1] - lastRtpTs) / rtpTimeScale) + sys.float_info.epsilon + ) playTimeAbsErr = rtpTsRelErr * (entry[3] - lastPlayTime) / playTimeScale # found one split, save in list and search for next new_splits[i] = entry[3] / playTimeScale - playTimeAbsErr @@ -259,9 +268,9 @@ def concat_teardown(x, splits, out_fmt, fs, in_fs, meta, tracefile, ivas_jbm, lo split_signals = [] split_meta = [] - for idx in range(len(splits)-1): + for idx in range(len(splits) - 1): # split - y = x[splits[idx]:splits[idx+1], :] + y = x[splits[idx] : splits[idx + 1], :] # windowing y = window(y) @@ -275,7 +284,7 @@ def concat_teardown(x, splits, out_fmt, fs, in_fs, meta, tracefile, ivas_jbm, lo for obj_meta in meta: # compute number of frames per split split_frames = int(splits[idx] / IVAS_FRAME_LEN_MS / fs * 1000) - split_next_frames = int(splits[idx+1] / IVAS_FRAME_LEN_MS / fs * 1000) + split_next_frames = int(splits[idx + 1] / IVAS_FRAME_LEN_MS / fs * 1000) # split obj_meta = obj_meta[split_frames:split_next_frames, :] diff --git a/ivas_processing_scripts/processing/processing_splitting_scaling.py b/ivas_processing_scripts/processing/processing_splitting_scaling.py index 83a4ac16ffc5483c1e5e066244f87e383990be4b..b6a9e31c65d4679890cba67f962734969c0db519 100644 --- a/ivas_processing_scripts/processing/processing_splitting_scaling.py +++ b/ivas_processing_scripts/processing/processing_splitting_scaling.py @@ -212,7 +212,9 @@ class Processing_splitting_scaling(Processing): splits, split_names, split_fs = read_splits_file(splits_info_file) if self.ivas_jbm and not noerror: # read out tracefile with jbm info - tracefile_info_file = Path(f"{in_file.with_suffix('').with_suffix('')}.tracefile.csv") + tracefile_info_file = Path( + f"{in_file.with_suffix('').with_suffix('')}.tracefile.csv" + ) tracefile_info = np.genfromtxt(tracefile_info_file, delimiter=";") validate_tracefile(tracefile_info) else: @@ -226,7 +228,15 @@ class Processing_splitting_scaling(Processing): ivas_jbm_splitting_flag = False file_splits, meta_splits, new_splits = concat_teardown( - x, splits, self.out_fmt, fs, split_fs, in_meta, tracefile_info, ivas_jbm_splitting_flag, logger + x, + splits, + self.out_fmt, + fs, + split_fs, + in_meta, + tracefile_info, + ivas_jbm_splitting_flag, + logger, ) # write out new splits @@ -323,7 +333,6 @@ def measure_loudness(file_splits, out_fmt, fs, loudness, loudness_fmt, meta, log def validate_tracefile(tracefile): - prevPlayTime = -1 prevRtpTs = -1 for j in range(tracefile.shape[0]): @@ -333,7 +342,9 @@ def validate_tracefile(tracefile): if entry[3] < 0: raise ValueError(f"Error in JBM trace file at line {j}: playTime < 0") if entry[3] <= prevPlayTime: - raise ValueError(f"Error in JBM trace file at line {j}: playTime not strictly increasing") + raise ValueError( + f"Error in JBM trace file at line {j}: playTime not strictly increasing" + ) prevPlayTime = entry[3] # require playTime > rcvTime @@ -343,7 +354,9 @@ def validate_tracefile(tracefile): # rtpTs must be strictly increasing if entry[1] >= 0: if entry[1] == prevRtpTs: - raise ValueError(f"Error in JBM trace file at line {j}: duplicated rtpTs found") + raise ValueError( + f"Error in JBM trace file at line {j}: duplicated rtpTs found" + ) # TODO: (treffehn) include RTP time stamp overflow handling? # else if (entry.rtpTs + rtpTsExtension < prevRtpTs) { # if (entry.rtpTs + rtpTsExtension + (1LL << 32) - prevRtpTs < diff --git a/ivas_processing_scripts/utils.py b/ivas_processing_scripts/utils.py index 7f593affdebe1c8fd404d2b51ea8210c95637726..18e5c6754002eb283489f8ae5f98cf796a7aa481 100755 --- a/ivas_processing_scripts/utils.py +++ b/ivas_processing_scripts/utils.py @@ -31,10 +31,10 @@ # import logging +import platform import shutil import subprocess as sp import sys -import platform from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor from itertools import cycle, repeat, tee from os import devnull