Loading examples/TEMPLATE.yml +4 −4 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ input_path: ".../ivas/items/HOA3" output_path: ".../temp_output" ### Metadata path or file(s) ### If input format is ISM{1-4} a path for the metadata files can be specified; ### default = null (for ISM search for item_name.{wav, raw, pcm}.{0-3}.csv in input folder, otherise ignored) ### default = null (for ISM search for item_name.{wav, raw, pcm}.{0-3}.csv in input folder, otherwise ignored) # metadata_path: ### Path can be set for all items with the 'all_items' key (automatic search for item_name.{wav, raw, pcm}.{0-3}.csv within this folder) # all_items: ".../metadata_folder" Loading Loading @@ -115,7 +115,7 @@ input: ### Horizontally concatenate input items into one long file; default = false # concatenate_input: true ### if concatenation is applied, the following two keys can be used to add zeros before or after the items ### duration is specified in miliseconds ### duration is specified in milliseconds # silence_pre: 2000 # silence_post: 2000 ### Specify the concatenation order in a list of strings. If not specified, the concatenation order would be Loading @@ -126,7 +126,7 @@ input: # concatenation_order: [] ### Specify preamble duration in ms; default = 0 # preamble: 10000 ### Flag wheter to use noise (amplitude +-4) for the preamble or silence; default = false (silence) ### Flag whether to use noise (amplitude +-4) for the preamble or silence; default = false (silence) # preamble_noise: true ### Additive background noise # background_noise: Loading Loading @@ -154,7 +154,7 @@ input: ### REQUIRED: either error_pattern (and errpatt_late_loss_rate or errpatt_delay) or error_profile ### delay error profile file # error_pattern: ".../dly_error_profile.dat" ### Late loss rate in precent for EVS ### Late loss rate in percent for EVS # errpatt_late_loss_rate: 1 ### Constant JBM delay in milliseconds for EVS # errpatt_delay: 200 Loading ivas_processing_scripts/__init__.py +4 −36 Original line number Diff line number Diff line Loading @@ -31,10 +31,7 @@ # import logging import sys from itertools import product from multiprocessing import Pool from time import sleep from ivas_processing_scripts.audiotools.metadata import ( check_ISM_metadata, Loading @@ -53,12 +50,7 @@ from ivas_processing_scripts.processing.processing import ( process_item, reorder_items_list, ) from ivas_processing_scripts.utils import ( DirManager, apply_func_parallel, progressbar_update, spinner, ) from ivas_processing_scripts.utils import DirManager, apply_func_parallel def logging_init(args, cfg): Loading Loading @@ -190,34 +182,10 @@ def main(args): (item, tmp_dir, out_dir, chain["processes"], logger, metadata) ) if cfg.multiprocessing: # set up values for progress display and chunksize count = len(item_args) width = 80 # submit tasks to the pool p = Pool() results = p.starmap_async( process_item, item_args, apply_func_parallel( process_item, item_args, None, "mp" if cfg.multiprocessing else None, True ) # poll progress progressbar_update(0, count, width) while not results.ready(): progressbar_update(count - int(results._number_left), count, width) spinner() sleep(0.1) progressbar_update(count, count, width) print("", flush=True, file=sys.stdout) results.get() p.close() p.join() else: apply_func_parallel(process_item, item_args, None, None, True) # copy configuration to output directory cfg.to_file(cfg.output_path.joinpath(f"{cfg.name}.yml")) Loading ivas_processing_scripts/audiotools/metadata.py +4 −2 Original line number Diff line number Diff line Loading @@ -376,7 +376,9 @@ def concat_meta_from_file( # add preamble if preamble: concat_meta_all_obj = add_remove_preamble(concat_meta_all_obj, preamble) concat_meta_all_obj = add_remove_metadata_preamble( concat_meta_all_obj, preamble ) write_ISM_metadata_in_file(concat_meta_all_obj, out_file) Loading Loading @@ -621,7 +623,7 @@ def metadata_search_MASA( return list_meta def add_remove_preamble( def add_remove_metadata_preamble( metadata, preamble, add: Optional[bool] = True, Loading ivas_processing_scripts/processing/preprocessing_2.py +2 −2 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ from ivas_processing_scripts.audiotools import audio from ivas_processing_scripts.audiotools.audioarray import trim from ivas_processing_scripts.audiotools.audiofile import write from ivas_processing_scripts.audiotools.metadata import ( add_remove_preamble, add_remove_metadata_preamble, write_ISM_metadata_in_file, ) from ivas_processing_scripts.audiotools.wrappers.bs1770 import ( Loading Loading @@ -83,7 +83,7 @@ class Preprocessing2(Processing): metadata = audio_object.object_pos # add preamble metadata = add_remove_preamble(metadata, preamble) metadata = add_remove_metadata_preamble(metadata, preamble) # repeat signal if self.repeat_signal: Loading ivas_processing_scripts/processing/processing.py +40 −108 Original line number Diff line number Diff line Loading @@ -31,35 +31,26 @@ # import logging import sys from abc import ABC, abstractmethod from itertools import repeat from multiprocessing import Pool from pathlib import Path from shutil import copyfile from time import sleep from typing import Iterable, Union from warnings import warn import numpy as np from ivas_processing_scripts.audiotools import audio from ivas_processing_scripts.audiotools.audioarray import window from ivas_processing_scripts.audiotools.audiofile import concat, trim from ivas_processing_scripts.audiotools.constants import IVAS_FRAME_LEN_MS from ivas_processing_scripts.audiotools.convert.__init__ import convert from ivas_processing_scripts.audiotools.metadata import ( add_remove_preamble, add_remove_metadata_preamble, concat_meta_from_file, ) from ivas_processing_scripts.constants import LOGGER_DATEFMT, LOGGER_FORMAT from ivas_processing_scripts.processing.config import TestConfig from ivas_processing_scripts.utils import ( list_audio, pairwise, progressbar_update, spinner, ) from ivas_processing_scripts.processing.tx import get_timescaled_splits from ivas_processing_scripts.utils import apply_func_parallel, list_audio, pairwise class Processing(ABC): Loading Loading @@ -202,7 +193,17 @@ def concat_setup(cfg: TestConfig, chain, logger: logging.Logger): def concat_teardown( x, splits, out_fmt, fs, in_fs, meta, tracefile, ivas_jbm, logger: logging.Logger x, splits, out_fmt, fs, in_fs, meta, tracefile, ivas_jbm, repeat_signal, preamble, logger: logging.Logger, ): if splits is None: raise ValueError("Splitting not possible without split marker") Loading @@ -213,7 +214,7 @@ def concat_teardown( if (out_fmt.startswith("ISM") or out_fmt.startswith("MASA")) and ivas_jbm: raise ValueError( "Splitting with JBM compensation not supportet for formats with metadata (e.g. MASA, ISM)" "Splitting with JBM compensation not supported for formats with metadata (e.g. MASA, ISM)" ) if logger and ivas_jbm: Loading @@ -228,59 +229,28 @@ def concat_teardown( relative_fs_change = fs_new / fs_old new_splits = [0] for split_i in splits: new_splits.append(int(float(split_i) * relative_fs_change)) new_splits.append(int(split_i * relative_fs_change)) splits = new_splits else: # adjust splits for jbm ivas conditions # following code is based on jbmtrim.cpp script rtpTimeScale = 1000 # in ms playTimeScale = 1000 # in ms new_splits = [None] * (len(splits) + 1) split_start = 1 / float(fs) i = 0 lastRtpTs = 0 lastPlayTime = 0 # find last JBM trace entry with lower or equal RTP time stamp for j in range(tracefile.shape[0]): entry = tracefile[j] # ignore frames with unknown RTP time stamp or playout time if entry[1] == -1 or entry[3] < 0: continue # check if the next position to cut is found if entry[1] / rtpTimeScale >= split_start: # interpolate between current and previous RTP time stamp to # increase accuracy in case of DTX where lot of time stamps are missing if (num := entry[1] / rtpTimeScale - split_start) == 0: rtpTsRelErr = num else: rtpTsRelErr = num / ( ((entry[1] - lastRtpTs) / rtpTimeScale) + sys.float_info.epsilon ) playTimeAbsErr = rtpTsRelErr * (entry[3] - lastPlayTime) / playTimeScale # found one split, save in list and search for next new_splits[i] = entry[3] / playTimeScale - playTimeAbsErr # get next split marker; add one to make computation more similar to jbmtrim split_start = (float(splits[i]) + 1) / float(fs) i += 1 if i >= len(new_splits): break lastRtpTs = entry[1] lastPlayTime = entry[3] # check if all splits are found if i < (len(new_splits) - 1): raise ValueError("Error in item splitting with JBM compensation") elif i < (len(new_splits)): # catch item with missing end warn("Last split after end of file for IVAS JBM condition") new_splits[i] = lastPlayTime / playTimeScale # set new values and use new sampling rate splits = new_splits for s in range(len(splits)): # subtract one again (was only used to make computation more similar to jbmtrim) splits[s] = int(np.floor(splits[s] * float(in_fs))) - 1 # handle signal repeat and preamble for JBM conditions since we have trace data # for preamble, the first split point should be at the end of the preamble preamble_smp = preamble * in_fs // 1000 if preamble > 0 else 0 # for repeat signal, the first split point should be the start of the repetition repeat_start = preamble_smp + splits[-1] if repeat_signal else 0 # adjust the offsets of the splits accordingly splits = [ preamble_smp + repeat_start, *[s + preamble_smp + repeat_start for s in splits], ] splits_ts = get_timescaled_splits(tracefile, splits, fs, in_fs) # the above function assumes the starting point is the first playout frame # for repeat signal or preamble, we don't want the split to start there if repeat_signal or preamble > 0: splits = splits_ts[1:] # check if last split ending coincides with last sample of signal if splits[-1] > len(x): Loading Loading @@ -331,10 +301,6 @@ def preprocess(cfg, logger): logger.info(f" Generating condition: {preprocessing['name']}") # set up values for progress display and chunksize count = len(cfg.items_list) width = 80 # run preprocessing args = list( zip( Loading @@ -346,25 +312,10 @@ def preprocess(cfg, logger): cfg.metadata_path, ) ) p = Pool() results = p.starmap_async( process_item, args, apply_func_parallel( process_item, args, None, "mp" if cfg.multiprocessing else None, True ) # poll progress progressbar_update(0, count, width) while not results.ready(): progressbar_update(count - int(results._number_left), count, width) spinner() sleep(0.1) progressbar_update(count, count, width) print("", flush=True, file=sys.stdout) results.get() p.close() p.join() # update the configuration to use preprocessing outputs as new inputs cfg.items_list = list_audio( cfg.out_dirs[0], select_list=getattr(cfg, "input_select", None) Loading Loading @@ -427,10 +378,6 @@ def preprocess_2(cfg, logger): if chain[0].concatenate_input: concat_setup(cfg, chain, logger) # set up values for progress display and chunksize count = len(cfg.items_list) width = 80 # run preprocessing 2 args = list( zip( Loading @@ -442,25 +389,10 @@ def preprocess_2(cfg, logger): cfg.metadata_path, ) ) p = Pool() results = p.starmap_async( process_item, args, apply_func_parallel( process_item, args, None, "mp" if cfg.multiprocessing else None, True ) # poll progress progressbar_update(0, count, width) while not results.ready(): progressbar_update(count - int(results._number_left), count, width) spinner() sleep(0.1) progressbar_update(count, count, width) print("", flush=True, file=sys.stdout) results.get() p.close() p.join() # update the configuration to use preprocessing 2 outputs as new inputs cfg.items_list = list_audio( cfg.out_dirs[0], select_list=getattr(cfg, "input_select", None) Loading Loading @@ -604,7 +536,7 @@ def remove_preamble(x, out_fmt, fs, repeat_signal, preamble_len_ms, meta, logger # remove preamble if preamble_len_ms > 0: meta = add_remove_preamble(meta, preamble_len_ms, add=False) meta = add_remove_metadata_preamble(meta, preamble_len_ms, add=False) # cut first half of signal if repeat_signal: Loading Loading
examples/TEMPLATE.yml +4 −4 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ input_path: ".../ivas/items/HOA3" output_path: ".../temp_output" ### Metadata path or file(s) ### If input format is ISM{1-4} a path for the metadata files can be specified; ### default = null (for ISM search for item_name.{wav, raw, pcm}.{0-3}.csv in input folder, otherise ignored) ### default = null (for ISM search for item_name.{wav, raw, pcm}.{0-3}.csv in input folder, otherwise ignored) # metadata_path: ### Path can be set for all items with the 'all_items' key (automatic search for item_name.{wav, raw, pcm}.{0-3}.csv within this folder) # all_items: ".../metadata_folder" Loading Loading @@ -115,7 +115,7 @@ input: ### Horizontally concatenate input items into one long file; default = false # concatenate_input: true ### if concatenation is applied, the following two keys can be used to add zeros before or after the items ### duration is specified in miliseconds ### duration is specified in milliseconds # silence_pre: 2000 # silence_post: 2000 ### Specify the concatenation order in a list of strings. If not specified, the concatenation order would be Loading @@ -126,7 +126,7 @@ input: # concatenation_order: [] ### Specify preamble duration in ms; default = 0 # preamble: 10000 ### Flag wheter to use noise (amplitude +-4) for the preamble or silence; default = false (silence) ### Flag whether to use noise (amplitude +-4) for the preamble or silence; default = false (silence) # preamble_noise: true ### Additive background noise # background_noise: Loading Loading @@ -154,7 +154,7 @@ input: ### REQUIRED: either error_pattern (and errpatt_late_loss_rate or errpatt_delay) or error_profile ### delay error profile file # error_pattern: ".../dly_error_profile.dat" ### Late loss rate in precent for EVS ### Late loss rate in percent for EVS # errpatt_late_loss_rate: 1 ### Constant JBM delay in milliseconds for EVS # errpatt_delay: 200 Loading
ivas_processing_scripts/__init__.py +4 −36 Original line number Diff line number Diff line Loading @@ -31,10 +31,7 @@ # import logging import sys from itertools import product from multiprocessing import Pool from time import sleep from ivas_processing_scripts.audiotools.metadata import ( check_ISM_metadata, Loading @@ -53,12 +50,7 @@ from ivas_processing_scripts.processing.processing import ( process_item, reorder_items_list, ) from ivas_processing_scripts.utils import ( DirManager, apply_func_parallel, progressbar_update, spinner, ) from ivas_processing_scripts.utils import DirManager, apply_func_parallel def logging_init(args, cfg): Loading Loading @@ -190,34 +182,10 @@ def main(args): (item, tmp_dir, out_dir, chain["processes"], logger, metadata) ) if cfg.multiprocessing: # set up values for progress display and chunksize count = len(item_args) width = 80 # submit tasks to the pool p = Pool() results = p.starmap_async( process_item, item_args, apply_func_parallel( process_item, item_args, None, "mp" if cfg.multiprocessing else None, True ) # poll progress progressbar_update(0, count, width) while not results.ready(): progressbar_update(count - int(results._number_left), count, width) spinner() sleep(0.1) progressbar_update(count, count, width) print("", flush=True, file=sys.stdout) results.get() p.close() p.join() else: apply_func_parallel(process_item, item_args, None, None, True) # copy configuration to output directory cfg.to_file(cfg.output_path.joinpath(f"{cfg.name}.yml")) Loading
ivas_processing_scripts/audiotools/metadata.py +4 −2 Original line number Diff line number Diff line Loading @@ -376,7 +376,9 @@ def concat_meta_from_file( # add preamble if preamble: concat_meta_all_obj = add_remove_preamble(concat_meta_all_obj, preamble) concat_meta_all_obj = add_remove_metadata_preamble( concat_meta_all_obj, preamble ) write_ISM_metadata_in_file(concat_meta_all_obj, out_file) Loading Loading @@ -621,7 +623,7 @@ def metadata_search_MASA( return list_meta def add_remove_preamble( def add_remove_metadata_preamble( metadata, preamble, add: Optional[bool] = True, Loading
ivas_processing_scripts/processing/preprocessing_2.py +2 −2 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ from ivas_processing_scripts.audiotools import audio from ivas_processing_scripts.audiotools.audioarray import trim from ivas_processing_scripts.audiotools.audiofile import write from ivas_processing_scripts.audiotools.metadata import ( add_remove_preamble, add_remove_metadata_preamble, write_ISM_metadata_in_file, ) from ivas_processing_scripts.audiotools.wrappers.bs1770 import ( Loading Loading @@ -83,7 +83,7 @@ class Preprocessing2(Processing): metadata = audio_object.object_pos # add preamble metadata = add_remove_preamble(metadata, preamble) metadata = add_remove_metadata_preamble(metadata, preamble) # repeat signal if self.repeat_signal: Loading
ivas_processing_scripts/processing/processing.py +40 −108 Original line number Diff line number Diff line Loading @@ -31,35 +31,26 @@ # import logging import sys from abc import ABC, abstractmethod from itertools import repeat from multiprocessing import Pool from pathlib import Path from shutil import copyfile from time import sleep from typing import Iterable, Union from warnings import warn import numpy as np from ivas_processing_scripts.audiotools import audio from ivas_processing_scripts.audiotools.audioarray import window from ivas_processing_scripts.audiotools.audiofile import concat, trim from ivas_processing_scripts.audiotools.constants import IVAS_FRAME_LEN_MS from ivas_processing_scripts.audiotools.convert.__init__ import convert from ivas_processing_scripts.audiotools.metadata import ( add_remove_preamble, add_remove_metadata_preamble, concat_meta_from_file, ) from ivas_processing_scripts.constants import LOGGER_DATEFMT, LOGGER_FORMAT from ivas_processing_scripts.processing.config import TestConfig from ivas_processing_scripts.utils import ( list_audio, pairwise, progressbar_update, spinner, ) from ivas_processing_scripts.processing.tx import get_timescaled_splits from ivas_processing_scripts.utils import apply_func_parallel, list_audio, pairwise class Processing(ABC): Loading Loading @@ -202,7 +193,17 @@ def concat_setup(cfg: TestConfig, chain, logger: logging.Logger): def concat_teardown( x, splits, out_fmt, fs, in_fs, meta, tracefile, ivas_jbm, logger: logging.Logger x, splits, out_fmt, fs, in_fs, meta, tracefile, ivas_jbm, repeat_signal, preamble, logger: logging.Logger, ): if splits is None: raise ValueError("Splitting not possible without split marker") Loading @@ -213,7 +214,7 @@ def concat_teardown( if (out_fmt.startswith("ISM") or out_fmt.startswith("MASA")) and ivas_jbm: raise ValueError( "Splitting with JBM compensation not supportet for formats with metadata (e.g. MASA, ISM)" "Splitting with JBM compensation not supported for formats with metadata (e.g. MASA, ISM)" ) if logger and ivas_jbm: Loading @@ -228,59 +229,28 @@ def concat_teardown( relative_fs_change = fs_new / fs_old new_splits = [0] for split_i in splits: new_splits.append(int(float(split_i) * relative_fs_change)) new_splits.append(int(split_i * relative_fs_change)) splits = new_splits else: # adjust splits for jbm ivas conditions # following code is based on jbmtrim.cpp script rtpTimeScale = 1000 # in ms playTimeScale = 1000 # in ms new_splits = [None] * (len(splits) + 1) split_start = 1 / float(fs) i = 0 lastRtpTs = 0 lastPlayTime = 0 # find last JBM trace entry with lower or equal RTP time stamp for j in range(tracefile.shape[0]): entry = tracefile[j] # ignore frames with unknown RTP time stamp or playout time if entry[1] == -1 or entry[3] < 0: continue # check if the next position to cut is found if entry[1] / rtpTimeScale >= split_start: # interpolate between current and previous RTP time stamp to # increase accuracy in case of DTX where lot of time stamps are missing if (num := entry[1] / rtpTimeScale - split_start) == 0: rtpTsRelErr = num else: rtpTsRelErr = num / ( ((entry[1] - lastRtpTs) / rtpTimeScale) + sys.float_info.epsilon ) playTimeAbsErr = rtpTsRelErr * (entry[3] - lastPlayTime) / playTimeScale # found one split, save in list and search for next new_splits[i] = entry[3] / playTimeScale - playTimeAbsErr # get next split marker; add one to make computation more similar to jbmtrim split_start = (float(splits[i]) + 1) / float(fs) i += 1 if i >= len(new_splits): break lastRtpTs = entry[1] lastPlayTime = entry[3] # check if all splits are found if i < (len(new_splits) - 1): raise ValueError("Error in item splitting with JBM compensation") elif i < (len(new_splits)): # catch item with missing end warn("Last split after end of file for IVAS JBM condition") new_splits[i] = lastPlayTime / playTimeScale # set new values and use new sampling rate splits = new_splits for s in range(len(splits)): # subtract one again (was only used to make computation more similar to jbmtrim) splits[s] = int(np.floor(splits[s] * float(in_fs))) - 1 # handle signal repeat and preamble for JBM conditions since we have trace data # for preamble, the first split point should be at the end of the preamble preamble_smp = preamble * in_fs // 1000 if preamble > 0 else 0 # for repeat signal, the first split point should be the start of the repetition repeat_start = preamble_smp + splits[-1] if repeat_signal else 0 # adjust the offsets of the splits accordingly splits = [ preamble_smp + repeat_start, *[s + preamble_smp + repeat_start for s in splits], ] splits_ts = get_timescaled_splits(tracefile, splits, fs, in_fs) # the above function assumes the starting point is the first playout frame # for repeat signal or preamble, we don't want the split to start there if repeat_signal or preamble > 0: splits = splits_ts[1:] # check if last split ending coincides with last sample of signal if splits[-1] > len(x): Loading Loading @@ -331,10 +301,6 @@ def preprocess(cfg, logger): logger.info(f" Generating condition: {preprocessing['name']}") # set up values for progress display and chunksize count = len(cfg.items_list) width = 80 # run preprocessing args = list( zip( Loading @@ -346,25 +312,10 @@ def preprocess(cfg, logger): cfg.metadata_path, ) ) p = Pool() results = p.starmap_async( process_item, args, apply_func_parallel( process_item, args, None, "mp" if cfg.multiprocessing else None, True ) # poll progress progressbar_update(0, count, width) while not results.ready(): progressbar_update(count - int(results._number_left), count, width) spinner() sleep(0.1) progressbar_update(count, count, width) print("", flush=True, file=sys.stdout) results.get() p.close() p.join() # update the configuration to use preprocessing outputs as new inputs cfg.items_list = list_audio( cfg.out_dirs[0], select_list=getattr(cfg, "input_select", None) Loading Loading @@ -427,10 +378,6 @@ def preprocess_2(cfg, logger): if chain[0].concatenate_input: concat_setup(cfg, chain, logger) # set up values for progress display and chunksize count = len(cfg.items_list) width = 80 # run preprocessing 2 args = list( zip( Loading @@ -442,25 +389,10 @@ def preprocess_2(cfg, logger): cfg.metadata_path, ) ) p = Pool() results = p.starmap_async( process_item, args, apply_func_parallel( process_item, args, None, "mp" if cfg.multiprocessing else None, True ) # poll progress progressbar_update(0, count, width) while not results.ready(): progressbar_update(count - int(results._number_left), count, width) spinner() sleep(0.1) progressbar_update(count, count, width) print("", flush=True, file=sys.stdout) results.get() p.close() p.join() # update the configuration to use preprocessing 2 outputs as new inputs cfg.items_list = list_audio( cfg.out_dirs[0], select_list=getattr(cfg, "input_select", None) Loading Loading @@ -604,7 +536,7 @@ def remove_preamble(x, out_fmt, fs, repeat_signal, preamble_len_ms, meta, logger # remove preamble if preamble_len_ms > 0: meta = add_remove_preamble(meta, preamble_len_ms, add=False) meta = add_remove_metadata_preamble(meta, preamble_len_ms, add=False) # cut first half of signal if repeat_signal: Loading