From a5d3feb2bd496e67c2f0bdf19cb03bb82153a916 Mon Sep 17 00:00:00 2001 From: knj Date: Fri, 26 Jan 2024 15:13:40 +0100 Subject: [PATCH 1/7] make batch_comp_audio work with MLD tool for mono files --- scripts/batch_comp_audio.py | 58 ++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/scripts/batch_comp_audio.py b/scripts/batch_comp_audio.py index 97e9f8f548..9f269b8c15 100755 --- a/scripts/batch_comp_audio.py +++ b/scripts/batch_comp_audio.py @@ -48,8 +48,9 @@ DIFF_EXPR = r"Max Diff\s+=\s+(\d+)" def main(args): - if shutil.which("CompAudio") is None: - print("CompAudio not in PATH - abort.") + tool = args.tool + if shutil.which(tool) is None: + print(f"{tool} not in PATH - abort.") sys.exit(-1) num_files_diff = 0 @@ -76,20 +77,25 @@ def main(args): repeat(fol1), repeat(fol2), repeat(outputs), + repeat(tool) ) else: # if only one thread is passed, do everything in the main thread # to allow for meaningful debugging if needed for f in common_files: - compare_files(f, fol1, fol2, outputs) + compare_files(f, fol1, fol2, outputs, tool) if args.sort: - out = dict(sorted(outputs.items(), key=lambda item: item[1])) + out = dict(sorted(outputs.items(), key=SORT_FUNC[tool])) else: out = outputs - for f, output_tuple in out.items(): - diff, snr, gain, seg_snr = output_tuple + for f, tool_output in out.items(): + + if tool == "CompAudio": + diff, snr, gain, seg_snr = tool_output + elif tool == "mld": + diff = tool_output if diff > 0: num_files_diff = num_files_diff + 1 @@ -99,9 +105,9 @@ def main(args): label = "[OKAY]" else: label = "[FAIL]" - result = f"{label} Max. diff (PCM) for file {f}: {diff}" + result = DIFF_STR[tool].format(label=label, f=f, diff=diff) - if args.verbose and diff != 0.0: + if tool == "CompAudio" and args.verbose and diff != 0.0: result += f", SNR = {snr:4.2f} dB (File 2 Gain = {gain:4.3f})" result += f", Seg. SNR = {seg_snr:4.2f} dB" @@ -113,24 +119,24 @@ def main(args): print(f"All files are bitexact", file=out_file) -def compare_files(f, fol1, fol2, outputs_dict): +def compare_files(f, fol1, fol2, outputs_dict, tool): """ - Compare file f in both folders fol1 and fol2 using CompAudio and + Compare file f in both folders fol1 and fol2 using the given tool and store the parsed difference in outputs_dict. """ f1 = os.path.join(fol1, f) f2 = os.path.join(fol2, f) - cmd = f"CompAudio {f1} {f2}" + cmd = f"{tool} {f1} {f2}" try: output = subprocess.check_output(cmd.split(" ")) except subprocess.CalledProcessError: - print("CompAudio returned a non-zero exit status. Check your files.") + print(f"{tool} returned a non-zero exit status. Check your files.") sys.exit(-1) - output_tuple = _parse_comp_audio(output) + tool_output = PARSE_FUNC[tool](output) with threading.Lock(): - outputs_dict.update({f: output_tuple}) + outputs_dict.update({f: tool_output}) def get_common_files(fol1, fol2): @@ -205,6 +211,27 @@ def _parse_comp_audio(output): return diff, snr, gain, seg_snr +def _parse_mld(output): + output = output.decode("utf-8") + mld = float(output.split()[-1]) + + return mld + + +PARSE_FUNC = { + "CompAudio": _parse_comp_audio, + "mld": _parse_mld, + } +SORT_FUNC = { + "CompAudio": lambda item: item[1], + "mld": lambda item: item, + } +DIFF_STR = { + "CompAudio": "{label} Max. diff (PCM) for file {f}: {diff}", + "mld": "{label} MLD diff for file {f}: {diff}", + } + + class OutFileManager: def __init__(self, out_file): self.out_file = out_file @@ -256,6 +283,9 @@ if __name__ == "__main__": parser.add_argument( "-t", "--num_threads", type=int, default=1, help="Number of threads to use" ) + parser.add_argument( + "--tool", choices=["mld", "CompAudio"], default="CompAudio", help="Compare tool to run" + ) args = parser.parse_args() main(args) -- GitLab From 3f88de3993e2c96d449556cfee691cbe1f0f65a1 Mon Sep 17 00:00:00 2001 From: knj Date: Fri, 26 Jan 2024 15:42:32 +0100 Subject: [PATCH 2/7] use audioarray.compare to handle non-mono files --- scripts/batch_comp_audio.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/scripts/batch_comp_audio.py b/scripts/batch_comp_audio.py index 9f269b8c15..e46e73c62b 100755 --- a/scripts/batch_comp_audio.py +++ b/scripts/batch_comp_audio.py @@ -33,12 +33,15 @@ import argparse import concurrent.futures import os +import pathlib import re import shutil import subprocess import sys import threading from itertools import repeat +from pyaudio3dtools.audiofile import readfile +from pyaudio3dtools.audioarray import compare FILES_EQUAL = "File A = File B" SNR_EXPR = r"SNR\s+=(.+)dB\s*\(File B Gain = (.+)\)" @@ -126,14 +129,20 @@ def compare_files(f, fol1, fol2, outputs_dict, tool): """ f1 = os.path.join(fol1, f) f2 = os.path.join(fol2, f) - cmd = f"{tool} {f1} {f2}" - try: - output = subprocess.check_output(cmd.split(" ")) - except subprocess.CalledProcessError: - print(f"{tool} returned a non-zero exit status. Check your files.") - sys.exit(-1) - tool_output = PARSE_FUNC[tool](output) + if tool == "CompAudio": + cmd = f"{tool} {f1} {f2}" + try: + output = subprocess.check_output(cmd.split(" ")) + except subprocess.CalledProcessError: + print(f"{tool} returned a non-zero exit status. Check your files.") + sys.exit(-1) + tool_output = _parse_comp_audio(output) + elif tool == "mld": + s1, fs1 = readfile(f1) + s2, fs2 = readfile(f2) + cmp_result = compare(s1, s2, fs1, per_frame=False, get_mld=True) + tool_output = cmp_result["MLD"] with threading.Lock(): outputs_dict.update({f: tool_output}) -- GitLab From 38a5d1439be414f57447bb12b3dbd3d34bcabc90 Mon Sep 17 00:00:00 2001 From: knj Date: Fri, 26 Jan 2024 16:03:25 +0100 Subject: [PATCH 3/7] fix bug with data type of signal arrays --- scripts/batch_comp_audio.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/batch_comp_audio.py b/scripts/batch_comp_audio.py index e46e73c62b..99203aa8f1 100755 --- a/scripts/batch_comp_audio.py +++ b/scripts/batch_comp_audio.py @@ -139,8 +139,8 @@ def compare_files(f, fol1, fol2, outputs_dict, tool): sys.exit(-1) tool_output = _parse_comp_audio(output) elif tool == "mld": - s1, fs1 = readfile(f1) - s2, fs2 = readfile(f2) + s1, fs1 = readfile(f1, outdtype="int16") + s2, fs2 = readfile(f2, outdtype="int16") cmp_result = compare(s1, s2, fs1, per_frame=False, get_mld=True) tool_output = cmp_result["MLD"] -- GitLab From e6aca3ab8a558e67a241ec163fc476a8489b6480 Mon Sep 17 00:00:00 2001 From: knj Date: Fri, 26 Jan 2024 16:15:43 +0100 Subject: [PATCH 4/7] add csv output and cleanup --- scripts/batch_comp_audio.py | 50 ++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/scripts/batch_comp_audio.py b/scripts/batch_comp_audio.py index 99203aa8f1..e9e40c4642 100755 --- a/scripts/batch_comp_audio.py +++ b/scripts/batch_comp_audio.py @@ -47,7 +47,10 @@ FILES_EQUAL = "File A = File B" SNR_EXPR = r"SNR\s+=(.+)dB\s*\(File B Gain = (.+)\)" SEG_SNR_EXPR = r"Seg. SNR\s+=(.+)dB" DIFF_EXPR = r"Max Diff\s+=\s+(\d+)" - +DIFF_STR = { + "CompAudio": "{label} Max. diff (PCM) for file {f}: {diff}", + "mld": "{label} MLD diff for file {f}: {diff}", + } def main(args): @@ -60,14 +63,14 @@ def main(args): with OutFileManager(args.out_file) as out_file: if args.diffs_only: - print("Only printing differing files!", file=out_file) + print("Only printing differing files!") fol1, fol2 = os.path.normpath(args.folder1), os.path.normpath(args.folder2) common_files = get_common_files(fol1, fol2) diff_files = get_diff_files(fol1, fol2) num_files_diff = len(diff_files) - print(f"Comparing {len(common_files)} files...", file=out_file) + print(f"Comparing {len(common_files)} files...") outputs = dict() if args.num_threads > 1: @@ -89,10 +92,17 @@ def main(args): compare_files(f, fol1, fol2, outputs, tool) if args.sort: - out = dict(sorted(outputs.items(), key=SORT_FUNC[tool])) + out = dict(sorted(outputs.items(), key=lambda item: item[1])) else: out = outputs + # write csv header + if out_file is not None: + if tool == "CompAudio": + out_file.write("filename,diff\n") + elif tool == "mld": + out_file.write("filename,mld\n") + for f, tool_output in out.items(): if tool == "CompAudio": @@ -114,12 +124,15 @@ def main(args): result += f", SNR = {snr:4.2f} dB (File 2 Gain = {gain:4.3f})" result += f", Seg. SNR = {seg_snr:4.2f} dB" - print(result, file=out_file) + print(result) + + if out_file is not None: + out_file.write(f"{f},{diff}\n") if num_files_diff > 0: - print(f"{num_files_diff} files differ/don't exist", file=out_file) + print(f"{num_files_diff} files differ/don't exist") else: - print(f"All files are bitexact", file=out_file) + print(f"All files are bitexact") def compare_files(f, fol1, fol2, outputs_dict, tool): @@ -220,27 +233,6 @@ def _parse_comp_audio(output): return diff, snr, gain, seg_snr -def _parse_mld(output): - output = output.decode("utf-8") - mld = float(output.split()[-1]) - - return mld - - -PARSE_FUNC = { - "CompAudio": _parse_comp_audio, - "mld": _parse_mld, - } -SORT_FUNC = { - "CompAudio": lambda item: item[1], - "mld": lambda item: item, - } -DIFF_STR = { - "CompAudio": "{label} Max. diff (PCM) for file {f}: {diff}", - "mld": "{label} MLD diff for file {f}: {diff}", - } - - class OutFileManager: def __init__(self, out_file): self.out_file = out_file @@ -287,7 +279,7 @@ if __name__ == "__main__": "--out_file", type=str, default=None, - help="If given, write output diffs to this file", + help="If given, write output diffs to this file as comma-separated values (csv)", ) parser.add_argument( "-t", "--num_threads", type=int, default=1, help="Number of threads to use" -- GitLab From f79cb7faa6c00a495c405f27c283ce6be55d3c0e Mon Sep 17 00:00:00 2001 From: knj Date: Fri, 26 Jan 2024 16:16:06 +0100 Subject: [PATCH 5/7] format script --- scripts/batch_comp_audio.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/scripts/batch_comp_audio.py b/scripts/batch_comp_audio.py index e9e40c4642..1389006f28 100755 --- a/scripts/batch_comp_audio.py +++ b/scripts/batch_comp_audio.py @@ -50,10 +50,10 @@ DIFF_EXPR = r"Max Diff\s+=\s+(\d+)" DIFF_STR = { "CompAudio": "{label} Max. diff (PCM) for file {f}: {diff}", "mld": "{label} MLD diff for file {f}: {diff}", - } +} -def main(args): +def main(args): tool = args.tool if shutil.which(tool) is None: print(f"{tool} not in PATH - abort.") @@ -83,7 +83,7 @@ def main(args): repeat(fol1), repeat(fol2), repeat(outputs), - repeat(tool) + repeat(tool), ) else: # if only one thread is passed, do everything in the main thread @@ -104,7 +104,6 @@ def main(args): out_file.write("filename,mld\n") for f, tool_output in out.items(): - if tool == "CompAudio": diff, snr, gain, seg_snr = tool_output elif tool == "mld": @@ -125,7 +124,7 @@ def main(args): result += f", Seg. SNR = {seg_snr:4.2f} dB" print(result) - + if out_file is not None: out_file.write(f"{f},{diff}\n") @@ -248,7 +247,6 @@ class OutFileManager: if __name__ == "__main__": - parser = argparse.ArgumentParser( description="Compare .wav files in two folders using CompAudio" ) @@ -285,8 +283,11 @@ if __name__ == "__main__": "-t", "--num_threads", type=int, default=1, help="Number of threads to use" ) parser.add_argument( - "--tool", choices=["mld", "CompAudio"], default="CompAudio", help="Compare tool to run" - ) + "--tool", + choices=["mld", "CompAudio"], + default="CompAudio", + help="Compare tool to run", + ) args = parser.parse_args() main(args) -- GitLab From 63238a208e1a88610369f6ccac7895dfa23fd5f4 Mon Sep 17 00:00:00 2001 From: knj Date: Mon, 29 Jan 2024 15:00:24 +0100 Subject: [PATCH 6/7] use regex that is compatible with older version, too --- scripts/batch_comp_audio.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/batch_comp_audio.py b/scripts/batch_comp_audio.py index 1389006f28..c4fda93f5c 100755 --- a/scripts/batch_comp_audio.py +++ b/scripts/batch_comp_audio.py @@ -44,7 +44,7 @@ from pyaudio3dtools.audiofile import readfile from pyaudio3dtools.audioarray import compare FILES_EQUAL = "File A = File B" -SNR_EXPR = r"SNR\s+=(.+)dB\s*\(File B Gain = (.+)\)" +SNR_EXPR = r"SNR\s+=(.+)dB\s*\(.+= (.+)\)" SEG_SNR_EXPR = r"Seg. SNR\s+=(.+)dB" DIFF_EXPR = r"Max Diff\s+=\s+(\d+)" DIFF_STR = { -- GitLab From 31bd8253227670161351539464d0b3f1f8813c0d Mon Sep 17 00:00:00 2001 From: knj Date: Mon, 29 Jan 2024 15:03:14 +0100 Subject: [PATCH 7/7] default to None for numof threads --- scripts/batch_comp_audio.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/batch_comp_audio.py b/scripts/batch_comp_audio.py index c4fda93f5c..ef47968cb8 100755 --- a/scripts/batch_comp_audio.py +++ b/scripts/batch_comp_audio.py @@ -73,7 +73,12 @@ def main(args): print(f"Comparing {len(common_files)} files...") outputs = dict() - if args.num_threads > 1: + if args.num_threads == 1: + # if only one thread is passed, do everything in the main thread + # to allow for meaningful debugging if needed + for f in common_files: + compare_files(f, fol1, fol2, outputs, tool) + else: with concurrent.futures.ThreadPoolExecutor( max_workers=args.num_threads ) as exc: @@ -85,11 +90,6 @@ def main(args): repeat(outputs), repeat(tool), ) - else: - # if only one thread is passed, do everything in the main thread - # to allow for meaningful debugging if needed - for f in common_files: - compare_files(f, fol1, fol2, outputs, tool) if args.sort: out = dict(sorted(outputs.items(), key=lambda item: item[1])) @@ -280,7 +280,7 @@ if __name__ == "__main__": help="If given, write output diffs to this file as comma-separated values (csv)", ) parser.add_argument( - "-t", "--num_threads", type=int, default=1, help="Number of threads to use" + "-t", "--num_threads", type=int, default=None, help="Number of threads to use" ) parser.add_argument( "--tool", -- GitLab