From a1475f7cd524bce56bad75c46a74beee6438f308 Mon Sep 17 00:00:00 2001 From: Adriana Vasilache Date: Fri, 13 Dec 2024 12:27:48 +0200 Subject: [PATCH 01/23] Issue 1231 fix - align to Basop --- lib_com/ivas_cnst.h | 5 +++++ lib_com/options.h | 2 +- lib_dec/ivas_qmetadata_dec.c | 16 +++++++++++++++- lib_enc/ivas_qmetadata_enc.c | 8 +++++++- 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index db01bdfe89..8c5be1b706 100755 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1141,7 +1141,12 @@ enum #define MASA_TRANSP_BITS 1 #define NO_BITS_MASA_ISM_NO_OBJ 2 + +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL +#define MASA2TOTAL_THR 0.9799999f +#else #define MASA2TOTAL_THR 0.98f +#endif #define BITS_MASA2TOTTAL_DCT0 6 #define STEP_M2T 0.1f #define MASA_HEADER_BITS 2 diff --git a/lib_com/options.h b/lib_com/options.h index 51db29c99c..e1d7a0f267 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -171,7 +171,7 @@ #define NONBE_FIX_1176_OSBA_REVERB_JBM_ASAN_ERROR /* Ericsson: Issue 1176, fix in TDREND_firfilt for subframes shorter than the filter length */ #define NONBE_1220_OMASA_JBM_BRATE_SW_FLUSH /* VA: issue 1220: fix bug in renderer flush in OMASA 1ISM JBM bitrate switching */ - +#define NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL /* Nokia: add fix for precision limitation in comparison with masa2total energy ratio threshold to be aligned with BASOP*/ /* ##################### End NON-BE switches ########################### */ /* ################## End DEVELOPMENT switches ######################### */ diff --git a/lib_dec/ivas_qmetadata_dec.c b/lib_dec/ivas_qmetadata_dec.c index ef5da3cb5d..4df30297fd 100644 --- a/lib_dec/ivas_qmetadata_dec.c +++ b/lib_dec/ivas_qmetadata_dec.c @@ -4359,7 +4359,9 @@ void ivas_omasa_decode_masa_to_total( float q_dct_data[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS], dct_data_tmp[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; int16_t n_streams, len_stream; - +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL + int32_t int_tmp; +#endif /* Setup coding parameters */ n_streams = 1; len_stream = nbands * nblocks; @@ -4414,6 +4416,10 @@ void ivas_omasa_decode_masa_to_total( { masa_to_total_energy_ratio[i][j] = max( 0.0f, q_dct_data[k] ); masa_to_total_energy_ratio[i][j] = min( 1.0f, masa_to_total_energy_ratio[i][j] ); +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL + int_tmp = (int32_t) ( MASA_SUR_COH_PRECISION * masa_to_total_energy_ratio[i][j] ); + masa_to_total_energy_ratio[i][j] = (float) ( int_tmp * MASA_SUR_COH_THRESHOLD ); +#endif k++; } } @@ -4425,6 +4431,10 @@ void ivas_omasa_decode_masa_to_total( for ( j = 0; j < nbands; j++ ) { masa_to_total_energy_ratio[i][j] = masa_to_total_energy_ratio[0][j]; +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL + int_tmp = (int32_t) ( MASA_SUR_COH_PRECISION * masa_to_total_energy_ratio[i][j] ); + masa_to_total_energy_ratio[i][j] = (float) ( int_tmp * MASA_SUR_COH_THRESHOLD ); +#endif } } } @@ -4436,6 +4446,10 @@ void ivas_omasa_decode_masa_to_total( for ( i = 0; i < nblocks; i++ ) { masa_to_total_energy_ratio[i][j] = masa_to_total_energy_ratio[i][0]; +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL + int_tmp = (int32_t) ( MASA_SUR_COH_PRECISION * masa_to_total_energy_ratio[i][j] ); + masa_to_total_energy_ratio[i][j] = (float) ( int_tmp * MASA_SUR_COH_THRESHOLD ); +#endif } } } diff --git a/lib_enc/ivas_qmetadata_enc.c b/lib_enc/ivas_qmetadata_enc.c index 562a4fa14e..d178cbf62c 100644 --- a/lib_enc/ivas_qmetadata_enc.c +++ b/lib_enc/ivas_qmetadata_enc.c @@ -6035,7 +6035,9 @@ void ivas_omasa_encode_masa_to_total( float dct_data[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; int16_t bits_pos, nb_bits; int16_t n_streams, len_stream; - +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL + int32_t int_tmp; +#endif #ifdef DEBUG_MODE_QMETADATA static FILE *pF = NULL; static FILE *pF_ratio = NULL; @@ -6196,6 +6198,10 @@ void ivas_omasa_encode_masa_to_total( { masa_to_total_energy_ratio[i][j] = max( 0.0f, q_dct_data[k] ); masa_to_total_energy_ratio[i][j] = min( 1.0f, masa_to_total_energy_ratio[i][j] ); +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL + int_tmp = (int32_t) ( MASA_SUR_COH_PRECISION * masa_to_total_energy_ratio[i][j] ); + masa_to_total_energy_ratio[i][j] = (float) ( int_tmp * MASA_SUR_COH_THRESHOLD ); +#endif k++; } } -- GitLab From 5ce99876f27fd45d5ee8820f21df7fcf8ba812a6 Mon Sep 17 00:00:00 2001 From: vaclav Date: Fri, 13 Dec 2024 11:28:10 +0100 Subject: [PATCH 02/23] issue 1244: fix to SWB BWE memory in case of switching from FB coding; under NONBE_1244_FIX_SWB_BWE_MEMORY --- lib_com/options.h | 2 ++ lib_enc/swb_pre_proc.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/lib_com/options.h b/lib_com/options.h index 059877b9b2..7ba00d5e4d 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -178,6 +178,8 @@ #define NONBE_1220_OMASA_JBM_BRATE_SW_FLUSH /* VA: issue 1220: fix bug in renderer flush in OMASA 1ISM JBM bitrate switching */ #define NONBE_1229_FIX_ISM1_DPID /* Eri: issue 1229: fix bug causing ISM 1 to use default -dpid instead of the specified one */ #define NONBE_1233_HQ_CLASSIFIER_DIV_BY_ZERO /* Eri: issue 1233: Address possible division by zero in hf_spectrum_sparseness() */ +#define NONBE_1244_FIX_SWB_BWE_MEMORY /* VA: issue 1244: fix to SWB BWE memory in case of switching from FB coding */ + /* ##################### End NON-BE switches ########################### */ diff --git a/lib_enc/swb_pre_proc.c b/lib_enc/swb_pre_proc.c index 610d485db4..72893243f2 100644 --- a/lib_enc/swb_pre_proc.c +++ b/lib_enc/swb_pre_proc.c @@ -442,7 +442,11 @@ void swb_pre_proc( if ( st->last_extl != SWB_BWE && st->last_extl != FB_BWE ) { /* resample 48 kHz to 32kHz */ +#ifdef NONBE_1244_FIX_SWB_BWE_MEMORY + if ( ( st->last_bwidth == FB && st->element_mode == EVS_MONO ) || ( st->bwidth == FB && st->element_mode > EVS_MONO ) ) +#else if ( st->last_bwidth == FB ) +#endif { inner_frame = L_FRAME48k; inner_Fs = 48000; -- GitLab From c525f0935524229a308e7d8a648c2ca14c77ccbd Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Fri, 31 Jan 2025 14:27:39 +0100 Subject: [PATCH 03/23] updates and fixes for diff_complexity.py support for WMOPS_DETAIL --- scripts/diff_complexity.py | 382 ++++++++++++++++++++++++------------- 1 file changed, 245 insertions(+), 137 deletions(-) diff --git a/scripts/diff_complexity.py b/scripts/diff_complexity.py index 1193b5b1c4..1093438d7c 100755 --- a/scripts/diff_complexity.py +++ b/scripts/diff_complexity.py @@ -28,6 +28,13 @@ submitted to and settled by the final, binding jurisdiction of the courts of Mun accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and the United Nations Convention on Contracts on the International Sales of Goods. """ +import argparse +import re +from io import StringIO +from pathlib import Path +from shutil import get_terminal_size + +import pandas as pd """ Script to diff IVAS logs produced by WMC tool instrumented binaries @@ -38,47 +45,65 @@ the United Nations Convention on Contracts on the International Sales of Goods. This allows: cdiff """ -import argparse -import re -from io import StringIO -from shutil import get_terminal_size -import pandas as pd - -REGEX_WMOPS_TABLE = r"\s?\w+(\s+\w+\.\w+)(\s+\w+\.\w+){3,6}" -REGEX_ROM = ( - r"((\w+\s+\w+)|(\w+\s+\w+\s+)\(.+\))\s?size\s+\(.+\/(\w+)\/.+\)\:\s(\d+)\s+\w+" -) +# without WMC_AUTO, can collide with manual instrumentation +# REGEX_WMOPS_TABLE = r"(\w+)(?:\[WMC_AUTO\])?((\s+\d+\.\d+){4,})" +REGEX_WMOPS_TABLE = r"(\w+(\[WMC_AUTO\])?)((\s+\d+\.\d+){4,})" +REGEX_ROM = r"(\w+\s+ROM.+)size.+\/([\w\_]+)\/.+:\s(\d+)" REGEX_MAX_MEM = r"(Maximum\s+.+)\s+size\:\s+(\d+)" +SUMMARY_COL_NAMES = ["BSL", "CUT", "CUT - BSL"] + +SORT_DICT = { + "min": "WMOPs min", + "avg": "WMOPs avg", + "max": "WMOPs max", + "cmin": "WMOPs(cum) min", + "cavg": "WMOPs(cum) avg", + "cmax": "WMOPs(cum) max", + "calls": "Calls", +} + PD_STRING_KWARGS = { - "index": False, + "index": True, "justify": "center", "max_colwidth": 30, } + NOCOLOUR = "\x1b[0m" RED = "\x1b[31m" GREEN = "\x1b[32m" BLUE = "\x1b[34m" +ROUTINE_NAME_MAP = {"_ivas_fx": "", "_fx": "", "_w32_x": ""} + + +def sanitize_routine_names(df): + # apply the mapping to remove or change routine names + for k, v in ROUTINE_NAME_MAP.items(): + df["Routine"] = df["Routine"].str.replace(k, v) + return df + -def log2df(log_file): +def log2df(log_file, rename=False): """ Parse a WMC tool logfile to a pandas dataframe """ with open(log_file, "r") as log: logfile = "".join(line for line in log) + # apply regexes wmops = [ - re.sub(r"\s+", ",", w.group().strip()) + re.sub(r"\s+", ",", w.expand(r"\1\3")) for w in re.finditer(REGEX_WMOPS_TABLE, logfile) ] - memory = [m.expand(r"\1 (\4), \5") for m in re.finditer(REGEX_ROM, logfile)] - memory.extend([m.expand(r"\1, \2") for m in re.finditer(REGEX_MAX_MEM, logfile)]) + memory = [m.expand(r"\1(\2),\3") for m in re.finditer(REGEX_ROM, logfile)] + memory.extend([m.expand(r"\1,\2") for m in re.finditer(REGEX_MAX_MEM, logfile)]) if not wmops or not memory: raise ValueError(f"Error parsing {log_file}!") + # convert to dataframe wmops = pd.read_csv( StringIO("\n".join(wmops)), header=None, @@ -94,123 +119,191 @@ def log2df(log_file): ], ) memory = pd.read_csv( - StringIO("\n".join(memory)), header=None, names=["Type", "Words"] - ) + StringIO("\n".join(memory)), header=None, names=["Type", "Bytes"] + ).set_index("Type") + memory["Bytes"] = memory["Bytes"].astype("int") + + # sanitize names + if rename: + wmops = sanitize_routine_names(wmops) + return wmops, memory -def main(bsl, cut, out_file, quiet=False, verbose=False): - if not quiet: - print(GREEN + f"Baseline conditon: {bsl}" + NOCOLOUR) - print(RED + f"Condition under test: {cut}" + NOCOLOUR) +def diff_wmops(bsl, cut): + # get total values + def get_tot(df): + return df[df["Routine"] == "total"].set_index("Routine").iloc[:, 1:4] - bsl_wmops, bsl_mem = log2df(bsl) - cut_wmops, cut_mem = log2df(cut) + bsl_wmops_tot = get_tot(bsl) + cut_wmops_tot = get_tot(cut) - if verbose: - PD_STRING_KWARGS["line_width"] = get_terminal_size()[0] - # outer merge on routines, only identical rows are tagged "BOTH" - merge = ( - pd.merge( - cut_wmops.set_index("Routine").drop("total").reset_index(), - bsl_wmops.set_index("Routine").drop("total").reset_index(), - how="outer", - indicator="Source", - ) - .sort_values(["Routine", "Source"], ascending=[True, False]) - .set_index("Source") - ) - merge.index = merge.index.rename_categories( - { - "left_only": RED + "CUT", - "right_only": GREEN + "BSL", - "both": BLUE + "BOTH", - } - ) + # build the wmops and memory tables + table_wmops = pd.concat( + [bsl_wmops_tot, cut_wmops_tot, cut_wmops_tot - bsl_wmops_tot] + ).T + table_wmops.columns = SUMMARY_COL_NAMES - unique = ( - merge.drop(BLUE + "BOTH", errors="ignore") - .reset_index() - .sort_values(["Routine", "Source"], ascending=[True, False]) - ) - common = ( - merge.drop(GREEN + "BSL", errors="ignore") - .drop(RED + "CUT", errors="ignore") - .reset_index() - .sort_values("Routine", ascending=False) - ) + return table_wmops - if not unique.empty: - print( - "Complexity difference of routines".center( - PD_STRING_KWARGS["line_width"], "-" - ) - ) - print(unique.to_string(**PD_STRING_KWARGS) + NOCOLOUR) - - if not common.empty: - print( - "Routines with no differences".center( - PD_STRING_KWARGS["line_width"], "-" - ) - ) - print(common.to_string(**PD_STRING_KWARGS) + NOCOLOUR) - else: - print( - "No differences in complexity of routines".center( - PD_STRING_KWARGS["line_width"], "-" - ) - ) - print(merge.to_string(**PD_STRING_KWARGS)) - SEPARATOR = "_" * PD_STRING_KWARGS["line_width"] - print(NOCOLOUR + SEPARATOR) - table_wmops = pd.concat( - [ - bsl_wmops.iloc[-1][2:5], - cut_wmops.iloc[-1][2:5], - cut_wmops.iloc[-1][2:5] - bsl_wmops.iloc[-1][2:5], - ], - axis=1, +def diff_mem(bsl, cut): + table_mem = pd.concat([bsl, cut, cut - bsl], axis=1) + table_mem.columns = SUMMARY_COL_NAMES + + return table_mem + + +def diff_routines(bsl, cut): + # outer merge on routines, only identical rows are tagged "BOTH" + merge = ( + pd.merge( + cut.set_index("Routine").drop("total").reset_index(), + bsl.set_index("Routine").drop("total").reset_index(), + how="outer", + indicator="Source", + ) + .sort_values(["Routine", "Source"], ascending=[True, False]) + .set_index("Source") + ) + merge.index = merge.index.rename_categories( + { + "left_only": "CUT", + "right_only": "BSL", + "both": "BOTH", + } ) - table_wmops.columns = ["BSL", "CUT", "CUT - BSL"] - table_mem = pd.concat( - [ - bsl_mem.iloc[:, 1], - cut_mem.iloc[:, 1], - cut_mem.iloc[:, 1] - bsl_mem.iloc[:, 1], - ], - axis=1, + # split into differing and identical routines + diff = ( + merge.drop("BOTH", errors="ignore") + .reset_index() + .sort_values(["Routine", "Source"], ascending=[True, False]) + ) + same = ( + merge.drop("BSL", errors="ignore") + .drop("CUT", errors="ignore") + .reset_index() + .sort_values("Routine", ascending=False) ) - table_mem.set_index(bsl_mem.iloc[:, 0], inplace=True) - table_mem.columns = ["BSL", "CUT", "CUT - BSL"] - table = pd.concat([table_wmops, table_mem]) + # get the intersection of the routines so we can calculate the diff + bsl = diff[diff["Source"] == "BSL"].drop(columns="Source").set_index("Routine") + cut = diff[diff["Source"] == "CUT"].drop(columns="Source").set_index("Routine") + overlaps = bsl.index.intersection(cut.index) - def fmt_diff(x): - if isinstance(x, int): - fmt = "{}" - else: - fmt = "{:.3f}" + # find the diff for intersecting routines + routines_diff = cut.loc[overlaps] - bsl.loc[overlaps] + + # retrieve the unique routines for each side + bsl_unique = bsl[~bsl.index.isin(overlaps)] + cut_unique = cut[~cut.index.isin(overlaps)] - if x > 0: - return RED + fmt.format(x) + NOCOLOUR - if x < 0: - return GREEN + fmt.format(x) + NOCOLOUR - else: - return BLUE + fmt.format(x) + NOCOLOUR + return bsl_unique, cut_unique, same, diff, routines_diff - table["CUT - BSL"] = table["CUT - BSL"].apply(fmt_diff) + +def main( + bsl, + cut, + out_file, + detailed=False, + sort_key=None, + quiet=False, + dump_bsl=None, + dump_cut=None, +): if not quiet: - print() - print(table.to_string(justify="left")) + print(GREEN + f"Baseline conditon: {bsl}" + NOCOLOUR) + print(RED + f"Condition under test: {cut}" + NOCOLOUR) + + # parse log files to dataframe + bsl_wmops, bsl_mem = log2df(bsl, True) + cut_wmops, cut_mem = log2df(cut, True) + + # get wmops and memory diff and concatenate into the summary table + table_wmops = diff_wmops(bsl_wmops, cut_wmops) + table_mem = diff_mem(bsl_mem, cut_mem) + summary_table = pd.concat([table_wmops, table_mem]) + if detailed: + bsl_unique, cut_unique, same, diff, routines_diff = diff_routines( + bsl_wmops, cut_wmops + ) + if sort_key: + for df in [bsl_unique, cut_unique, same, diff, routines_diff]: + df.sort_values([SORT_DICT[sort_key]], inplace=True) + + # write output files if out_file: - table.to_csv(out_file) - elif not quiet: - print("\nNo output file specified - console output only!") + summary_table.to_csv(out_file) + if detailed: + detailed_output = out_file.with_stem(f"{out_file.stem}_diff_detailed") + routines_diff.to_csv(detailed_output) + + if dump_bsl: + w, m = log2df(bsl) + pd.concat([w, m.T]).set_index("Routine").to_csv(args.dump_bsl) + if not quiet: + print(GREEN + f"Wrote BSL data to {args.dump_bsl}" + NOCOLOUR) + if dump_cut: + w, m = log2df(cut) + pd.concat([w, m.T]).set_index("Routine").to_csv(args.dump_cut) + if not quiet: + print(RED + f"Wrote CUT data to {args.dump_cut}" + NOCOLOUR) + + # print to CLI + if not quiet: + PD_STRING_KWARGS["line_width"] = get_terminal_size()[0] + + def fmt_df(x, has_int=False, diff=False): + x = float(x) + fmt = "{:.3f}" + if has_int and x % 1 == 0: + fmt = "{:.0f}" + if diff: + if x > 0: + return RED + fmt.format(x) + NOCOLOUR + elif x < 0: + return GREEN + fmt.format(x) + NOCOLOUR + else: + return BLUE + fmt.format(x) + NOCOLOUR + else: + return fmt.format(x) + + def print_df(df, title, has_int=False, diff=False): + df = df.map(fmt_df, has_int=has_int, diff=diff) + print(title.center(PD_STRING_KWARGS["line_width"], "-")) + print(df.to_string(**PD_STRING_KWARGS) + NOCOLOUR) + + if detailed: + if not same.empty: + print(BLUE) + same = same.drop(columns="Source").set_index("Routine") + print_df(same, "Routines with no differences") + if not bsl_unique.empty: + print(GREEN) + print_df(bsl_unique, "Routines only in BSL") + if not cut_unique.empty: + print(RED) + print_df(cut_unique, "Routines only in CUT") + if not routines_diff.empty: + print_df(routines_diff, "Diff of routines", diff=True) + + # summary table + summary_table["BSL"] = summary_table["BSL"].apply( + fmt_df, + has_int=True, + ) + summary_table["CUT"] = summary_table["CUT"].apply( + fmt_df, + has_int=True, + ) + summary_table["CUT - BSL"] = summary_table["CUT - BSL"].apply( + fmt_df, has_int=True, diff=True + ) + print("WMOPs and Memory Summary".center(PD_STRING_KWARGS["line_width"], "-")) + print(summary_table.to_string(justify="left")) if __name__ == "__main__": @@ -220,46 +313,61 @@ if __name__ == "__main__": parser.add_argument( "bsl", - type=str, + type=Path, help="input logfile for baseline condition", ) - parser.add_argument( "cut", - type=str, + type=Path, help="input logfile for condition under test", ) - parser.add_argument( "-o", - "--outfile", - required=False, - type=str, + "--output", + type=Path, help="output csv table", ) - parser.add_argument( - "-q", - "--quiet", - required=False, + "-db", + "--dump_bsl", + type=Path, + help="Dump BSL data to specified .csv file", + ) + parser.add_argument( + "-dc", + "--dump_cut", + type=Path, + help="Dump CUT data to specified .csv file", + ) + parser.add_argument( + "-d", + "--detailed", action="store_true", - help="no console output", - default=False, + help="print detailed info about routines, if used with -o/--output, writes an addtional _detailed.csv file", ) - parser.add_argument( - "-v", - "--verbose", - required=False, + "-s", + "--sort", + choices=SORT_DICT.keys(), + default=None, + help="Sort WMOPs data by this column, only affects detailed output (default = %(default)s)", + ) + parser.add_argument( + "-q", + "--quiet", action="store_true", - help="print detailed info about routines", - default=False, + help="no console output", ) args = parser.parse_args() - if args.verbose and args.quiet: - print("Both verbose and quiet options specified, defaulting to verbose") - args.quiet = False - - main(args.bsl, args.cut, args.outfile, args.quiet, args.verbose) + main( + args.bsl, + args.cut, + args.output, + args.detailed, + args.sort, + args.quiet, + args.dump_bsl, + args.dump_cut, + ) -- GitLab From 0ec99414a7827f7e08e58a14da6fdadaae1450ac Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Fri, 31 Jan 2025 14:46:35 +0100 Subject: [PATCH 04/23] [tmp] add script to parse log folders --- scripts/run_diff.py | 66 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 scripts/run_diff.py diff --git a/scripts/run_diff.py b/scripts/run_diff.py new file mode 100644 index 0000000000..06a7714363 --- /dev/null +++ b/scripts/run_diff.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 +from diff_complexity import ( + log2df, + diff_wmops, + diff_mem, +) +from pathlib import Path +import pandas as pd +from tqdm import tqdm +import numpy as np + +REF_LOGDIR = Path("float_detail_run_21_1_2025/output/logs") +CUT_LOGDIR = Path("basop_detail_run_21_1_2025/output/logs") + +ref_logfiles = sorted( + f + for f in REF_LOGDIR.glob("*.txt") + if not f.name.endswith("pcm.txt") and "dec" in f.stem + # and "ltv48_STEREO" in f.stem +) +cut_logfiles = sorted( + f + for f in CUT_LOGDIR.glob("*.txt") + if not f.name.endswith("pcm.txt") and "dec" in f.stem + # and "ltv48_STEREO" in f.stem +) + +unique = set(f.name for f in ref_logfiles).difference(f.name for f in cut_logfiles) +if unique: + raise FileNotFoundError( + f"One or more files were not found in either directory {unique}" + ) + +records = [] +crashes = [] +for ref, cut in tqdm(zip(ref_logfiles, cut_logfiles), total=len(ref_logfiles)): + # parse logfiles + try: + ref_wmops, ref_mem = log2df(ref) + except ValueError: + crashes.append(str(ref)) + continue + try: + cut_wmops, cut_mem = log2df(cut) + except ValueError: + crashes.append(str(cut)) + continue + + # get the diff for wmops and memory + wmops = diff_wmops(ref_wmops, cut_wmops) + mem = diff_mem(ref_mem, cut_mem) + + # only extract the difference column + diff = pd.DataFrame(pd.concat([wmops, mem])["CUT - BSL"]).T + diff.rename({"CUT - BSL": "Values"}, inplace=True, axis=1) + + diff.insert(0, "Name", ref.stem) + records.append(diff) + +df = pd.DataFrame(np.squeeze(records), columns=diff.columns) +df.set_index("Name", inplace=True) +df.sort_values("WMOPs max", inplace=True, ascending=False) +df.to_csv("all_diff.csv", float_format="%.3f") + +with open("crashes.log", "w") as f: + [print(c, file=f) for c in crashes] -- GitLab From 5ff54f093d76969e91041fa34eb42e626d674d33 Mon Sep 17 00:00:00 2001 From: Adriana Vasilache Date: Mon, 3 Feb 2025 19:46:54 +0200 Subject: [PATCH 05/23] bring DCT_FX to FP --- lib_com/ivas_rom_com.c | 44 ++++++- lib_com/ivas_rom_com.h | 8 +- lib_com/ivas_tools.c | 245 +++++++++++++++++++++++++++++++++++ lib_dec/ivas_qmetadata_dec.c | 117 +++++++++++++++-- 4 files changed, 404 insertions(+), 10 deletions(-) diff --git a/lib_com/ivas_rom_com.c b/lib_com/ivas_rom_com.c index 5f81d801f7..d7969f99c1 100644 --- a/lib_com/ivas_rom_com.c +++ b/lib_com/ivas_rom_com.c @@ -2778,6 +2778,48 @@ const int32_t sep_object_brate[][MAX_NUM_OBJECTS] = }; /* column wise DCT matrices for 4 5, and 8 dim */ +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL +const Word32 dct4_fx[4 * 4] = { // Q31 + 1073741824, 1402951040, 1073741824, 581109056, + 1073741824, 581109056, -1073741824, -1402951040, + 1073741824, -581109056, -1073741824, 1402951040, + 1073741824, -1402951040, 1073741824, -581109056 +}; + +const Word32 dct5_fx[5 * 5] = { // Q31 + 960354688, 1291711360, 1098867328, 798219648, 419618304, + 960354688, 798219648, -419618304, -1291711360, -1098867328, + 960354688, 0, -1358283392, 0, 1358283392, + 960354688, -798219648, -419618304, 1291711360, -1098867328, + 960354688, -1291711360, 1098867328, -798219648, 419618304 +}; + +const Word32 dct8_fx[8 * 8] = { // Q31 + 759350208, 1053125952, 991922688, 892708928, 759350208, 596570944, 410813632, 209379648, + 759350208, 892708928, 410813632, -209379648, -759350208, -1053125952, -991922688, -596570944, + 759350208, 596570944, -410813632, -1053125952, -759350208, 209379648, 991922688, 892708928, + 759350208, 209379648, -991922688, -596570944, 759350208, 892708928, -410813632, -1053125952, + 759350208, -209379648, -991922688, 596570944, 759350208, -892708928, -410813632, 1053125952, + 759350208, -596570944, -410813632, 1053125952, -759350208, -209379648, 991922688, -892708928, + 759350208, -892708928, 410813632, 209379648, -759350208, 1053125952, -991922688, 596570944, + 759350208, -1053125952, 991922688, -892708928, 759350208, -596570944, 410813632, -209379648 +}; + +const Word32 dct12_fx[12 * 12] = { // Q31 + 619978560, 869301376, 846752832, 810030848, 759350208, 695569984, 619978560, 533649696, 438301408, 335436960, 226989024, 114460880, + 619978560, 810030848, 619978560, 335436960, 0, -335436960, -619978560, -810030848, -876602816, -810030848, -619978560, -335436960, + 619978560, 695569984, 226989024, -335436960, -759350208, -869301376, -619978560, -114460880, 438301408, 810030848, 846752832, 533649696, + 619978560, 533649696, -226989024, -810030848, -759350208, -114460880, 619978560, 869301376, 438301408, -335436960, -846752832, -695569984, + 619978560, 335436960, -619978560, -810030848, 0, 810030848, 619978560, -335436960, -876602816, -335436960, 619978560, 810030848, 619978560, + 114460880, -846752832, -335436960, 759350208, 533649696, -619978560, -695569984, 438301408, 810030848, -226989024, -869301376, 619978560, + -114460880, -846752832, 335436960, 759350208, -533649696, -619978560, 695569984, 438301408, -810030848, -226989024, 869301376, 619978560, + -335436960, -619978560, 810030848, 0, -810030848, 619978560, 335436960, -876602816, 335436960, 619978560, -810030848, 619978560, -533649696, + -226989024, 810030848, -759350208, 114460880, 619978560, -869301376, 438301408, 335436960, -846752832, 695569984, 619978560, -695569984, + 226989024, 335436960, -759350208, 869301376, -619978560, 114460880, 438301408, -810030848, 846752832, -533649696, 619978560, -810030848, + 619978560, -335436960, 0, 335436960, -619978560, 810030848, -876602816, 810030848, -619978560, 335436960, 619978560, -869301376, 846752832, + -810030848, 759350208, -695569984, 619978560, -533649696, 438301408, -335436960, 226989024, -114460880 +}; +#else const float dct4[4*4] = { 0.5000f, 0.6533f, 0.5000f, 0.2706f, @@ -2822,7 +2864,7 @@ const float dct12[12*12]= 0.2887f, -0.3772f, 0.2887f, -0.1562f, -0.0000f, 0.1562f, -0.2887f, 0.3772f, -0.4082f, 0.3772f, -0.2887f, 0.1562f, 0.2887f, -0.4048f, 0.3943f, -0.3772f, 0.3536f, -0.3239f, 0.2887f, -0.2485f, 0.2041f, -0.1562f, 0.1057f, -0.0533f }; - +#endif /*----------------------------------------------------------------------------------* * ISM ROM tables *----------------------------------------------------------------------------------*/ diff --git a/lib_com/ivas_rom_com.h b/lib_com/ivas_rom_com.h index c6c8250b03..f9a0075605 100644 --- a/lib_com/ivas_rom_com.h +++ b/lib_com/ivas_rom_com.h @@ -325,11 +325,17 @@ extern const float McMASA_LFEGain_vectors[64]; *----------------------------------------------------------------------------------*/ extern const int32_t sep_object_brate[][MAX_NUM_OBJECTS]; +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL +extern const Word32 dct4_fx[]; +extern const Word32 dct5_fx[]; +extern const Word32 dct8_fx[]; +extern const Word32 dct12_fx[]; +#else extern const float dct4[]; extern const float dct5[]; extern const float dct8[]; extern const float dct12[]; - +#endif /*----------------------------------------------------------------------------------* * ISM ROM tables *----------------------------------------------------------------------------------*/ diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index f91dc214c8..bd02a9a5d2 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -1274,3 +1274,248 @@ float rand_triangular_signed( return 0.5f - 0.5f * sqrtf( 1.0f - rand_val ); } } +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL +Word16 matrix_product_fx( + const Word32 *X_fx, /* i : left hand matrix Qx*/ + const Word16 rowsX, /* i : number of rows of the left hand matrix Q0*/ + const Word16 colsX, /* i : number of columns of the left hand matrix Q0*/ + const Word16 transpX, /* i : flag indicating the transposition of the left hand matrix prior to the multiplication Q0*/ + const Word32 *Y_fx, /* i : right hand matrix Qy*/ + const Word16 rowsY, /* i : number of rows of the right hand matrix Q0*/ + const Word16 colsY, /* i : number of columns of the right hand matrix Q0*/ + const Word16 transpY, /* i : flag indicating the transposition of the right hand matrix prior to the multiplication Q0*/ + Word32 *Z_fx /* o : resulting matrix after the matrix multiplication Qx + Qy - 31*/ +) +{ + Word16 i, j, k; + Word16 x_idx, y_idx; + Word32 *Zp_fx = Z_fx; + + /* Processing */ + + if( transpX == 1 && transpY == 0 ) /* We use X transpose */ + { + if( rowsX != rowsY ) + { + return EXIT_FAILURE; + } + for( j = 0; j < colsY; ++j ) + { + for( i = 0; i < colsX; ++i ) + { + ( *Zp_fx ) = 0; + + for( k = 0; k < rowsX; ++k ) + { + x_idx = k + i*rowsX; /*Q0*/ + y_idx = k + j*rowsY; /*Q0*/ + ( *Zp_fx ) = *Zp_fx + ( X_fx[x_idx] * Y_fx[y_idx] ); /*Qx + Qy - 31*/ + } + Zp_fx++; + } + } + } + else if( transpX == 0 && transpY == 1 ) /* We use Y transpose */ + { + if( colsX != colsY ) + { + return EXIT_FAILURE; + } + for( j = 0; j < rowsY; ++j ) + { + for( i = 0; i < rowsX; ++i ) + { + ( *Zp_fx ) = 0; + for( k = 0; k < colsX; ++k ) + { + x_idx = i + k*rowsX; /*Q0*/ + y_idx = j + k*rowsY; /*Q0*/ + ( *Zp_fx ) = (*Zp_fx) + ( X_fx[x_idx] * Y_fx[y_idx] ); /*Qx + Qy - 31*/ + } + Zp_fx++; + } + } + } + else if( transpX == 1 && transpY == 1 ) /* We use both transpose */ + { + if( rowsX != colsY ) + { + return EXIT_FAILURE; + } + for( j = 0; j < rowsY; ++j ) + { + for( i = 0; i < colsX; ++i ) + { + ( *Zp_fx ) = 0; + move32(); + for( k = 0; k < colsX; ++k ) + { + x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ + y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ + ( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); /*Qx + Qy - 31*/ + move32(); + } + + Zp_fx++; + } + } + } + else /* Regular case */ + { + if( NE_16( colsX, rowsY ) ) + { + return EXIT_FAILURE; + } + + for( j = 0; j < colsY; ++j ) + { + for( i = 0; i < rowsX; ++i ) + { + ( *Zp_fx ) = 0; + + for( k = 0; k < colsX; ++k ) + { + x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ + y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ + ( *Zp_fx ) = L_add_sat( *Zp_fx, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); /*Qx + Qy - 31*/ + // TODO: overflow of Z_fx to be checked + move32(); + } + Zp_fx++; + } + } + } + + return EXIT_SUCCESS; +} + +Word16 matrix_product_q30_fx( + const Word32 *X_fx, /* i : left hand matrix Q31*/ + const Word16 rowsX, /* i : number of rows of the left hand matrix Q0*/ + const Word16 colsX, /* i : number of columns of the left hand matrix Q0*/ + const Word16 transpX, /* i : flag indicating the transposition of the left hand matrix prior to the multiplication Q0*/ + const Word32 *Y_fx, /* i : right hand matrix Q25*/ + const Word16 rowsY, /* i : number of rows of the right hand matrix Q0*/ + const Word16 colsY, /* i : number of columns of the right hand matrix Q0*/ + const Word16 transpY, /* i : flag indicating the transposition of the right hand matrix prior to the multiplication Q0*/ + Word32 *Z_fx /* o : resulting matrix after the matrix multiplication Q30*/ +) +{ + Word16 i, j, k; + Word16 x_idx, y_idx; + Word32 *Zp_fx = Z_fx; + long long int W_tmp; + + /* Processing */ + test(); + test(); + test(); + if( transpX == 1 && transpY == 0 ) /* We use X transpose */ + { + if( rowsX != rowsY ) + { + return EXIT_FAILURE; + } + for( j = 0; j < colsY; ++j ) + { + for( i = 0; i < colsX; ++i ) + { + //( *Zp_fx ) = 0; + W_tmp = 0; + for( k = 0; k < rowsX; ++k ) + { + //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[k + i * rowsX], Y_fx[k + j * rowsY] ) ); + x_idx = k + i * rowsX; /* Q0 */ + y_idx = k + j * rowsY; /* Q0 */ + W_tmp += X_fx[x_idx] * Y_fx[y_idx]; /* Q56 */ + } + W_tmp = W_tmp << 6; /* W_shl( W_tmp, 6 ); */ /*Q62*/ + ( *Zp_fx ) = ( W_tmp + 0x80000000 ) >> 32; /* W_round64_L( W_tmp ); */ /*Q30*/ + Zp_fx++; + } + } + } + else if( transpX == 0 && transpY ==1 ) /* We use Y transpose */ + { + if( colsX != colsY ) + { + return EXIT_FAILURE; + } + for( j = 0; j < rowsY; ++j ) + { + for( i = 0; i < rowsX; ++i ) + { + //( *Zp_fx ) = 0; + W_tmp = 0; + + for( k = 0; k < colsX; ++k ) + { + //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[i + k * rowsX], Y_fx[j + k * rowsY] ) ); + x_idx = i + k * rowsX; /*Q0*/ + y_idx = j + k * rowsY; /*Q0*/ + W_tmp += X_fx[x_idx]*Y_fx[y_idx]; /* Q56 */ + } + W_tmp = W_tmp << 6; /*Q62*/ + ( *Zp_fx ) = ( W_tmp + 0x80000000 ) >> 32; /*Q30*/ + Zp_fx++; + } + } + } + else if( transpX == 1 && transpY ==1 ) /* We use both transpose */ + { + if( rowsX != colsY ) + { + return EXIT_FAILURE; + } + for( j = 0; j < rowsY; ++j ) + { + for( i = 0; i < colsX; ++i ) + { + //( *Zp_fx ) = 0; + W_tmp = 0; + for( k = 0; k < colsX; ++k ) + { + //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[k + i * rowsX], Y_fx[j + k * rowsY] ) ); + x_idx = k + i * rowsX; /*Q0*/ + y_idx = j + k * rowsY; /*Q0*/ + W_tmp += X_fx[x_idx] * Y_fx[y_idx]; // Q56 + } + W_tmp = W_tmp << 6; /*Q62*/ + ( *Zp_fx ) = ( W_tmp + 0x80000000 ) >> 32; /*Q30*/ + + Zp_fx++; + } + } + } + else /* Regular case */ + { + if( colsX != rowsY ) + { + return EXIT_FAILURE; + } + + for( j = 0; j < colsY; ++j ) + { + for( i = 0; i < rowsX; ++i ) + { + //( *Zp_fx ) = 0; + W_tmp = 0; + + for( k = 0; k < colsX; ++k ) + { + //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[i + k * rowsX], Y_fx[k + j * rowsY] ) ); + x_idx = i + k * rowsX; /*Q0*/ + y_idx = k + j * rowsY; /*Q0*/ + W_tmp += X_fx[x_idx] * Y_fx[y_idx]; // Q56 + } + W_tmp = W_tmp << 6; /*Q62*/ + ( *Zp_fx ) = ( W_tmp + 0x80000000 ) >> 32; /*Q30*/ + + Zp_fx++; + } + } + } + + return EXIT_SUCCESS; +} +#endif \ No newline at end of file diff --git a/lib_dec/ivas_qmetadata_dec.c b/lib_dec/ivas_qmetadata_dec.c index 4df30297fd..8181e06e39 100644 --- a/lib_dec/ivas_qmetadata_dec.c +++ b/lib_dec/ivas_qmetadata_dec.c @@ -97,7 +97,13 @@ static int16_t read_surround_coherence_hr( uint16_t *bitstream, int16_t *p_bit_p static int16_t read_coherence_data_hr_512( uint16_t *bitstream, int16_t *p_bit_pos, IVAS_QMETADATA *hQMetaData, const int16_t idx_dir, const int16_t nbits_coh ); -static void read_stream_dct_coeffs_omasa( int16_t *q_idx, float *q_dct_data, const int16_t len_stream, uint16_t *bit_stream, int16_t *index, const int16_t first_line ); +static void read_stream_dct_coeffs_omasa( int16_t *q_idx, +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL + Word32 * q_dct_data_fx, +#else + float *q_dct_data, +#endif + const int16_t len_stream, uint16_t *bit_stream, int16_t *index, const int16_t first_line ); /*-----------------------------------------------------------------------* @@ -4248,7 +4254,11 @@ static void decode_combined_index( static void read_stream_dct_coeffs_omasa( int16_t *q_idx, +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL + Word32 * q_dct_data_fx, +#else float *q_dct_data, +#endif const int16_t len_stream, uint16_t *bit_stream, int16_t *index, @@ -4325,6 +4335,20 @@ static void read_stream_dct_coeffs_omasa( } /* deindex */ +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL + q_dct_data_fx[0] = L_shl( Mpy_32_16_1( step, shl( q_idx[0], 7 ) ), 2 ); // q = 25 + FOR( i = 1; i < len_stream; i++ ) + { + IF( s_and( q_idx[i], 1 ) == 0 ) + { + q_dct_data_fx[i] = L_shl( Mpy_32_16_1( step, negate( shl( q_idx[i], 6 ) ) ), 2 ); /*Q25*/ + } + ELSE + { + q_dct_data_fx[i] = L_shl( Mpy_32_16_1( step, shl( q_idx[i] + 1, 6 ) ), 2 ); /*Q25*/ + } + } +#else q_dct_data[0] = q_idx[0] * step; for ( i = 1; i < len_stream; i++ ) { @@ -4337,7 +4361,7 @@ static void read_stream_dct_coeffs_omasa( q_dct_data[i] = ( ( q_idx[i] + 1 ) >> 1 ) * step; } } - +#endif return; } @@ -4356,8 +4380,13 @@ void ivas_omasa_decode_masa_to_total( { int16_t i, j, k; int16_t q_idx[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL + Word32 q_dct_data_fx[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS], + dct_data_tmp_fx[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; +#else float q_dct_data[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS], dct_data_tmp[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; +#endif int16_t n_streams, len_stream; #ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL int32_t int_tmp; @@ -4374,10 +4403,86 @@ void ivas_omasa_decode_masa_to_total( set_s( q_idx, 0, nbands * nblocks ); for ( i = 0; i < n_streams; i++ ) { - read_stream_dct_coeffs_omasa( &q_idx[i * len_stream], &q_dct_data[i * len_stream], len_stream, bit_stream, index, i == 0 ); + read_stream_dct_coeffs_omasa( &q_idx[i * len_stream], +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL + &q_dct_data_fx[i * len_stream], +#else + &q_dct_data[i * len_stream], +#endif + len_stream, bit_stream, index, i == 0 ); } /* inverse DCT2 transform */ +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL + SWITCH( len_stream ) + { + case 4: + matrix_product_q30_fx( dct4_fx, nblocks, nblocks, 1, q_dct_data_fx, nblocks, 1, 0, dct_data_tmp_fx ); + Copy32( dct_data_tmp_fx, q_dct_data_fx, nblocks ); /*Q30*/ + BREAK; + case 5: + matrix_product_q30_fx( dct5_fx, nbands, nbands, 1, q_dct_data_fx, nbands, 1, 0, dct_data_tmp_fx ); + Copy32( dct_data_tmp_fx, q_dct_data_fx, nbands ); /*Q30*/ + BREAK; + case 8: + matrix_product_q30_fx( dct8_fx, nbands, nbands, 1, q_dct_data_fx, nbands, 1, 0, dct_data_tmp_fx ); + Copy32( dct_data_tmp_fx, q_dct_data_fx, nbands ); /*Q30*/ + BREAK; + case 12: + matrix_product_q30_fx( dct12_fx, nbands, nbands, 1, q_dct_data_fx, nbands, 1, 0, dct_data_tmp_fx ); + Copy32( dct_data_tmp_fx, q_dct_data_fx, nbands ); /*Q30*/ + BREAK; + case 20: + matrix_product_fx( dct5_fx, nbands, nbands, 1, q_dct_data_fx, nbands, nblocks, 0, dct_data_tmp_fx ); + matrix_product_q30_fx( dct_data_tmp_fx, nbands, nblocks, 0, dct4_fx, nblocks, nblocks, 0, q_dct_data_fx ); /* reuse of variable*/ + BREAK; + case 32: + matrix_product_fx( dct8_fx, nbands, nbands, 1, q_dct_data_fx, nbands, nblocks, 0, dct_data_tmp_fx ); + matrix_product_q30_fx( dct_data_tmp_fx, nbands, nblocks, 0, dct4_fx, nblocks, nblocks, 0, q_dct_data_fx ); + BREAK; + default: + printf( "Incorrect number of coefficients for OMASA.\n" ); + BREAK; + } + k = 0; + move16(); + FOR( i = 0; i < nblocks; i++ ) + { + FOR( j = 0; j < nbands; j++ ) + { + masa_to_total_energy_ratio_fx[i][j] = L_max( 0, q_dct_data_fx[k] ); // Q30 + move32(); + masa_to_total_energy_ratio_fx[i][j] = L_min( ONE_IN_Q30, masa_to_total_energy_ratio_fx[i][j] ); /*Q30*/ + move32(); + k = add( k, 1 ); + } + } + + IF( EQ_16( nblocks, 1 ) ) + { + FOR( i = 1; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + FOR( j = 0; j < nbands; j++ ) + { + masa_to_total_energy_ratio_fx[i][j] = masa_to_total_energy_ratio_fx[0][j]; /*Q30*/ + move32(); + } + } + } + + IF( EQ_16( nbands, 1 ) ) + { + FOR( j = 1; j < 5; j++ ) + { + FOR( i = 0; i < nblocks; i++ ) + { + masa_to_total_energy_ratio_fx[i][j] = masa_to_total_energy_ratio_fx[i][0]; /*Q30*/ + move32(); + } + } + } + +#else switch ( len_stream ) { case 4: @@ -4446,13 +4551,9 @@ void ivas_omasa_decode_masa_to_total( for ( i = 0; i < nblocks; i++ ) { masa_to_total_energy_ratio[i][j] = masa_to_total_energy_ratio[i][0]; -#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL - int_tmp = (int32_t) ( MASA_SUR_COH_PRECISION * masa_to_total_energy_ratio[i][j] ); - masa_to_total_energy_ratio[i][j] = (float) ( int_tmp * MASA_SUR_COH_THRESHOLD ); -#endif } } } - +#endif return; } -- GitLab From 17128f7b03119e606b37cee249890d35e2a7e9ac Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 6 Feb 2025 14:08:56 +0100 Subject: [PATCH 06/23] fix issue 1273: fix counter overflow in ISM metadata encoder; under NONBE_1273_ISM_METADATA_COUNTER --- lib_com/options.h | 2 ++ lib_enc/ivas_ism_metadata_enc.c | 12 +++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index efaddf4e6a..052a90e1a9 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -168,6 +168,8 @@ /* any switch which is non-be wrt selection floating point code */ /* all switches in this category should start with "NONBE_" */ +#define NONBE_1273_ISM_METADATA_COUNTER /* VA: issue 1273: fix counter overflow in ISM metadata encoder */ + /* ##################### End NON-BE switches ########################### */ diff --git a/lib_enc/ivas_ism_metadata_enc.c b/lib_enc/ivas_ism_metadata_enc.c index c7b991e2f6..c81190eee7 100644 --- a/lib_enc/ivas_ism_metadata_enc.c +++ b/lib_enc/ivas_ism_metadata_enc.c @@ -276,7 +276,9 @@ ivas_error ivas_ism_metadata_enc( } else if ( hIsmMeta[ch]->ism_md_fec_cnt_enc == ISM_MD_FEC_CNT_MAX ) { - +#ifdef NONBE_1273_ISM_METADATA_COUNTER + hIsmMeta[ch]->ism_md_fec_cnt_enc = 0; +#endif lowrate_metadata_flag[ch] = 1; hIsmMeta[ch]->position_angle.angle1_diff_cnt = ISM_FEC_MAX; @@ -555,7 +557,11 @@ ivas_error ivas_ism_metadata_enc( if ( hIsmMeta[ch]->ism_metadata_flag == 0 ) { +#ifdef NONBE_1273_ISM_METADATA_COUNTER + hIsmMeta[ch]->ism_md_fec_cnt_enc = min( hIsmMeta[ch]->ism_md_fec_cnt_enc++, ISM_MD_FEC_CNT_MAX ); +#else hIsmMeta[ch]->ism_md_fec_cnt_enc++; +#endif } else { @@ -699,7 +705,11 @@ ivas_error ivas_ism_metadata_enc( if ( hIsmMeta[ch]->ism_metadata_flag == 0 ) { +#ifdef NONBE_1273_ISM_METADATA_COUNTER + hIsmMeta[ch]->ism_md_fec_cnt_enc = min( hIsmMeta[ch]->ism_md_fec_cnt_enc++, ISM_MD_FEC_CNT_MAX ); +#else hIsmMeta[ch]->ism_md_fec_cnt_enc++; +#endif } else { -- GitLab From a04dd23b77c69cd14f15f1b6bdbf13e71c8698dd Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 6 Feb 2025 14:19:03 +0100 Subject: [PATCH 07/23] attempt to fix compiler warning --- lib_enc/ivas_ism_metadata_enc.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/lib_enc/ivas_ism_metadata_enc.c b/lib_enc/ivas_ism_metadata_enc.c index c81190eee7..b27235ae4b 100644 --- a/lib_enc/ivas_ism_metadata_enc.c +++ b/lib_enc/ivas_ism_metadata_enc.c @@ -557,10 +557,9 @@ ivas_error ivas_ism_metadata_enc( if ( hIsmMeta[ch]->ism_metadata_flag == 0 ) { -#ifdef NONBE_1273_ISM_METADATA_COUNTER - hIsmMeta[ch]->ism_md_fec_cnt_enc = min( hIsmMeta[ch]->ism_md_fec_cnt_enc++, ISM_MD_FEC_CNT_MAX ); -#else hIsmMeta[ch]->ism_md_fec_cnt_enc++; +#ifdef NONBE_1273_ISM_METADATA_COUNTER + hIsmMeta[ch]->ism_md_fec_cnt_enc = min( hIsmMeta[ch]->ism_md_fec_cnt_enc, ISM_MD_FEC_CNT_MAX ); #endif } else @@ -705,10 +704,9 @@ ivas_error ivas_ism_metadata_enc( if ( hIsmMeta[ch]->ism_metadata_flag == 0 ) { -#ifdef NONBE_1273_ISM_METADATA_COUNTER - hIsmMeta[ch]->ism_md_fec_cnt_enc = min( hIsmMeta[ch]->ism_md_fec_cnt_enc++, ISM_MD_FEC_CNT_MAX ); -#else hIsmMeta[ch]->ism_md_fec_cnt_enc++; +#ifdef NONBE_1273_ISM_METADATA_COUNTER + hIsmMeta[ch]->ism_md_fec_cnt_enc = min( hIsmMeta[ch]->ism_md_fec_cnt_enc, ISM_MD_FEC_CNT_MAX ); #endif } else -- GitLab From 4e79c6a0bf028edab2cd338392a2d6ed3c9c7118 Mon Sep 17 00:00:00 2001 From: Adriana Vasilache Date: Thu, 6 Feb 2025 16:55:55 +0200 Subject: [PATCH 08/23] update fix 1231 --- lib_com/ivas_cnst.h | 9 +-- lib_com/ivas_prot.h | 26 ++++++ lib_com/ivas_rom_com.c | 4 +- lib_com/ivas_rom_com.h | 4 +- lib_com/ivas_tools.c | 148 ++++++++++++++++++----------------- lib_dec/ivas_qmetadata_dec.c | 123 +++++++++++++++-------------- lib_enc/ivas_qmetadata_enc.c | 103 +++++++++++++++++++++++- 7 files changed, 276 insertions(+), 141 deletions(-) diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 47ef7ce7a1..cde0689360 100755 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1141,14 +1141,13 @@ enum #define MASA_TRANSP_BITS 1 #define NO_BITS_MASA_ISM_NO_OBJ 2 - -#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL -#define MASA2TOTAL_THR 0.9799999f -#else #define MASA2TOTAL_THR 0.98f -#endif + #define BITS_MASA2TOTTAL_DCT0 6 #define STEP_M2T 0.1f +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL +#define STEP_M2T_FX 214748365 // Q31 +#endif #define MASA_HEADER_BITS 2 #define MASA_SUBFRAME_BITS 1 #define MASA_LOWBITRATE_MODE_BITS 1 diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 987455ea7c..ba42beb541 100755 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -756,6 +756,32 @@ int16_t get_igf_startline( float rand_triangular_signed( int16_t *seed ); +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL +Word16 matrix_product_fx( + const Word32 *X_fx, /* i : left hand matrix Qx*/ + const Word16 rowsX, /* i : number of rows of the left hand matrix Q0*/ + const Word16 colsX, /* i : number of columns of the left hand matrix Q0*/ + const Word16 transpX, /* i : flag indicating the transposition of the left hand matrix prior to the multiplication Q0*/ + const Word32 *Y_fx, /* i : right hand matrix Qy*/ + const Word16 rowsY, /* i : number of rows of the right hand matrix Q0*/ + const Word16 colsY, /* i : number of columns of the right hand matrix Q0*/ + const Word16 transpY, /* i : flag indicating the transposition of the right hand matrix prior to the multiplication Q0*/ + Word32 *Z_fx /* o : resulting matrix after the matrix multiplication Qx + Qy - 31*/ +); + +Word16 matrix_product_q30_fx( + const Word32 *X_fx, /* i : left hand matrix Q31*/ + const Word16 rowsX, /* i : number of rows of the left hand matrix Q0*/ + const Word16 colsX, /* i : number of columns of the left hand matrix Q0*/ + const Word16 transpX, /* i : flag indicating the transposition of the left hand matrix prior to the multiplication Q0*/ + const Word32 *Y_fx, /* i : right hand matrix Q25*/ + const Word16 rowsY, /* i : number of rows of the right hand matrix Q0*/ + const Word16 colsY, /* i : number of columns of the right hand matrix Q0*/ + const Word16 transpY, /* i : flag indicating the transposition of the right hand matrix prior to the multiplication Q0*/ + Word32 *Z_fx /* o : resulting matrix after the matrix multiplication Q30*/ +); +#endif + void dtx_read_padding_bits( DEC_CORE_HANDLE st, diff --git a/lib_com/ivas_rom_com.c b/lib_com/ivas_rom_com.c index d7969f99c1..2e55c8799a 100644 --- a/lib_com/ivas_rom_com.c +++ b/lib_com/ivas_rom_com.c @@ -2819,7 +2819,7 @@ const Word32 dct12_fx[12 * 12] = { // Q31 619978560, -335436960, 0, 335436960, -619978560, 810030848, -876602816, 810030848, -619978560, 335436960, 619978560, -869301376, 846752832, -810030848, 759350208, -695569984, 619978560, -533649696, 438301408, -335436960, 226989024, -114460880 }; -#else +#endif const float dct4[4*4] = { 0.5000f, 0.6533f, 0.5000f, 0.2706f, @@ -2864,7 +2864,7 @@ const float dct12[12*12]= 0.2887f, -0.3772f, 0.2887f, -0.1562f, -0.0000f, 0.1562f, -0.2887f, 0.3772f, -0.4082f, 0.3772f, -0.2887f, 0.1562f, 0.2887f, -0.4048f, 0.3943f, -0.3772f, 0.3536f, -0.3239f, 0.2887f, -0.2485f, 0.2041f, -0.1562f, 0.1057f, -0.0533f }; -#endif + /*----------------------------------------------------------------------------------* * ISM ROM tables *----------------------------------------------------------------------------------*/ diff --git a/lib_com/ivas_rom_com.h b/lib_com/ivas_rom_com.h index f9a0075605..b19ae93c17 100644 --- a/lib_com/ivas_rom_com.h +++ b/lib_com/ivas_rom_com.h @@ -330,12 +330,12 @@ extern const Word32 dct4_fx[]; extern const Word32 dct5_fx[]; extern const Word32 dct8_fx[]; extern const Word32 dct12_fx[]; -#else +#endif extern const float dct4[]; extern const float dct5[]; extern const float dct8[]; extern const float dct12[]; -#endif + /*----------------------------------------------------------------------------------* * ISM ROM tables *----------------------------------------------------------------------------------*/ diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index bd02a9a5d2..2b6835190c 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -41,6 +41,9 @@ #include "ivas_prot.h" #include "wmc_auto.h" #include "ivas_rom_com.h" +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL +#include "basop_settings.h" +#endif /*--------------------------------------------------------------- * sumAbs() @@ -1292,68 +1295,67 @@ Word16 matrix_product_fx( Word32 *Zp_fx = Z_fx; /* Processing */ - - if( transpX == 1 && transpY == 0 ) /* We use X transpose */ + + if ( transpX == 1 && transpY == 0 ) /* We use X transpose */ { - if( rowsX != rowsY ) + if ( rowsX != rowsY ) { return EXIT_FAILURE; } - for( j = 0; j < colsY; ++j ) + for ( j = 0; j < colsY; ++j ) { - for( i = 0; i < colsX; ++i ) + for ( i = 0; i < colsX; ++i ) { ( *Zp_fx ) = 0; - - for( k = 0; k < rowsX; ++k ) + + for ( k = 0; k < rowsX; ++k ) { - x_idx = k + i*rowsX; /*Q0*/ - y_idx = k + j*rowsY; /*Q0*/ - ( *Zp_fx ) = *Zp_fx + ( X_fx[x_idx] * Y_fx[y_idx] ); /*Qx + Qy - 31*/ + x_idx = k + i * rowsX; /*Q0*/ + y_idx = k + j * rowsY; /*Q0*/ + ( *Zp_fx ) = *Zp_fx + Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ); /*Qx + Qy - 31*/ } Zp_fx++; } } } - else if( transpX == 0 && transpY == 1 ) /* We use Y transpose */ + else if ( transpX == 0 && transpY == 1 ) /* We use Y transpose */ { - if( colsX != colsY ) + if ( colsX != colsY ) { return EXIT_FAILURE; } - for( j = 0; j < rowsY; ++j ) + for ( j = 0; j < rowsY; ++j ) { - for( i = 0; i < rowsX; ++i ) + for ( i = 0; i < rowsX; ++i ) { ( *Zp_fx ) = 0; - for( k = 0; k < colsX; ++k ) + for ( k = 0; k < colsX; ++k ) { - x_idx = i + k*rowsX; /*Q0*/ - y_idx = j + k*rowsY; /*Q0*/ - ( *Zp_fx ) = (*Zp_fx) + ( X_fx[x_idx] * Y_fx[y_idx] ); /*Qx + Qy - 31*/ + x_idx = i + k * rowsX; /*Q0*/ + y_idx = j + k * rowsY; /*Q0*/ + ( *Zp_fx ) = ( *Zp_fx ) + Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ); /*Qx + Qy - 31*/ } Zp_fx++; } } } - else if( transpX == 1 && transpY == 1 ) /* We use both transpose */ + else if ( transpX == 1 && transpY == 1 ) /* We use both transpose */ { - if( rowsX != colsY ) + if ( rowsX != colsY ) { return EXIT_FAILURE; } - for( j = 0; j < rowsY; ++j ) + for ( j = 0; j < rowsY; ++j ) { - for( i = 0; i < colsX; ++i ) + for ( i = 0; i < colsX; ++i ) { ( *Zp_fx ) = 0; - move32(); - for( k = 0; k < colsX; ++k ) + + for ( k = 0; k < colsX; ++k ) { - x_idx = add( k, imult1616( i, rowsX ) ); /*Q0*/ - y_idx = add( j, imult1616( k, rowsY ) ); /*Q0*/ - ( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); /*Qx + Qy - 31*/ - move32(); + x_idx = k + i * rowsX; /*Q0*/ + y_idx = j + k * rowsY; /*Q0*/ + ( *Zp_fx ) = ( *Zp_fx ) + Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ); /*Qx + Qy - 31*/ } Zp_fx++; @@ -1362,22 +1364,22 @@ Word16 matrix_product_fx( } else /* Regular case */ { - if( NE_16( colsX, rowsY ) ) + if ( colsX != rowsY ) { return EXIT_FAILURE; } - for( j = 0; j < colsY; ++j ) + for ( j = 0; j < colsY; ++j ) { - for( i = 0; i < rowsX; ++i ) + for ( i = 0; i < rowsX; ++i ) { ( *Zp_fx ) = 0; - - for( k = 0; k < colsX; ++k ) + + for ( k = 0; k < colsX; ++k ) { - x_idx = add( i, imult1616( k, rowsX ) ); /*Q0*/ - y_idx = add( k, imult1616( j, rowsY ) ); /*Q0*/ - ( *Zp_fx ) = L_add_sat( *Zp_fx, Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ) ); /*Qx + Qy - 31*/ + x_idx = i + k * rowsX; /*Q0*/ + y_idx = k + j * rowsY; /*Q0*/ + ( *Zp_fx ) = ( *Zp_fx ) + Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ); /*Qx + Qy - 31 L_sat_add() */ // TODO: overflow of Z_fx to be checked move32(); } @@ -1410,75 +1412,75 @@ Word16 matrix_product_q30_fx( test(); test(); test(); - if( transpX == 1 && transpY == 0 ) /* We use X transpose */ + if ( transpX == 1 && transpY == 0 ) /* We use X transpose */ { - if( rowsX != rowsY ) + if ( rowsX != rowsY ) { return EXIT_FAILURE; } - for( j = 0; j < colsY; ++j ) + for ( j = 0; j < colsY; ++j ) { - for( i = 0; i < colsX; ++i ) + for ( i = 0; i < colsX; ++i ) { //( *Zp_fx ) = 0; W_tmp = 0; - for( k = 0; k < rowsX; ++k ) + for ( k = 0; k < rowsX; ++k ) { //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[k + i * rowsX], Y_fx[k + j * rowsY] ) ); - x_idx = k + i * rowsX; /* Q0 */ - y_idx = k + j * rowsY; /* Q0 */ - W_tmp += X_fx[x_idx] * Y_fx[y_idx]; /* Q56 */ + x_idx = k + i * rowsX; /* Q0 */ + y_idx = k + j * rowsY; /* Q0 */ + W_tmp += ( (long long int) X_fx[x_idx] * (long long int) Y_fx[y_idx] ); /* Q56 */ } - W_tmp = W_tmp << 6; /* W_shl( W_tmp, 6 ); */ /*Q62*/ - ( *Zp_fx ) = ( W_tmp + 0x80000000 ) >> 32; /* W_round64_L( W_tmp ); */ /*Q30*/ + W_tmp = W_tmp << 6; /* W_shl( W_tmp, 6 ); */ /*Q62*/ + ( *Zp_fx ) = ( W_tmp + 0x80000000 ) >> 32; /* W_round64_L( W_tmp ); */ /*Q30*/ Zp_fx++; } } } - else if( transpX == 0 && transpY ==1 ) /* We use Y transpose */ + else if ( transpX == 0 && transpY == 1 ) /* We use Y transpose */ { - if( colsX != colsY ) + if ( colsX != colsY ) { return EXIT_FAILURE; } - for( j = 0; j < rowsY; ++j ) + for ( j = 0; j < rowsY; ++j ) { - for( i = 0; i < rowsX; ++i ) + for ( i = 0; i < rowsX; ++i ) { //( *Zp_fx ) = 0; W_tmp = 0; - for( k = 0; k < colsX; ++k ) + for ( k = 0; k < colsX; ++k ) { //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[i + k * rowsX], Y_fx[j + k * rowsY] ) ); - x_idx = i + k * rowsX; /*Q0*/ - y_idx = j + k * rowsY; /*Q0*/ - W_tmp += X_fx[x_idx]*Y_fx[y_idx]; /* Q56 */ + x_idx = i + k * rowsX; /*Q0*/ + y_idx = j + k * rowsY; /*Q0*/ + W_tmp += ( (long long int) X_fx[x_idx] * (long long int) Y_fx[y_idx] ); /* Q56 */ } - W_tmp = W_tmp << 6; /*Q62*/ - ( *Zp_fx ) = ( W_tmp + 0x80000000 ) >> 32; /*Q30*/ + W_tmp = W_tmp << 6; /*Q62*/ + ( *Zp_fx ) = ( W_tmp + 0x80000000 ) >> 32; /*Q30*/ Zp_fx++; } } } - else if( transpX == 1 && transpY ==1 ) /* We use both transpose */ + else if ( transpX == 1 && transpY == 1 ) /* We use both transpose */ { - if( rowsX != colsY ) + if ( rowsX != colsY ) { return EXIT_FAILURE; } - for( j = 0; j < rowsY; ++j ) + for ( j = 0; j < rowsY; ++j ) { - for( i = 0; i < colsX; ++i ) + for ( i = 0; i < colsX; ++i ) { //( *Zp_fx ) = 0; W_tmp = 0; - for( k = 0; k < colsX; ++k ) + for ( k = 0; k < colsX; ++k ) { //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[k + i * rowsX], Y_fx[j + k * rowsY] ) ); - x_idx = k + i * rowsX; /*Q0*/ - y_idx = j + k * rowsY; /*Q0*/ - W_tmp += X_fx[x_idx] * Y_fx[y_idx]; // Q56 + x_idx = k + i * rowsX; /*Q0*/ + y_idx = j + k * rowsY; /*Q0*/ + W_tmp += ( (long long int) X_fx[x_idx] * (long long int) Y_fx[y_idx] ); // Q56 } W_tmp = W_tmp << 6; /*Q62*/ ( *Zp_fx ) = ( W_tmp + 0x80000000 ) >> 32; /*Q30*/ @@ -1489,28 +1491,28 @@ Word16 matrix_product_q30_fx( } else /* Regular case */ { - if( colsX != rowsY ) + if ( colsX != rowsY ) { return EXIT_FAILURE; } - for( j = 0; j < colsY; ++j ) + for ( j = 0; j < colsY; ++j ) { - for( i = 0; i < rowsX; ++i ) + for ( i = 0; i < rowsX; ++i ) { //( *Zp_fx ) = 0; W_tmp = 0; - - for( k = 0; k < colsX; ++k ) + + for ( k = 0; k < colsX; ++k ) { //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[i + k * rowsX], Y_fx[k + j * rowsY] ) ); - x_idx = i + k * rowsX; /*Q0*/ - y_idx = k + j * rowsY; /*Q0*/ - W_tmp += X_fx[x_idx] * Y_fx[y_idx]; // Q56 + x_idx = i + k * rowsX; /*Q0*/ + y_idx = k + j * rowsY; /*Q0*/ + W_tmp += ( (long long int) X_fx[x_idx] * (long long int) Y_fx[y_idx] ); // Q56 } W_tmp = W_tmp << 6; /*Q62*/ ( *Zp_fx ) = ( W_tmp + 0x80000000 ) >> 32; /*Q30*/ - + Zp_fx++; } } diff --git a/lib_dec/ivas_qmetadata_dec.c b/lib_dec/ivas_qmetadata_dec.c index 8181e06e39..2462065d03 100644 --- a/lib_dec/ivas_qmetadata_dec.c +++ b/lib_dec/ivas_qmetadata_dec.c @@ -40,6 +40,10 @@ #include "ivas_rom_dec.h" #include "wmc_auto.h" #include "prot.h" +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL +#include "basop_settings.h" +#endif + /*-----------------------------------------------------------------------* * Local function prototypes @@ -97,13 +101,16 @@ static int16_t read_surround_coherence_hr( uint16_t *bitstream, int16_t *p_bit_p static int16_t read_coherence_data_hr_512( uint16_t *bitstream, int16_t *p_bit_pos, IVAS_QMETADATA *hQMetaData, const int16_t idx_dir, const int16_t nbits_coh ); -static void read_stream_dct_coeffs_omasa( int16_t *q_idx, -#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL - Word32 * q_dct_data_fx, -#else - float *q_dct_data, -#endif - const int16_t len_stream, uint16_t *bit_stream, int16_t *index, const int16_t first_line ); +static void read_stream_dct_coeffs_omasa( int16_t *q_idx, +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL + Word32 *q_dct_data_fx, +#else + float *q_dct_data, +#endif + const int16_t len_stream, + uint16_t *bit_stream, + int16_t *index, + const int16_t first_line ); /*-----------------------------------------------------------------------* @@ -4254,8 +4261,8 @@ static void decode_combined_index( static void read_stream_dct_coeffs_omasa( int16_t *q_idx, -#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL - Word32 * q_dct_data_fx, +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL + Word32 *q_dct_data_fx, #else float *q_dct_data, #endif @@ -4268,8 +4275,12 @@ static void read_stream_dct_coeffs_omasa( int16_t i, j, i_min; float step; - int16_t GR1, GR2; + int16_t GR1, GR2; +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL + int64_t step_fx; + step_fx = STEP_M2T_FX; +#endif step = STEP_M2T; sign = 1; if ( first_line == 0 ) @@ -4335,17 +4346,17 @@ static void read_stream_dct_coeffs_omasa( } /* deindex */ -#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL - q_dct_data_fx[0] = L_shl( Mpy_32_16_1( step, shl( q_idx[0], 7 ) ), 2 ); // q = 25 - FOR( i = 1; i < len_stream; i++ ) +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL + q_dct_data_fx[0] = (Word32) ( ( step_fx * q_idx[0] ) >> 6 ); // Q25 + for ( i = 1; i < len_stream; i++ ) { - IF( s_and( q_idx[i], 1 ) == 0 ) + if ( ( q_idx[i] & 1 ) == 0 ) { - q_dct_data_fx[i] = L_shl( Mpy_32_16_1( step, negate( shl( q_idx[i], 6 ) ) ), 2 ); /*Q25*/ + q_dct_data_fx[i] = (Word32) ( ( step_fx * ( -q_idx[i] ) ) >> 7 ); // Q25 } ELSE { - q_dct_data_fx[i] = L_shl( Mpy_32_16_1( step, shl( q_idx[i] + 1, 6 ) ), 2 ); /*Q25*/ + q_dct_data_fx[i] = (Word32) ( ( step_fx * ( q_idx[i] + 1 ) ) >> 7 ); // Q25 } } #else @@ -4388,9 +4399,7 @@ void ivas_omasa_decode_masa_to_total( dct_data_tmp[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; #endif int16_t n_streams, len_stream; -#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL - int32_t int_tmp; -#endif + /* Setup coding parameters */ n_streams = 1; len_stream = nbands * nblocks; @@ -4404,33 +4413,33 @@ void ivas_omasa_decode_masa_to_total( for ( i = 0; i < n_streams; i++ ) { read_stream_dct_coeffs_omasa( &q_idx[i * len_stream], -#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL - &q_dct_data_fx[i * len_stream], -#else - &q_dct_data[i * len_stream], -#endif - len_stream, bit_stream, index, i == 0 ); +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL + &q_dct_data_fx[i * len_stream], +#else + &q_dct_data[i * len_stream], +#endif + len_stream, bit_stream, index, i == 0 ); } /* inverse DCT2 transform */ -#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL - SWITCH( len_stream ) +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL + SWITCH( len_stream ) { case 4: matrix_product_q30_fx( dct4_fx, nblocks, nblocks, 1, q_dct_data_fx, nblocks, 1, 0, dct_data_tmp_fx ); - Copy32( dct_data_tmp_fx, q_dct_data_fx, nblocks ); /*Q30*/ + mvl2l( dct_data_tmp_fx, q_dct_data_fx, nblocks ); /*Q30*/ BREAK; case 5: matrix_product_q30_fx( dct5_fx, nbands, nbands, 1, q_dct_data_fx, nbands, 1, 0, dct_data_tmp_fx ); - Copy32( dct_data_tmp_fx, q_dct_data_fx, nbands ); /*Q30*/ + mvl2l( dct_data_tmp_fx, q_dct_data_fx, nbands ); /*Q30*/ BREAK; case 8: matrix_product_q30_fx( dct8_fx, nbands, nbands, 1, q_dct_data_fx, nbands, 1, 0, dct_data_tmp_fx ); - Copy32( dct_data_tmp_fx, q_dct_data_fx, nbands ); /*Q30*/ + mvl2l( dct_data_tmp_fx, q_dct_data_fx, nbands ); /*Q30*/ BREAK; case 12: matrix_product_q30_fx( dct12_fx, nbands, nbands, 1, q_dct_data_fx, nbands, 1, 0, dct_data_tmp_fx ); - Copy32( dct_data_tmp_fx, q_dct_data_fx, nbands ); /*Q30*/ + mvl2l( dct_data_tmp_fx, q_dct_data_fx, nbands ); /*Q30*/ BREAK; case 20: matrix_product_fx( dct5_fx, nbands, nbands, 1, q_dct_data_fx, nbands, nblocks, 0, dct_data_tmp_fx ); @@ -4444,40 +4453,48 @@ void ivas_omasa_decode_masa_to_total( printf( "Incorrect number of coefficients for OMASA.\n" ); BREAK; } + + /* this is to make sure the comparison to the threshold 0.98 will go the same way in fixed point and floating + point without having to drag the fixed point values to the comparison place in the code; 1052266987 is 0.98 in Q30 + it is not needed in the fixed point*/ + for ( i = 0; i < nblocks * nbands; i++ ) + { + if ( q_dct_data_fx[i] >= 1052266987 && q_dct_data_fx[i] < 1052400000 ) + { + q_dct_data_fx[i] = 1052400000; + } + } + k = 0; - move16(); - FOR( i = 0; i < nblocks; i++ ) + for ( i = 0; i < nblocks; i++ ) { - FOR( j = 0; j < nbands; j++ ) + for ( j = 0; j < nbands; j++ ) { - masa_to_total_energy_ratio_fx[i][j] = L_max( 0, q_dct_data_fx[k] ); // Q30 - move32(); - masa_to_total_energy_ratio_fx[i][j] = L_min( ONE_IN_Q30, masa_to_total_energy_ratio_fx[i][j] ); /*Q30*/ - move32(); - k = add( k, 1 ); + masa_to_total_energy_ratio[i][j] = q_dct_data_fx[k] / (float) ( 1 << 30 ); + masa_to_total_energy_ratio[i][j] = max( 0.0f, masa_to_total_energy_ratio[i][j] ); + masa_to_total_energy_ratio[i][j] = min( 1.0f, masa_to_total_energy_ratio[i][j] ); + k++; } } - IF( EQ_16( nblocks, 1 ) ) + if ( nblocks == 1 ) { - FOR( i = 1; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + for ( i = 1; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { - FOR( j = 0; j < nbands; j++ ) + for ( j = 0; j < nbands; j++ ) { - masa_to_total_energy_ratio_fx[i][j] = masa_to_total_energy_ratio_fx[0][j]; /*Q30*/ - move32(); + masa_to_total_energy_ratio[i][j] = masa_to_total_energy_ratio[0][j]; } } } - IF( EQ_16( nbands, 1 ) ) + if ( nbands == 1 ) { - FOR( j = 1; j < 5; j++ ) + for ( j = 1; j < 5; j++ ) { - FOR( i = 0; i < nblocks; i++ ) + for ( i = 0; i < nblocks; i++ ) { - masa_to_total_energy_ratio_fx[i][j] = masa_to_total_energy_ratio_fx[i][0]; /*Q30*/ - move32(); + masa_to_total_energy_ratio[i][j] = masa_to_total_energy_ratio[i][0]; } } } @@ -4521,10 +4538,6 @@ void ivas_omasa_decode_masa_to_total( { masa_to_total_energy_ratio[i][j] = max( 0.0f, q_dct_data[k] ); masa_to_total_energy_ratio[i][j] = min( 1.0f, masa_to_total_energy_ratio[i][j] ); -#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL - int_tmp = (int32_t) ( MASA_SUR_COH_PRECISION * masa_to_total_energy_ratio[i][j] ); - masa_to_total_energy_ratio[i][j] = (float) ( int_tmp * MASA_SUR_COH_THRESHOLD ); -#endif k++; } } @@ -4536,10 +4549,6 @@ void ivas_omasa_decode_masa_to_total( for ( j = 0; j < nbands; j++ ) { masa_to_total_energy_ratio[i][j] = masa_to_total_energy_ratio[0][j]; -#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL - int_tmp = (int32_t) ( MASA_SUR_COH_PRECISION * masa_to_total_energy_ratio[i][j] ); - masa_to_total_energy_ratio[i][j] = (float) ( int_tmp * MASA_SUR_COH_THRESHOLD ); -#endif } } } diff --git a/lib_enc/ivas_qmetadata_enc.c b/lib_enc/ivas_qmetadata_enc.c index d178cbf62c..87162a945d 100644 --- a/lib_enc/ivas_qmetadata_enc.c +++ b/lib_enc/ivas_qmetadata_enc.c @@ -41,7 +41,9 @@ #include "ivas_stat_enc.h" #include "wmc_auto.h" #include "prot.h" - +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL +#include "basop_settings.h" +#endif /*-----------------------------------------------------------------------* * Local function prototypes @@ -6033,10 +6035,16 @@ void ivas_omasa_encode_masa_to_total( int16_t q_idx[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; float dct_data_tmp[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; float dct_data[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; + int16_t bits_pos, nb_bits; int16_t n_streams, len_stream; + #ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL - int32_t int_tmp; + Word32 q_dct_data_fx[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS], + dct_data_tmp_fx[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; + + int64_t step_fx; + step_fx = STEP_M2T_FX; #endif #ifdef DEBUG_MODE_QMETADATA static FILE *pF = NULL; @@ -6146,6 +6154,96 @@ void ivas_omasa_encode_masa_to_total( } /* reconstruct masa2total */ +#ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL + q_dct_data_fx[0] = (Word32) ( ( step_fx * q_idx[0] ) >> 6 ); // Q25 + for ( i = 1; i < len_stream; i++ ) + { + if ( ( q_idx[i] & 1 ) == 0 ) + { + q_dct_data_fx[i] = (Word32) ( ( step_fx * ( -q_idx[i] ) ) >> 7 ); // Q25 + } + ELSE + { + q_dct_data_fx[i] = (Word32) ( ( step_fx * ( q_idx[i] + 1 ) ) >> 7 ); // Q25 + } + } + SWITCH( len_stream ) + { + case 4: + matrix_product_q30_fx( dct4_fx, nblocks, nblocks, 1, q_dct_data_fx, nblocks, 1, 0, dct_data_tmp_fx ); + mvl2l( dct_data_tmp_fx, q_dct_data_fx, nblocks ); /*Q30*/ + BREAK; + case 5: + matrix_product_q30_fx( dct5_fx, nbands, nbands, 1, q_dct_data_fx, nbands, 1, 0, dct_data_tmp_fx ); + mvl2l( dct_data_tmp_fx, q_dct_data_fx, nbands ); /*Q30*/ + BREAK; + case 8: + matrix_product_q30_fx( dct8_fx, nbands, nbands, 1, q_dct_data_fx, nbands, 1, 0, dct_data_tmp_fx ); + mvl2l( dct_data_tmp_fx, q_dct_data_fx, nbands ); /*Q30*/ + BREAK; + case 12: + matrix_product_q30_fx( dct12_fx, nbands, nbands, 1, q_dct_data_fx, nbands, 1, 0, dct_data_tmp_fx ); + mvl2l( dct_data_tmp_fx, q_dct_data_fx, nbands ); /*Q30*/ + BREAK; + case 20: + matrix_product_fx( dct5_fx, nbands, nbands, 1, q_dct_data_fx, nbands, nblocks, 0, dct_data_tmp_fx ); + matrix_product_q30_fx( dct_data_tmp_fx, nbands, nblocks, 0, dct4_fx, nblocks, nblocks, 0, q_dct_data_fx ); /* reuse of variable*/ + BREAK; + case 32: + matrix_product_fx( dct8_fx, nbands, nbands, 1, q_dct_data_fx, nbands, nblocks, 0, dct_data_tmp_fx ); + matrix_product_q30_fx( dct_data_tmp_fx, nbands, nblocks, 0, dct4_fx, nblocks, nblocks, 0, q_dct_data_fx ); + BREAK; + default: + printf( "Incorrect number of coefficients for OMASA.\n" ); + BREAK; + } + + /* this is to make sure the comparison to the threshold 0.98 will go the same way in fixed point and floating + point without having to drag the fixed point values to the comparison place in the code; 1052266987 is 0.98 in Q30 + it is not needed in the fixed point*/ + for ( i = 0; i < nblocks * nbands; i++ ) + { + if ( q_dct_data_fx[i] >= 1052266987 && q_dct_data_fx[i] < 1052400000 ) + { + q_dct_data_fx[i] = 1052400000; + } + } + + k = 0; + for ( i = 0; i < nblocks; i++ ) + { + for ( j = 0; j < nbands; j++ ) + { + masa_to_total_energy_ratio[i][j] = q_dct_data_fx[k] / (float) ( 1 << 30 ); + masa_to_total_energy_ratio[i][j] = max( 0.0f, masa_to_total_energy_ratio[i][j] ); + masa_to_total_energy_ratio[i][j] = min( 1.0f, masa_to_total_energy_ratio[i][j] ); + k++; + } + } + + if ( nblocks == 1 ) + { + for ( i = 1; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + for ( j = 0; j < nbands; j++ ) + { + masa_to_total_energy_ratio[i][j] = masa_to_total_energy_ratio[0][j]; + } + } + } + + if ( nbands == 1 ) + { + for ( j = 1; j < 5; j++ ) + { + for ( i = 0; i < nblocks; i++ ) + { + masa_to_total_energy_ratio[i][j] = masa_to_total_energy_ratio[i][0]; + } + } + } + +#else q_dct_data[0] = q_idx[0] * step; for ( i = 1; i < len_stream; i++ ) { @@ -6205,6 +6303,7 @@ void ivas_omasa_encode_masa_to_total( k++; } } +#endif assert( nb_bits == ( hMetaData->nb_bits_tot - bits_pos ) ); #ifdef DEBUG_MODE_QMETADATA -- GitLab From cba90f9d7e9fe26f6801cb588823b8ff820bcae3 Mon Sep 17 00:00:00 2001 From: Adriana Vasilache Date: Fri, 7 Feb 2025 12:01:52 +0200 Subject: [PATCH 09/23] clang review --- lib_com/ivas_tools.c | 20 +++++++++----------- lib_enc/ivas_qmetadata_enc.c | 7 ++++--- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index 2b6835190c..053cd714e5 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -1380,7 +1380,7 @@ Word16 matrix_product_fx( x_idx = i + k * rowsX; /*Q0*/ y_idx = k + j * rowsY; /*Q0*/ ( *Zp_fx ) = ( *Zp_fx ) + Mpy_32_32( X_fx[x_idx], Y_fx[y_idx] ); /*Qx + Qy - 31 L_sat_add() */ - // TODO: overflow of Z_fx to be checked + /* TODO: overflow of Z_fx to be checked */ move32(); } Zp_fx++; @@ -1422,11 +1422,10 @@ Word16 matrix_product_q30_fx( { for ( i = 0; i < colsX; ++i ) { - //( *Zp_fx ) = 0; W_tmp = 0; for ( k = 0; k < rowsX; ++k ) { - //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[k + i * rowsX], Y_fx[k + j * rowsY] ) ); + /*( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[k + i * rowsX], Y_fx[k + j * rowsY] ) ); */ x_idx = k + i * rowsX; /* Q0 */ y_idx = k + j * rowsY; /* Q0 */ W_tmp += ( (long long int) X_fx[x_idx] * (long long int) Y_fx[y_idx] ); /* Q56 */ @@ -1447,12 +1446,12 @@ Word16 matrix_product_q30_fx( { for ( i = 0; i < rowsX; ++i ) { - //( *Zp_fx ) = 0; + W_tmp = 0; for ( k = 0; k < colsX; ++k ) { - //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[i + k * rowsX], Y_fx[j + k * rowsY] ) ); + /* ( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[i + k * rowsX], Y_fx[j + k * rowsY] ) ); */ x_idx = i + k * rowsX; /*Q0*/ y_idx = j + k * rowsY; /*Q0*/ W_tmp += ( (long long int) X_fx[x_idx] * (long long int) Y_fx[y_idx] ); /* Q56 */ @@ -1473,14 +1472,13 @@ Word16 matrix_product_q30_fx( { for ( i = 0; i < colsX; ++i ) { - //( *Zp_fx ) = 0; W_tmp = 0; for ( k = 0; k < colsX; ++k ) { - //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[k + i * rowsX], Y_fx[j + k * rowsY] ) ); + /* ( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[k + i * rowsX], Y_fx[j + k * rowsY] ) ); */ x_idx = k + i * rowsX; /*Q0*/ y_idx = j + k * rowsY; /*Q0*/ - W_tmp += ( (long long int) X_fx[x_idx] * (long long int) Y_fx[y_idx] ); // Q56 + W_tmp += ( (long long int) X_fx[x_idx] * (long long int) Y_fx[y_idx] ); /* Q56*/ } W_tmp = W_tmp << 6; /*Q62*/ ( *Zp_fx ) = ( W_tmp + 0x80000000 ) >> 32; /*Q30*/ @@ -1500,15 +1498,15 @@ Word16 matrix_product_q30_fx( { for ( i = 0; i < rowsX; ++i ) { - //( *Zp_fx ) = 0; W_tmp = 0; for ( k = 0; k < colsX; ++k ) { - //( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[i + k * rowsX], Y_fx[k + j * rowsY] ) ); + /* ( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[i + k * rowsX], Y_fx[k + j * rowsY] ) ); */ x_idx = i + k * rowsX; /*Q0*/ y_idx = k + j * rowsY; /*Q0*/ - W_tmp += ( (long long int) X_fx[x_idx] * (long long int) Y_fx[y_idx] ); // Q56 + W_tmp += ( (long long int) X_fx[x_idx] * (long long int) Y_fx[y_idx] ); /* Q56*/ + } W_tmp = W_tmp << 6; /*Q62*/ ( *Zp_fx ) = ( W_tmp + 0x80000000 ) >> 32; /*Q30*/ diff --git a/lib_enc/ivas_qmetadata_enc.c b/lib_enc/ivas_qmetadata_enc.c index 87162a945d..9d6cdf4350 100644 --- a/lib_enc/ivas_qmetadata_enc.c +++ b/lib_enc/ivas_qmetadata_enc.c @@ -6198,9 +6198,10 @@ void ivas_omasa_encode_masa_to_total( BREAK; } - /* this is to make sure the comparison to the threshold 0.98 will go the same way in fixed point and floating - point without having to drag the fixed point values to the comparison place in the code; 1052266987 is 0.98 in Q30 - it is not needed in the fixed point*/ + /* this is to make sure the comparison to the threshold 0.98 will go the same way in */ + /* fixed point and floating point without having to drag the fixed point values to the */ + /* comparison place in the code; */ + /* 1052266987 is 0.98 in Q30 it is not needed in the fixed point */ for ( i = 0; i < nblocks * nbands; i++ ) { if ( q_dct_data_fx[i] >= 1052266987 && q_dct_data_fx[i] < 1052400000 ) -- GitLab From 43bfd73a58d2386095bcc4684642cdf06da581a0 Mon Sep 17 00:00:00 2001 From: Adriana Vasilache Date: Fri, 7 Feb 2025 12:38:25 +0200 Subject: [PATCH 10/23] clang review --- lib_com/ivas_tools.c | 29 +++++++++++++---------------- lib_dec/ivas_qmetadata_dec.c | 15 ++++++++------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index 053cd714e5..16bdc4f000 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -1406,7 +1406,7 @@ Word16 matrix_product_q30_fx( Word16 i, j, k; Word16 x_idx, y_idx; Word32 *Zp_fx = Z_fx; - long long int W_tmp; + int64_t W_tmp; /* Processing */ test(); @@ -1426,9 +1426,9 @@ Word16 matrix_product_q30_fx( for ( k = 0; k < rowsX; ++k ) { /*( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[k + i * rowsX], Y_fx[k + j * rowsY] ) ); */ - x_idx = k + i * rowsX; /* Q0 */ - y_idx = k + j * rowsY; /* Q0 */ - W_tmp += ( (long long int) X_fx[x_idx] * (long long int) Y_fx[y_idx] ); /* Q56 */ + x_idx = k + i * rowsX; /* Q0 */ + y_idx = k + j * rowsY; /* Q0 */ + W_tmp += ( (int64_t) X_fx[x_idx] * (int64_t) Y_fx[y_idx] ); /* Q56 */ } W_tmp = W_tmp << 6; /* W_shl( W_tmp, 6 ); */ /*Q62*/ ( *Zp_fx ) = ( W_tmp + 0x80000000 ) >> 32; /* W_round64_L( W_tmp ); */ /*Q30*/ @@ -1446,15 +1446,13 @@ Word16 matrix_product_q30_fx( { for ( i = 0; i < rowsX; ++i ) { - W_tmp = 0; - for ( k = 0; k < colsX; ++k ) { /* ( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[i + k * rowsX], Y_fx[j + k * rowsY] ) ); */ - x_idx = i + k * rowsX; /*Q0*/ - y_idx = j + k * rowsY; /*Q0*/ - W_tmp += ( (long long int) X_fx[x_idx] * (long long int) Y_fx[y_idx] ); /* Q56 */ + x_idx = i + k * rowsX; /*Q0*/ + y_idx = j + k * rowsY; /*Q0*/ + W_tmp += ( (int64_t) X_fx[x_idx] * (int64_t) Y_fx[y_idx] ); /* Q56 */ } W_tmp = W_tmp << 6; /*Q62*/ ( *Zp_fx ) = ( W_tmp + 0x80000000 ) >> 32; /*Q30*/ @@ -1476,9 +1474,9 @@ Word16 matrix_product_q30_fx( for ( k = 0; k < colsX; ++k ) { /* ( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[k + i * rowsX], Y_fx[j + k * rowsY] ) ); */ - x_idx = k + i * rowsX; /*Q0*/ - y_idx = j + k * rowsY; /*Q0*/ - W_tmp += ( (long long int) X_fx[x_idx] * (long long int) Y_fx[y_idx] ); /* Q56*/ + x_idx = k + i * rowsX; /*Q0*/ + y_idx = j + k * rowsY; /*Q0*/ + W_tmp += ( (int64_t) X_fx[x_idx] * (int64_t) Y_fx[y_idx] ); /* Q56*/ } W_tmp = W_tmp << 6; /*Q62*/ ( *Zp_fx ) = ( W_tmp + 0x80000000 ) >> 32; /*Q30*/ @@ -1503,10 +1501,9 @@ Word16 matrix_product_q30_fx( for ( k = 0; k < colsX; ++k ) { /* ( *Zp_fx ) = L_add( *Zp_fx, Mpy_32_32( X_fx[i + k * rowsX], Y_fx[k + j * rowsY] ) ); */ - x_idx = i + k * rowsX; /*Q0*/ - y_idx = k + j * rowsY; /*Q0*/ - W_tmp += ( (long long int) X_fx[x_idx] * (long long int) Y_fx[y_idx] ); /* Q56*/ - + x_idx = i + k * rowsX; /*Q0*/ + y_idx = k + j * rowsY; /*Q0*/ + W_tmp += ( (int64_t) X_fx[x_idx] * (int64_t) Y_fx[y_idx] ); /* Q56*/ } W_tmp = W_tmp << 6; /*Q62*/ ( *Zp_fx ) = ( W_tmp + 0x80000000 ) >> 32; /*Q30*/ diff --git a/lib_dec/ivas_qmetadata_dec.c b/lib_dec/ivas_qmetadata_dec.c index 2462065d03..e66d03c965 100644 --- a/lib_dec/ivas_qmetadata_dec.c +++ b/lib_dec/ivas_qmetadata_dec.c @@ -4121,7 +4121,7 @@ static int16_t read_surround_coherence_hr( } else { - idx_ER[j] = 7; // masa_sq( error_ratio_surr, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS ); + idx_ER[j] = 7; /* masa_sq( error_ratio_surr, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS ); */ no_cv_vec[j] = idx_cb_sur_coh_masa[idx_ER[j]] + 2; } } @@ -4347,16 +4347,16 @@ static void read_stream_dct_coeffs_omasa( /* deindex */ #ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL - q_dct_data_fx[0] = (Word32) ( ( step_fx * q_idx[0] ) >> 6 ); // Q25 + q_dct_data_fx[0] = (Word32) ( ( step_fx * q_idx[0] ) >> 6 ); /* Q25 */ for ( i = 1; i < len_stream; i++ ) { if ( ( q_idx[i] & 1 ) == 0 ) { - q_dct_data_fx[i] = (Word32) ( ( step_fx * ( -q_idx[i] ) ) >> 7 ); // Q25 + q_dct_data_fx[i] = (Word32) ( ( step_fx * ( -q_idx[i] ) ) >> 7 ); /* Q25 */ } ELSE { - q_dct_data_fx[i] = (Word32) ( ( step_fx * ( q_idx[i] + 1 ) ) >> 7 ); // Q25 + q_dct_data_fx[i] = (Word32) ( ( step_fx * ( q_idx[i] + 1 ) ) >> 7 ); /* Q25 */ } } #else @@ -4454,9 +4454,10 @@ void ivas_omasa_decode_masa_to_total( BREAK; } - /* this is to make sure the comparison to the threshold 0.98 will go the same way in fixed point and floating - point without having to drag the fixed point values to the comparison place in the code; 1052266987 is 0.98 in Q30 - it is not needed in the fixed point*/ + /* this is to make sure the comparison to the threshold 0.98 will go the same way in */ + /* fixed point and floating point without having to drag the fixed point values to the */ + /* comparison place in the code; 1052266987 is 0.98 in Q30 it is not needed in the fixed point*/ + for ( i = 0; i < nblocks * nbands; i++ ) { if ( q_dct_data_fx[i] >= 1052266987 && q_dct_data_fx[i] < 1052400000 ) -- GitLab From 23c46267b5c8d72efbca787bce4c6d107105d133 Mon Sep 17 00:00:00 2001 From: Adriana Vasilache Date: Fri, 7 Feb 2025 14:26:26 +0200 Subject: [PATCH 11/23] clang review --- lib_com/ivas_tools.c | 2 +- lib_dec/ivas_qmetadata_dec.c | 7 ++++--- lib_enc/ivas_qmetadata_enc.c | 1 + 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index 16bdc4f000..29915d341d 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -1515,4 +1515,4 @@ Word16 matrix_product_q30_fx( return EXIT_SUCCESS; } -#endif \ No newline at end of file +#endif diff --git a/lib_dec/ivas_qmetadata_dec.c b/lib_dec/ivas_qmetadata_dec.c index e66d03c965..349cf13a45 100644 --- a/lib_dec/ivas_qmetadata_dec.c +++ b/lib_dec/ivas_qmetadata_dec.c @@ -4273,15 +4273,16 @@ static void read_stream_dct_coeffs_omasa( { int16_t sign; int16_t i, j, i_min; - +#ifndef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL float step; - +#endif int16_t GR1, GR2; #ifdef NONBE_1231_BASOP_819_THRESHOLD_MASA2TOTAL int64_t step_fx; step_fx = STEP_M2T_FX; -#endif +#else step = STEP_M2T; +#endif sign = 1; if ( first_line == 0 ) { diff --git a/lib_enc/ivas_qmetadata_enc.c b/lib_enc/ivas_qmetadata_enc.c index 9d6cdf4350..550f1fb697 100644 --- a/lib_enc/ivas_qmetadata_enc.c +++ b/lib_enc/ivas_qmetadata_enc.c @@ -6032,6 +6032,7 @@ void ivas_omasa_encode_masa_to_total( float data[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; float q_dct_data[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; float step = STEP_M2T; + int16_t q_idx[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; float dct_data_tmp[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; float dct_data[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; -- GitLab From 45afd0eb6ca5ba5214c19771c67673323142a60a Mon Sep 17 00:00:00 2001 From: Adriana Vasilache Date: Mon, 10 Feb 2025 21:26:03 +0200 Subject: [PATCH 12/23] fix usan --- lib_com/ivas_tools.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index 29915d341d..a38c105028 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -1430,7 +1430,7 @@ Word16 matrix_product_q30_fx( y_idx = k + j * rowsY; /* Q0 */ W_tmp += ( (int64_t) X_fx[x_idx] * (int64_t) Y_fx[y_idx] ); /* Q56 */ } - W_tmp = W_tmp << 6; /* W_shl( W_tmp, 6 ); */ /*Q62*/ + W_tmp = W_tmp * 64; /* W_shl( W_tmp, 6 ); */ /*Q62*/ ( *Zp_fx ) = ( W_tmp + 0x80000000 ) >> 32; /* W_round64_L( W_tmp ); */ /*Q30*/ Zp_fx++; } @@ -1454,7 +1454,7 @@ Word16 matrix_product_q30_fx( y_idx = j + k * rowsY; /*Q0*/ W_tmp += ( (int64_t) X_fx[x_idx] * (int64_t) Y_fx[y_idx] ); /* Q56 */ } - W_tmp = W_tmp << 6; /*Q62*/ + W_tmp = W_tmp * 64; /*Q62*/ ( *Zp_fx ) = ( W_tmp + 0x80000000 ) >> 32; /*Q30*/ Zp_fx++; } @@ -1478,7 +1478,7 @@ Word16 matrix_product_q30_fx( y_idx = j + k * rowsY; /*Q0*/ W_tmp += ( (int64_t) X_fx[x_idx] * (int64_t) Y_fx[y_idx] ); /* Q56*/ } - W_tmp = W_tmp << 6; /*Q62*/ + W_tmp = W_tmp * 64; /*Q62*/ ( *Zp_fx ) = ( W_tmp + 0x80000000 ) >> 32; /*Q30*/ Zp_fx++; @@ -1505,7 +1505,7 @@ Word16 matrix_product_q30_fx( y_idx = k + j * rowsY; /*Q0*/ W_tmp += ( (int64_t) X_fx[x_idx] * (int64_t) Y_fx[y_idx] ); /* Q56*/ } - W_tmp = W_tmp << 6; /*Q62*/ + W_tmp = W_tmp * 64; /*Q62*/ ( *Zp_fx ) = ( W_tmp + 0x80000000 ) >> 32; /*Q30*/ Zp_fx++; -- GitLab From a8b2d2c73bc70c681ac56dc603407c8f3acb6b8b Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Tue, 11 Feb 2025 10:48:01 +0100 Subject: [PATCH 13/23] rename script for parsing batch complexity run logs --- scripts/parse_complexity_run_logs.py | 97 ++++++++++++++++++++++++++++ scripts/run_diff.py | 66 ------------------- 2 files changed, 97 insertions(+), 66 deletions(-) create mode 100644 scripts/parse_complexity_run_logs.py delete mode 100644 scripts/run_diff.py diff --git a/scripts/parse_complexity_run_logs.py b/scripts/parse_complexity_run_logs.py new file mode 100644 index 0000000000..f10dd2a7c8 --- /dev/null +++ b/scripts/parse_complexity_run_logs.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python3 +""" +(C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, +Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +contributors to this repository. All Rights Reserved. + +This software is protected by copyright law and by international treaties. +The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, +Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +contributors to this repository retain full ownership rights in their respective contributions in +the software. This notice grants no license of any kind, including but not limited to patent +license, nor is any license granted by implication, estoppel or otherwise. + +Contributors are required to enter into the IVAS codec Public Collaboration agreement before making +contributions. + +This software is provided "AS IS", without any express or implied warranties. The software is in the +development stage. It is intended exclusively for experts who have experience with such software and +solely for the purpose of inspection. All implied warranties of non-infringement, merchantability +and fitness for a particular purpose are hereby disclaimed and excluded. + +Any dispute, controversy or claim arising under or in relation to providing this software shall be +submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in +accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and +the United Nations Convention on Contracts on the International Sales of Goods. +""" + +# place this script along with diff_complexity.py in the root folder of the logs +from diff_complexity import ( + log2df, + diff_wmops, + diff_mem, +) +from pathlib import Path +import pandas as pd +from tqdm import tqdm +import numpy as np + +REF_LOGDIR = Path("float_detail_run_21_1_2025/output/logs") +CUT_LOGDIR = Path("basop_detail_run_21_1_2025/output/logs") + +ref_logfiles = sorted( + f + for f in REF_LOGDIR.glob("*.txt") + if not f.name.endswith("pcm.txt") and "dec" in f.stem + # and "ltv48_STEREO" in f.stem +) +cut_logfiles = sorted( + f + for f in CUT_LOGDIR.glob("*.txt") + if not f.name.endswith("pcm.txt") and "dec" in f.stem + # and "ltv48_STEREO" in f.stem +) + +unique = set(f.name for f in ref_logfiles).difference(f.name for f in cut_logfiles) +if unique: + raise FileNotFoundError( + f"One or more files were not found in either directory {unique}" + ) + +records = [] +crashes = [] +for ref, cut in tqdm(zip(ref_logfiles, cut_logfiles), total=len(ref_logfiles)): + # parse logfiles + try: + ref_wmops, ref_mem = log2df(ref) + except ValueError: + crashes.append(str(ref)) + continue + try: + cut_wmops, cut_mem = log2df(cut) + except ValueError: + crashes.append(str(cut)) + continue + + # get the diff for wmops and memory + wmops = diff_wmops(ref_wmops, cut_wmops) + mem = diff_mem(ref_mem, cut_mem) + + # only extract the difference column + diff = pd.DataFrame(pd.concat([wmops, mem])["CUT - BSL"]).T + diff.rename({"CUT - BSL": "Values"}, inplace=True, axis=1) + + diff.insert(0, "Name", ref.stem) + records.append(diff) + +df = pd.DataFrame(np.squeeze(records), columns=diff.columns) +df.set_index("Name", inplace=True) +df.sort_values("WMOPs max", inplace=True, ascending=False) +df.to_csv("all_diff.csv", float_format="%.3f") + +with open("crashes.log", "w") as f: + [print(c, file=f) for c in crashes] diff --git a/scripts/run_diff.py b/scripts/run_diff.py deleted file mode 100644 index 06a7714363..0000000000 --- a/scripts/run_diff.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python3 -from diff_complexity import ( - log2df, - diff_wmops, - diff_mem, -) -from pathlib import Path -import pandas as pd -from tqdm import tqdm -import numpy as np - -REF_LOGDIR = Path("float_detail_run_21_1_2025/output/logs") -CUT_LOGDIR = Path("basop_detail_run_21_1_2025/output/logs") - -ref_logfiles = sorted( - f - for f in REF_LOGDIR.glob("*.txt") - if not f.name.endswith("pcm.txt") and "dec" in f.stem - # and "ltv48_STEREO" in f.stem -) -cut_logfiles = sorted( - f - for f in CUT_LOGDIR.glob("*.txt") - if not f.name.endswith("pcm.txt") and "dec" in f.stem - # and "ltv48_STEREO" in f.stem -) - -unique = set(f.name for f in ref_logfiles).difference(f.name for f in cut_logfiles) -if unique: - raise FileNotFoundError( - f"One or more files were not found in either directory {unique}" - ) - -records = [] -crashes = [] -for ref, cut in tqdm(zip(ref_logfiles, cut_logfiles), total=len(ref_logfiles)): - # parse logfiles - try: - ref_wmops, ref_mem = log2df(ref) - except ValueError: - crashes.append(str(ref)) - continue - try: - cut_wmops, cut_mem = log2df(cut) - except ValueError: - crashes.append(str(cut)) - continue - - # get the diff for wmops and memory - wmops = diff_wmops(ref_wmops, cut_wmops) - mem = diff_mem(ref_mem, cut_mem) - - # only extract the difference column - diff = pd.DataFrame(pd.concat([wmops, mem])["CUT - BSL"]).T - diff.rename({"CUT - BSL": "Values"}, inplace=True, axis=1) - - diff.insert(0, "Name", ref.stem) - records.append(diff) - -df = pd.DataFrame(np.squeeze(records), columns=diff.columns) -df.set_index("Name", inplace=True) -df.sort_values("WMOPs max", inplace=True, ascending=False) -df.to_csv("all_diff.csv", float_format="%.3f") - -with open("crashes.log", "w") as f: - [print(c, file=f) for c in crashes] -- GitLab From 62754613bb56d71b6da58023c0a7b188b0d5cd7e Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Thu, 13 Feb 2025 10:21:48 +0100 Subject: [PATCH 14/23] check for complexity artifact folder not being empty this handles failures in previous job runs which still lead to archiving the empty directory --- .gitlab-ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 30e0f22dc5..2a5cbb88b6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2409,7 +2409,9 @@ coverage-test-on-main-scheduled: - public_dir="$CI_JOB_NAME-public" # if is needed to catch case when no artifact is there (first run), similarly as above - - if [[ -d $public_dir ]]; then + # 1. check for public_dir being there as this might not be the case when artifact download failed + # 2. check for public dir not being empty - handle job failures in prev job that happen after the dir is created. In that case, the empty dir is in the artifacts + - if [ -d $public_dir ] && [ ! -z "$( ls -A $public_dir )" ]; then - mv $public_dir/* wmops/ # check here if we have the split-by-levels files present - if not, fake them up with the existing global one # this is needed for the first run with split graphs on a branch where the global version did run previously -- GitLab From 05091bc5e572bb6b93e51b11a3cff8a9146f1f38 Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 13 Feb 2025 10:35:22 +0100 Subject: [PATCH 15/23] issue 1279: Avoid possible overflow of counter st->Nb_ACELP_frames; under NONBE_1279_COUNTER_OVERFLOW --- lib_com/options.h | 2 +- lib_enc/acelp_core_enc.c | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 7e2678dda5..0f1889ab8a 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -170,7 +170,7 @@ #define NONBE_FIX_GSC_BSTR /* VA: issue 1264: Fix bitstream synchronization between encoder and decoder in ACELP GSC in OMASA */ #define NONBE_1273_ISM_METADATA_COUNTER /* VA: issue 1273: fix counter overflow in ISM metadata encoder */ - +#define NONBE_1279_COUNTER_OVERFLOW /* VA: issue 1279: Avoid possible overflow of counter st->Nb_ACELP_frames */ /* ##################### End NON-BE switches ########################### */ diff --git a/lib_enc/acelp_core_enc.c b/lib_enc/acelp_core_enc.c index b12783d1c8..45d633cfc9 100644 --- a/lib_enc/acelp_core_enc.c +++ b/lib_enc/acelp_core_enc.c @@ -167,7 +167,14 @@ ivas_error acelp_core_enc( { st->Nb_ACELP_frames = 0; } +#ifdef NONBE_1279_COUNTER_OVERFLOW + if ( st->Nb_ACELP_frames < MAX16B ) + { + st->Nb_ACELP_frames++; + } +#else st->Nb_ACELP_frames++; +#endif if ( st->L_frame == L_FRAME ) { -- GitLab From 57b442467ed159ee86637f609458eff19ac14d7f Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 13 Feb 2025 13:43:46 +0100 Subject: [PATCH 16/23] issue 1277: Fix Mismatch in DTX high-rate threshold between EVS float and BASOP; under NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD --- lib_com/options.h | 1 + lib_enc/dtx.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/lib_com/options.h b/lib_com/options.h index 7e2678dda5..ef3411efeb 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -170,6 +170,7 @@ #define NONBE_FIX_GSC_BSTR /* VA: issue 1264: Fix bitstream synchronization between encoder and decoder in ACELP GSC in OMASA */ #define NONBE_1273_ISM_METADATA_COUNTER /* VA: issue 1273: fix counter overflow in ISM metadata encoder */ +#define NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD /* VA/Eri: issue 1277: Fix Mismatch in DTX high-rate threshold between EVS float and BASOP */ /* ##################### End NON-BE switches ########################### */ diff --git a/lib_enc/dtx.c b/lib_enc/dtx.c index 37ba226601..4efa8e1f63 100644 --- a/lib_enc/dtx.c +++ b/lib_enc/dtx.c @@ -65,6 +65,13 @@ #define MAX_BRATE_DTX_EVS ACELP_24k40 /* maximum bitrate to which the default DTX is applied in EVS; otherwise DTX is applied only in silence */ #define MAX_BRATE_DTX_IVAS IVAS_80k /* maximum bitrate to which the default DTX is applied in IVAS; otherwise DTX is applied only in silence */ + +#ifdef NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD +#define DTX_THR_EVS 15 /* lp_noise threshold for DTX at higher bitrates in EVS */ // ToDo: to be removed once EVS is CR fixed +#define DTX_THR 5 /* lp_noise threshold for DTX at higher bitrates */ +#endif + + /*-------------------------------------------------------------------* * Local function prototypes *-------------------------------------------------------------------*/ @@ -89,6 +96,15 @@ void dtx( DTX_ENC_HANDLE hDtxEnc = st->hDtxEnc; int16_t last_br_cng_flag, last_br_flag, br_dtx_flag; int32_t total_brate_ref; +#ifdef NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD + int16_t dtx_thr; + + dtx_thr = DTX_THR; + if ( st->element_mode == EVS_MONO ) + { + dtx_thr = DTX_THR_EVS; // ToDo: to be removed once EVS is CR fixed + } +#endif total_brate_ref = st->total_brate; @@ -99,10 +115,18 @@ void dtx( } else { +#ifdef NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD + last_br_cng_flag = st->last_total_brate_cng <= MAX_BRATE_DTX_EVS || st->lp_noise < dtx_thr || ( st->element_mode == IVAS_SCE && st->last_total_brate_cng <= MAX_BRATE_DTX_IVAS ); +#else last_br_cng_flag = st->last_total_brate_cng <= MAX_BRATE_DTX_EVS || st->lp_noise < 15 || ( st->element_mode == IVAS_SCE && st->last_total_brate_cng <= MAX_BRATE_DTX_IVAS ); +#endif last_br_flag = ( st->element_mode == EVS_MONO && st->last_total_brate <= MAX_BRATE_DTX_EVS ) || ( st->element_mode != EVS_MONO && last_ivas_total_brate <= MAX_BRATE_DTX_IVAS ) || +#ifdef NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD + st->lp_noise < dtx_thr; +#else st->lp_noise < 15; +#endif } /* Initialization */ @@ -181,7 +205,11 @@ void dtx( { br_dtx_flag = ( st->element_mode == EVS_MONO && st->total_brate <= MAX_BRATE_DTX_EVS ) || ( st->element_mode != EVS_MONO && ivas_total_brate <= MAX_BRATE_DTX_IVAS ) || +#ifdef NONBE_FIX_1277_EVS_DTX_HIGH_RATE_THRESHOLD + st->lp_noise < dtx_thr; +#else st->lp_noise < 15; +#endif } if ( st->Opt_DTX_ON && vad == 0 && -- GitLab From 3d29b863ded5960baac7170a1104bde4f2cb2320 Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 13 Feb 2025 17:44:16 +0100 Subject: [PATCH 17/23] one more try --- ci/run-first-frame-is-sid-test.sh | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ci/run-first-frame-is-sid-test.sh b/ci/run-first-frame-is-sid-test.sh index 6c9d0d3038..26f9703374 100755 --- a/ci/run-first-frame-is-sid-test.sh +++ b/ci/run-first-frame-is-sid-test.sh @@ -6,9 +6,10 @@ make -j IVAS_cod mv IVAS_cod IVAS_cod_nosan # run all modes and cut bitstream to start with an SID. Use mono output to limit runtime, test is only about decoding the first frame -modes_no_sba=$(scripts/runIvasCodec.py -l | grep dtx | grep -vE "FOA|HOA" ) +modes_no_sba=$(scripts/runIvasCodec.py -l | grep dtx | grep -vE "stereo|FOA|HOA" ) modes_hoa=$(scripts/runIvasCodec.py -l | grep dtx | grep -E "HOA") modes_foa=$(scripts/runIvasCodec.py -l | grep dtx | grep "FOA") +modes_stereo=$(scripts/runIvasCodec.py -l | grep dtx | grep "stereo") # config vars testcase_timeout=20 @@ -26,11 +27,13 @@ cp IVAS_cod_nosan CLANG1/IVAS_cod exit_code_msan=0 echo "-------------- 1. Encoder + Msan decoder -------------- " echo "-------------- 1.1 all DTX modes except SBA -------------- " -scripts/IvasBuildAndRunChecks.py --checks CLANG1 -m $modes_no_sba -U 80:100 $common_args || exit_code_msan=$? +scripts/IvasBuildAndRunChecks.py --checks CLANG1 -m $modes_no_sba -U 0:20 $common_args || exit_code_msan=$? echo "-------------- 1.2 HOA2 + HOA3 DTX modes -------------- " scripts/IvasBuildAndRunChecks.py --checks CLANG1 -m $modes_hoa -U 70:80 $common_args || exit_code_msan=$? echo "-------------- 1.3 FOA DTX modes -------------- " scripts/IvasBuildAndRunChecks.py --checks CLANG1 -m $modes_foa -U 75:110 $common_args || exit_code_msan=$? +echo "-------------- 1.4 stereo DTX modes -------------- " +scripts/IvasBuildAndRunChecks.py --checks CLANG1 -m $modes_stereo -U 40:60 $common_args || exit_code_msan=$? # archive encoder logs separately mkdir logs_enc logs_dec_msan mv CLANG1/logs/*.enc.txt logs_enc/ @@ -45,11 +48,13 @@ cp -r CLANG1/enc CLANG3/enc exit_code_asan_usan=0 echo "-------------- 2. Asan + Usan decoder -------------- " echo "-------------- 2.1 all DTX modes except SBA -------------- " -scripts/IvasBuildAndRunChecks.py --checks CLANG2 CLANG3 --decoder_only -m $modes_no_sba -U 80:100 $common_args || exit_code_asan_usan=$? +scripts/IvasBuildAndRunChecks.py --checks CLANG2 CLANG3 --decoder_only -m $modes_no_sba -U 0:20 $common_args || exit_code_asan_usan=$? echo "-------------- 2.2 HOA2 + HOA3 DTX modes -------------- " scripts/IvasBuildAndRunChecks.py --checks CLANG2 CLANG3 --decoder_only -m $modes_hoa -U 70:80 $common_args || exit_code_asan_usan=$? echo "-------------- 2.3 FOA DTX modes -------------- " scripts/IvasBuildAndRunChecks.py --checks CLANG2 CLANG3 --decoder_only -m $modes_foa -U 75:110 $common_args || exit_code_asan_usan=$? +echo "-------------- 2.4 stereo DTX modes -------------- " +scripts/IvasBuildAndRunChecks.py --checks CLANG2 CLANG3 --decoder_only -m $modes_stereo -U 40:60 $common_args || exit_code_asan_usan=$? mv CLANG2/logs logs_dec_asan mv CLANG3/logs logs_dec_usan -- GitLab From 8792fa88809576555a7a3a419d62c7ba1ceb564c Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 13 Feb 2025 17:51:17 +0100 Subject: [PATCH 18/23] update comment --- ci/run-first-frame-is-sid-test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/run-first-frame-is-sid-test.sh b/ci/run-first-frame-is-sid-test.sh index 26f9703374..a6e81f9352 100755 --- a/ci/run-first-frame-is-sid-test.sh +++ b/ci/run-first-frame-is-sid-test.sh @@ -26,7 +26,7 @@ cp IVAS_cod_nosan CLANG1/IVAS_cod exit_code_msan=0 echo "-------------- 1. Encoder + Msan decoder -------------- " -echo "-------------- 1.1 all DTX modes except SBA -------------- " +echo "-------------- 1.1 all DTX modes except SBA and stereo -------------- " scripts/IvasBuildAndRunChecks.py --checks CLANG1 -m $modes_no_sba -U 0:20 $common_args || exit_code_msan=$? echo "-------------- 1.2 HOA2 + HOA3 DTX modes -------------- " scripts/IvasBuildAndRunChecks.py --checks CLANG1 -m $modes_hoa -U 70:80 $common_args || exit_code_msan=$? @@ -47,7 +47,7 @@ cp -r CLANG1/enc CLANG3/enc exit_code_asan_usan=0 echo "-------------- 2. Asan + Usan decoder -------------- " -echo "-------------- 2.1 all DTX modes except SBA -------------- " +echo "-------------- 2.1 all DTX modes except SBA and stereo -------------- " scripts/IvasBuildAndRunChecks.py --checks CLANG2 CLANG3 --decoder_only -m $modes_no_sba -U 0:20 $common_args || exit_code_asan_usan=$? echo "-------------- 2.2 HOA2 + HOA3 DTX modes -------------- " scripts/IvasBuildAndRunChecks.py --checks CLANG2 CLANG3 --decoder_only -m $modes_hoa -U 70:80 $common_args || exit_code_asan_usan=$? -- GitLab From 4acaa6ec66500c7245336a0d8b043b8c459e9ef8 Mon Sep 17 00:00:00 2001 From: vaclav Date: Fri, 14 Feb 2025 10:41:33 +0100 Subject: [PATCH 19/23] revert debugging modifications --- lib_com/bitstream.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/bitstream.c b/lib_com/bitstream.c index 63fe8ec37f..1331d60b26 100644 --- a/lib_com/bitstream.c +++ b/lib_com/bitstream.c @@ -1714,7 +1714,7 @@ ivas_error write_indices_ivas( { int16_t i, n; uint16_t *pt_stream; -#ifndef ENABLE_BITRATE_VERIFICATION +#ifdef ENABLE_BITRATE_VERIFICATION Encoder_State **sts; int32_t ivas_total_brate; int16_t ch; @@ -1729,7 +1729,7 @@ ivas_error write_indices_ivas( bit_stream[i] = 0; } -#ifndef ENABLE_BITRATE_VERIFICATION +#ifdef ENABLE_BITRATE_VERIFICATION i = 0; for ( n = 0; n < st_ivas->nSCE; n++ ) -- GitLab From 9b3bcb31abc7623cb8f9a2846642ff365ecd83f0 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Fri, 14 Feb 2025 17:21:33 +0100 Subject: [PATCH 20/23] add "RS" to table names of MASA and ISM3 rate switching conditions this might fix the missing/unchanged complexity values in the graphs for these modes --- scripts/config/ivas_modes.json | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/scripts/config/ivas_modes.json b/scripts/config/ivas_modes.json index 05e49d687d..236802a126 100644 --- a/scripts/config/ivas_modes.json +++ b/scripts/config/ivas_modes.json @@ -1946,7 +1946,7 @@ "EXT": [] }, "in_config": "MASA2TC", - "table_name": "MASA 2TC @{table_bitrate} kbps {bandwidth}", + "table_name": "MASA 2TC @{table_bitrate} kbps RS {bandwidth}", "nummetadata": 1, "metadatafilenames": [ "{item}.met" @@ -1954,9 +1954,6 @@ "rs": true, "amr": false, "mono": false, - "rs": true, - "amr": false, - "mono": false, "bitrates": { "wb": { "all": "{sw_files_path}/sw_13k2_512k.bin" @@ -3310,7 +3307,7 @@ "EXT": [] }, "in_config": "ISM3", - "table_name": "ISM3@{table_bitrate} kbps {bandwidth}", + "table_name": "ISM3@{table_bitrate} kbps RS {bandwidth}", "nummetadata": 3, "metadatafilenames": [ "stvISM{mdi}.csv" -- GitLab From a0298544441ee797be92c59d15dad3e834c1bece Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Tue, 18 Feb 2025 08:18:53 +0100 Subject: [PATCH 21/23] create parallel lc3plus unittest folders for basop and float --- .../{lc3plus => lc3plus_basop}/.gitignore | 0 .../lc3plus_basop/ivas_lc3plus_unit_test.c | 875 ++++++++++++++++++ .../ivas_lc3plus_unit_test_payload_format.c | 451 +++++++++ .../split_rend_lc3plus_cmdlines.py | 191 ++++ .../split_rendering/lc3plus_float/.gitignore | 1 + .../ivas_lc3plus_unit_test.c | 0 .../ivas_lc3plus_unit_test_payload_format.c | 0 7 files changed, 1518 insertions(+) rename scripts/split_rendering/{lc3plus => lc3plus_basop}/.gitignore (100%) create mode 100644 scripts/split_rendering/lc3plus_basop/ivas_lc3plus_unit_test.c create mode 100644 scripts/split_rendering/lc3plus_basop/ivas_lc3plus_unit_test_payload_format.c create mode 100644 scripts/split_rendering/lc3plus_basop/split_rend_lc3plus_cmdlines.py create mode 100644 scripts/split_rendering/lc3plus_float/.gitignore rename scripts/split_rendering/{lc3plus => lc3plus_float}/ivas_lc3plus_unit_test.c (100%) rename scripts/split_rendering/{lc3plus => lc3plus_float}/ivas_lc3plus_unit_test_payload_format.c (100%) diff --git a/scripts/split_rendering/lc3plus/.gitignore b/scripts/split_rendering/lc3plus_basop/.gitignore similarity index 100% rename from scripts/split_rendering/lc3plus/.gitignore rename to scripts/split_rendering/lc3plus_basop/.gitignore diff --git a/scripts/split_rendering/lc3plus_basop/ivas_lc3plus_unit_test.c b/scripts/split_rendering/lc3plus_basop/ivas_lc3plus_unit_test.c new file mode 100644 index 0000000000..d4617c13c2 --- /dev/null +++ b/scripts/split_rendering/lc3plus_basop/ivas_lc3plus_unit_test.c @@ -0,0 +1,875 @@ +/****************************************************************************************************** + +(C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, +Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +contributors to this repository. All Rights Reserved. + +This software is protected by copyright law and by international treaties. +The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, +Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +contributors to this repository retain full ownership rights in their respective contributions in +the software. This notice grants no license of any kind, including but not limited to patent +license, nor is any license granted by implication, estoppel or otherwise. + +Contributors are required to enter into the IVAS codec Public Collaboration agreement before making +contributions. + +This software is provided "AS IS", without any express or implied warranties. The software is in the +development stage. It is intended exclusively for experts who have experience with such software and +solely for the purpose of inspection. All implied warranties of non-infringement, merchantability +and fitness for a particular purpose are hereby disclaimed and excluded. + +Any dispute, controversy or claim arising under or in relation to providing this software shall be +submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in +accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and +the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include +#include +#include "options.h" +#include "isar_lc3plus_enc.h" +#include "isar_lc3plus_common.h" +#include "isar_lc3plus_dec.h" +#include "ivas_error_utils.h" +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +#include "lc3.h" +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +#define MAX_SAMPLES_PER_CHANNEL 960 / 4 +#else +#define MAX_SAMPLES_PER_CHANNEL 960 +#endif +#define DEFAULT_BPS 256000 + +#ifndef PCM_SAMPLE_TYPEDEF_DEFINED +#define PCM_SAMPLE_TYPEDEF_DEFINED +typedef int32_t PcmSample; +#endif + +static int encodeAndDecodeOneStereoFrame( LC3PLUS_CONFIG config, uint32_t bps ) +{ + ivas_error err; + int32_t encDelay = -1; + int32_t decDelay = -1; + + ISAR_LC3PLUS_ENC_HANDLE encHandle; + err = ISAR_LC3PLUS_ENC_Open( config, bps, &encHandle ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + err = ISAR_LC3PLUS_ENC_GetDelay( encHandle, &encDelay ); + if ( IVAS_ERR_OK != err ) + { + ISAR_LC3PLUS_ENC_Close( &encHandle ); + return err; + } + if ( encDelay == -1 || encDelay == 0 ) + { + ISAR_LC3PLUS_ENC_Close( &encHandle ); + return IVAS_ERROR( IVAS_ERR_INTERNAL, "encDelay is zero or uninitialized\n" ); + } + + /* encode one frame */ + int16_t numSamplesPerChannels = config.samplerate / ( 1000000 / config.isar_frame_duration_us ); + PcmSample *pcm_in[2]; + PcmSample pcm_in_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( PcmSample )]; + memset( pcm_in_ch1, 0, numSamplesPerChannels * sizeof( PcmSample ) ); + PcmSample pcm_in_ch2[MAX_SAMPLES_PER_CHANNEL * sizeof( PcmSample )]; + memset( pcm_in_ch2, 0, numSamplesPerChannels * sizeof( PcmSample ) ); + pcm_in[0] = pcm_in_ch1; + pcm_in[1] = pcm_in_ch2; + + int32_t bitstreamSizePerIvasFrame = 0; + err = ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame ); + if ( IVAS_ERR_OK != err ) + { + ISAR_LC3PLUS_ENC_Close( &encHandle ); + return err; + } + uint8_t *bitstream_out = malloc( bitstreamSizePerIvasFrame ); + memset( bitstream_out, 0, bitstreamSizePerIvasFrame ); + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int perChannelBitrate = lc3plus_enc_get_real_bitrate(encHandle->handles[0]); + int perLc3plusFrameDataBlockOctets = encHandle->num_ftds * perChannelBitrate / 8 / (1000*1000/config.lc3plus_frame_duration_us); + int targetOctets = bps / 8 / (1000*1000/config.isar_frame_duration_us); + printf("IVAS-FS=%i LC3plus-FS=%i ch=%i targetBps=%i targetOctets=%i\n", config.isar_frame_duration_us, config.lc3plus_frame_duration_us, config.channels, bps, targetOctets); + printf(" coreBps=%i corePerChBps=%i coreCodecOctets=%i nFtds=%i \n", perChannelBitrate * encHandle->num_encs, perChannelBitrate, perLc3plusFrameDataBlockOctets, encHandle->num_ftds); + int pfOctets = bitstreamSizePerIvasFrame - perLc3plusFrameDataBlockOctets; + int pfBps = pfOctets * 8 * (1000*1000 / config.isar_frame_duration_us); + printf(" payloadFormatBps=%i payloadFormatOctets=%i \n\n", pfBps, pfOctets); + if(pfBps <= 0) + { + ISAR_LC3PLUS_ENC_Close( &encHandle ); + return err; + } + + Word16 Q_in[16]; + memset(Q_in, 0, sizeof(Q_in) ); + err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out, bitstreamSizePerIvasFrame, Q_in ); +#else + err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out ); +#endif + if ( IVAS_ERR_OK != err ) + { + ISAR_LC3PLUS_ENC_Close( &encHandle ); + free( bitstream_out ); + return err; + } + ISAR_LC3PLUS_ENC_Close( &encHandle ); + + /* decode one frame */ + ISAR_LC3PLUS_DEC_HANDLE decHandle; + err = ISAR_LC3PLUS_DEC_Open( config, +#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING + 1 /*caching enabled*/, +#endif + &decHandle ); + if ( IVAS_ERR_OK != err ) + { + free( bitstream_out ); + return err; + } + + err = ISAR_LC3PLUS_DEC_GetDelay( decHandle, &decDelay ); + if ( IVAS_ERR_OK != err ) + { + ISAR_LC3PLUS_DEC_Close( &decHandle ); + free( bitstream_out ); + return err; + } + if ( decDelay == -1 || decDelay == 0 ) + { + ISAR_LC3PLUS_DEC_Close( &decHandle ); + free( bitstream_out ); + return IVAS_ERROR( IVAS_ERR_INTERNAL, "decDelay is zero or uninitialized\n" ); + } + + uint8_t *bitstream_in = bitstream_out; + + PcmSample *pcm_out[2]; + PcmSample pcm_out_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( PcmSample )]; + memset( pcm_out_ch1, 0, numSamplesPerChannels * sizeof( PcmSample ) ); + PcmSample pcm_out_ch2[MAX_SAMPLES_PER_CHANNEL * sizeof( PcmSample )]; + memset( pcm_out_ch2, 0, numSamplesPerChannels * sizeof( PcmSample ) ); + pcm_out[0] = pcm_out_ch1; + pcm_out[1] = pcm_out_ch2; + + err = ISAR_LC3PLUS_DEC_Conceal( decHandle, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + ISAR_LC3PLUS_DEC_Close( &decHandle ); + free( bitstream_out ); + return err; + } + + err = ISAR_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstreamSizePerIvasFrame, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + ISAR_LC3PLUS_DEC_Close( &decHandle ); + free( bitstream_out ); + return err; + } + + err = ISAR_LC3PLUS_DEC_Conceal( decHandle, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + ISAR_LC3PLUS_DEC_Close( &decHandle ); + free( bitstream_out ); + return err; + } + + ISAR_LC3PLUS_DEC_Close( &decHandle ); + free( bitstream_out ); + + return 0; +} + + +static int openCloseEncoder( void ) +{ + ivas_error err; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif + uint32_t bps = 128000; + + ISAR_LC3PLUS_ENC_HANDLE encHandle; + err = ISAR_LC3PLUS_ENC_Open( config, bps, &encHandle ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + ISAR_LC3PLUS_ENC_Close( &encHandle ); + return 0; +} + +static int tryOpenEncoderWithInvalidBitrate( void ) +{ + ivas_error err; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif + /* lc3plus max bitrate is 320000 per channel */ + uint32_t invalid_high_bps = 700000; + uint32_t invalid_low_bps = 8; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + uint32_t limitedBitrate; +#endif + ISAR_LC3PLUS_ENC_HANDLE encHandle; + err = ISAR_LC3PLUS_ENC_Open( config, invalid_high_bps, &encHandle ); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + /* setting an invalid bitrate should result in a limited bitrate*/ + if ( IVAS_ERR_OK != err ) +#else + /* setting an invalid bitrate should trigger an error - which is what we expect */ + if ( IVAS_ERR_LC3PLUS_INVALID_BITRATE != err ) +#endif + { + return 1; + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + limitedBitrate = lc3plus_enc_get_real_bitrate(encHandle->handles[0]); + if(limitedBitrate != 320000) + { + return 1; + } +#endif + ISAR_LC3PLUS_ENC_Close(&encHandle); + err = ISAR_LC3PLUS_ENC_Open( config, invalid_low_bps, &encHandle ); + /* setting an invalid bitrate should trigger an error - which is what we expect */ + if ( IVAS_ERR_LC3PLUS_INVALID_BITRATE != err ) + { + return 1; + } + ISAR_LC3PLUS_ENC_Close(&encHandle); + return 0; +} + +static int tryOpenEncoderWithInvalidFrameDuration( void ) +{ + ivas_error err; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif + config.lc3plus_frame_duration_us = 1234; /*unsupported frame duration*/ + uint32_t bps = 320000; + + ISAR_LC3PLUS_ENC_HANDLE encHandle; + err = ISAR_LC3PLUS_ENC_Open( config, bps, &encHandle ); + /* setting an invalid fame duration should trigger an error - which is what we expect */ + if ( IVAS_ERR_OK == err ) + { + return 1; + } + return 0; +} + +static int tryOpenEncoderWithInvalidSampleRate( void ) +{ + ivas_error err; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif + config.samplerate = 1234; /*unsupported sample rate */ + uint32_t bps = 320000; + + ISAR_LC3PLUS_ENC_HANDLE encHandle; + err = ISAR_LC3PLUS_ENC_Open( config, bps, &encHandle ); + /* setting an invalid sample rate should trigger an error - which is what we expect */ + if ( IVAS_ERR_OK == err ) + { + return 1; + } + return 0; +} + +static int tryCallEncoderApiWithInvalidParams( void ) +{ + ISAR_LC3PLUS_ENC_HANDLE invalidEncHandle = NULL; + int32_t *invalidBsSize = NULL; + int32_t bsSize; + int32_t *invalidDelayInSamples = NULL; + int32_t delayInSamples; + PcmSample **invalidPcm_in = NULL; + void *invalidBitstream_out = NULL; + + const int16_t numSamplesPerChannels = MAX_SAMPLES_PER_CHANNEL; + PcmSample *pcm_in[1]; + PcmSample pcm_in_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( PcmSample )]; + memset( pcm_in_ch1, 0, numSamplesPerChannels * sizeof( PcmSample ) ); + pcm_in[0] = pcm_in_ch1; + uint8_t bitstream_out[1200]; + + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_GetDelay( invalidEncHandle, invalidDelayInSamples ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_GetDelay( invalidEncHandle, &delayInSamples ) ) + { + return 1; + } + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( invalidEncHandle, invalidBsSize ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( invalidEncHandle, &bsSize ) ) + { + return 1; + } + ISAR_LC3PLUS_ENC_Close( &invalidEncHandle ); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + Word16 Q_in[16]; + memset(Q_in, 0, sizeof(Q_in) ); + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, invalidBitstream_out, bsSize, Q_in ) ) +#else + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, invalidBitstream_out ) ) +#endif + { + return 1; + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + memset(Q_in, 0, sizeof(Q_in) ); + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, invalidBitstream_out, bsSize, Q_in) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, bitstream_out, bsSize, Q_in ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, bitstream_out, bsSize, Q_in ) ) +#else + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, invalidBitstream_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, bitstream_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, bitstream_out ) ) +#endif + { + return 1; + } + return 0; +} + + +static int tryCallDecoderApiWithInvalidParams( void ) +{ + ISAR_LC3PLUS_DEC_HANDLE invalidDecHandle = NULL; + + int32_t *invalidDelayInSamples = NULL; + int32_t delayInSamples; + PcmSample **invalidPcm_out = NULL; + void *invalidBitstream_in = NULL; + int32_t invalidBitstream_in_size = 0; + int32_t bitstream_in_size = 100; + + const int16_t numSamplesPerChannels = MAX_SAMPLES_PER_CHANNEL; + PcmSample *pcm_out[1]; + PcmSample pcm_out_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( PcmSample )]; + memset( pcm_out_ch1, 0, numSamplesPerChannels * sizeof( PcmSample ) ); + pcm_out[0] = pcm_out_ch1; + uint8_t bitstream_in[1200]; + + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_GetDelay( invalidDecHandle, invalidDelayInSamples ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_GetDelay( invalidDecHandle, &delayInSamples ) ) + { + return 1; + } + ISAR_LC3PLUS_DEC_Close( &invalidDecHandle ); + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, invalidBitstream_in_size, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, invalidBitstream_in_size, pcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, bitstream_in_size, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, bitstream_in_size, pcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, bitstream_in, invalidBitstream_in_size, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, bitstream_in, invalidBitstream_in_size, pcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, bitstream_in, bitstream_in_size, pcm_out ) ) + { + return 1; + } + + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Conceal( invalidDecHandle, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Conceal( invalidDecHandle, pcm_out ) ) + { + return 1; + } + return 0; +} + +static int openCloseDecoderWithCaching( void ) +{ + ivas_error err; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif + ISAR_LC3PLUS_DEC_HANDLE decHandle; + err = ISAR_LC3PLUS_DEC_Open( config, +#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING + 1 /*caching enabled*/, +#endif + &decHandle ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + ISAR_LC3PLUS_DEC_Close( &decHandle ); + return 0; +} + +static int openCloseDecoderWithoutCaching( void ) +{ + ivas_error err; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif + ISAR_LC3PLUS_DEC_HANDLE decHandle; + err = ISAR_LC3PLUS_DEC_Open( config, +#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING + 1 /*caching enabled*/, +#endif + &decHandle ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + ISAR_LC3PLUS_DEC_Close( &decHandle ); + return 0; +} + + +static int tryOpenDecoderWithInvalidFrameDuration( void ) +{ + ivas_error err; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif + config.lc3plus_frame_duration_us = 1234; /*unsupported frame duration*/ + + ISAR_LC3PLUS_DEC_HANDLE decHandle; + err = ISAR_LC3PLUS_DEC_Open( config, +#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING + 1 /*caching enabled*/, +#endif + &decHandle ); + /* setting an invalid fame duration should trigger an error - which is what we expect */ + if ( IVAS_ERR_OK == err ) + { + return 1; + } + return 0; +} + +static int tryOpenDecoderWithInvalidSampleRate( void ) +{ + ivas_error err; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif + config.samplerate = 1234; /*unsupported sample rate*/ + + ISAR_LC3PLUS_DEC_HANDLE decHandle; + err = ISAR_LC3PLUS_DEC_Open( config, +#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING + 1 /*caching enabled*/, +#endif + &decHandle ); + /* setting an invalid sample rate should trigger an error - which is what we expect */ + if ( IVAS_ERR_OK == err ) + { + return 1; + } + return 0; +} + +static int encodeOneFrame( void ) +{ + ivas_error err; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif + uint32_t bps = 128000; + + ISAR_LC3PLUS_ENC_HANDLE encHandle; + err = ISAR_LC3PLUS_ENC_Open( config, bps, &encHandle ); + if ( IVAS_ERR_OK != err ) + return err; + + int16_t numSamplesPerChannels = config.samplerate / ( 1000000 / config.isar_frame_duration_us ); + + PcmSample *pcm[1]; + PcmSample pcm_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( PcmSample )]; + memset( pcm_ch1, 0, numSamplesPerChannels * sizeof( PcmSample ) ); + pcm[0] = pcm_ch1; + + int32_t bitstreamSizePerIvasFrame = 0; + err = ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame ); + if ( IVAS_ERR_OK != err ) + return err; + uint8_t *bitstream_out = malloc( bitstreamSizePerIvasFrame ); + memset( bitstream_out, 0, bitstreamSizePerIvasFrame ); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + Word16 Q_in[16]; + memset(Q_in, 0, sizeof(Q_in) ); + err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm, bitstream_out, bitstreamSizePerIvasFrame, Q_in ); + +#else + err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm, bitstream_out ); +#endif + if ( IVAS_ERR_OK != err ) + return err; + + ISAR_LC3PLUS_ENC_Close( &encHandle ); + free( bitstream_out ); + return 0; +} + + +static int encodeAndDecodeOneMonoFrame( void ) +{ + ivas_error err; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif + uint32_t bps = 128000; + + ISAR_LC3PLUS_ENC_HANDLE encHandle; + err = ISAR_LC3PLUS_ENC_Open( config, bps, &encHandle ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* encode one frame */ + int16_t numSamplesPerChannels = config.samplerate / ( 1000000 / config.isar_frame_duration_us ); + PcmSample *pcm_in[1]; + PcmSample pcm_in_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( PcmSample )]; + memset( pcm_in_ch1, 0, numSamplesPerChannels * sizeof( PcmSample ) ); + pcm_in[0] = pcm_in_ch1; + + int32_t bitstreamSizePerIvasFrame = 0; + err = ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame ); + if ( IVAS_ERR_OK != err ) + return err; + + uint8_t *bitstream_out = malloc( bitstreamSizePerIvasFrame ); + memset( bitstream_out, 0, bitstreamSizePerIvasFrame ); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + Word16 Q_in[16]; + memset(Q_in, 0, sizeof(Q_in) ); + err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out, bitstreamSizePerIvasFrame, Q_in ); +#else + err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out ); +#endif + if ( IVAS_ERR_OK != err ) + return err; + ISAR_LC3PLUS_ENC_Close( &encHandle ); + + /* decode one frame */ + ISAR_LC3PLUS_DEC_HANDLE decHandle; + err = ISAR_LC3PLUS_DEC_Open( config, +#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING + 1 /*caching enabled*/, +#endif + &decHandle ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + uint8_t *bitstream_in = bitstream_out; + + PcmSample *pcm_out[1]; + PcmSample pcm_out_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( PcmSample )]; + memset( pcm_out_ch1, 0, numSamplesPerChannels * sizeof( PcmSample ) ); + pcm_out[0] = pcm_out_ch1; + err = ISAR_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstreamSizePerIvasFrame, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + err = ISAR_LC3PLUS_DEC_Conceal( decHandle, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + ISAR_LC3PLUS_DEC_Close( &decHandle ); + free( bitstream_out ); + + return 0; +} + +static int encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_48kHz( void ) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS ); +} + +static int encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_32kHz( void ) +{ + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 32000 }; + return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS ); +} + +static int encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_16kHz( void ) +{ + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 16000 }; + return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS ); +} + +static int encodeAndDecodeOneStereoFrameIvas5msLc3plus5ms_48kHz( void ) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS ); +} + +static int encodeAndDecodeOneStereoFrameIvas10msLc3plus10ms_48kHz( void ) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS ); +} + +static int encodeAndDecodeOneMonoFrameIvas20msLc3plus10ms_48kHz( void ) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 1, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS ); +} + +static int encodeAndDecodeOneMonoFrameIvas5msLc3plus5ms_48kHz( void ) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5 * 1000, .channels = 1, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS ); +} + +static int encodeAndDecodeOneStereoFrameIvas20msLc3plus2_5ms_48kHz( void ) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 2.5 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 2.5 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS ); +} + + +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_80kbpsPerChannel( void ) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, config.channels * 82*1000 ); +} + +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_96kbpsPerChannel( void ) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, config.channels * 98*1000 ); +} + +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_124kbpsPerChannel( void ) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, config.channels * 126*1000 ); +} + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_800kbpsPerChannel( void ) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, config.channels * 800*1000 ); +} +#endif + +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_204800bpsPerChannel( void ) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, config.channels * 204800 ); +} + +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_205600bpsPerChannel( void ) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, config.channels * 205600 ); +} + +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_206400bpsPerChannel( void ) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, config.channels * 206400 ); +} + +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_207200bpsPerChannel( void ) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, config.channels * 207200 ); +} + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +#include "ivas_lc3plus_unit_test_payload_format.c" +#endif + +int main( + int argc, + char *argv[] ) +{ + (void)argc; + (void)argv; + int ret = 0; + ret = openCloseEncoder(); + if ( ret != 0 ) + return 1; + ret = tryOpenEncoderWithInvalidBitrate(); + if ( ret != 0 ) + return 1; + ret = tryOpenEncoderWithInvalidFrameDuration(); + if ( ret != 0 ) + return 1; + ret = tryOpenEncoderWithInvalidSampleRate(); + if ( ret != 0 ) + return 1; + ret = tryCallEncoderApiWithInvalidParams(); + if ( ret != 0 ) + return 1; + ret = openCloseDecoderWithCaching(); + if ( ret != 0 ) + return 1; + ret = openCloseDecoderWithoutCaching(); + if ( ret != 0 ) + return 1; + ret = tryOpenDecoderWithInvalidFrameDuration(); + if ( ret != 0 ) + return 1; + ret = tryOpenDecoderWithInvalidSampleRate(); + if ( ret != 0 ) + return 1; + ret = tryCallDecoderApiWithInvalidParams(); + if ( ret != 0 ) + return 1; + ret = encodeOneFrame(); + if ( ret != 0 ) + return 1; + ret = encodeAndDecodeOneMonoFrame(); + if ( ret != 0 ) + return 1; + ret = encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_48kHz(); + if ( ret != 0 ) + return 1; + ret = encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_32kHz(); + if ( ret != 0 ) + return 1; + ret = encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_16kHz(); + if ( ret != 0 ) + return 1; + ret = encodeAndDecodeOneStereoFrameIvas5msLc3plus5ms_48kHz(); + if ( ret != 0 ) + return 1; + ret = encodeAndDecodeOneStereoFrameIvas10msLc3plus10ms_48kHz(); + if ( ret != 0 ) + return 1; + ret = encodeAndDecodeOneMonoFrameIvas20msLc3plus10ms_48kHz(); + if ( ret != 0 ) + return 1; + ret = encodeAndDecodeOneMonoFrameIvas5msLc3plus5ms_48kHz(); + if ( ret != 0 ) + return 1; + ret = encodeAndDecodeOneStereoFrameIvas20msLc3plus2_5ms_48kHz(); + if ( ret != 0 ) + return 1; + ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_80kbpsPerChannel(); + if ( ret != 0 ) + return 1; + ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_96kbpsPerChannel(); + if ( ret != 0 ) + return 1; + ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_124kbpsPerChannel(); + if ( ret != 0 ) + return 1; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_800kbpsPerChannel(); + if ( ret != 0 ) + return 1; +#endif + /* start configs around the FDL threshold */ + ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_204800bpsPerChannel(); + if ( ret != 0 ) + return 1; + ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_205600bpsPerChannel(); + if ( ret != 0 ) + return 1; + ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_206400bpsPerChannel(); + if ( ret != 0 ) + return 1; + ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_207200bpsPerChannel(); + if ( ret != 0 ) + return 1; + /* end configs around the FDL threshold */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ret = run_all_payload_tests(); + if ( ret != 0 ) + return 1; +#endif + return 0; +} +#else +int main( void ) +{ + return EXIT_SUCCESS; +} +#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/scripts/split_rendering/lc3plus_basop/ivas_lc3plus_unit_test_payload_format.c b/scripts/split_rendering/lc3plus_basop/ivas_lc3plus_unit_test_payload_format.c new file mode 100644 index 0000000000..a303d01f53 --- /dev/null +++ b/scripts/split_rendering/lc3plus_basop/ivas_lc3plus_unit_test_payload_format.c @@ -0,0 +1,451 @@ +/****************************************************************************************************** + +(C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, +Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +contributors to this repository. All Rights Reserved. + +This software is protected by copyright law and by international treaties. +The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, +Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +contributors to this repository retain full ownership rights in their respective contributions in +the software. This notice grants no license of any kind, including but not limited to patent +license, nor is any license granted by implication, estoppel or otherwise. + +Contributors are required to enter into the IVAS codec Public Collaboration agreement before making +contributions. + +This software is provided "AS IS", without any express or implied warranties. The software is in the +development stage. It is intended exclusively for experts who have experience with such software and +solely for the purpose of inspection. All implied warranties of non-infringement, merchantability +and fitness for a particular purpose are hereby disclaimed and excluded. + +Any dispute, controversy or claim arising under or in relation to providing this software shall be +submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in +accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and +the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include +#include +#include "isar_lc3plus_payload.h" +#include "ivas_error_utils.h" +#include "isar_lc3plus_common.h" +#include "options.h" + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + +/* included by ivas_lc3plus_unit_test.c */ + +#define LC3PLUS_MAX_NUM_CODERS 16 +#define LC3PLUS_MAX_BS_SIZE LC3PLUS_MAX_NUM_CODERS *( 720 * LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES ) +#define SIZE_70 70 +#define SIZE_160 160 +#define SIZE_320 320 +#define SIZE_600 600 + +static int pack_and_unpack_payload_config_2ch_10ms_lc3plus_20ms_ivas( void ) +{ + LC3PLUS_RTP_FTD sender_ftds[LC3PLUS_MAX_NUM_CODERS]; + int32_t sender_ftds_num = 0; + const LC3PLUS_RTP_FDL fdl_req = LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA; + + LC3PLUS_RTP_FTD *ftd_L_01 = &sender_ftds[0]; + ftd_L_01->fc = LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL; + ftd_L_01->fdi = LC3PLUS_RTP_FTD_FDI_10000_US; + ftd_L_01->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_L_01->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_L_01->frame_data = NULL; + ftd_L_01->frame_data_length = SIZE_160; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_R_01 = &sender_ftds[1]; + ftd_R_01->fc = LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME; + ftd_R_01->fdi = LC3PLUS_RTP_FTD_FDI_10000_US; + ftd_R_01->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_R_01->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_R_01->frame_data = NULL; + ftd_R_01->frame_data_length = SIZE_600; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_L_02 = &sender_ftds[2]; + ftd_L_02->fc = LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL; + ftd_L_02->fdi = LC3PLUS_RTP_FTD_FDI_10000_US; + ftd_L_02->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_L_02->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_L_02->frame_data = NULL; + ftd_L_02->frame_data_length = SIZE_320; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_R_02 = &sender_ftds[3]; + ftd_R_02->fc = LC3PLUS_RTP_FTD_FC_LAST_OVERALL; + ftd_R_02->fdi = LC3PLUS_RTP_FTD_FDI_10000_US; + ftd_R_02->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_R_02->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_R_02->frame_data = NULL; + ftd_R_02->frame_data_length = SIZE_160; + sender_ftds_num++; + + const size_t packed_buffer_capacity = LC3PLUS_MAX_BS_SIZE; + size_t packed_buffer_actual_size; + uint8_t packed_buffer[LC3PLUS_MAX_BS_SIZE]; + memset( packed_buffer, 0, packed_buffer_capacity ); + // prepare bitstream buffer headers & layout + LC3PLUS_RTP_ERR error = LC3PLUS_RTP_payload_serialize( packed_buffer, packed_buffer_capacity, &packed_buffer_actual_size, fdl_req, sender_ftds, sender_ftds_num ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_serialize failed\n" ); + } + + // copy encoded frames into their expected memory locations + uint8_t frame_data_L_01[SIZE_160]; + memset( frame_data_L_01, 0x01, sizeof( frame_data_L_01 ) ); + uint8_t frame_data_R_01[SIZE_600]; + memset( frame_data_R_01, 0x02, sizeof( frame_data_R_01 ) ); + uint8_t frame_data_L_02[SIZE_320]; + memset( frame_data_L_02, 0x03, sizeof( frame_data_L_02 ) ); + uint8_t frame_data_R_02[SIZE_160]; + memset( frame_data_R_02, 0x04, sizeof( frame_data_R_02 ) ); + memcpy( sender_ftds[0].frame_data, frame_data_L_01, sender_ftds[0].frame_data_length ); + memcpy( sender_ftds[1].frame_data, frame_data_R_01, sender_ftds[1].frame_data_length ); + memcpy( sender_ftds[2].frame_data, frame_data_L_02, sender_ftds[2].frame_data_length ); + memcpy( sender_ftds[3].frame_data, frame_data_R_02, sender_ftds[3].frame_data_length ); + + uint8_t *receiverBuffer = malloc( packed_buffer_actual_size ); + assert( NULL != receiverBuffer ); + memcpy( receiverBuffer, packed_buffer, packed_buffer_actual_size ); + + LC3PLUS_RTP_PAYLOAD payload_config; + error = LC3PLUS_RTP_payload_deserialize( &payload_config, receiverBuffer, packed_buffer_actual_size ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_deserialize failed\n" ); + } + + assert( payload_config.fdl_request == fdl_req ); + assert( payload_config.frame_duration_us == 10000 ); + assert( payload_config.high_resolution_enabled == 0 ); + assert( payload_config.sampling_rate_hz == 48000 ); + assert( payload_config.num_ftds == 4 ); + assert( payload_config.num_media_times == 2 ); + assert( payload_config.num_channels == 2 ); + for ( int32_t i = 0; i < payload_config.num_ftds; ++i ) + { + assert( payload_config.ftds[i].frame_data_length == sender_ftds[i].frame_data_length ); + assert( payload_config.ftds[i].h == sender_ftds[i].h ); + assert( payload_config.ftds[i].fdi == sender_ftds[i].fdi ); + assert( payload_config.ftds[i].bwr == sender_ftds[i].bwr ); + assert( payload_config.ftds[i].fc == sender_ftds[i].fc ); + assert( payload_config.ftds[i].frame_data_length == sender_ftds[i].frame_data_length ); + assert( payload_config.ftds[i].frame_data != sender_ftds[i].frame_data ); + assert( 0 == memcmp( payload_config.ftds[i].frame_data, sender_ftds[i].frame_data, sender_ftds[i].frame_data_length ) ); + } + + free( receiverBuffer ); + return 0; +} + +static int pack_and_unpack_payload_config_2ch_5ms_lc3plus_20ms_ivas( void ) +{ + LC3PLUS_RTP_FTD sender_ftds[LC3PLUS_MAX_NUM_CODERS]; + int32_t sender_ftds_num = 0; + const LC3PLUS_RTP_FDL fdl_req = LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA; + + LC3PLUS_RTP_FTD *ftd_L_01 = &sender_ftds[0]; + ftd_L_01->fc = LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL; + ftd_L_01->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_L_01->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_L_01->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_L_01->frame_data = NULL; + ftd_L_01->frame_data_length = SIZE_70; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_R_01 = &sender_ftds[1]; + ftd_R_01->fc = LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME; + ftd_R_01->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_R_01->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_R_01->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_R_01->frame_data = NULL; + ftd_R_01->frame_data_length = SIZE_320; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_L_02 = &sender_ftds[2]; + ftd_L_02->fc = LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL; + ftd_L_02->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_L_02->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_L_02->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_L_02->frame_data = NULL; + ftd_L_02->frame_data_length = SIZE_70; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_R_02 = &sender_ftds[3]; + ftd_R_02->fc = LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME; + ftd_R_02->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_R_02->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_R_02->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_R_02->frame_data = NULL; + ftd_R_02->frame_data_length = SIZE_160; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_L_03 = &sender_ftds[4]; + ftd_L_03->fc = LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL; + ftd_L_03->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_L_03->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_L_03->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_L_03->frame_data = NULL; + ftd_L_03->frame_data_length = SIZE_70; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_R_03 = &sender_ftds[5]; + ftd_R_03->fc = LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME; + ftd_R_03->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_R_03->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_R_03->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_R_03->frame_data = NULL; + ftd_R_03->frame_data_length = SIZE_320; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_L_04 = &sender_ftds[6]; + ftd_L_04->fc = LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL; + ftd_L_04->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_L_04->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_L_04->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_L_04->frame_data = NULL; + ftd_L_04->frame_data_length = SIZE_70; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_R_04 = &sender_ftds[7]; + ftd_R_04->fc = LC3PLUS_RTP_FTD_FC_LAST_OVERALL; + ftd_R_04->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_R_04->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_R_04->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_R_04->frame_data = NULL; + ftd_R_04->frame_data_length = SIZE_160; + sender_ftds_num++; + + const size_t packed_buffer_capacity = LC3PLUS_MAX_BS_SIZE; + size_t packed_buffer_actual_size; + uint8_t packed_buffer[LC3PLUS_MAX_BS_SIZE]; + memset( packed_buffer, 0, packed_buffer_capacity ); + // prepare bitstream buffer headers & layout + LC3PLUS_RTP_ERR error = LC3PLUS_RTP_payload_serialize( packed_buffer, packed_buffer_capacity, &packed_buffer_actual_size, fdl_req, sender_ftds, sender_ftds_num ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_serialize failed\n" ); + } + + + // copy encoded frames into their expected memory locations + uint8_t frame_data_L_01[SIZE_70]; + assert( ftd_L_01->frame_data_length == sizeof( frame_data_L_01 ) ); + memset( frame_data_L_01, 0x01, sizeof( frame_data_L_01 ) ); + uint8_t frame_data_R_01[SIZE_320]; + assert( ftd_R_01->frame_data_length == sizeof( frame_data_R_01 ) ); + memset( frame_data_R_01, 0x02, sizeof( frame_data_R_01 ) ); + uint8_t frame_data_L_02[SIZE_70]; + assert( ftd_L_02->frame_data_length == sizeof( frame_data_L_02 ) ); + memset( frame_data_L_02, 0x03, sizeof( frame_data_L_02 ) ); + uint8_t frame_data_R_02[SIZE_160]; + assert( ftd_R_02->frame_data_length == sizeof( frame_data_R_02 ) ); + memset( frame_data_R_02, 0x04, sizeof( frame_data_R_02 ) ); + uint8_t frame_data_L_03[SIZE_70]; + assert( ftd_L_03->frame_data_length == sizeof( frame_data_L_03 ) ); + memset( frame_data_L_03, 0x05, sizeof( frame_data_L_03 ) ); + uint8_t frame_data_R_03[SIZE_320]; + assert( ftd_R_03->frame_data_length == sizeof( frame_data_R_03 ) ); + memset( frame_data_R_03, 0x06, sizeof( frame_data_R_03 ) ); + uint8_t frame_data_L_04[SIZE_70]; + assert( ftd_L_04->frame_data_length == sizeof( frame_data_L_04 ) ); + memset( frame_data_L_04, 0x07, sizeof( frame_data_L_04 ) ); + uint8_t frame_data_R_04[SIZE_160]; + assert( ftd_R_04->frame_data_length == sizeof( frame_data_R_04 ) ); + memset( frame_data_R_04, 0x08, sizeof( frame_data_R_04 ) ); + memcpy( sender_ftds[0].frame_data, frame_data_L_01, sender_ftds[0].frame_data_length ); + memcpy( sender_ftds[1].frame_data, frame_data_R_01, sender_ftds[1].frame_data_length ); + memcpy( sender_ftds[2].frame_data, frame_data_L_02, sender_ftds[2].frame_data_length ); + memcpy( sender_ftds[3].frame_data, frame_data_R_02, sender_ftds[3].frame_data_length ); + memcpy( sender_ftds[4].frame_data, frame_data_L_03, sender_ftds[4].frame_data_length ); + memcpy( sender_ftds[5].frame_data, frame_data_R_03, sender_ftds[5].frame_data_length ); + memcpy( sender_ftds[6].frame_data, frame_data_L_04, sender_ftds[6].frame_data_length ); + memcpy( sender_ftds[7].frame_data, frame_data_R_04, sender_ftds[7].frame_data_length ); + + uint8_t *receiverBuffer = malloc( packed_buffer_actual_size ); + assert( NULL != receiverBuffer ); + memcpy( receiverBuffer, packed_buffer, packed_buffer_actual_size ); + + LC3PLUS_RTP_PAYLOAD payload_config; + error = LC3PLUS_RTP_payload_deserialize( &payload_config, receiverBuffer, packed_buffer_actual_size ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_deserialize failed\n" ); + } + + assert( payload_config.fdl_request == fdl_req ); + assert( payload_config.frame_duration_us == 5000 ); + assert( payload_config.high_resolution_enabled == 0 ); + assert( payload_config.sampling_rate_hz == 48000 ); + assert( payload_config.num_ftds == 8 ); + assert( payload_config.num_media_times == 4 ); + assert( payload_config.num_channels == 2 ); + for ( int32_t i = 0; i < payload_config.num_ftds; ++i ) + { + assert( payload_config.ftds[i].frame_data_length == sender_ftds[i].frame_data_length ); + assert( payload_config.ftds[i].h == sender_ftds[i].h ); + assert( payload_config.ftds[i].fdi == sender_ftds[i].fdi ); + assert( payload_config.ftds[i].bwr == sender_ftds[i].bwr ); + assert( payload_config.ftds[i].fc == sender_ftds[i].fc ); + assert( payload_config.ftds[i].frame_data_length == sender_ftds[i].frame_data_length ); + assert( payload_config.ftds[i].frame_data != sender_ftds[i].frame_data ); + assert( 0 == memcmp( payload_config.ftds[i].frame_data, sender_ftds[i].frame_data, sender_ftds[i].frame_data_length ) ); + } + + free( receiverBuffer ); + return 0; +} + +static int try_unpack_invalid_values( void ) +{ + LC3PLUS_RTP_FTD sender_ftds[LC3PLUS_MAX_NUM_CODERS]; + int32_t sender_ftds_num = 0; + const LC3PLUS_RTP_FDL fdl_req = LC3PLUS_RTP_FDL_LENGTH_3_MAX; + + LC3PLUS_RTP_FTD *ftd_L_01 = &sender_ftds[0]; + ftd_L_01->fc = LC3PLUS_RTP_FTD_FC_LAST_OVERALL; + ftd_L_01->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_L_01->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_L_01->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_L_01->frame_data = NULL; + ftd_L_01->frame_data_length = SIZE_70; + sender_ftds_num++; + + const size_t packed_buffer_capacity = LC3PLUS_MAX_BS_SIZE; + size_t packed_buffer_actual_size; + uint8_t packed_buffer[LC3PLUS_MAX_BS_SIZE]; + memset( packed_buffer, 0, packed_buffer_capacity ); + // prepare bitstream buffer headers & layout + LC3PLUS_RTP_ERR error = LC3PLUS_RTP_payload_serialize( packed_buffer, packed_buffer_capacity, &packed_buffer_actual_size, fdl_req, sender_ftds, sender_ftds_num ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_serialize failed\n" ); + } + + // copy encoded frames into their expected memory locations + uint8_t frame_data_L_01[SIZE_70]; + assert( ftd_L_01->frame_data_length == sizeof( frame_data_L_01 ) ); + memset( frame_data_L_01, 0x01, sizeof( frame_data_L_01 ) ); + + uint8_t *receiverBuffer = malloc( packed_buffer_actual_size ); + assert( NULL != receiverBuffer ); + memcpy( receiverBuffer, packed_buffer, packed_buffer_actual_size ); + + int32_t fdl_req_length; + error = LC3PLUS_RTP_frame_data_length_get_size( &fdl_req_length, fdl_req ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_frame_data_length_get_size error\n" ); + } + for ( int16_t packed_buffer_incorrect_size = 0; packed_buffer_incorrect_size < ( fdl_req_length + 2 + SIZE_70 ); ++packed_buffer_incorrect_size ) + { + LC3PLUS_RTP_PAYLOAD payload_config; + error = LC3PLUS_RTP_payload_deserialize( &payload_config, receiverBuffer, packed_buffer_incorrect_size ); + if ( error == LC3PLUS_RTP_ERR_NO_ERROR ) + { + free( receiverBuffer ); + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_deserialize failed to detect error\n" ); + } + } + + LC3PLUS_RTP_PAYLOAD payload_config; + error = LC3PLUS_RTP_payload_deserialize( &payload_config, receiverBuffer, packed_buffer_actual_size ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + free( receiverBuffer ); + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_deserialize failed\n" ); + } + free( receiverBuffer ); + return 0; +} + +#define LC3PLUS_RTP_TEST_NUM_FTDS_UT 3 +static int pack_and_unpack_different_fdl_sizes( void ) +{ + int32_t iFtdUt; + LC3PLUS_RTP_FDL fdl_requests_ut[LC3PLUS_RTP_TEST_NUM_FTDS_UT]; + fdl_requests_ut[0] = LC3PLUS_RTP_FDL_LENGTH_1_MIN; + fdl_requests_ut[1] = LC3PLUS_RTP_FDL_LENGTH_2_MIN; + fdl_requests_ut[2] = LC3PLUS_RTP_FDL_LENGTH_3_MIN; + + for ( iFtdUt = 0; iFtdUt < LC3PLUS_RTP_TEST_NUM_FTDS_UT; ++iFtdUt ) + { + LC3PLUS_RTP_FTD sender_ftds[LC3PLUS_MAX_NUM_CODERS]; + int32_t sender_ftds_num = 0; + + LC3PLUS_RTP_FTD *ftd_L_01 = &sender_ftds[0]; + ftd_L_01->fc = LC3PLUS_RTP_FTD_FC_LAST_OVERALL; + ftd_L_01->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_L_01->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_L_01->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_L_01->frame_data = NULL; + ftd_L_01->frame_data_length = fdl_requests_ut[iFtdUt]; + sender_ftds_num++; + + const size_t packed_buffer_capacity = LC3PLUS_MAX_BS_SIZE; + size_t packed_buffer_actual_size; + uint8_t packed_buffer[LC3PLUS_MAX_BS_SIZE]; + memset( packed_buffer, 0, packed_buffer_capacity ); + // prepare bitstream buffer headers & layout + LC3PLUS_RTP_ERR error = LC3PLUS_RTP_payload_serialize( packed_buffer, packed_buffer_capacity, &packed_buffer_actual_size, fdl_requests_ut[iFtdUt], sender_ftds, sender_ftds_num ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_serialize failed\n" ); + } + + // copy encoded frames into their expected memory locations + uint8_t frame_data_L_01[SIZE_600]; + assert( ftd_L_01->frame_data_length <= sizeof( frame_data_L_01 ) ); + memset( frame_data_L_01, 0x01, ftd_L_01->frame_data_length ); + + uint8_t *receiverBuffer = malloc( packed_buffer_actual_size ); + assert( NULL != receiverBuffer ); + memcpy( receiverBuffer, packed_buffer, packed_buffer_actual_size ); + + LC3PLUS_RTP_PAYLOAD payload_config; + error = LC3PLUS_RTP_payload_deserialize( &payload_config, receiverBuffer, packed_buffer_actual_size ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + free( receiverBuffer ); + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_deserialize failed\n" ); + } + assert( payload_config.fdl_request == fdl_requests_ut[iFtdUt] ); + assert( payload_config.ftds[0].frame_data_length == fdl_requests_ut[iFtdUt] ); + free( receiverBuffer ); + } + return 0; +} + +static int run_all_payload_tests( void ) +{ + if ( pack_and_unpack_payload_config_2ch_10ms_lc3plus_20ms_ivas() != 0 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); + } + if ( pack_and_unpack_payload_config_2ch_5ms_lc3plus_20ms_ivas() != 0 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); + } + if ( try_unpack_invalid_values() != 0 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); + } + if ( pack_and_unpack_different_fdl_sizes() != 0 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); + } + return 0; +} +#endif diff --git a/scripts/split_rendering/lc3plus_basop/split_rend_lc3plus_cmdlines.py b/scripts/split_rendering/lc3plus_basop/split_rend_lc3plus_cmdlines.py new file mode 100644 index 0000000000..033c25bb60 --- /dev/null +++ b/scripts/split_rendering/lc3plus_basop/split_rend_lc3plus_cmdlines.py @@ -0,0 +1,191 @@ +""" +Generate command lines for split rendering with LC3plus +""" + +import itertools +import os + +# Paths +ENC_PATH = "./IVAS_cod" +DEC_PATH = "./IVAS_dec" +REND_PATH = "./IVAS_rend" +TEMP_DIR = "tmp" + +# Config values to iterate over +ISM_CONFIGS_NUM_OBJECTS = [1, 2, 3, 4] +IVAS_BITRATES = [128000] +PRE_HEAD_ROT_FILES = [ + "Workspace_msvc/trajectories/pre-renderer_pose_files/pre_yaw-20static.csv" +] +POST_HEAD_ROT_FILES = [ + "Workspace_msvc/trajectories/post-renderer_pose_files/post_0static.csv" +] +RENDER_CONFIG_FILES = [ + ####################################################### + # Alternative 2 - LC3plus with CLDFB pose correction + "Workspace_msvc/renderer_configs/split_renderer_config_768_1dof.txt", + "Workspace_msvc/renderer_configs/split_renderer_config_512_2dof.txt", + None, # Alternative 2 is the default when no rendering config file is given on command line + ####################################################### + # Alternative 3 - LC3plus with multi-stream (TD) pose correction + "Workspace_msvc/renderer_configs/split_renderer_config_768_1dof_tdposecorr.txt", + "Workspace_msvc/renderer_configs/split_renderer_config_1536_2dof_tdposecorr.txt", +] + + +def audio_for_ism(num_objects): + return f"scripts/testv/stv{num_objects}ISM48s.wav" + + +def metadata_for_ism(num_objects): + return f"scripts/testv/stvISM{num_objects}.csv" + + +def basename(file_path): + basename_w_ext = os.path.basename(file_path) + return os.path.splitext(basename_w_ext)[0] + + +# Full chain: IVAS_cod -> IVAS_dec -> IVAS_rend(post) +def full_chain( + num_objects, ivas_bitrate, pre_head_rot_file, render_config_file, post_head_rot_file +): + bs_name = f"{TEMP_DIR}/ism{num_objects}_b{ivas_bitrate}_full_chain.g192" + cod = [ + ENC_PATH, + "-ism", + str(num_objects), + *[metadata_for_ism(i + 1) for i in range(num_objects)], + str(ivas_bitrate), + "48", + audio_for_ism(num_objects), + bs_name, + ] + + render_config_infix = ( + f"##{basename(render_config_file)}" if render_config_file else "" + ) + split_bs_name = bs_name.replace( + ".g192", f"##{basename(pre_head_rot_file)}{render_config_infix}##split.bs" + ) + render_config_args = ( + ["-render_config", render_config_file] if render_config_file else [] + ) + dec = [ + DEC_PATH, + "-T", + pre_head_rot_file, + *render_config_args, + "SPLIT_BINAURAL", + "48", + bs_name, + split_bs_name, + ] + + binaural_output_name = split_bs_name.replace( + ".bs", f"##{basename(post_head_rot_file)}##binaural.wav" + ) + rend = [ + REND_PATH, + "-i", + split_bs_name, + "-if", + "BINAURAL_SPLIT_CODED", + "-of", + "BINAURAL", + "-fs", + "48", + "-tf", + post_head_rot_file, + "-o", + binaural_output_name, + ] + + return [cod, dec, rend] + + +# Renderer chain: IVAS_rend(pre) -> IVAS_rend(post) +def rend_chain(num_objects, pre_head_rot_file, render_config_file, post_head_rot_file): + render_config_infix = ( + f"##{basename(render_config_file)}" if render_config_file else "" + ) + split_bs_name = f"{TEMP_DIR}/ism{num_objects}_rend_chain##{basename(pre_head_rot_file)}{render_config_infix}##split.bs" + render_config_args = ( + ["-render_config", render_config_file] if render_config_file else [] + ) + pre = [ + REND_PATH, + "-i", + audio_for_ism(num_objects), + "-if", + f"ISM{num_objects}", + "-im", + *[metadata_for_ism(i + 1) for i in range(num_objects)], + "-of", + "BINAURAL_SPLIT_CODED", + "-fs", + "48", + *render_config_args, + "-tf", + pre_head_rot_file, + "-o", + split_bs_name, + ] + + binaural_output_name = split_bs_name.replace( + ".bs", f"##{basename(post_head_rot_file)}##binaural.wav" + ) + post = [ + REND_PATH, + "-i", + split_bs_name, + "-if", + "BINAURAL_SPLIT_CODED", + "-of", + "BINAURAL", + "-fs", + "48", + "-tf", + post_head_rot_file, + "-o", + binaural_output_name, + ] + + return [pre, post] + + +def print_command_list(list_of_lists): + for lst in list_of_lists: + print(" ".join(lst)) + print("") # newline + + +def main(): + print("\n##########################################") + print("# Full chain: enc -> dec -> rend(post)") + print("##########################################\n") + for args_full_chain in itertools.product( + # Ordering here must match argument order in function call below! + ISM_CONFIGS_NUM_OBJECTS, + IVAS_BITRATES, + PRE_HEAD_ROT_FILES, + RENDER_CONFIG_FILES, + POST_HEAD_ROT_FILES, + ): + print_command_list(full_chain(*args_full_chain)) + + print("\n##########################################") + print("# Renderer chain: rend(pre) -> rend(post)") + print("##########################################\n") + for args_rend_chain in itertools.product( + # Ordering here must match argument order in function call below! + ISM_CONFIGS_NUM_OBJECTS, + PRE_HEAD_ROT_FILES, + RENDER_CONFIG_FILES, + POST_HEAD_ROT_FILES, + ): + print_command_list(rend_chain(*args_rend_chain)) + + +if __name__ == "__main__": + main() diff --git a/scripts/split_rendering/lc3plus_float/.gitignore b/scripts/split_rendering/lc3plus_float/.gitignore new file mode 100644 index 0000000000..9cd2def1f8 --- /dev/null +++ b/scripts/split_rendering/lc3plus_float/.gitignore @@ -0,0 +1 @@ +ivas_lc3plus_unit_test \ No newline at end of file diff --git a/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test.c b/scripts/split_rendering/lc3plus_float/ivas_lc3plus_unit_test.c similarity index 100% rename from scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test.c rename to scripts/split_rendering/lc3plus_float/ivas_lc3plus_unit_test.c diff --git a/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test_payload_format.c b/scripts/split_rendering/lc3plus_float/ivas_lc3plus_unit_test_payload_format.c similarity index 100% rename from scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test_payload_format.c rename to scripts/split_rendering/lc3plus_float/ivas_lc3plus_unit_test_payload_format.c -- GitLab From 7341da415c32d1470956c766553416cb55e5c37b Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Tue, 18 Feb 2025 08:19:42 +0100 Subject: [PATCH 22/23] use new float folder for lc3plus test --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2a5cbb88b6..2ab15a78b6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -872,7 +872,7 @@ lc3-wrapper-unit-test: script: - cmake -B cmake-build -G "Unix Makefiles" -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true - cmake --build cmake-build -- -j - - scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test + - scripts/split_rendering/lc3plus_float/ivas_lc3plus_unit_test # compare split-rendering bitexactness between target and source branch split-rendering-pytest-on-merge-request: -- GitLab From da3a4a526ec112d620e6bec4c8e2dbe0bcbb0b88 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Tue, 18 Feb 2025 09:17:07 +0100 Subject: [PATCH 23/23] fix CMakeLists for new lc3plus unittest dir --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c5beb9a0d..c2143c9090 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -174,7 +174,7 @@ target_include_directories(lib_util PUBLIC lib_util PRIVATE lib_com lib_enc lib_ target_include_directories(lib_util PRIVATE lib_lc3plus lib_isar) if(NOT WMOPS) - add_executable(ivas_lc3plus_unit_test scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test.c) + add_executable(ivas_lc3plus_unit_test scripts/split_rendering/lc3plus_float/ivas_lc3plus_unit_test.c) target_link_libraries(ivas_lc3plus_unit_test lib_rend lib_dec lib_util lib_com lib_debug lib_isar) endif() @@ -213,7 +213,7 @@ if(COPY_EXECUTABLES_FROM_BUILD_DIR) add_custom_command(TARGET IVAS_rend POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") add_custom_command(TARGET ISAR_post_rend POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") if (NOT WMOPS) - add_custom_command(TARGET ivas_lc3plus_unit_test POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/split_rendering/lc3plus") + add_custom_command(TARGET ivas_lc3plus_unit_test POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/split_rendering/lc3plus_float") endif() endif() -- GitLab