Commit dc086029 authored by norvell's avatar norvell
Browse files

Add OMASA/OSBA rendering using scene description file

parent 70a89368
Loading
Loading
Loading
Loading
Loading
+164 −113
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import numpy as np
import pytest
import re
import errno
import tempfile

from .compare_audio import compare_audio_arrays
from .constants import (
@@ -377,6 +378,7 @@ def compare_renderer_args(
            f"CuT not BE to REF! SNR : {snr:3.2f} dB, Gain CuT: {gain_b:1.3f}, Max Diff = {int(max_diff)}"
        )


def binauralize_input_and_output(
    record_property,
    props_to_record,
@@ -392,34 +394,61 @@ def binauralize_input_and_output(
    out_sr,
):

    # Use current folder as location for temporary directory, since scene description does not handle spaces in path
    with tempfile.TemporaryDirectory(dir=".") as tmp_dir:
        tmp_dir = Path(tmp_dir)
        scene_out = str(tmp_dir.joinpath("scene_out.txt"))
        scene_in = str(tmp_dir.joinpath("scene_in.txt"))

        # File names for binauralized input, if needed
        dut_output_file_binaural = dut_output_file[0:-4] + ".BINAURAL.wav"
        ref_output_file_binaural = ref_output_file[0:-4] + ".BINAURAL.wav"

        # Identify metadata
    in_meta_files = [str(SCRIPTS_DIR.joinpath(m)) for m in re.findall(r'\b\S+\.csv\b', enc_opts)] # All .csv files in enc_opts are ISM metadata files.
    in_meta_files = in_meta_files + [str(SCRIPTS_DIR.joinpath(m)) for m in re.findall(r'\b\S+\.met\b', enc_opts)] # All .met files in enc_opts are MASA metadata files.
        in_meta_files = [
            str(SCRIPTS_DIR.joinpath(m)) for m in re.findall(r"\b\S+\.csv\b", enc_opts)
        ]  # All .csv files in enc_opts are ISM metadata files.
        in_meta_files = in_meta_files + [
            str(SCRIPTS_DIR.joinpath(m)) for m in re.findall(r"\b\S+\.met\b", enc_opts)
        ]  # All .met files in enc_opts are MASA metadata files.
        n_obj = len(in_meta_files)
        out_meta_files = None
        if output_config == "EXT":
        if "ISM" in in_fmt and n_obj > 0:
            out_meta_files = [f"{dut_output_file}.{i}.csv" for i in range(0,n_obj)]
            out_meta_files = []
            if n_obj > 0:
                out_meta_files = out_meta_files + [
                    f"{dut_output_file}.{i}.csv" for i in range(0, n_obj)
                ]
            if "MASA" in in_fmt:
            out_meta_files = [f"{dut_output_file}.met"]
                out_meta_files = out_meta_files + [f"{dut_output_file}.met"]
        if output_config == "EXT":
            output_config = in_fmt
        if output_config == "":
            output_config = "MONO"  # EVS mono
    metadata_input = None # Todo: This can be used for OMASA/OSBA rendering
        metadata_input = None

        if "OSBA" in in_fmt or "OMASA" in in_fmt:
            scene_description_file(in_fmt, scene_in, n_obj, input_file, in_meta_files)
            input_file = scene_in
            in_meta_files = None
            in_fmt = "META"

        if "OSBA" in output_config or "OMASA" in output_config:
            scene_description_file(
                output_config, scene_out, n_obj, dut_output_file, out_meta_files
            )
            dut_output_file = scene_out
            out_meta_files = None
            output_config = "META"

        # Identify headtracking and orientation trajectories
    trj_file = findstr(r'-t\s+(\S+)', dec_opts)
    non_diegetic_pan = findstr(r'-non_diegetic_pan\s+(\S+)', dec_opts)
        trj_file = findstr(r"-t\s+(\S+)", dec_opts)
        non_diegetic_pan = findstr(r"-non_diegetic_pan\s+(\S+)", dec_opts)
        if non_diegetic_pan is not None:
            output_config = "STEREO"
        name_extension = None
    refrot_file = findstr(r'-rf\s+(\S+)', dec_opts)
    rot_tmp_file = findstr(r'-rvf\s+(\S+)', dec_opts)
        refrot_file = findstr(r"-rf\s+(\S+)", dec_opts)
        rot_tmp_file = findstr(r"-rvf\s+(\S+)", dec_opts)
        refveclev_file = None
        refvec_file = None
        if "-otr ref_vec_lev".upper() in dec_opts.upper():
@@ -429,13 +458,13 @@ def binauralize_input_and_output(
                refvec_file = rot_tmp_file

        # Rendering configuration
    config_file = findstr(r'-render_config\s+(\S+)', dec_opts)
        config_file = findstr(r"-render_config\s+(\S+)", dec_opts)
        binary_suffix = "_ref"
    frame_size = findstr(r'-fr\s+(\S+)', dec_opts)
        frame_size = findstr(r"-fr\s+(\S+)", dec_opts)
        # hrtf_file = findstr(r'-hrtf\s+(\S+)', dec_opts)
        hrtf_file = None  # Default HRTFs used for binaural rendering of output

    aeid = findstr(r'-aeid\s+(\S+)', dec_opts)
        aeid = findstr(r"-aeid\s+(\S+)", dec_opts)

        if not output_config.upper() in PEAQ_SUPPORTED_FMT:
            # Render output to BINAURAL
@@ -504,6 +533,7 @@ def binauralize_input_and_output(
            ref_output_file_binaural = input_file
        return (ref_output_file_binaural, dut_output_file_binaural)


def findstr(exp, s, one_element=True):
    result = [SCRIPTS_DIR.joinpath(x) for x in re.findall(exp, s)]
    if len(result) == 0:
@@ -512,6 +542,7 @@ def findstr(exp, s, one_element=True):
        return result[0]
    return result


def check_and_makedir(dir_path):
    if not os.path.exists(dir_path):
        try:
@@ -519,3 +550,23 @@ def check_and_makedir(dir_path):
        except OSError as e:
            if e.errno != errno.EEXIST:
                raise  # raises the error again


def scene_description_file(in_fmt, metadata_tmp, n_obj, input_file, in_meta_files):
    with open(metadata_tmp, "w") as fp_meta:
        currdir = Path(
            metadata_tmp
        ).parent  # File names must be relative to config file location
        fp_meta.write(f"{os.path.relpath(input_file, currdir)}\n")  # Input file
        fp_meta.write(f"{n_obj+1}\n")  # Number of sources
        for n in range(0, n_obj):
            fp_meta.write(
                f"ISM\n{n+1}\n{os.path.relpath(in_meta_files[n], currdir)}\n"
            )  # ISM metadata
        fp_meta.write(f"{in_fmt.split('_')[0][1:]}\n")  # SBA or MASA
        fp_meta.write(f"{n_obj+1}\n")
        fp_meta.write(f"{in_fmt.split('_')[-1]}\n")  # SBA or MASA parameter
        if "MASA" in in_fmt:
            fp_meta.write(
                f"{os.path.relpath(in_meta_files[n_obj], currdir)}\n"
            )  # MASA metadata