From 4b6e567749283add8d43a7aed8dcd33e82749e0e Mon Sep 17 00:00:00 2001 From: Treffehn Date: Tue, 9 May 2023 18:37:21 +0200 Subject: [PATCH 1/7] added loudness info at the end --- ivas_processing_scripts/audiotools/wrappers/bs1770.py | 7 +++++++ ivas_processing_scripts/processing/processing.py | 1 + 2 files changed, 8 insertions(+) diff --git a/ivas_processing_scripts/audiotools/wrappers/bs1770.py b/ivas_processing_scripts/audiotools/wrappers/bs1770.py index fe756c07..40cf89ce 100755 --- a/ivas_processing_scripts/audiotools/wrappers/bs1770.py +++ b/ivas_processing_scripts/audiotools/wrappers/bs1770.py @@ -251,6 +251,7 @@ def scale_files( loudness: float, fs: Optional[int] = 48000, in_meta: Optional[list] = None, + logger: Optional[logging.Logger] = None, ) -> None: """ Scales audio files to desired loudness @@ -284,8 +285,14 @@ def scale_files( else: audio_obj = audio.fromfile(fmt, file, fs) + # TODO: just for testing: remove later + if logger: + measured_loudness, _ = get_loudness(audio_obj) + logger.info(f"measured loudness of file {file.name} for condition {file.parent.name}: {measured_loudness}") + # adjust loudness scaled_audio = loudness_norm(audio_obj, loudness) # write into file write(file, scaled_audio, audio_obj.fs) + diff --git a/ivas_processing_scripts/processing/processing.py b/ivas_processing_scripts/processing/processing.py index 6c4fabc0..c68ef1bc 100755 --- a/ivas_processing_scripts/processing/processing.py +++ b/ivas_processing_scripts/processing/processing.py @@ -356,6 +356,7 @@ def reverse_process_2(cfg, logger): cfg.postprocessing["loudness"], cfg.postprocessing["fs"], out_meta_splits, + logger, ) return -- GitLab From ecb41a64afafde535ee2f0c89242b2f43e7a9366 Mon Sep 17 00:00:00 2001 From: Treffehn Date: Wed, 10 May 2023 15:43:09 +0200 Subject: [PATCH 2/7] added logging in loudness_norm and fixed some minor issues --- .../audiotools/convert/__init__.py | 2 +- .../audiotools/wrappers/bs1770.py | 54 +++++++++++++------ .../processing/processing.py | 1 + 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/ivas_processing_scripts/audiotools/convert/__init__.py b/ivas_processing_scripts/audiotools/convert/__init__.py index 9698dd4f..d3149054 100755 --- a/ivas_processing_scripts/audiotools/convert/__init__.py +++ b/ivas_processing_scripts/audiotools/convert/__init__.py @@ -251,7 +251,7 @@ def process_audio( logger.debug( f"Applying loudness adjustment to {loudness} LKFS for format {loudness_fmt} using ITU STL bs1770demo" ) - x.audio = loudness_norm(x, loudness, loudness_fmt) + x.audio = loudness_norm(x, loudness, loudness_fmt, logger=logger) """low-pass filtering""" if fc is not None: diff --git a/ivas_processing_scripts/audiotools/wrappers/bs1770.py b/ivas_processing_scripts/audiotools/wrappers/bs1770.py index 40cf89ce..c43319c6 100755 --- a/ivas_processing_scripts/audiotools/wrappers/bs1770.py +++ b/ivas_processing_scripts/audiotools/wrappers/bs1770.py @@ -45,9 +45,6 @@ from ivas_processing_scripts.audiotools.wrappers.filter import resample_itu from ivas_processing_scripts.constants import DEFAULT_CONFIG_BINARIES from ivas_processing_scripts.utils import find_binary, get_devnull, run -logger = logging.getLogger("__main__") -logger.setLevel(logging.DEBUG) - def bs1770demo( input: audio.Audio, @@ -131,7 +128,7 @@ def bs1770demo( write(tmp_file, tmp_sig, 48000) # run command - result = run(cmd, logger=logger) + result = run(cmd) # parse output measured_loudness = float(result.stdout.splitlines()[3].split(":")[1]) @@ -198,6 +195,8 @@ def loudness_norm( input: audio.Audio, target_loudness: Optional[float] = -26, loudness_format: Optional[str] = None, + logger: Optional[logging.Logger] = None, + file_name_logging: Optional[Union[str, Path]] = None, ) -> np.ndarray: """ Iterative loudness normalization using ITU-R BS.1770-4 @@ -212,6 +211,10 @@ def loudness_norm( Desired loudness level in LKFS loudness_format: Optional[str] Loudness format to render to for loudness computation (default input format) + logger: Optional[logging.Logger] + Logger to log loudness information + file_name_logging: Optional[Union[str, Path]] + Name of processed file for logging information Returns ------- @@ -224,10 +227,12 @@ def loudness_norm( scale_factor = 1 num_iter = 1 + # save loudness before and after scaling for the logger info + loudness_before, scale_factor_new = get_loudness( + input, target_loudness, loudness_format + ) + while np.abs(measured_loudness - target_loudness) > 0.5 and num_iter < 10: - measured_loudness, scale_factor_new = get_loudness( - input, target_loudness, loudness_format - ) # scale input input.audio *= scale_factor_new @@ -235,11 +240,25 @@ def loudness_norm( # update scale factor scale_factor *= scale_factor_new + # measure loudness and get scaling factor + measured_loudness, scale_factor_new = get_loudness( + input, target_loudness, loudness_format + ) + num_iter += 1 + loudness_after = measured_loudness + + # log loudness before and after adjustment + if logger: + if file_name_logging: + logger.debug(f"File {file_name_logging} loudness; before: {loudness_before}, after: {loudness_after}") + else: + logger.debug(f"Loudness; before: {loudness_before}, after: {loudness_after}") + if num_iter >= 10: warn( - f"Loudness did not converge to desired value, stopping at: {measured_loudness:.2f}" + f"Loudness did not converge to desired value, stopping at: {loudness_after:.2f}" ) return input.audio @@ -249,6 +268,7 @@ def scale_files( file_list: list[list[Union[Path, str]]], fmt: str, loudness: float, + loudness_format: Optional[str] = None, fs: Optional[int] = 48000, in_meta: Optional[list] = None, logger: Optional[logging.Logger] = None, @@ -264,15 +284,22 @@ def scale_files( Audio format of files in list loudness: float Desired loudness level in LKFS/dBov + loudness_format: Optional[str] + Format for loudness measurement fs: Optional[int] Sampling rate in_meta: Optional[list] Metadata for ISM with same structure as file_list but one layer more for the list of metadata for one file + logger: Optional[logging.Logger] + Logger to log loudness information """ - if fmt.startswith("ISM") and in_meta: - meta_bool = True + if fmt.startswith("ISM"): + if in_meta: + meta_bool = True + else: + raise ValueError("No metadata available for loudness measurement") else: in_meta = copy.copy(file_list) meta_bool = False @@ -285,13 +312,8 @@ def scale_files( else: audio_obj = audio.fromfile(fmt, file, fs) - # TODO: just for testing: remove later - if logger: - measured_loudness, _ = get_loudness(audio_obj) - logger.info(f"measured loudness of file {file.name} for condition {file.parent.name}: {measured_loudness}") - # adjust loudness - scaled_audio = loudness_norm(audio_obj, loudness) + scaled_audio = loudness_norm(audio_obj, loudness, loudness_format, logger, file) # write into file write(file, scaled_audio, audio_obj.fs) diff --git a/ivas_processing_scripts/processing/processing.py b/ivas_processing_scripts/processing/processing.py index c68ef1bc..e7cc42af 100755 --- a/ivas_processing_scripts/processing/processing.py +++ b/ivas_processing_scripts/processing/processing.py @@ -354,6 +354,7 @@ def reverse_process_2(cfg, logger): out_paths_splits, cfg.postprocessing["fmt"], cfg.postprocessing["loudness"], + cfg.postprocessing.get("loudness_fmt", None), cfg.postprocessing["fs"], out_meta_splits, logger, -- GitLab From 6d37df12454b0eb37328a6b1aed945b0a125933a Mon Sep 17 00:00:00 2001 From: Treffehn Date: Wed, 10 May 2023 16:00:57 +0200 Subject: [PATCH 3/7] removed loudness adjustment in postprocessing if there is concatenation --- ivas_processing_scripts/processing/chains.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/ivas_processing_scripts/processing/chains.py b/ivas_processing_scripts/processing/chains.py index bfa80451..a360c87e 100755 --- a/ivas_processing_scripts/processing/chains.py +++ b/ivas_processing_scripts/processing/chains.py @@ -192,6 +192,7 @@ def get_processing_chain( # get pre and post processing configurations pre_cfg = getattr(cfg, "preprocessing", {}) + pre2_cfg = getattr(cfg, "preprocessing_2", {}) post_cfg = cfg.postprocessing # default to input values if preprocessing was not requested @@ -383,6 +384,14 @@ def get_processing_chain( raise SystemExit(f"Unknown condition {condition}!") # add postprocessing step based on condition + # if concatenation and splitting do loudness adjustment only on splitted files + if pre2_cfg.get("concatenate_input", False): + loudness_postprocessing = None + loudness_fmt_postprocessing = None + else: + loudness_postprocessing = post_cfg.get("loudness") + loudness_fmt_postprocessing = post_cfg.get("loudness_fmt") + chain["processes"].append( Postprocessing( { @@ -391,8 +400,8 @@ def get_processing_chain( "out_fs": post_cfg.get("fs"), "out_fmt": post_cfg.get("fmt"), "out_cutoff": tmp_lp_cutoff, - "out_loudness": post_cfg.get("loudness"), - "out_loudness_fmt": post_cfg.get("loudness_fmt"), + "out_loudness": loudness_postprocessing, + "out_loudness_fmt": loudness_fmt_postprocessing, "bin_dataset": post_cfg.get("bin_dataset"), "bin_lfe_gain": post_cfg.get("bin_lfe_gain"), "limit": post_cfg.get("limit", True), -- GitLab From d336ddd7fd565b3dc2bd97fc72278f0ec6783dd3 Mon Sep 17 00:00:00 2001 From: Treffehn Date: Wed, 10 May 2023 16:47:32 +0200 Subject: [PATCH 4/7] added logging in preprocessing2 --- .../audiotools/wrappers/bs1770.py | 2 +- .../processing/preprocessing_2.py | 16 +++++++++++++--- ivas_processing_scripts/processing/processing.py | 1 + 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/ivas_processing_scripts/audiotools/wrappers/bs1770.py b/ivas_processing_scripts/audiotools/wrappers/bs1770.py index c43319c6..e35a10b3 100755 --- a/ivas_processing_scripts/audiotools/wrappers/bs1770.py +++ b/ivas_processing_scripts/audiotools/wrappers/bs1770.py @@ -252,7 +252,7 @@ def loudness_norm( # log loudness before and after adjustment if logger: if file_name_logging: - logger.debug(f"File {file_name_logging} loudness; before: {loudness_before}, after: {loudness_after}") + logger.info(f"File {file_name_logging} loudness; before: {loudness_before}, after: {loudness_after}") else: logger.debug(f"Loudness; before: {loudness_before}, after: {loudness_after}") diff --git a/ivas_processing_scripts/processing/preprocessing_2.py b/ivas_processing_scripts/processing/preprocessing_2.py index 0bacc8ee..ac55892a 100644 --- a/ivas_processing_scripts/processing/preprocessing_2.py +++ b/ivas_processing_scripts/processing/preprocessing_2.py @@ -66,6 +66,7 @@ class Preprocessing2(Processing): # add preamble if self.preamble: + logger.debug(f"Add preamble of length {self.preamble}ms") # also apply preamble to ISM metadata if self.in_fmt.startswith("ISM"): # read out old @@ -91,14 +92,21 @@ class Preprocessing2(Processing): # add background noise if self.background_noise: - audio_object.audio = self.add_background_noise(audio_object, in_meta) + logger.debug(f"Add background noise from file {self.background_noise.get('background_noise_path', 'file missing')} and SNR {self.background_noise.get('snr', 'snr missing')}") + audio_object.audio = self.add_background_noise(audio_object, in_meta, logger) # save file write(out_file, audio_object.audio, fs=audio_object.fs) return - def add_background_noise(self, audio_object: audio.Audio, in_meta) -> np.ndarray: + def add_background_noise(self, audio_object: audio.Audio, in_meta, logger) -> np.ndarray: + # check if SNR and background noise are given + if not self.background_noise["background_noise_path"] or not Path(self.background_noise["background_noise_path"]).exists(): + raise ValueError("Background noise does not exist") + if not self.background_noise["snr"]: + raise ValueError("SNR value needed for using background noise") + # range for random delay range_delay = (1, 2400000) @@ -133,6 +141,7 @@ class Preprocessing2(Processing): out_format = self.out_fmt loudness_signal, _ = get_loudness(audio_object, loudness_format=out_format) + logger.debug(f"Loudness of audio signal: {loudness_signal}LKFS") # compute desired loudness of background noise loudness_noise = loudness_signal - self.background_noise["snr"] @@ -149,7 +158,8 @@ class Preprocessing2(Processing): )[: len(audio_object.audio)] # scale background noise to desired loudness based on output format - noise_object.audio = loudness_norm(noise_object, loudness_noise, out_format) + logger.debug(f"Scaling of background noise to {self.background_noise['snr']}dB SNR") + noise_object.audio = loudness_norm(noise_object, loudness_noise, out_format, logger) # add array to signal audio_object.audio = noise_object.audio + audio_object.audio diff --git a/ivas_processing_scripts/processing/processing.py b/ivas_processing_scripts/processing/processing.py index e7cc42af..d7ed0393 100755 --- a/ivas_processing_scripts/processing/processing.py +++ b/ivas_processing_scripts/processing/processing.py @@ -324,6 +324,7 @@ def preprocess_2(cfg, logger): def reverse_process_2(cfg, logger): # remove preamble if cfg.pre2.preamble: + logger.info("Remove preamble") remove_preamble(cfg) # reverse concatenation -- GitLab From 09eace5ee449c1ee582fb8dbfff8e80ec308f34a Mon Sep 17 00:00:00 2001 From: Treffehn Date: Thu, 11 May 2023 14:04:07 +0200 Subject: [PATCH 5/7] removed loudness info from console but keep in log file --- ivas_processing_scripts/__init__.py | 2 +- .../audiotools/wrappers/bs1770.py | 13 +++++++--- ivas_processing_scripts/processing/config.py | 9 +++++-- .../processing/preprocessing_2.py | 25 ++++++++++++++----- 4 files changed, 36 insertions(+), 13 deletions(-) diff --git a/ivas_processing_scripts/__init__.py b/ivas_processing_scripts/__init__.py index 16ac8b93..4a6fa6e8 100755 --- a/ivas_processing_scripts/__init__.py +++ b/ivas_processing_scripts/__init__.py @@ -70,7 +70,7 @@ def logging_init(args, cfg): cfg.output_path.joinpath(f"{cfg.name}{LOGGER_SUFFIX}"), mode="w" ) file_handler.setFormatter(logging.Formatter(LOGGER_FORMAT, datefmt=LOGGER_DATEFMT)) - file_handler.setLevel(logging.DEBUG if args.debug else logging.INFO) + file_handler.setLevel(logging.DEBUG) logger.addHandler(file_handler) logger.info(f"Processing test configuration file {args.config}") diff --git a/ivas_processing_scripts/audiotools/wrappers/bs1770.py b/ivas_processing_scripts/audiotools/wrappers/bs1770.py index 66310540..6ea85389 100755 --- a/ivas_processing_scripts/audiotools/wrappers/bs1770.py +++ b/ivas_processing_scripts/audiotools/wrappers/bs1770.py @@ -258,9 +258,13 @@ def loudness_norm( # log loudness before and after adjustment if logger: if file_name_logging: - logger.info(f"File {file_name_logging} loudness; before: {loudness_before}, after: {loudness_after}") + logger.debug( + f"File {file_name_logging} loudness; before: {loudness_before}, after: {loudness_after}" + ) else: - logger.debug(f"Loudness; before: {loudness_before}, after: {loudness_after}") + logger.debug( + f"Loudness; before: {loudness_before}, after: {loudness_after}" + ) if num_iter >= 10: warn( @@ -319,8 +323,9 @@ def scale_files( audio_obj = audio.fromfile(fmt, file, fs) # adjust loudness - scaled_audio = loudness_norm(audio_obj, loudness, loudness_format, logger, file) + scaled_audio = loudness_norm( + audio_obj, loudness, loudness_format, logger, file + ) # write into file write(file, scaled_audio, audio_obj.fs) - diff --git a/ivas_processing_scripts/processing/config.py b/ivas_processing_scripts/processing/config.py index 7027ce75..2a3e9165 100755 --- a/ivas_processing_scripts/processing/config.py +++ b/ivas_processing_scripts/processing/config.py @@ -141,8 +141,13 @@ class TestConfig: # validate preprocessing on concatenated file stage if (pre_proc_2 := getattr(cfg, "preprocessing_2", None)) is not None: bg_noise_folder = Path(pre_proc_2["background_noise_path"]).parent - if bg_noise_folder.resolve().absolute() == cfg.input_path.resolve().absolute(): - raise ValueError(f"Background noise file has to be placed outside the input folder!") + if ( + bg_noise_folder.resolve().absolute() + == cfg.input_path.resolve().absolute() + ): + raise ValueError( + f"Background noise file has to be placed outside the input folder!" + ) for cond_name, cond_cfg in cfg.get("conditions_to_generate").items(): type = cond_cfg.get("type") diff --git a/ivas_processing_scripts/processing/preprocessing_2.py b/ivas_processing_scripts/processing/preprocessing_2.py index ac55892a..1b354ebb 100644 --- a/ivas_processing_scripts/processing/preprocessing_2.py +++ b/ivas_processing_scripts/processing/preprocessing_2.py @@ -92,17 +92,26 @@ class Preprocessing2(Processing): # add background noise if self.background_noise: - logger.debug(f"Add background noise from file {self.background_noise.get('background_noise_path', 'file missing')} and SNR {self.background_noise.get('snr', 'snr missing')}") - audio_object.audio = self.add_background_noise(audio_object, in_meta, logger) + logger.debug( + f"Add background noise from file {self.background_noise.get('background_noise_path', 'file missing')} and SNR {self.background_noise.get('snr', 'snr missing')}" + ) + audio_object.audio = self.add_background_noise( + audio_object, in_meta, logger + ) # save file write(out_file, audio_object.audio, fs=audio_object.fs) return - def add_background_noise(self, audio_object: audio.Audio, in_meta, logger) -> np.ndarray: + def add_background_noise( + self, audio_object: audio.Audio, in_meta, logger + ) -> np.ndarray: # check if SNR and background noise are given - if not self.background_noise["background_noise_path"] or not Path(self.background_noise["background_noise_path"]).exists(): + if ( + not self.background_noise["background_noise_path"] + or not Path(self.background_noise["background_noise_path"]).exists() + ): raise ValueError("Background noise does not exist") if not self.background_noise["snr"]: raise ValueError("SNR value needed for using background noise") @@ -158,8 +167,12 @@ class Preprocessing2(Processing): )[: len(audio_object.audio)] # scale background noise to desired loudness based on output format - logger.debug(f"Scaling of background noise to {self.background_noise['snr']}dB SNR") - noise_object.audio = loudness_norm(noise_object, loudness_noise, out_format, logger) + logger.debug( + f"Scaling of background noise to {self.background_noise['snr']}dB SNR" + ) + noise_object.audio = loudness_norm( + noise_object, loudness_noise, out_format, logger + ) # add array to signal audio_object.audio = noise_object.audio + audio_object.audio -- GitLab From 8f8314dae84945e6b1f602ffef70e606de72ed92 Mon Sep 17 00:00:00 2001 From: Treffehn Date: Thu, 11 May 2023 14:27:17 +0200 Subject: [PATCH 6/7] formatting --- ivas_processing_scripts/audiotools/wrappers/bs1770.py | 1 - ivas_processing_scripts/processing/config.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/ivas_processing_scripts/audiotools/wrappers/bs1770.py b/ivas_processing_scripts/audiotools/wrappers/bs1770.py index 6ea85389..f856a156 100755 --- a/ivas_processing_scripts/audiotools/wrappers/bs1770.py +++ b/ivas_processing_scripts/audiotools/wrappers/bs1770.py @@ -239,7 +239,6 @@ def loudness_norm( ) while np.abs(measured_loudness - target_loudness) > 0.5 and num_iter < 10: - # scale input input.audio *= scale_factor_new diff --git a/ivas_processing_scripts/processing/config.py b/ivas_processing_scripts/processing/config.py index 2a3e9165..a90487e6 100755 --- a/ivas_processing_scripts/processing/config.py +++ b/ivas_processing_scripts/processing/config.py @@ -146,7 +146,7 @@ class TestConfig: == cfg.input_path.resolve().absolute() ): raise ValueError( - f"Background noise file has to be placed outside the input folder!" + "Background noise file has to be placed outside the input folder!" ) for cond_name, cond_cfg in cfg.get("conditions_to_generate").items(): -- GitLab From cfdf9531331410eb4edd3bdc246d86b7641ddf95 Mon Sep 17 00:00:00 2001 From: Treffehn Date: Thu, 11 May 2023 18:37:56 +0200 Subject: [PATCH 7/7] formatting --- ivas_processing_scripts/audiotools/wrappers/bs1770.py | 6 +++++- ivas_processing_scripts/processing/preprocessing_2.py | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ivas_processing_scripts/audiotools/wrappers/bs1770.py b/ivas_processing_scripts/audiotools/wrappers/bs1770.py index 1525670d..a137eeae 100755 --- a/ivas_processing_scripts/audiotools/wrappers/bs1770.py +++ b/ivas_processing_scripts/audiotools/wrappers/bs1770.py @@ -341,7 +341,11 @@ def scale_files( # adjust loudness scaled_audio = loudness_norm( - audio_obj, loudness, loudness_format, logger=logger, file_name_logging=file, + audio_obj, + loudness, + loudness_format, + logger=logger, + file_name_logging=file, ) # write into file diff --git a/ivas_processing_scripts/processing/preprocessing_2.py b/ivas_processing_scripts/processing/preprocessing_2.py index 00129484..0da4a2fc 100644 --- a/ivas_processing_scripts/processing/preprocessing_2.py +++ b/ivas_processing_scripts/processing/preprocessing_2.py @@ -171,7 +171,11 @@ class Preprocessing2(Processing): f"Scaling of background noise to {self.background_noise['snr']}dB SNR" ) noise_object.audio = loudness_norm( - noise_object, loudness_noise, out_format, rms=True, logger=logger, + noise_object, + loudness_noise, + out_format, + rms=True, + logger=logger, ) # add array to signal -- GitLab