Loading ivas_processing_scripts/audiotools/wrappers/reverb.py +67 −0 Original line number Diff line number Diff line Loading @@ -184,3 +184,70 @@ def reverb_stereo( y.audio = np.column_stack([y_left.audio, y_right.audio]) return y def reverb_foa( input: Audio, foa_IR: Audio, align: Optional[float] = None, ) -> Audio: """ Wrapper for the ITU-T reverb binary to convolve mono audio signal with an FOA impulse response Parameters ---------- input: Audio Input audio signal IR: Audio Impulse response align: float multiplicative factor to apply to the reverberated sound in order to align its energy level with the second file Returns ------- output: Audio Convolved audio signal with FOA IR """ # convert to float32 foa_IR.audio = np.float32(foa_IR.audio) # separate into each channel IR_w = copy(foa_IR) IR_w.name = "MONO" IR_w.num_channels = 1 IR_w.audio = np.reshape(foa_IR.audio[:, 0], (-1, 1)) IR_x = copy(foa_IR) IR_x.name = "MONO" IR_x.num_channels = 1 IR_x.audio = np.reshape(foa_IR.audio[:, 1], (-1, 1)) IR_y = copy(foa_IR) IR_y.name = "MONO" IR_y.num_channels = 1 IR_y.audio = np.reshape(foa_IR.audio[:, 2], (-1, 1)) IR_z = copy(foa_IR) IR_z.name = "MONO" IR_z.num_channels = 1 IR_z.audio = np.reshape(foa_IR.audio[:, 3], (-1, 1)) # calculate the scaling (multiplicative) factor such that the maximum gain of the IR filter across all frequencies is 0dB if align is None: H = fft(foa_IR.audio, axis=0) align = 1.0 / np.max(np.abs(H)) # convolve mono input with left and right IR y_w = reverb(input, IR_w, align=align) y_x = reverb(input, IR_x, align=align) y_y = reverb(input, IR_y, align=align) y_z = reverb(input, IR_z, align=align) # combine into foa output y = copy(input) y.name = "FOA" y.num_channels = 4 y.audio = np.column_stack([y_w.audio, y_x.audio, y_y.audio, y_z.audio]) return y ivas_processing_scripts/generation/process_foa_items.py +2 −115 Original line number Diff line number Diff line Loading @@ -32,17 +32,13 @@ import logging import os from copy import copy from math import floor from typing import Optional import numpy as np import scipy.signal as ssg from scipy.fft import fft from ivas_processing_scripts.audiotools import audio, audiofile from ivas_processing_scripts.audiotools.audio import Audio from ivas_processing_scripts.audiotools.wrappers.bs1770 import get_loudness from ivas_processing_scripts.audiotools.wrappers.reverb import reverb_foa from ivas_processing_scripts.generation import config SEED_RANDOM_NOISE = 0 Loading @@ -54,112 +50,6 @@ def csv_formatdata(data): yield ["%0.2f" % v for v in row] def filter_one( input: Audio, IR: Audio, align: Optional[float] = None, ) -> Audio: """ Parameters ---------- input: Audio Input audio signal IR: Audio Impulse response align: float multiplicative factor to apply to the reverberated sound in order to align its energy level with a second filePath to the output file Returns ------- output: Audio Convolved audio signal with IR """ # resample IR to input signal tmp_IR = copy(IR) if input.fs != IR.fs: tmp_IR.audio = ssg.resample_poly(IR.audio, input.fs, IR.fs) tmp_IR.fs = input.fs # down-scale IR to prevent saturation # max_value = np.max(np.abs(IR.audio)) # if max_value > 1.0: # IR.audio = IR.audio / max_value tmp_IR.audio = tmp_IR.audio * align output = copy(input) intranspose = input.audio.transpose() outfilt = ssg.lfilter(tmp_IR.audio, [1.0], intranspose) output.audio = outfilt.transpose() return output def filter_foa( input: Audio, foa_IR: Audio, align: Optional[float] = None, ) -> Audio: """ Parameters ---------- input: Audio Input audio signal IR: Audio Impulse response align: float multiplicative factor to apply to the reverberated sound in order to align its energy level with the second file Returns ------- output: Audio Convolved audio signal with FOA IR """ # convert to float32 foa_IR.audio = np.float32(foa_IR.audio) # separate into each channel IR_w = copy(foa_IR) IR_w.name = "MONO" IR_w.num_channels = 1 IR_w.audio = foa_IR.audio[:, 0] IR_x = copy(foa_IR) IR_x.name = "MONO" IR_x.num_channels = 1 IR_x.audio = foa_IR.audio[:, 1] IR_y = copy(foa_IR) IR_y.name = "MONO" IR_y.num_channels = 1 IR_y.audio = foa_IR.audio[:, 2] IR_z = copy(foa_IR) IR_z.name = "MONO" IR_z.num_channels = 1 IR_z.audio = foa_IR.audio[:, 3] # calculate the scaling (multiplicative) factor such that the maximum gain of the IR filter across all frequencies is 0dB if align is None: H = fft(foa_IR.audio, axis=0) align = 1.0 / np.max(np.abs(H)) # convolve mono input with left and right IR y_w = filter_one(input, IR_w, align=align) y_x = filter_one(input, IR_x, align=align) y_y = filter_one(input, IR_y, align=align) y_z = filter_one(input, IR_z, align=align) # combine into foa output y = copy(input) y.name = "FOA" y.num_channels = 4 y.audio = np.column_stack([y_w.audio, y_x.audio, y_y.audio, y_z.audio]) return y def generate_foa_items( cfg: config.TestConfig, logger: logging.Logger, Loading Loading @@ -205,9 +95,6 @@ def generate_foa_items( # extract the number of audio sources N_sources = len(np.atleast_1d(scene["source"])) # read the IR (check if foa or two mono files were provided) # source_IR = np.atleast_1d(scene["IR"]) # read the overlap length if "overlap" in scene.keys(): source_overlap = float(scene["overlap"]) Loading @@ -231,7 +118,7 @@ def generate_foa_items( IR = audio.fromfile("FOA", os.path.join(cfg.IR_path, IR_file), fs=cfg.IR_fs) # convolve with FOA IR x = filter_foa(x, IR) x = reverb_foa(x, IR) # adjust the level of the foa signal _, scale_factor, _ = get_loudness(x, cfg.loudness, "BINAURAL") Loading Loading
ivas_processing_scripts/audiotools/wrappers/reverb.py +67 −0 Original line number Diff line number Diff line Loading @@ -184,3 +184,70 @@ def reverb_stereo( y.audio = np.column_stack([y_left.audio, y_right.audio]) return y def reverb_foa( input: Audio, foa_IR: Audio, align: Optional[float] = None, ) -> Audio: """ Wrapper for the ITU-T reverb binary to convolve mono audio signal with an FOA impulse response Parameters ---------- input: Audio Input audio signal IR: Audio Impulse response align: float multiplicative factor to apply to the reverberated sound in order to align its energy level with the second file Returns ------- output: Audio Convolved audio signal with FOA IR """ # convert to float32 foa_IR.audio = np.float32(foa_IR.audio) # separate into each channel IR_w = copy(foa_IR) IR_w.name = "MONO" IR_w.num_channels = 1 IR_w.audio = np.reshape(foa_IR.audio[:, 0], (-1, 1)) IR_x = copy(foa_IR) IR_x.name = "MONO" IR_x.num_channels = 1 IR_x.audio = np.reshape(foa_IR.audio[:, 1], (-1, 1)) IR_y = copy(foa_IR) IR_y.name = "MONO" IR_y.num_channels = 1 IR_y.audio = np.reshape(foa_IR.audio[:, 2], (-1, 1)) IR_z = copy(foa_IR) IR_z.name = "MONO" IR_z.num_channels = 1 IR_z.audio = np.reshape(foa_IR.audio[:, 3], (-1, 1)) # calculate the scaling (multiplicative) factor such that the maximum gain of the IR filter across all frequencies is 0dB if align is None: H = fft(foa_IR.audio, axis=0) align = 1.0 / np.max(np.abs(H)) # convolve mono input with left and right IR y_w = reverb(input, IR_w, align=align) y_x = reverb(input, IR_x, align=align) y_y = reverb(input, IR_y, align=align) y_z = reverb(input, IR_z, align=align) # combine into foa output y = copy(input) y.name = "FOA" y.num_channels = 4 y.audio = np.column_stack([y_w.audio, y_x.audio, y_y.audio, y_z.audio]) return y
ivas_processing_scripts/generation/process_foa_items.py +2 −115 Original line number Diff line number Diff line Loading @@ -32,17 +32,13 @@ import logging import os from copy import copy from math import floor from typing import Optional import numpy as np import scipy.signal as ssg from scipy.fft import fft from ivas_processing_scripts.audiotools import audio, audiofile from ivas_processing_scripts.audiotools.audio import Audio from ivas_processing_scripts.audiotools.wrappers.bs1770 import get_loudness from ivas_processing_scripts.audiotools.wrappers.reverb import reverb_foa from ivas_processing_scripts.generation import config SEED_RANDOM_NOISE = 0 Loading @@ -54,112 +50,6 @@ def csv_formatdata(data): yield ["%0.2f" % v for v in row] def filter_one( input: Audio, IR: Audio, align: Optional[float] = None, ) -> Audio: """ Parameters ---------- input: Audio Input audio signal IR: Audio Impulse response align: float multiplicative factor to apply to the reverberated sound in order to align its energy level with a second filePath to the output file Returns ------- output: Audio Convolved audio signal with IR """ # resample IR to input signal tmp_IR = copy(IR) if input.fs != IR.fs: tmp_IR.audio = ssg.resample_poly(IR.audio, input.fs, IR.fs) tmp_IR.fs = input.fs # down-scale IR to prevent saturation # max_value = np.max(np.abs(IR.audio)) # if max_value > 1.0: # IR.audio = IR.audio / max_value tmp_IR.audio = tmp_IR.audio * align output = copy(input) intranspose = input.audio.transpose() outfilt = ssg.lfilter(tmp_IR.audio, [1.0], intranspose) output.audio = outfilt.transpose() return output def filter_foa( input: Audio, foa_IR: Audio, align: Optional[float] = None, ) -> Audio: """ Parameters ---------- input: Audio Input audio signal IR: Audio Impulse response align: float multiplicative factor to apply to the reverberated sound in order to align its energy level with the second file Returns ------- output: Audio Convolved audio signal with FOA IR """ # convert to float32 foa_IR.audio = np.float32(foa_IR.audio) # separate into each channel IR_w = copy(foa_IR) IR_w.name = "MONO" IR_w.num_channels = 1 IR_w.audio = foa_IR.audio[:, 0] IR_x = copy(foa_IR) IR_x.name = "MONO" IR_x.num_channels = 1 IR_x.audio = foa_IR.audio[:, 1] IR_y = copy(foa_IR) IR_y.name = "MONO" IR_y.num_channels = 1 IR_y.audio = foa_IR.audio[:, 2] IR_z = copy(foa_IR) IR_z.name = "MONO" IR_z.num_channels = 1 IR_z.audio = foa_IR.audio[:, 3] # calculate the scaling (multiplicative) factor such that the maximum gain of the IR filter across all frequencies is 0dB if align is None: H = fft(foa_IR.audio, axis=0) align = 1.0 / np.max(np.abs(H)) # convolve mono input with left and right IR y_w = filter_one(input, IR_w, align=align) y_x = filter_one(input, IR_x, align=align) y_y = filter_one(input, IR_y, align=align) y_z = filter_one(input, IR_z, align=align) # combine into foa output y = copy(input) y.name = "FOA" y.num_channels = 4 y.audio = np.column_stack([y_w.audio, y_x.audio, y_y.audio, y_z.audio]) return y def generate_foa_items( cfg: config.TestConfig, logger: logging.Logger, Loading Loading @@ -205,9 +95,6 @@ def generate_foa_items( # extract the number of audio sources N_sources = len(np.atleast_1d(scene["source"])) # read the IR (check if foa or two mono files were provided) # source_IR = np.atleast_1d(scene["IR"]) # read the overlap length if "overlap" in scene.keys(): source_overlap = float(scene["overlap"]) Loading @@ -231,7 +118,7 @@ def generate_foa_items( IR = audio.fromfile("FOA", os.path.join(cfg.IR_path, IR_file), fs=cfg.IR_fs) # convolve with FOA IR x = filter_foa(x, IR) x = reverb_foa(x, IR) # adjust the level of the foa signal _, scale_factor, _ = get_loudness(x, cfg.loudness, "BINAURAL") Loading