Commit 0babb6b9 authored by Jan Kiene's avatar Jan Kiene
Browse files

add 1st version util functions for head rot and br switching

parent 14b375eb
Loading
Loading
Loading
Loading
+34 −3
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ the United Nations Convention on Contracts on the International Sales of Goods.
"""

import pytest
import numpy as np
from . import (
    is_be_to_ref,
    get_bitstream_path,
@@ -41,6 +42,7 @@ from . import (
from .constants import *
from pathlib import Path
import subprocess
import random
from contextlib import contextmanager
from tempfile import TemporaryDirectory

@@ -48,6 +50,32 @@ from tempfile import TemporaryDirectory
### --------------- Helper functions ---------------


def create_head_rotation_file(
    trajectory: np.ndarray,
    strategy: str,
    switch_time: int,
    length_frames: int,
    axis: str = None,
):
    assert strategy in ["from_array", "rotate_axis", "constant"]

    length_str = f"-l{length_frames}" if length_frames > 0 else ""
    fname = f"head_rotation_trajectory-{strategy}-{switch_time}{length_str}"

    if strategy == "from_array":
        rots = trajectory
    elif strategy == "rotate_axis":
        raise NotImplementedError("only idea for now")
    elif strategy == "constant":
        assert len(trajectory) == 1
        rots = np.repeat(trajectory, length_frames)

    out_path = DUT_PATH.joinpath(fname)
    rots.astype(np.int32).tofile(out_path)

    return out_path


def get_output_path(bitstream_path, output_format, output_sampling_rate):
    output_name = (
        f"{bitstream_path.stem}.dec-{output_format}-{output_sampling_rate}kHz.wav"
@@ -61,6 +89,9 @@ def get_bitstream_and_options(
):
    """
    Utility to get either the stored reference bitstream or the processed version as a temporary file

    The reason for implementing this as a context manager instead of a simple function is that this way
    the temporary processed bitstream files are cleaned up automatically and do not exploce disk space even more...
    """
    options = list()
    with TemporaryDirectory() as tmp_dir:
@@ -201,7 +232,7 @@ def test_decoder_objectbased(
            str(dut_output),
            dut_decoder_frontend,
            update_ref == 1,
            add_option_list=options
            add_option_list=options,
        )


@@ -243,7 +274,7 @@ def test_decoder_scenebased(
            str(dut_output),
            dut_decoder_frontend,
            update_ref == 1,
            add_option_list=options
            add_option_list=options,
        )


@@ -291,5 +322,5 @@ def test_decoder_combined_formats(
            str(dut_output),
            dut_decoder_frontend,
            update_ref == 1,
            add_option_list=options
            add_option_list=options,
        )
+22 −14
Original line number Diff line number Diff line
@@ -53,44 +53,52 @@ from . import TESTV_PATH, DUT_PATH, is_be_to_ref, get_bitstream_path, get_testv_
### --------------- Helper functions ---------------


def create_br_switching_file(bitrates: np.ndarray, strategy: str, switch_time: int, length_frames: int, seed: int=None):
def create_br_switching_file(
    bitrates: np.ndarray,
    strategy: str,
    switch_time: int,
    length_frames: int = 0,
    seed: int = None,
):
    """
    Create bitrate switching pattern files on the fly and return path to it

    bitrates - array of bitrate values to include
    strategy - how to create pattern:
        "from_list" - use given array as is
        "from_array" - use given array as is
        "exhaustive" - generate array where every bitrate is preceeded and followed at least once by every other bitrate
        "random" - randomly pick from bitrates
    switch_time - number of frames before next switch
    length_frames - for "random" strategy: length of pattern in frames
    seed - for "exhaustive" and "random" strategies: inject seed for shuffling/choosing from array
    """
    assert strategy in ["from_list", "exhaustive", "random"]
    assert strategy in ["from_array", "exhaustive", "random"]

    seed_str = f"_{seed}" if strategy == "random" else ""
    fname = f"br_sw_pattern-{strategy}{seed_str}-{switch_time}"
    seed_str = f"_{seed}" if strategy == "random" or strategy == "exhaustive" else ""
    length_str = f"-l{length_frames}" if length_frames > 0 else ""
    fname = f"br_sw_pattern-{strategy}{seed_str}-{switch_time}{length_str}"

    # TODO: maybe calculate seed based on given parameter to automatically have reproducibility
    if seed is not None:
        random.seed(seed)

    if strategy == "from_list":
        brs = bitrates.astype(np.int32)
    elif strategy == "exhaustive":
    brs = np.asarray(bitrates)

    # NOTE: nothing to do for from_array
    if strategy == "exhaustive":
        # TODO: review, probably needs more work to be really exhaustive...
        n = len(bitrates) - 1
        permuts = permutations(bitrates, 2)
        split_permuts = [permuts[i * n: (i + 1) * n] for i in range(len(bitrates))]
        n = len(brs) - 1
        permuts = list(permutations(brs, 2))
        split_permuts = [permuts[i * n : (i + 1) * n] for i in range(len(brs))]
        for i in range(len(split_permuts)):
            random.shuffle(split_permuts[i])
        split_permuts = np.asarray(split_permuts)
        brs = np.concatenate([split_permuts[:, i] for i in range(n)]).astype(np.int32)
        brs = np.concatenate([split_permuts[:, i] for i in range(n)])
    elif strategy == "random":
        brs = np.asarray(random.choices(bitrates, k=length_frames)).astype(np.int32)
        brs = np.asarray(random.choices(brs, k=length_frames))

    out_path = DUT_PATH.joinpath(fname)
    brs.astype.tofile(out_path)
    brs.astype(np.int32).tofile(out_path)

    return out_path