Commit 8546bbd9 authored by Anika Treffehn's avatar Anika Treffehn
Browse files

added ivas jbm condition splitting compensation

parent 31c1c37b
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -238,6 +238,7 @@ def get_processing_chain(
    tmp_mnru_q = None
    tmp_esdru_alpha = None
    tx_condition = False
    ivas_jbm = False

    # override / add values based on specific conditions
    cond_cfg = cfg.conditions_to_generate[condition]
@@ -395,6 +396,7 @@ def get_processing_chain(
                    "error_profile": tx_cfg_tmp.get("error_profile", None),
                    "n_frames_per_packet": tx_cfg_tmp.get("n_frames_per_packet", None),
                }
                ivas_jbm = True
            else:
                raise ValueError(
                    "Type of bitstream procesing either missing or not valid"
@@ -507,6 +509,7 @@ def get_processing_chain(
                "loudness_fmt": post_cfg.get("loudness_fmt", None),
                "tx_condition": tx_condition,
                "condition_in_output_filename": cfg.condition_in_output_filename,
                "ivas_jbm": ivas_jbm,
            }
        )
    )
+73 −57
Original line number Diff line number Diff line
@@ -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
from ivas_processing_scripts.audiotools.audioarray import window
@@ -173,74 +174,92 @@ 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, logger: logging.Logger):
    if not splits:
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")

    if logger:
    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)")

    if logger and ivas_jbm:
        logger.debug("Split files with JBM compensation")
    elif logger:
        logger.debug("Split files")

    if not ivas_jbm:
        # if sampling rate changed, adjust splits
        fs_new = float(fs)
        fs_old = float(in_fs)
        relative_fs_change = fs_new / fs_old
    new_splits = []
        new_splits = [0]
        for split_i in splits:
            new_splits.append(int(float(split_i) * relative_fs_change))
        splits = new_splits
    # TODO: add jbmtrim compensation
#     rtpTsRelErr = (entry.rtpTs / rtpTimeScale - nextCutTime) / ((entry.rtpTs - lastRtpTs) / rtpTimeScale);
#     double
#     playTimeAbsErr = rtpTsRelErr * (entry.playTime - lastPlayTime) / playTimeScale;
#     if (currBeginPlayTime < 0) {
#     // found begin of item
#     currBeginPlayTime = entry.playTime / playTimeScale - playTimeAbsErr;
#     // now look for end of item
#     nextCutTime += itemLength;
#     }
#     else {
#     // found complete item
#     double currEndPlayTime = entry.playTime / playTimeScale - playTimeAbsErr;
#     mappedStart = currBeginPlayTime;
#     mappedLength = currEndPlayTime - currBeginPlayTime;
#     return true;
#     }
#     }
#     lastRtpTs = entry.rtpTs;
#     lastPlayTime = entry.playTime;
#     }
#     // check if item
#     begin
#     was
#     found
#     if (currBeginPlayTime < 0)
#     {
#         cerr << "Invalid item start position specified: " << itemStart << endl;
#
#
# return false;
# }
# // return item
# with missing end
# mappedStart = currBeginPlayTime;
# mappedLength = lastPlayTime / playTimeScale - currBeginPlayTime;
    else:
        # adjust splits for jbm ivas conditions
        # following code is based on jbmtrim.cpp script
        rtpTimeScale = 1000  # in ms
        playTimeScale = 1000  # in ms
        new_splits = [None] * (len(splits) + 1)

        split_start = 0
        i = 0
        lastRtpTs = 0
        lastPlayTime = 0
        # find last JBM trace entry with lower or equal RTP time stamp
        for j in range(tracefile.shape[0]):
            entry = tracefile[j]
            # ignore frames with unknown RTP time stamp or playout time
            if entry[1] == -1 or entry[3] < 0:
                continue
            # check if the next position to cut is found
            if entry[1] / rtpTimeScale >= split_start:
                # interpolate between current and previous RTP time stamp to
                # increase accuracy in case of DTX where lot of time stamps are missing
                if (num := entry[1] / rtpTimeScale - split_start) == 0:
                    rtpTsRelErr = num
                else:
                    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
                split_start = float(splits[i]) / float(fs)
                i += 1
                if i >= len(new_splits):
                    break
            lastRtpTs = entry[1]
            lastPlayTime = entry[3]

        # check if all splits are found
        if i < (len(new_splits) - 1):
            raise ValueError("Error in item splitting with JBM compensation")
        elif i < (len(new_splits)):
            # catch item with missing end
            warn("Last split after end of file for IVA JBM condition")
            new_splits[i] = lastPlayTime / playTimeScale

        # set new values and use new sampling rate
        splits = new_splits
        for s in range(len(splits)):
            splits[s] = int(np.floor(splits[s] * float(in_fs)))

    # check if last split ending coincides with last sample of signal
    if splits[-1] > len(x):
        raise ValueError(
            f"Last split index {splits[-1]} is larger than the signal length {len(x)}"
        )
    elif splits[-1] < len(x):
    elif (splits[-1] < len(x)) and not ivas_jbm:
        warn(
            f"Last split index {splits[-1]} is smaller than the signal length {len(x)}"
        )

    split_old = 0
    split_signals = []
    split_meta = []
    for idx, split in enumerate(splits):
    for idx in range(len(splits)-1):
        # split
        y = x[split_old:split, :]
        y = x[splits[idx]:splits[idx+1], :]

        # windowing
        y = window(y)
@@ -250,15 +269,14 @@ def concat_teardown(x, splits, out_fmt, fs, in_fs, meta, tracefile, logger: logg

        # split ISM metadata
        if out_fmt.startswith("ISM"):
            # TODO: (treffehn) add error message if output is ism or masa and jbm was used
            split_meta_object = []
            for obj_meta in meta:
                # compute number of frames per split
                split_old_frames = int(split_old / IVAS_FRAME_LEN_MS / fs * 1000)
                split_frames = int(split / IVAS_FRAME_LEN_MS / fs * 1000)
                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
                obj_meta = obj_meta[split_old_frames:split_frames, :]
                obj_meta = obj_meta[split_frames:split_next_frames, :]

                # add signal to list
                split_meta_object.append(obj_meta)
@@ -267,8 +285,6 @@ def concat_teardown(x, splits, out_fmt, fs, in_fs, meta, tracefile, logger: logg
        else:
            split_meta = repeat(None)

        split_old = split

    return split_signals, split_meta


+2 −3
Original line number Diff line number Diff line
@@ -210,8 +210,7 @@ class Processing_splitting_scaling(Processing):
                )
            )
            splits, split_names, split_fs = read_splits_file(splits_info_file)
            # TODO: (treffehn) if jbm and ivas instead of noerror
            if not noerror:
            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 = np.genfromtxt(tracefile_info_file, delimiter=";")
@@ -220,7 +219,7 @@ class Processing_splitting_scaling(Processing):

            # split file
            file_splits, meta_splits = concat_teardown(
                x, splits, self.out_fmt, fs, split_fs, in_meta, tracefile_info, logger
                x, splits, self.out_fmt, fs, split_fs, in_meta, tracefile_info, self.ivas_jbm, logger
            )

            # set new out_files