Commit 37d12f10 authored by Anika Treffehn's avatar Anika Treffehn
Browse files

Merge branch...

Merge branch '6-evs-multi-channel-configurations-add-option-to-code-lfe-with-9-6-kbit-s-nb-evs' into 'main'

Resolve "EVS Multi-channel configurations: Add option to code LFE with 9.6 kbit/s NB EVS"

See merge request !31
parents eea25d7b 075a0733
Loading
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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`.
+4 −0
Original line number Diff line number Diff line
@@ -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
+13 −0
Original line number Diff line number Diff line
@@ -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(
                "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
+38 −3
Original line number Diff line number Diff line
@@ -100,6 +100,17 @@ 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 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:
            if self.tx.get("type", None) == "JBM":
@@ -176,7 +187,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, 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 +265,30 @@ 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:
            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:
            if self.cod_opts:
            cmd.extend(self.cod_opts)
                cod_opts = self.cod_opts
            else:
                cod_opts = []

        cmd.extend(cod_opts)

        cmd.extend(
            [