From e9477ed1db1ab39875027ced6290b39eb761baa4 Mon Sep 17 00:00:00 2001 From: Vladimir Malenovsky Date: Fri, 8 Aug 2025 20:29:23 +0200 Subject: [PATCH 1/2] allow -inf, n/a, ... to be used to avoid level normalization --- .../generation/generate_ismN_items.py | 37 ++++++++++++++++--- .../generation/generate_masa_items.py | 28 +++++++++++++- .../generation/generate_mc_items.py | 28 +++++++++++++- .../generation/generate_omasa_items.py | 32 ++++++++++++++-- .../generation/generate_osba_items.py | 32 ++++++++++++++-- .../generation/generate_sba_items.py | 29 ++++++++++++++- .../generation/generate_stereo_items.py | 29 ++++++++++++++- 7 files changed, 200 insertions(+), 15 deletions(-) diff --git a/ivas_processing_scripts/generation/generate_ismN_items.py b/ivas_processing_scripts/generation/generate_ismN_items.py index adec1961..35e1102a 100644 --- a/ivas_processing_scripts/generation/generate_ismN_items.py +++ b/ivas_processing_scripts/generation/generate_ismN_items.py @@ -32,6 +32,7 @@ import logging from itertools import groupby, repeat from pathlib import Path +import sys import numpy as np @@ -249,6 +250,25 @@ def generate_ismN_scene( if isinstance(scene["level"], list) else scene["level"] ) + + # check if level is "-Inf" string or "N/A" or "n/a" or "NaN" + if isinstance(level, str): + if level.lower() in ["-inf"]: + level = -np.inf + elif level.lower() in ["none", "no", "", "null", "n/a", "na", "nan"]: + level = None + else: + # convert to float + try: + level = float(level) + except ValueError: + logger.error( + f"Error: Level {level} is not a valid entry!" + ) + sys.exit(-1) + elif isinstance(level, (int, float)): + # do nothing, it is already a number + pass else: level = -26 @@ -270,11 +290,18 @@ def generate_ismN_scene( x.fs = cfg.fs # adjust the level of the audio source file (need to convert to MONO first) - x_temp = audio.ChannelBasedAudio("MONO") # create a temporary mono audio object - x_temp.audio = x.audio.copy() - x_temp.fs = x.fs - x_temp.audio, _ = loudness_norm(x_temp, level, loudness_format="MONO") - x.audio = x_temp.audio + if np.isinf(level): + # set all channels to zero + x.audio = np.zeros_like(x.audio) + elif level is None: + # do not change the level of the audio source signal + logger.info("-- Level of the audio source signal is not changed") + else: + x_temp = audio.ChannelBasedAudio("MONO") # create a temporary mono audio object + x_temp.audio = x.audio.copy() + x_temp.fs = x.fs + x_temp.audio, _ = loudness_norm(x_temp, level, loudness_format="MONO") + x.audio = x_temp.audio # ensure the length of the audio source signal is a multiple of 20ms if len(x.audio) % frame_len != 0: diff --git a/ivas_processing_scripts/generation/generate_masa_items.py b/ivas_processing_scripts/generation/generate_masa_items.py index 57ab3cbd..7d5676c0 100644 --- a/ivas_processing_scripts/generation/generate_masa_items.py +++ b/ivas_processing_scripts/generation/generate_masa_items.py @@ -247,6 +247,25 @@ def generate_MASA_scene( if isinstance(scene["level"], list) else scene["level"] ) + + # check if level is "-Inf" string or "N/A" or "n/a" or "NaN" + if isinstance(level, str): + if level.lower() in ["-inf"]: + level = -np.inf + elif level.lower() in ["none", "no", "", "null", "n/a", "na", "nan"]: + level = None + else: + # convert to float + try: + level = float(level) + except ValueError: + logger.error( + f"Error: Level {level} is not a valid entry!" + ) + sys.exit(-1) + elif isinstance(level, (int, float)): + # do nothing, it is already a number + pass else: level = -26 @@ -299,7 +318,14 @@ def generate_MASA_scene( x = reverb_hoa3(x, IR, mode=None) # adjust the level of the FOA/HOA2/HOA3 signal - x.audio, _ = loudness_norm(x, level, loudness_format="STEREO") + if np.isinf(level): + # set all channels to zero + x.audio = np.zeros_like(x.audio) + elif level is None: + # do not change the level of the audio source signal + logger.info("-- Level of the audio source signal is not changed") + else: + x.audio, _ = loudness_norm(x, level, loudness_format="STEREO") # ensure the length of the audio source signal is a multiple of 20ms if len(x.audio) % frame_len != 0: diff --git a/ivas_processing_scripts/generation/generate_mc_items.py b/ivas_processing_scripts/generation/generate_mc_items.py index 1b627e73..ac0775ce 100644 --- a/ivas_processing_scripts/generation/generate_mc_items.py +++ b/ivas_processing_scripts/generation/generate_mc_items.py @@ -247,6 +247,25 @@ def generate_MC_scene( if isinstance(scene["level"], list) else scene["level"] ) + + # check if level is "-Inf" string or "N/A" or "n/a" or "NaN" + if isinstance(level, str): + if level.lower() in ["-inf"]: + level = -np.inf + elif level.lower() in ["none", "no", "", "null", "n/a", "na", "nan"]: + level = None + else: + # convert to float + try: + level = float(level) + except ValueError: + logger.error( + f"Error: Level {level} is not a valid entry!" + ) + sys.exit(-1) + elif isinstance(level, (int, float)): + # do nothing, it is already a number + pass else: level = -26 @@ -299,7 +318,14 @@ def generate_MC_scene( x = reverb_hoa3(x, IR, mode=None) # adjust the level of the FOA/HOA2/HOA3 signal - x.audio, _ = loudness_norm(x, level, loudness_format="STEREO") + if np.isinf(level): + # set all channels to zero + x.audio = np.zeros_like(x.audio) + elif level is None: + # do not change the level of the audio source signal + logger.info("-- Level of the audio source signal is not changed") + else: + x.audio, _ = loudness_norm(x, level, loudness_format="STEREO") # ensure the length of the audio source signal is a multiple of 20ms if len(x.audio) % frame_len != 0: diff --git a/ivas_processing_scripts/generation/generate_omasa_items.py b/ivas_processing_scripts/generation/generate_omasa_items.py index 972ee69a..cff89937 100644 --- a/ivas_processing_scripts/generation/generate_omasa_items.py +++ b/ivas_processing_scripts/generation/generate_omasa_items.py @@ -244,6 +244,25 @@ def generate_OMASA_scene( if isinstance(scene["level"], list) else scene["level"] ) + + # check if level is "-Inf" string or "N/A" or "n/a" or "NaN" + if isinstance(level, str): + if level.lower() in ["-inf"]: + level = -np.inf + elif level.lower() in ["none", "no", "", "null", "n/a", "na", "nan"]: + level = None + else: + # convert to float + try: + level = float(level) + except ValueError: + logger.error( + f"Error: Level {level} is not a valid entry!" + ) + sys.exit(-1) + elif isinstance(level, (int, float)): + # do nothing, it is already a number + pass else: level = -26 @@ -284,10 +303,17 @@ def generate_OMASA_scene( x.fs = cfg.fs # adjust the level of the source file - if fmt in ["FOA", "HOA2", "HOA3"]: - x.audio, _ = loudness_norm(x, level, loudness_format="STEREO") + if np.isinf(level): + # set all channels to zero + x.audio = np.zeros_like(x.audio) + elif level is None: + # do not change the level of the audio source signal + logger.info("-- Level of the audio source signal is not changed") else: - x.audio, _ = loudness_norm(x, level, loudness_format="MONO") + if fmt in ["FOA", "HOA2", "HOA3"]: + x.audio, _ = loudness_norm(x, level, loudness_format="STEREO") + else: + x.audio, _ = loudness_norm(x, level, loudness_format="MONO") # ensure the length of the audio source signal is a multiple of 20ms if len(x.audio) % frame_len != 0: diff --git a/ivas_processing_scripts/generation/generate_osba_items.py b/ivas_processing_scripts/generation/generate_osba_items.py index 156c3d2d..c9378505 100644 --- a/ivas_processing_scripts/generation/generate_osba_items.py +++ b/ivas_processing_scripts/generation/generate_osba_items.py @@ -235,6 +235,25 @@ def generate_OSBA_scene( if isinstance(scene["level"], list) else scene["level"] ) + + # check if level is "-Inf" string or "N/A" or "n/a" or "NaN" + if isinstance(level, str): + if level.lower() in ["-inf"]: + level = -np.inf + elif level.lower() in ["none", "no", "", "null", "n/a", "na", "nan"]: + level = None + else: + # convert to float + try: + level = float(level) + except ValueError: + logger.error( + f"Error: Level {level} is not a valid entry!" + ) + sys.exit(-1) + elif isinstance(level, (int, float)): + # do nothing, it is already a number + pass else: level = -26 @@ -275,10 +294,17 @@ def generate_OSBA_scene( x.fs = cfg.fs # adjust the level of the source file - if fmt in ["FOA", "HOA2", "HOA3"]: - x.audio, _ = loudness_norm(x, level, loudness_format="STEREO") + if np.isinf(level): + # set all channels to zero + x.audio = np.zeros_like(x.audio) + elif level is None: + # do not change the level of the audio source signal + logger.info("-- Level of the audio source signal is not changed") else: - x.audio, _ = loudness_norm(x, level, loudness_format="MONO") + if fmt in ["FOA", "HOA2", "HOA3"]: + x.audio, _ = loudness_norm(x, level, loudness_format="STEREO") + else: + x.audio, _ = loudness_norm(x, level, loudness_format="MONO") # ensure the length of the audio source signal is a multiple of 20ms if len(x.audio) % frame_len != 0: diff --git a/ivas_processing_scripts/generation/generate_sba_items.py b/ivas_processing_scripts/generation/generate_sba_items.py index feadf510..a3d8d3c8 100644 --- a/ivas_processing_scripts/generation/generate_sba_items.py +++ b/ivas_processing_scripts/generation/generate_sba_items.py @@ -33,6 +33,7 @@ import logging from itertools import groupby, repeat from pathlib import Path +import sys import numpy as np @@ -238,6 +239,25 @@ def generate_sba_scene( if isinstance(scene["level"], list) else scene["level"] ) + + # check if level is "-Inf" string or "N/A" or "n/a" or "NaN" + if isinstance(level, str): + if level.lower() in ["-inf"]: + level = -np.inf + elif level.lower() in ["none", "no", "", "null", "n/a", "na", "nan"]: + level = None + else: + # convert to float + try: + level = float(level) + except ValueError: + logger.error( + f"Error: Level {level} is not a valid entry!" + ) + sys.exit(-1) + elif isinstance(level, (int, float)): + # do nothing, it is already a number + pass else: level = -26 @@ -269,7 +289,14 @@ def generate_sba_scene( x = reverb_hoa3(x, IR, mode=None) # adjust the level of the FOA/HOA2/HOA3 signal - x.audio, _ = loudness_norm(x, level, loudness_format="STEREO") + if np.isinf(level): + # set all channels to zero + x.audio = np.zeros_like(x.audio) + elif level is None: + # do not change the level of the audio source signal + logger.info("-- Level of the audio source signal is not changed") + else: + x.audio, _ = loudness_norm(x, level, loudness_format="STEREO") # ensure the length of the audio source signal is a multiple of 20ms if len(x.audio) % frame_len != 0: diff --git a/ivas_processing_scripts/generation/generate_stereo_items.py b/ivas_processing_scripts/generation/generate_stereo_items.py index 2cd80fe5..b43e7fc7 100644 --- a/ivas_processing_scripts/generation/generate_stereo_items.py +++ b/ivas_processing_scripts/generation/generate_stereo_items.py @@ -34,6 +34,7 @@ import logging import os from itertools import groupby, repeat from pathlib import Path +import sys import numpy as np @@ -244,6 +245,25 @@ def generate_stereo_scene( if isinstance(scene["level"], list) else scene["level"] ) + + # check if level is "-Inf" string or "N/A" or "n/a" or "NaN" + if isinstance(level, str): + if level.lower() in ["-inf"]: + level = -np.inf + elif level.lower() in ["none", "no", "", "null", "n/a", "na", "nan"]: + level = None + else: + # convert to float + try: + level = float(level) + except ValueError: + logger.error( + f"Error: Level {level} is not a valid entry!" + ) + sys.exit(-1) + elif isinstance(level, (int, float)): + # do nothing, it is already a number + pass else: level = -26 @@ -270,7 +290,14 @@ def generate_stereo_scene( x = reverb_stereo(x, IR, mode=None) # adjust the level of the STEREO signal - x.audio, _ = loudness_norm(x, level, loudness_format="STEREO") + if np.isinf(level): + # set all channels to zero + x.audio = np.zeros_like(x.audio) + elif level is None: + # do not change the level of the audio source signal + logger.info("-- Level of the audio source signal is not changed") + else: + x.audio, _ = loudness_norm(x, level, loudness_format="STEREO") # ensure the length of the audio source signal is a multiple of 20ms if len(x.audio) % frame_len != 0: -- GitLab From d8876df9b057b4626e8502eb57e272ef95cca38d Mon Sep 17 00:00:00 2001 From: Vladimir Malenovsky Date: Fri, 8 Aug 2025 20:33:00 +0200 Subject: [PATCH 2/2] fix formatting --- .../generation/generate_ismN_items.py | 10 +++++----- .../generation/generate_masa_items.py | 4 +--- .../generation/generate_mc_items.py | 4 +--- .../generation/generate_omasa_items.py | 4 +--- .../generation/generate_osba_items.py | 4 +--- .../generation/generate_sba_items.py | 6 ++---- .../generation/generate_stereo_items.py | 6 ++---- 7 files changed, 13 insertions(+), 25 deletions(-) diff --git a/ivas_processing_scripts/generation/generate_ismN_items.py b/ivas_processing_scripts/generation/generate_ismN_items.py index 35e1102a..a19acd6e 100644 --- a/ivas_processing_scripts/generation/generate_ismN_items.py +++ b/ivas_processing_scripts/generation/generate_ismN_items.py @@ -30,9 +30,9 @@ # the United Nations Convention on Contracts on the International Sales of Goods. # import logging +import sys from itertools import groupby, repeat from pathlib import Path -import sys import numpy as np @@ -262,9 +262,7 @@ def generate_ismN_scene( try: level = float(level) except ValueError: - logger.error( - f"Error: Level {level} is not a valid entry!" - ) + logger.error(f"Error: Level {level} is not a valid entry!") sys.exit(-1) elif isinstance(level, (int, float)): # do nothing, it is already a number @@ -297,7 +295,9 @@ def generate_ismN_scene( # do not change the level of the audio source signal logger.info("-- Level of the audio source signal is not changed") else: - x_temp = audio.ChannelBasedAudio("MONO") # create a temporary mono audio object + x_temp = audio.ChannelBasedAudio( + "MONO" + ) # create a temporary mono audio object x_temp.audio = x.audio.copy() x_temp.fs = x.fs x_temp.audio, _ = loudness_norm(x_temp, level, loudness_format="MONO") diff --git a/ivas_processing_scripts/generation/generate_masa_items.py b/ivas_processing_scripts/generation/generate_masa_items.py index 7d5676c0..7a0e020c 100644 --- a/ivas_processing_scripts/generation/generate_masa_items.py +++ b/ivas_processing_scripts/generation/generate_masa_items.py @@ -259,9 +259,7 @@ def generate_MASA_scene( try: level = float(level) except ValueError: - logger.error( - f"Error: Level {level} is not a valid entry!" - ) + logger.error(f"Error: Level {level} is not a valid entry!") sys.exit(-1) elif isinstance(level, (int, float)): # do nothing, it is already a number diff --git a/ivas_processing_scripts/generation/generate_mc_items.py b/ivas_processing_scripts/generation/generate_mc_items.py index ac0775ce..29e6b661 100644 --- a/ivas_processing_scripts/generation/generate_mc_items.py +++ b/ivas_processing_scripts/generation/generate_mc_items.py @@ -259,9 +259,7 @@ def generate_MC_scene( try: level = float(level) except ValueError: - logger.error( - f"Error: Level {level} is not a valid entry!" - ) + logger.error(f"Error: Level {level} is not a valid entry!") sys.exit(-1) elif isinstance(level, (int, float)): # do nothing, it is already a number diff --git a/ivas_processing_scripts/generation/generate_omasa_items.py b/ivas_processing_scripts/generation/generate_omasa_items.py index cff89937..13fc3470 100644 --- a/ivas_processing_scripts/generation/generate_omasa_items.py +++ b/ivas_processing_scripts/generation/generate_omasa_items.py @@ -256,9 +256,7 @@ def generate_OMASA_scene( try: level = float(level) except ValueError: - logger.error( - f"Error: Level {level} is not a valid entry!" - ) + logger.error(f"Error: Level {level} is not a valid entry!") sys.exit(-1) elif isinstance(level, (int, float)): # do nothing, it is already a number diff --git a/ivas_processing_scripts/generation/generate_osba_items.py b/ivas_processing_scripts/generation/generate_osba_items.py index c9378505..29ff66a7 100644 --- a/ivas_processing_scripts/generation/generate_osba_items.py +++ b/ivas_processing_scripts/generation/generate_osba_items.py @@ -247,9 +247,7 @@ def generate_OSBA_scene( try: level = float(level) except ValueError: - logger.error( - f"Error: Level {level} is not a valid entry!" - ) + logger.error(f"Error: Level {level} is not a valid entry!") sys.exit(-1) elif isinstance(level, (int, float)): # do nothing, it is already a number diff --git a/ivas_processing_scripts/generation/generate_sba_items.py b/ivas_processing_scripts/generation/generate_sba_items.py index a3d8d3c8..4f95bf98 100644 --- a/ivas_processing_scripts/generation/generate_sba_items.py +++ b/ivas_processing_scripts/generation/generate_sba_items.py @@ -31,9 +31,9 @@ # import logging +import sys from itertools import groupby, repeat from pathlib import Path -import sys import numpy as np @@ -251,9 +251,7 @@ def generate_sba_scene( try: level = float(level) except ValueError: - logger.error( - f"Error: Level {level} is not a valid entry!" - ) + logger.error(f"Error: Level {level} is not a valid entry!") sys.exit(-1) elif isinstance(level, (int, float)): # do nothing, it is already a number diff --git a/ivas_processing_scripts/generation/generate_stereo_items.py b/ivas_processing_scripts/generation/generate_stereo_items.py index b43e7fc7..8b616e64 100644 --- a/ivas_processing_scripts/generation/generate_stereo_items.py +++ b/ivas_processing_scripts/generation/generate_stereo_items.py @@ -32,9 +32,9 @@ import logging import os +import sys from itertools import groupby, repeat from pathlib import Path -import sys import numpy as np @@ -257,9 +257,7 @@ def generate_stereo_scene( try: level = float(level) except ValueError: - logger.error( - f"Error: Level {level} is not a valid entry!" - ) + logger.error(f"Error: Level {level} is not a valid entry!") sys.exit(-1) elif isinstance(level, (int, float)): # do nothing, it is already a number -- GitLab