From 7081fa6d0c95ef4316af32db56325009dc2d5d3f Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Mon, 5 May 2025 10:22:29 +0200 Subject: [PATCH 1/4] Memory reduction in audioarray.compare --- scripts/pyaudio3dtools/audioarray.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/scripts/pyaudio3dtools/audioarray.py b/scripts/pyaudio3dtools/audioarray.py index 29522a7659..a34899d6af 100644 --- a/scripts/pyaudio3dtools/audioarray.py +++ b/scripts/pyaudio3dtools/audioarray.py @@ -308,9 +308,6 @@ def compare( lengths_differ = ref.shape[0] != test.shape[0] - test_orig = test.copy() - ref_orig = ref.copy() - if lengths_differ: if handle_differing_lengths == "fail": raise RuntimeError( @@ -442,19 +439,21 @@ def compare( tmpfile_test = Path(tmpdir).joinpath("test.wav") ### need to resample to 48kHz for MLD computation to be correct + ### write out and delete tmp variables to reduce memory usage if fs != 48000: ref_tmp = np.clip( - resample(ref_orig.astype(float), fs, 48000), -32768, 32767 - ) + resample(ref.astype(float), fs, 48000), -32768, 32767 + ).astype(np.int16) + wavfile.write(str(tmpfile_ref), 48000, ref_tmp) + del ref_tmp test_tmp = np.clip( - resample(test_orig.astype(float), fs, 48000), -32768, 32767 - ) + resample(test.astype(float), fs, 48000), -32768, 32767 + ).astype(np.int16) + wavfile.write(str(tmpfile_test), 48000, test_tmp) + del test_tmp else: - ref_tmp = ref_orig.copy() - test_tmp = test_orig.copy() - - wavfile.write(str(tmpfile_ref), 48000, ref_tmp.astype(np.int16)) - wavfile.write(str(tmpfile_test), 48000, test_tmp.astype(np.int16)) + wavfile.write(str(tmpfile_ref), 48000, ref) + wavfile.write(str(tmpfile_test), 48000, test) cmd = [ str(wdiff), -- GitLab From 499844570c5368b81a3f794bf89f33d871fa2c5a Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Mon, 5 May 2025 13:39:34 +0200 Subject: [PATCH 2/4] Move MLD check first since it uses files without length alignment --- scripts/pyaudio3dtools/audioarray.py | 154 ++++++++++++++------------- 1 file changed, 79 insertions(+), 75 deletions(-) diff --git a/scripts/pyaudio3dtools/audioarray.py b/scripts/pyaudio3dtools/audioarray.py index a34899d6af..a19739b70e 100644 --- a/scripts/pyaudio3dtools/audioarray.py +++ b/scripts/pyaudio3dtools/audioarray.py @@ -306,6 +306,85 @@ def compare( framesize = fs // 50 + # MLD (wav-diff) tool is run first, since it uses the input signals without length difference check for JBM test cases. + if get_mld: + + def parse_wav_diff(proc: subprocess.CompletedProcess) -> float: + if proc.returncode: + raise ChildProcessError(f"{proc.stderr}\n{proc.stdout}") + line = proc.stdout.splitlines()[-1].strip() + start = line.find(">") + 1 + stop = line.rfind("<") + mld = float(line[start:stop].strip()) + + return mld + + mld_max = 0 + toolsdir = Path(__file__).parent.parent.joinpath("tools") + + curr_platform = platform.system() + if curr_platform not in {"Windows", "Linux", "Darwin"}: + raise NotImplementedError( + f"wav-diff tool not available for {curr_platform}" + ) + + search_path = toolsdir.joinpath(curr_platform.replace("Windows", "Win32")) + wdiff = search_path.joinpath("wav-diff").with_suffix(".exe" if curr_platform == "Windows" else "") + + if not wdiff.exists(): + wdiff = shutil.which("wav-diff") + if wdiff is None: + raise FileNotFoundError( + f"wav-diff tool not found in {search_path} or PATH!" + ) + + with tempfile.TemporaryDirectory() as tmpdir: + tmpfile_ref = Path(tmpdir).joinpath("ref.wav") + tmpfile_test = Path(tmpdir).joinpath("test.wav") + + ### need to resample to 48kHz for MLD computation to be correct + ### write out and delete tmp variables to reduce memory usage + if fs != 48000: + ref_tmp = np.clip( + resample(ref.astype(float), fs, 48000), -32768, 32767 + ).astype(np.int16) + wavfile.write(str(tmpfile_ref), 48000, ref_tmp) + del ref_tmp + test_tmp = np.clip( + resample(test.astype(float), fs, 48000), -32768, 32767 + ).astype(np.int16) + wavfile.write(str(tmpfile_test), 48000, test_tmp) + del test_tmp + else: + wavfile.write(str(tmpfile_ref), 48000, ref) + wavfile.write(str(tmpfile_test), 48000, test) + + cmd = [ + str(wdiff), + "--print-ctest-measurement", + # wav-diff return code is 1 if differences are found which + # would cause parse_wav_diff to raise an Exception on these cases + "--no-fail", + str(tmpfile_ref), + str(tmpfile_test), + ] + if ref_jbm_tf and test_jbm_tf: + cmd.extend( + [ + "--ref-jbm-trace", + str(ref_jbm_tf), + "--cut-jbm-trace", + str(test_jbm_tf), + ] + ) + proc = subprocess.run(cmd, capture_output=True, text=True) + mld_max = parse_wav_diff(proc) + + result["MLD"] = mld_max + + + # Run remanining tests after checking if the lenght differs + lengths_differ = ref.shape[0] != test.shape[0] if lengths_differ: @@ -403,81 +482,6 @@ def compare( result["nframes_diff"] = nframes_diff result["nframes_diff_percentage"] = nframes_diff_percentage - if get_mld: - - def parse_wav_diff(proc: subprocess.CompletedProcess) -> float: - if proc.returncode: - raise ChildProcessError(f"{proc.stderr}\n{proc.stdout}") - line = proc.stdout.splitlines()[-1].strip() - start = line.find(">") + 1 - stop = line.rfind("<") - mld = float(line[start:stop].strip()) - - return mld - - mld_max = 0 - toolsdir = Path(__file__).parent.parent.joinpath("tools") - - curr_platform = platform.system() - if curr_platform not in {"Windows", "Linux", "Darwin"}: - raise NotImplementedError( - f"wav-diff tool not available for {curr_platform}" - ) - - search_path = toolsdir.joinpath(curr_platform.replace("Windows", "Win32")) - wdiff = search_path.joinpath("wav-diff").with_suffix(".exe" if curr_platform == "Windows" else "") - - if not wdiff.exists(): - wdiff = shutil.which("wav-diff") - if wdiff is None: - raise FileNotFoundError( - f"wav-diff tool not found in {search_path} or PATH!" - ) - - with tempfile.TemporaryDirectory() as tmpdir: - tmpfile_ref = Path(tmpdir).joinpath("ref.wav") - tmpfile_test = Path(tmpdir).joinpath("test.wav") - - ### need to resample to 48kHz for MLD computation to be correct - ### write out and delete tmp variables to reduce memory usage - if fs != 48000: - ref_tmp = np.clip( - resample(ref.astype(float), fs, 48000), -32768, 32767 - ).astype(np.int16) - wavfile.write(str(tmpfile_ref), 48000, ref_tmp) - del ref_tmp - test_tmp = np.clip( - resample(test.astype(float), fs, 48000), -32768, 32767 - ).astype(np.int16) - wavfile.write(str(tmpfile_test), 48000, test_tmp) - del test_tmp - else: - wavfile.write(str(tmpfile_ref), 48000, ref) - wavfile.write(str(tmpfile_test), 48000, test) - - cmd = [ - str(wdiff), - "--print-ctest-measurement", - # wav-diff return code is 1 if differences are found which - # would cause parse_wav_diff to raise an Exception on these cases - "--no-fail", - str(tmpfile_ref), - str(tmpfile_test), - ] - if ref_jbm_tf and test_jbm_tf: - cmd.extend( - [ - "--ref-jbm-trace", - str(ref_jbm_tf), - "--cut-jbm-trace", - str(test_jbm_tf), - ] - ) - proc = subprocess.run(cmd, capture_output=True, text=True) - mld_max = parse_wav_diff(proc) - - result["MLD"] = mld_max - if get_ssnr: # length of segment is always 20ms len_seg = int(0.02 * fs) -- GitLab From 89fa9cb63fbe5537d44fcd33ee5dd84a3c4b45ec Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Mon, 5 May 2025 13:45:12 +0200 Subject: [PATCH 3/4] Move result dict init in audioarray.compare --- scripts/pyaudio3dtools/audioarray.py | 44 +++++++++++++++------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/scripts/pyaudio3dtools/audioarray.py b/scripts/pyaudio3dtools/audioarray.py index a19739b70e..709e9943ba 100644 --- a/scripts/pyaudio3dtools/audioarray.py +++ b/scripts/pyaudio3dtools/audioarray.py @@ -306,6 +306,29 @@ def compare( framesize = fs // 50 + # Init result dict + result = { + "bitexact": True, + "max_abs_diff": 0, + "max_abs_diff_pos_sample": 0, + "max_abs_diff_pos_channel": 0, + "nsamples_diff": 0, + "nsamples_diff_percentage": 0.0, + "first_diff_pos_sample": -1, + "first_diff_pos_channel": -1, + "first_diff_pos_frame": -1, + } + + if get_mld: + result["MLD"] = 0 + if get_ssnr: + result["SSNR"] = np.asarray([np.inf] * ref.shape[1]) + + if per_frame: + result["max_abs_diff_pos_frame"] = 0 + result["nframes_diff"] = 0 + result["nframes_diff_percentage"] = 0.0 + # MLD (wav-diff) tool is run first, since it uses the input signals without length difference check for JBM test cases. if get_mld: @@ -414,27 +437,6 @@ def compare( diff = abs(test - ref) max_diff = int(diff.max()) - result = { - "bitexact": True, - "max_abs_diff": 0, - "max_abs_diff_pos_sample": 0, - "max_abs_diff_pos_channel": 0, - "nsamples_diff": 0, - "nsamples_diff_percentage": 0.0, - "first_diff_pos_sample": -1, - "first_diff_pos_channel": -1, - "first_diff_pos_frame": -1, - } - - if get_mld: - result["MLD"] = 0 - if get_ssnr: - result["SSNR"] = np.asarray([np.inf] * ref.shape[1]) - - if per_frame: - result["max_abs_diff_pos_frame"] = 0 - result["nframes_diff"] = 0 - result["nframes_diff_percentage"] = 0.0 if max_diff != 0: if diff.ndim == 1: -- GitLab From b3ddc5627389d161394adc3e18f9104ebd588120 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Mon, 5 May 2025 13:57:55 +0200 Subject: [PATCH 4/4] With result init moved, prevent overwriting the result dict --- scripts/pyaudio3dtools/audioarray.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/scripts/pyaudio3dtools/audioarray.py b/scripts/pyaudio3dtools/audioarray.py index 709e9943ba..f548622242 100644 --- a/scripts/pyaudio3dtools/audioarray.py +++ b/scripts/pyaudio3dtools/audioarray.py @@ -463,17 +463,15 @@ def compare( nframes = nsamples_total // framesize nframes_diff = 0 - result = { - "bitexact": False, - "max_abs_diff": max_diff, - "max_abs_diff_pos_sample": max_diff_pos[0], - "max_abs_diff_pos_channel": max_diff_pos[2], - "nsamples_diff": nsamples_diff, - "nsamples_diff_percentage": nsamples_diff_percentage, - "first_diff_pos_sample": first_diff_pos[0], - "first_diff_pos_channel": first_diff_pos[2], - "first_diff_pos_frame": first_diff_pos[1], - } + result["bitexact"] = False + result["max_abs_diff"] = max_diff + result["max_abs_diff_pos_sample"] = max_diff_pos[0] + result["max_abs_diff_pos_channel"] = max_diff_pos[2] + result["nsamples_diff"] = nsamples_diff + result["nsamples_diff_percentage"] = nsamples_diff_percentage + result["first_diff_pos_sample"] = first_diff_pos[0] + result["first_diff_pos_channel"] = first_diff_pos[2] + result["first_diff_pos_frame"] = first_diff_pos[1] if per_frame: for fr in range(nframes): -- GitLab