From 457b72815b57587e116b026248fe4378c3c3af5b Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Mon, 1 May 2023 16:51:46 +0200 Subject: [PATCH 1/9] initial version --- examples/TEMPLATE.yml | 4 ++++ ivas_processing_scripts/processing/chains.py | 13 +++++++++++ ivas_processing_scripts/processing/evs.py | 24 ++++++++++++++++++-- 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/examples/TEMPLATE.yml b/examples/TEMPLATE.yml index 47f6a195..1968aee5 100755 --- a/examples/TEMPLATE.yml +++ b/examples/TEMPLATE.yml @@ -247,11 +247,15 @@ conditions_to_generate: bitrates: # - 9600 - [13200, 13200, 8000, 13200, 9600] + ### for multi-channel configs, code LFE with 9.6 kbps NB (as mandated by IVAS-3) + evs_lfe_9k6bps_nb: true + ### Encoder options cod: ### Path to encoder binary; default search for IVAS_cod in bin folder (primary) and PATH (secondary) bin: ~/git/ivas-codec/IVAS_cod ### Encoder input sampling rate in Hz (resampling performed in case of mismatch); default = null (no resampling) # fs: 32000 + ### Decoder options dec: ### Path to encoder binary; default search for IVAS_dec in bin folder (primary) and PATH (secondary) bin: ~/git/ivas-codec/IVAS_dec diff --git a/ivas_processing_scripts/processing/chains.py b/ivas_processing_scripts/processing/chains.py index 027ac447..54df54b6 100755 --- a/ivas_processing_scripts/processing/chains.py +++ b/ivas_processing_scripts/processing/chains.py @@ -32,6 +32,7 @@ from pathlib import Path from typing import Optional +from warnings import warn from ivas_processing_scripts.processing.config import TestConfig from ivas_processing_scripts.processing.evs import EVS @@ -242,6 +243,9 @@ def get_processing_chain( cod_cfg = cond_cfg["cod"] dec_cfg = cond_cfg["dec"] + # 9.6 kbit/s NB for EVS LFE coding + evs_lfe_9k6bps_nb = cond_cfg.get("evs_lfe_9k6bps_nb", None) + # Frame error pattern bitstream modification if "tx" in cond_cfg.keys() or hasattr(cfg, "tx"): # local specification overwrites global one @@ -295,6 +299,7 @@ def get_processing_chain( "multiprocessing": cfg.multiprocessing, "tx": tx_cfg, "preamble": preamble, + "evs_lfe_9k6bps_nb": evs_lfe_9k6bps_nb, } ) ) @@ -305,6 +310,14 @@ def get_processing_chain( cod_cfg = cond_cfg["cod"] dec_cfg = cond_cfg["dec"] + # 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) + + if evs_lfe_9k6bps_nb is not None: + warn( + f"Option evs_lfe_9k6bps_nb only applicable to evs conditions - ignoring for ivas." + ) + # Frame error pattern bitstream modification if "tx" in cond_cfg.keys() or hasattr(cfg, "tx"): # local specification overwrites global one diff --git a/ivas_processing_scripts/processing/evs.py b/ivas_processing_scripts/processing/evs.py index ebe6ebf0..55e1e88a 100755 --- a/ivas_processing_scripts/processing/evs.py +++ b/ivas_processing_scripts/processing/evs.py @@ -33,6 +33,7 @@ import logging import os.path import platform +import re from itertools import repeat from pathlib import Path from shutil import copyfile @@ -100,6 +101,15 @@ class EVS(Processing): self.bitrate.extend( [self.bitrate[-1]] * (self.in_fmt.num_channels - len(self.bitrate)) ) + + # special handling for LFE: check, whether evs_lfe_9k6bps_nb is true in multi-channel configs + self.proc_chan_lfe_9k6bps_nb = [False] * self.in_fmt.num_channels + if self.in_fmt.lfe_index is not None and self.evs_lfe_9k6bps_nb is True: + lfe_index = self.in_fmt.lfe_index + for i in lfe_index: + self.bitrate[i] = 9600 + self.proc_chan_lfe_9k6bps_nb[i] = True + # existence of error pattern files (if given) already here if self.tx is not None: if self.tx.get("type", None) == "JBM": @@ -176,7 +186,7 @@ class EVS(Processing): logger.debug(f"Running EVS encoders for {out_file.stem.split('.')[0]}") apply_func_parallel( self.enc, - zip(split_chan_files, split_chan_bs, self.bitrate, repeat(logger)), + zip(split_chan_files, split_chan_bs, self.bitrate, self.proc_chan_lfe_9k6bps_nb, repeat(logger)), None, "mt" if self.multiprocessing else None, show_progress=False, @@ -248,12 +258,22 @@ class EVS(Processing): in_pcm_file: Path, bitstream: Path, bitrate: int, + proc_chan_lfe_9k6bps_nb: bool, logger: Optional[logging.Logger] = None, ) -> None: cmd = [self.cod_bin] + # in case of LFE 9.6 kbps NB processing strip any "-max_band XX" from cmd.extend and amend by "-max_band NB" + if proc_chan_lfe_9k6bps_nb is True: + cod_opts = [] + regex = re.compile(r'-max_band.*') + cod_opts = [i for i in self.cod_opts if not regex.match(i)] + cod_opts.append('-max_band NB') + else: + cod_opts = self.cod_opts + if self.cod_opts: - cmd.extend(self.cod_opts) + cmd.extend(cod_opts) cmd.extend( [ -- GitLab From b5b9ef94eeb6ac1f085f4a63538a89778278384b Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Mon, 1 May 2023 17:11:07 +0200 Subject: [PATCH 2/9] fixed regex --- ivas_processing_scripts/processing/evs.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/ivas_processing_scripts/processing/evs.py b/ivas_processing_scripts/processing/evs.py index 55e1e88a..911203fb 100755 --- a/ivas_processing_scripts/processing/evs.py +++ b/ivas_processing_scripts/processing/evs.py @@ -266,9 +266,22 @@ class EVS(Processing): # in case of LFE 9.6 kbps NB processing strip any "-max_band XX" from cmd.extend and amend by "-max_band NB" if proc_chan_lfe_9k6bps_nb is True: cod_opts = [] - regex = re.compile(r'-max_band.*') - cod_opts = [i for i in self.cod_opts if not regex.match(i)] - cod_opts.append('-max_band NB') + # search for + regex = re.compile(r'-max_band.*', re.I) + last_was_max_band = False + for i in self.cod_opts: + # the additional arguments are expected in form of a list, where "-max_band" are "SWB" are two entries + # then when we have detected "-max_band" in the previous run, we have to skip i again + if last_was_max_band is True: + last_was_max_band = False + continue + if regex.match(i): + last_was_max_band = True + else: + cod_opts.append(i) + last_was_max_band = False + cod_opts.append('-max_band') + cod_opts.append('NB') else: cod_opts = self.cod_opts -- GitLab From 10a91031abb32889b913ddcc74e1df6bcaea9871 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Mon, 1 May 2023 17:11:33 +0200 Subject: [PATCH 3/9] comments --- ivas_processing_scripts/processing/evs.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ivas_processing_scripts/processing/evs.py b/ivas_processing_scripts/processing/evs.py index 911203fb..b2e3366f 100755 --- a/ivas_processing_scripts/processing/evs.py +++ b/ivas_processing_scripts/processing/evs.py @@ -266,7 +266,7 @@ class EVS(Processing): # in case of LFE 9.6 kbps NB processing strip any "-max_band XX" from cmd.extend and amend by "-max_band NB" if proc_chan_lfe_9k6bps_nb is True: cod_opts = [] - # search for + # search for -max_band XXX regex = re.compile(r'-max_band.*', re.I) last_was_max_band = False for i in self.cod_opts: @@ -280,6 +280,7 @@ class EVS(Processing): else: cod_opts.append(i) last_was_max_band = False + # add -max_band NB cod_opts.append('-max_band') cod_opts.append('NB') else: -- GitLab From bb17591c617d226f4acb679a90f913165990b483 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Mon, 1 May 2023 18:01:50 +0200 Subject: [PATCH 4/9] apply special LFE handlung only for channel-based audio --- ivas_processing_scripts/processing/evs.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/ivas_processing_scripts/processing/evs.py b/ivas_processing_scripts/processing/evs.py index b2e3366f..73e8ec2e 100755 --- a/ivas_processing_scripts/processing/evs.py +++ b/ivas_processing_scripts/processing/evs.py @@ -104,11 +104,13 @@ class EVS(Processing): # special handling for LFE: check, whether evs_lfe_9k6bps_nb is true in multi-channel configs self.proc_chan_lfe_9k6bps_nb = [False] * self.in_fmt.num_channels - if self.in_fmt.lfe_index is not None and self.evs_lfe_9k6bps_nb is True: - lfe_index = self.in_fmt.lfe_index - for i in lfe_index: - self.bitrate[i] = 9600 - self.proc_chan_lfe_9k6bps_nb[i] = True + # if channel-based audio, determine the LFE channels + if isinstance(self.in_fmt, audio.ChannelBasedAudio): + if self.in_fmt.lfe_index is not None and self.evs_lfe_9k6bps_nb is True: + lfe_index = self.in_fmt.lfe_index + for i in lfe_index: + self.bitrate[i] = 9600 + self.proc_chan_lfe_9k6bps_nb[i] = True # existence of error pattern files (if given) already here if self.tx is not None: -- GitLab From 80dee299f4ef6b9a0107f2b19d2089cb78312f11 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Mon, 1 May 2023 19:09:44 +0200 Subject: [PATCH 5/9] formatting --- .../audiotools/wrappers/gen_patt.py | 2 +- ivas_processing_scripts/processing/chains.py | 2 +- ivas_processing_scripts/processing/evs.py | 14 ++++++++++---- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/ivas_processing_scripts/audiotools/wrappers/gen_patt.py b/ivas_processing_scripts/audiotools/wrappers/gen_patt.py index f801b07b..d8737ef4 100644 --- a/ivas_processing_scripts/audiotools/wrappers/gen_patt.py +++ b/ivas_processing_scripts/audiotools/wrappers/gen_patt.py @@ -138,7 +138,7 @@ def create_error_pattern( gen_patt(100, "ep.g192", 5, working_dir=tmp_dir_test) if not tmp_sta_file_test.exists(): raise RuntimeError( - "Used version of gen-patt was detected to be faulty (unable to write \"sta\"-file). See bin/README.md for details." + 'Used version of gen-patt was detected to be faulty (unable to write "sta"-file). See bin/README.md for details.' ) with TemporaryDirectory() as tmp_dir: diff --git a/ivas_processing_scripts/processing/chains.py b/ivas_processing_scripts/processing/chains.py index 54df54b6..6d857f68 100755 --- a/ivas_processing_scripts/processing/chains.py +++ b/ivas_processing_scripts/processing/chains.py @@ -316,7 +316,7 @@ def get_processing_chain( if evs_lfe_9k6bps_nb is not None: warn( f"Option evs_lfe_9k6bps_nb only applicable to evs conditions - ignoring for ivas." - ) + ) # Frame error pattern bitstream modification if "tx" in cond_cfg.keys() or hasattr(cfg, "tx"): diff --git a/ivas_processing_scripts/processing/evs.py b/ivas_processing_scripts/processing/evs.py index 73e8ec2e..211f8f09 100755 --- a/ivas_processing_scripts/processing/evs.py +++ b/ivas_processing_scripts/processing/evs.py @@ -188,7 +188,13 @@ class EVS(Processing): logger.debug(f"Running EVS encoders for {out_file.stem.split('.')[0]}") apply_func_parallel( self.enc, - zip(split_chan_files, split_chan_bs, self.bitrate, self.proc_chan_lfe_9k6bps_nb, repeat(logger)), + zip( + split_chan_files, + split_chan_bs, + self.bitrate, + self.proc_chan_lfe_9k6bps_nb, + repeat(logger), + ), None, "mt" if self.multiprocessing else None, show_progress=False, @@ -269,7 +275,7 @@ class EVS(Processing): if proc_chan_lfe_9k6bps_nb is True: cod_opts = [] # search for -max_band XXX - regex = re.compile(r'-max_band.*', re.I) + regex = re.compile(r"-max_band.*", re.I) last_was_max_band = False for i in self.cod_opts: # the additional arguments are expected in form of a list, where "-max_band" are "SWB" are two entries @@ -283,8 +289,8 @@ class EVS(Processing): cod_opts.append(i) last_was_max_band = False # add -max_band NB - cod_opts.append('-max_band') - cod_opts.append('NB') + cod_opts.append("-max_band") + cod_opts.append("NB") else: cod_opts = self.cod_opts -- GitLab From f631c76cb8bc284470ac50a591c5e97d25231fed Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Mon, 1 May 2023 19:21:59 +0200 Subject: [PATCH 6/9] flake warnig --- ivas_processing_scripts/processing/chains.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivas_processing_scripts/processing/chains.py b/ivas_processing_scripts/processing/chains.py index 6d857f68..0eb913a0 100755 --- a/ivas_processing_scripts/processing/chains.py +++ b/ivas_processing_scripts/processing/chains.py @@ -315,7 +315,7 @@ def get_processing_chain( if evs_lfe_9k6bps_nb is not None: warn( - f"Option evs_lfe_9k6bps_nb only applicable to evs conditions - ignoring for ivas." + "Option evs_lfe_9k6bps_nb only applicable to evs conditions - ignoring for ivas." ) # Frame error pattern bitstream modification -- GitLab From 9fe68a63034a9043b846585d86b4380b94d1eab1 Mon Sep 17 00:00:00 2001 From: Treffehn Date: Wed, 3 May 2023 15:38:15 +0200 Subject: [PATCH 7/9] fixed bug when no cod_opts are given and simplified function --- ivas_processing_scripts/processing/evs.py | 37 +++++++++-------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/ivas_processing_scripts/processing/evs.py b/ivas_processing_scripts/processing/evs.py index 211f8f09..6818170b 100755 --- a/ivas_processing_scripts/processing/evs.py +++ b/ivas_processing_scripts/processing/evs.py @@ -33,7 +33,6 @@ import logging import os.path import platform -import re from itertools import repeat from pathlib import Path from shutil import copyfile @@ -273,29 +272,23 @@ class EVS(Processing): # in case of LFE 9.6 kbps NB processing strip any "-max_band XX" from cmd.extend and amend by "-max_band NB" if proc_chan_lfe_9k6bps_nb is True: - cod_opts = [] - # search for -max_band XXX - regex = re.compile(r"-max_band.*", re.I) - last_was_max_band = False - for i in self.cod_opts: - # the additional arguments are expected in form of a list, where "-max_band" are "SWB" are two entries - # then when we have detected "-max_band" in the previous run, we have to skip i again - if last_was_max_band is True: - last_was_max_band = False - continue - if regex.match(i): - last_was_max_band = True - else: - cod_opts.append(i) - last_was_max_band = False - # add -max_band NB - cod_opts.append("-max_band") - cod_opts.append("NB") + if self.cod_opts: + cod_opts = self.cod_opts + # for finding index of max_band entry use lower case version + cod_opts_lower = [x.lower() for x in self.cod_opts] + if "-max_band" in cod_opts_lower: + idx_max_band = cod_opts_lower.index("-max_band") + # use original version and not lower case version due to possible paths in there + cod_opts[idx_max_band+1] = "NB" + else: + cod_opts = ["-max_band", "NB"] else: - cod_opts = self.cod_opts + if self.cod_opts: + cod_opts = self.cod_opts + else: + cod_opts = [] - if self.cod_opts: - cmd.extend(cod_opts) + cmd.extend(cod_opts) cmd.extend( [ -- GitLab From 9b9f8ba034f6b1da0ed7c254ebb9fb13b3d30a5f Mon Sep 17 00:00:00 2001 From: Treffehn Date: Wed, 3 May 2023 15:41:22 +0200 Subject: [PATCH 8/9] formatting --- ivas_processing_scripts/processing/evs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivas_processing_scripts/processing/evs.py b/ivas_processing_scripts/processing/evs.py index 6818170b..7c52eaab 100755 --- a/ivas_processing_scripts/processing/evs.py +++ b/ivas_processing_scripts/processing/evs.py @@ -279,7 +279,7 @@ class EVS(Processing): if "-max_band" in cod_opts_lower: idx_max_band = cod_opts_lower.index("-max_band") # use original version and not lower case version due to possible paths in there - cod_opts[idx_max_band+1] = "NB" + cod_opts[idx_max_band + 1] = "NB" else: cod_opts = ["-max_band", "NB"] else: -- GitLab From 075a0733dacba098839019566bc39bd4c1958d39 Mon Sep 17 00:00:00 2001 From: Treffehn Date: Wed, 3 May 2023 15:49:09 +0200 Subject: [PATCH 9/9] added info in Readme --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 07f1e541..990df678 100755 --- a/README.md +++ b/README.md @@ -386,6 +386,8 @@ conditions_to_generate: bitrates: # - 9600 - [13200, 13200, 8000, 13200, 9600] + ### for multi-channel configs, code LFE with 9.6 kbps NB (as mandated by IVAS-3) + evs_lfe_9k6bps_nb: true cod: ### Path to encoder binary; default search for IVAS_cod in bin folder (primary) and PATH (secondary) bin: ~/git/ivas-codec/IVAS_cod @@ -468,6 +470,7 @@ This configuration has to match the channel configuration. If the provided list For the encoding stage `cod` and the decoding stage `dec`, the path to the IVAS_cod and IVAS_dec binaries can be specified under the key `bin`. Additionally some resampling can be applied by using the key `fs` followed by the desired sampling rate. The general bitstream processing configuration can be locally overwritten for each EVS and IVAS condition with the key `tx`. +The additional key `evs_lfe_9k6bps_nb` is only available for EVS conditions and ensures a bitrate of 9.6kbps and narrow band processing of the LFE channel(s). #### IVAS The configuration of the IVAS condition is similar to the EVS condition. However, only one bitrate for all channels (and metadata) can be specified. In addition to that, the encoder and decoder take some additional arguments defined by the key `opts`. -- GitLab