Commit 66bec923 authored by norvell's avatar norvell
Browse files

Added MLD tool

parent 5c6931f1
Loading
Loading
Loading
Loading
Loading

scripts/parse_mld.py

0 → 100644
+29 −0
Original line number Diff line number Diff line
#!/usr/bin/python3

import argparse
import re


# Main routine
if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Parse HTML report to extract MLD values')
    parser.add_argument('html_report',type=str,help='HTML report input file, e.g. report.html')
    parser.add_argument('csv_file',type=str,help='Output CSV file, e.g. output.csv')
    args = parser.parse_args()
    html_report = args.html_report
    csv_file    = args.csv_file
    
    mld = {}
    
    with open(html_report,'r') as infile:
        for line in infile.readlines():
            if "col-name" in line: 
                test_name = re.search('\[(.*)\]', line).group(1)
                mld[test_name] = 0.0
            if "MLD" in line:
                mld_val = float(line.split()[1])
                mld[test_name] = mld_val
                
    with open(csv_file,'w') as outfile:
        for test_name in mld:
            outfile.write(test_name + ';' + str(mld[test_name])+'\n')
 No newline at end of file
+35 −1
Original line number Diff line number Diff line
@@ -37,6 +37,11 @@ from typing import Callable, Iterable, Optional, Tuple
import numpy as np
import multiprocessing as mp
import scipy.signal as sig
import scipy.io.wavfile as wavfile
import subprocess
import platform
import tempfile
from pathlib import Path

main_logger = logging.getLogger("__main__")
logger = main_logger.getChild(__name__)
@@ -221,7 +226,7 @@ def cut(x: np.ndarray, limits: Tuple[int, int]) -> np.ndarray:
    return y


def compare(ref: np.ndarray, test: np.ndarray, fs: int, per_frame: bool = True) -> dict:
def compare(ref: np.ndarray, test: np.ndarray, fs: int, per_frame: bool = True, get_mld: bool = False) -> dict:
    """Compare two audio arrays

    Parameters
@@ -232,6 +237,10 @@ def compare(ref: np.ndarray, test: np.ndarray, fs: int, per_frame: bool = True)
        Input test array
    fs: int
        Input sampling rate in Hz
    per_frame: bool
        Compute difference per frame (default True)
    get_mld: bool
        Run MLD tool if there is a difference between the signals (default False)

    Returns
    -------
@@ -251,6 +260,7 @@ def compare(ref: np.ndarray, test: np.ndarray, fs: int, per_frame: bool = True)
        "first_diff_pos_sample": -1,
        "first_diff_pos_channel": -1,
        "first_diff_pos_frame": -1,
        "MLD": 0 if get_mld else None,
    }
    if per_frame:
        result["max_abs_diff_pos_frame"] = 0
@@ -303,6 +313,30 @@ def compare(ref: np.ndarray, test: np.ndarray, fs: int, per_frame: bool = True)
            result["nframes_diff"] = nframes_diff
            result["nframes_diff_percentage"] = nframes_diff_percentage

        if get_mld:
            
            mld_max = 0
            toolsdir = Path(__file__).parent.parent.joinpath("tools")
            if platform.system() == "Windows":
                mld = toolsdir.joinpath( "Win32").joinpath("mld.exe" )
            elif platform.system() in ["Linux", "Darwin"]:
                mld = toolsdir.joinpath(platform.system()).joinpath( "mld" )
            else:
                assert False, f"MLD tool not available for {platform.system()}"

            with tempfile.TemporaryDirectory() as tmpdir:
                for i in range(nchannels):
                    tmpfile_ref = Path(tmpdir).joinpath(f"ref_ch{i+1}.wav")
                    tmpfile_test = Path(tmpdir).joinpath(f"test_ch{i+1}.wav")
                    r48 = resample(ref[:,i], fs, 48000);
                    t48 = resample(test[:,i], fs, 48000);
                    wavfile.write(str(tmpfile_ref), 48000, r48)
                    wavfile.write(str(tmpfile_test), 48000, t48)
                    out = subprocess.check_output([mld,tmpfile_ref,tmpfile_test])
                    mld_max = max(mld_max, float(out.split()[3]))

            result["MLD"] = mld_max

    return result


+22.2 KiB

File added.

No diff preview for this file type.

scripts/tools/Win32/mld.exe

0 → 100644LFS
+131 B

File added.

No diff preview for this file type.

+8 −2
Original line number Diff line number Diff line
@@ -12,7 +12,7 @@ import pyivastest
import numpy as np


def cmp_pcm(file1, file2, out_config, fs) -> (int, str):
def cmp_pcm(file1, file2, out_config, fs, get_mld = False) -> (int, str):
    """
    Compare 2 PCM files for bitexactness
    """
@@ -34,6 +34,8 @@ def cmp_pcm(file1, file2, out_config, fs) -> (int, str):
    s1, _ = pyaudio3dtools.audiofile.readfile(file1, nchannels, fs, outdtype=np.int16)
    s2, _ = pyaudio3dtools.audiofile.readfile(file2, nchannels, fs, outdtype=np.int16)

    nchannels = s1.shape[1] # In case of wav input, override the nchannels with the one from the wav header

    if s1.shape != s2.shape:
        print(
            f"file size in samples: file 1 = {s1.shape[0]},",
@@ -41,7 +43,7 @@ def cmp_pcm(file1, file2, out_config, fs) -> (int, str):
        )
        return 1, "FAIL: File lengths differ"

    cmp_result = pyaudio3dtools.audioarray.compare(s1, s2, fs, per_frame=False)
    cmp_result = pyaudio3dtools.audioarray.compare(s1, s2, fs, per_frame=False, get_mld=get_mld)

    if cmp_result["bitexact"]:
        return 0, "SUCCESS: Files are bitexact"
@@ -50,6 +52,9 @@ def cmp_pcm(file1, file2, out_config, fs) -> (int, str):
        first_msg = f"First diff found at sample num {cmp_result['first_diff_pos_sample']} in channel {cmp_result['first_diff_pos_channel']}, frame {cmp_result['first_diff_pos_frame']} (assuming {nchannels} channels, {fs} sampling rate)"
        print(diff_msg)
        print(first_msg)
        if get_mld:
            mld_msg = f"MLD: {cmp_result['MLD']}"
            print(mld_msg)        
        return 1, "FAIL: Files have different content"


@@ -65,6 +70,7 @@ if __name__ == "__main__":
        choices=pyivastest.constants.OC_TO_NCHANNELS.keys(),
    )
    parser.add_argument("-s", "--sampling_rate", type=int, default=48000, dest="fs")
    parser.add_argument("--get_mld", action="store_true")
    args = parser.parse_args()

    result, msg = cmp_pcm(**vars(args))
Loading