Commit 4be6ffdb authored by Vladimir Malenovsky's avatar Vladimir Malenovsky
Browse files

compare binary encoder files based on their histograms

parent 79b32de9
Loading
Loading
Loading
Loading
Loading

tests/cmp_bin_files.py

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

import argparse
import os
import sys
import pdb

THIS_PATH = os.path.join(os.getcwd(), __file__)
sys.path.append(os.path.join(os.path.dirname(THIS_PATH), "../scripts"))

import numpy as np
import pyaudio3dtools
import pyivastest
from collections import OrderedDict


def cmp_bin_files(ref_file, cut_file, dtype=np.int16, nsamples_per_frame=960, len_check=0, min_diff_thr=0.1) -> (int, str):
    """
    Compare two int16 binary files based on their histograms
    """
    print(f"Comparing {os.path.basename(ref_file)} between Ref and Dut ... ", end="")

    # read the files
    with open(ref_file, "r") as f:
        ref = np.fromfile(f, dtype=dtype)

    with open(cut_file, "r") as f:
        cut = np.fromfile(f, dtype=dtype)
        
    # remove the duplicates of each value
    if nsamples_per_frame > 1:
        ref = ref[::nsamples_per_frame]
        cut = cut[::nsamples_per_frame]

    # check the lengths
    N = ref.shape[0] + cut.shape[0]
    if len_check and ref.shape != cut.shape:
        print( f"files have different length, ref: {ref.shape[0]}, cut: {cut.shape[0]}" )
        result = 1
        reason = f"files have different length!"
        return result, reason

    # calculate histograms from data
    unique_values = np.sort(np.unique(np.concatenate([ref, cut])))
    ref_hist,_ = np.histogram(ref, bins=np.append(unique_values, unique_values[-1] + 10))
    cut_hist,_ = np.histogram(cut, bins=np.append(unique_values, unique_values[-1] + 10))
    diff_hist = cut_hist - ref_hist
    
    # convert to dict and sort by absolute value of difference
    diff = {unique_values[i]: diff_hist[i] for i in range(len(unique_values))}      
    diff = dict(sorted(diff.items(), key=lambda k: abs(k[1]), reverse=True))
    
    # calcualte the total number of differences
    total_num_diff = sum(np.abs(list(diff.values())))
    total_num_diff_ratio = total_num_diff / N
    
    if total_num_diff_ratio > min_diff_thr:
        print( f"files are different, total number of differences is {total_num_diff} ({(total_num_diff_ratio*100):.2f}%), exceeding the threshold of {(min_diff_thr*100):.2f}%!" )
        result = 1
        reason = f"files are different, total number of differences is {total_num_diff} ({(total_num_diff_ratio*100):.2f}%), exceeding the threshold of {(min_diff_thr*100):.2f}%!"
    elif total_num_diff_ratio > 0 and total_num_diff_ratio < min_diff_thr:
        print( f"files are different, total number of differences is {total_num_diff} ({(total_num_diff_ratio*100):.2f}%)." )
        result = 0
        reason = f"files are different, total number of differences is {total_num_diff} ({(total_num_diff_ratio*100):.2f}%)."
    else:
        print( f"files are bit-exact." )
        result = 0
        reason = f"files are bit-exact."
        
    return result, reason


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("ref_file", type=str)
    parser.add_argument("cut_file", type=str)
    parser.add_argument("--data_type", type=str, default='int16', dest="dtype")
    parser.add_argument("--nsamples_per_frame", type=str, default=960, dest="nsamples_per_frame")
    parser.add_argument("--len_check", type=int, default=0, dest="len_check")
    parser.add_argument("--min_diff_thr", type=float, default=0.0, dest="min_diff_thr")
    args = parser.parse_args()
    
    # convert dtype from str
    if isinstance(args.dtype, str):
        args.dtype = np.dtype(getattr(np, args.dtype))

    result, msg = cmp_bin_files(**vars(args))
    print(msg)
    sys.exit(result)
+726 −0

File added.

Preview size limit exceeded, changes collapsed.

tests/constants.py

0 → 100644
+33 −0
Original line number Diff line number Diff line
import numpy as np

# regex patterns for parsing the output from cmp_pcm -> mainly for BASOP ci
MLD_PATTERN = r"MLD: ([\d\.]*)"
MAX_DIFF_PATTERN = r"MAXIMUM ABS DIFF: (\d*)"
MAX_ENC_DIFF_PATTERN = r"The total number of differences is \d (\d+\.\d+)%"

# list of encoder filename patterns with their data type and number of samples per frame
# note: instead of specifying the number of samples per frame, you can use a formula incl. 'fs', e.g. 'fs/50'
ENC_AUX_FILES = [
    ['bits_nominal', np.int16, 'fs/50'],
    ['bwidth', np.int16, 'fs/50'],
    ['clas', np.int16, 'fs/50'],
    ['cng_type', np.int16, 'fs/50'],
    ['coder_type', np.int16, 'fs/50'],
    ['core', np.int16, 'fs/50'],
    ['core_brate', np.float32, 640],
    ['count_SWB', np.int16, 'fs/50'],
    ['count_WB', np.int16, 'fs/50'],
    ['element_brate', np.float32, 'fs/50'],
    ['element_mode', np.int16, 'fs/50'],
    ['extl', np.int16, 'fs/50'],
    ['extl_brate', np.float32, 'fs/50'],
    ['ivas_total_brate', np.float32, 'fs/50'],
    ['L_frame', np.int16, 'fs/50'],
    ['localVAD', np.int16, 'fs/50'],
    ['sp_aud_decision0', np.int16, 'fs/50'],
    ['sp_aud_decision1', np.int16, 'fs/50'],
    ['sp_aud_decision2', np.int16, 'fs/50'],
    ['tdm_LRTD_flag', np.int16, 'fs/50'],
    ['total_brate', np.float32, 'fs/50'],
    ['vad_flag', np.int16, 'fs/50']
]