Loading scripts/pyaudio3dtools/audioarray.py +20 −5 Original line number Diff line number Diff line Loading @@ -232,6 +232,7 @@ def compare( fs: int, per_frame: bool = True, get_mld: bool = False, get_ssnr: bool = False, ) -> dict: """Compare two audio arrays Loading Loading @@ -266,8 +267,13 @@ def compare( "first_diff_pos_sample": -1, "first_diff_pos_channel": -1, "first_diff_pos_frame": -1, "MLD": 0 if get_mld else None, } if get_mld: result["MLD"] = 0 if get_ssnr: result["SSNR"] = np.zeros(ref.shape[1]) if per_frame: result["max_abs_diff_pos_frame"] = 0 result["nframes_diff"] = 0 Loading Loading @@ -320,7 +326,6 @@ def compare( result["nframes_diff_percentage"] = nframes_diff_percentage if get_mld: mld_max = 0 toolsdir = Path(__file__).parent.parent.joinpath("tools") if platform.system() == "Windows": Loading @@ -343,6 +348,12 @@ def compare( result["MLD"] = mld_max if get_ssnr: # length of segment is always 20ms len_seg = int(0.02 * fs) print(len_seg, ref.shape, test.shape) result["SSNR"] = ssnr(ref, test, len_seg, thresh_low=-50, thresh_high=-15) return result Loading Loading @@ -527,11 +538,14 @@ def ssnr( """ ss = list() ref_sig_norm = ref_sig / -np.iinfo(np.int16).min test_sig_norm = test_sig / -np.iinfo(np.int16).min denom_add = 10**-13 * len_seg segment_counter = np.zeros(ref_sig.shape[1]) for ref_seg, test_seg in zip( get_framewise(ref_sig, len_seg, zero_pad=True), get_framewise(test_sig, len_seg, zero_pad=True), get_framewise(ref_sig_norm, len_seg, zero_pad=True), get_framewise(test_sig_norm, len_seg, zero_pad=True), ): nrg_ref = np.sum(ref_seg**2, axis=0) Loading @@ -551,5 +565,6 @@ def ssnr( ss.append(ss_seg) ssnr = 10 * np.log10(10 ** (np.sum(ss, axis=0) / segment_counter) - 1) # round to 2 decimals. this is just to be in line with the meg conformance tool ssnr = np.round(10 * np.log10(10 ** (np.sum(ss, axis=0) / segment_counter) - 1), 2) return ssnr scripts/ssnr.py +2 −12 Original line number Diff line number Diff line import argparse import sys import pathlib import numpy as np from pyaudio3dtools import audiofile, audioarray THRESH_LOW = -50 THRESH_HIGH = -15 def main(args): ref_sig, fs_ref = audiofile.readfile(args.ref_file) test_sig, fs_test = audiofile.readfile(args.test_file) Loading @@ -17,14 +12,9 @@ def main(args): print("Files need to have same sampling rate!") return -1 # normalize 16Bit wav signals to range of [-1, 1] ref_sig /= -np.iinfo(np.int16).min test_sig /= -np.iinfo(np.int16).min len_seg = int(20 * fs_ref / 1000) ssnr = audioarray.ssnr( ref_sig, test_sig, len_seg, thresh_low=THRESH_LOW, thresh_high=THRESH_HIGH ) print(len_seg, ref_sig.shape, test_sig.shape) ssnr = audioarray.ssnr(ref_sig, test_sig, len_seg, thresh_low=-50, thresh_high=-15) for i, s in enumerate(ssnr, start=1): print(f"Channel {i}: {s}") Loading tests/cmp_pcm.py +12 −7 Original line number Diff line number Diff line Loading @@ -13,14 +13,15 @@ import pyivastest def cmp_pcm( file1, file2, ref_file, cmp_file, out_config, fs, get_mld=False, allow_differing_lengths=False, mld_lim=0, abs_tol=0, get_ssnr=False, ) -> (int, str): """ Compare 2 PCM files for bitexactness Loading @@ -39,8 +40,8 @@ def cmp_pcm( else: nchannels = pyivastest.constants.OC_TO_NCHANNELS[out_config.upper()] s1, _ = pyaudio3dtools.audiofile.readfile(file1, nchannels, fs, outdtype=np.int16) s2, _ = pyaudio3dtools.audiofile.readfile(file2, nchannels, fs, outdtype=np.int16) s1, _ = pyaudio3dtools.audiofile.readfile(ref_file, nchannels, fs, outdtype=np.int16) s2, _ = pyaudio3dtools.audiofile.readfile(cmp_file, nchannels, fs, outdtype=np.int16) # In case of wav input, override the nchannels with the one from the wav header nchannels = s1.shape[1] Loading @@ -62,7 +63,7 @@ def cmp_pcm( return 1, reason cmp_result = pyaudio3dtools.audioarray.compare( s1, s2, fs, per_frame=False, get_mld=get_mld s1, s2, fs, per_frame=False, get_mld=get_mld, get_ssnr=get_ssnr, ) output_differs = 0 Loading Loading @@ -90,13 +91,17 @@ def cmp_pcm( else: reason += f" > {mld_lim}" if get_ssnr: for i, s in enumerate(cmp_result["SSNR"], start=1): print(f"Channel {i} SSNR: {s}") return output_differs, reason if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("file1", type=str) parser.add_argument("file2", type=str) parser.add_argument("ref_file", type=str) parser.add_argument("cmp_file", type=str) parser.add_argument( "-o", "--out_config", Loading tests/codec_be_on_mr_nonselection/test_param_file.py +3 −1 Original line number Diff line number Diff line Loading @@ -152,6 +152,7 @@ def test_param_file_tests( get_mld, get_mld_lim, abs_tol, get_ssnr, ): enc_opts, dec_opts, sim_opts, eid_opts = param_file_test_dict[test_tag] Loading Loading @@ -341,14 +342,15 @@ def test_param_file_tests( fs = int(sampling_rate) * 1000 output_differs, reason = cmp_pcm( dut_output_file, ref_output_file, dut_output_file, output_config, fs, get_mld=get_mld, mld_lim=get_mld_lim, abs_tol=abs_tol, allow_differing_lengths=allow_differing_lengths, get_ssnr=get_ssnr, ) md_out_files = get_expected_md_files(ref_output_file, enc_split, output_config) Loading tests/conftest.py +15 −0 Original line number Diff line number Diff line Loading @@ -171,6 +171,13 @@ def pytest_addoption(parser): help="MLD limit for comparison (default: 0)", default="0", ) parser.addoption( "--ssnr", action="store_true", help="Compute Segmental SNR (SSNR) between ref and dut output instead of just comparing for bitexactness", ) parser.addoption( "--create_ref", action="store_true", Loading Loading @@ -242,6 +249,14 @@ def get_mld_lim(request): return float(request.config.getoption("--mld-lim")) @pytest.fixture(scope="session", autouse=True) def get_ssnr(request): """ Return indication to compute ssnr during ref/dut comparison. """ return request.config.option.ssnr @pytest.fixture(scope="session") def abs_tol(request) -> int: """ Loading Loading
scripts/pyaudio3dtools/audioarray.py +20 −5 Original line number Diff line number Diff line Loading @@ -232,6 +232,7 @@ def compare( fs: int, per_frame: bool = True, get_mld: bool = False, get_ssnr: bool = False, ) -> dict: """Compare two audio arrays Loading Loading @@ -266,8 +267,13 @@ def compare( "first_diff_pos_sample": -1, "first_diff_pos_channel": -1, "first_diff_pos_frame": -1, "MLD": 0 if get_mld else None, } if get_mld: result["MLD"] = 0 if get_ssnr: result["SSNR"] = np.zeros(ref.shape[1]) if per_frame: result["max_abs_diff_pos_frame"] = 0 result["nframes_diff"] = 0 Loading Loading @@ -320,7 +326,6 @@ def compare( result["nframes_diff_percentage"] = nframes_diff_percentage if get_mld: mld_max = 0 toolsdir = Path(__file__).parent.parent.joinpath("tools") if platform.system() == "Windows": Loading @@ -343,6 +348,12 @@ def compare( result["MLD"] = mld_max if get_ssnr: # length of segment is always 20ms len_seg = int(0.02 * fs) print(len_seg, ref.shape, test.shape) result["SSNR"] = ssnr(ref, test, len_seg, thresh_low=-50, thresh_high=-15) return result Loading Loading @@ -527,11 +538,14 @@ def ssnr( """ ss = list() ref_sig_norm = ref_sig / -np.iinfo(np.int16).min test_sig_norm = test_sig / -np.iinfo(np.int16).min denom_add = 10**-13 * len_seg segment_counter = np.zeros(ref_sig.shape[1]) for ref_seg, test_seg in zip( get_framewise(ref_sig, len_seg, zero_pad=True), get_framewise(test_sig, len_seg, zero_pad=True), get_framewise(ref_sig_norm, len_seg, zero_pad=True), get_framewise(test_sig_norm, len_seg, zero_pad=True), ): nrg_ref = np.sum(ref_seg**2, axis=0) Loading @@ -551,5 +565,6 @@ def ssnr( ss.append(ss_seg) ssnr = 10 * np.log10(10 ** (np.sum(ss, axis=0) / segment_counter) - 1) # round to 2 decimals. this is just to be in line with the meg conformance tool ssnr = np.round(10 * np.log10(10 ** (np.sum(ss, axis=0) / segment_counter) - 1), 2) return ssnr
scripts/ssnr.py +2 −12 Original line number Diff line number Diff line import argparse import sys import pathlib import numpy as np from pyaudio3dtools import audiofile, audioarray THRESH_LOW = -50 THRESH_HIGH = -15 def main(args): ref_sig, fs_ref = audiofile.readfile(args.ref_file) test_sig, fs_test = audiofile.readfile(args.test_file) Loading @@ -17,14 +12,9 @@ def main(args): print("Files need to have same sampling rate!") return -1 # normalize 16Bit wav signals to range of [-1, 1] ref_sig /= -np.iinfo(np.int16).min test_sig /= -np.iinfo(np.int16).min len_seg = int(20 * fs_ref / 1000) ssnr = audioarray.ssnr( ref_sig, test_sig, len_seg, thresh_low=THRESH_LOW, thresh_high=THRESH_HIGH ) print(len_seg, ref_sig.shape, test_sig.shape) ssnr = audioarray.ssnr(ref_sig, test_sig, len_seg, thresh_low=-50, thresh_high=-15) for i, s in enumerate(ssnr, start=1): print(f"Channel {i}: {s}") Loading
tests/cmp_pcm.py +12 −7 Original line number Diff line number Diff line Loading @@ -13,14 +13,15 @@ import pyivastest def cmp_pcm( file1, file2, ref_file, cmp_file, out_config, fs, get_mld=False, allow_differing_lengths=False, mld_lim=0, abs_tol=0, get_ssnr=False, ) -> (int, str): """ Compare 2 PCM files for bitexactness Loading @@ -39,8 +40,8 @@ def cmp_pcm( else: nchannels = pyivastest.constants.OC_TO_NCHANNELS[out_config.upper()] s1, _ = pyaudio3dtools.audiofile.readfile(file1, nchannels, fs, outdtype=np.int16) s2, _ = pyaudio3dtools.audiofile.readfile(file2, nchannels, fs, outdtype=np.int16) s1, _ = pyaudio3dtools.audiofile.readfile(ref_file, nchannels, fs, outdtype=np.int16) s2, _ = pyaudio3dtools.audiofile.readfile(cmp_file, nchannels, fs, outdtype=np.int16) # In case of wav input, override the nchannels with the one from the wav header nchannels = s1.shape[1] Loading @@ -62,7 +63,7 @@ def cmp_pcm( return 1, reason cmp_result = pyaudio3dtools.audioarray.compare( s1, s2, fs, per_frame=False, get_mld=get_mld s1, s2, fs, per_frame=False, get_mld=get_mld, get_ssnr=get_ssnr, ) output_differs = 0 Loading Loading @@ -90,13 +91,17 @@ def cmp_pcm( else: reason += f" > {mld_lim}" if get_ssnr: for i, s in enumerate(cmp_result["SSNR"], start=1): print(f"Channel {i} SSNR: {s}") return output_differs, reason if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("file1", type=str) parser.add_argument("file2", type=str) parser.add_argument("ref_file", type=str) parser.add_argument("cmp_file", type=str) parser.add_argument( "-o", "--out_config", Loading
tests/codec_be_on_mr_nonselection/test_param_file.py +3 −1 Original line number Diff line number Diff line Loading @@ -152,6 +152,7 @@ def test_param_file_tests( get_mld, get_mld_lim, abs_tol, get_ssnr, ): enc_opts, dec_opts, sim_opts, eid_opts = param_file_test_dict[test_tag] Loading Loading @@ -341,14 +342,15 @@ def test_param_file_tests( fs = int(sampling_rate) * 1000 output_differs, reason = cmp_pcm( dut_output_file, ref_output_file, dut_output_file, output_config, fs, get_mld=get_mld, mld_lim=get_mld_lim, abs_tol=abs_tol, allow_differing_lengths=allow_differing_lengths, get_ssnr=get_ssnr, ) md_out_files = get_expected_md_files(ref_output_file, enc_split, output_config) Loading
tests/conftest.py +15 −0 Original line number Diff line number Diff line Loading @@ -171,6 +171,13 @@ def pytest_addoption(parser): help="MLD limit for comparison (default: 0)", default="0", ) parser.addoption( "--ssnr", action="store_true", help="Compute Segmental SNR (SSNR) between ref and dut output instead of just comparing for bitexactness", ) parser.addoption( "--create_ref", action="store_true", Loading Loading @@ -242,6 +249,14 @@ def get_mld_lim(request): return float(request.config.getoption("--mld-lim")) @pytest.fixture(scope="session", autouse=True) def get_ssnr(request): """ Return indication to compute ssnr during ref/dut comparison. """ return request.config.option.ssnr @pytest.fixture(scope="session") def abs_tol(request) -> int: """ Loading