Index: webrtc/modules/audio_processing/test/py_quality_assessment/quality_assessment/noise_generation.py |
diff --git a/webrtc/modules/audio_processing/test/py_quality_assessment/quality_assessment/noise_generation.py b/webrtc/modules/audio_processing/test/py_quality_assessment/quality_assessment/noise_generation.py |
index 9bfce34db25e851770ac2ed6dc5fa589c1cf3eda..090d3506ab8cb78bb319083a90d706fa9469e652 100644 |
--- a/webrtc/modules/audio_processing/test/py_quality_assessment/quality_assessment/noise_generation.py |
+++ b/webrtc/modules/audio_processing/test/py_quality_assessment/quality_assessment/noise_generation.py |
@@ -47,23 +47,34 @@ class NoiseGenerator(object): |
signal. |
A noise generator generates one or more input-reference pairs. |
+ |
+ TODO(alessiob): Rename from NoiseGenerator to InputReferencePairGenerator. |
""" |
NAME = None |
REGISTERED_CLASSES = {} |
def __init__(self): |
- # Input |
+ # Init dictionaries with one entry for each noise generator configuration |
+ # (e.g., different SNRs). |
+ # Noisy audio track files (stored separately in a cache folder). |
self._noisy_signal_filepaths = None |
- self._output_paths = None |
+ # Path to be used for the APM simulation output files. |
+ self._apm_output_paths = None |
+ # Reference audio track files (stored separately in a cache folder). |
self._reference_signal_filepaths = None |
- self.clear() |
+ self.Clear() |
@classmethod |
- def register_class(cls, class_to_register): |
- """Register an NoiseGenerator implementation. |
+ def RegisterClass(cls, class_to_register): |
+ """Registers an NoiseGenerator implementation. |
Decorator to automatically register the classes that extend NoiseGenerator. |
+ Example usage: |
+ |
+ @NoiseGenerator.RegisterClass |
+ class IdentityGenerator(NoiseGenerator): |
+ pass |
""" |
cls.REGISTERED_CLASSES[class_to_register.NAME] = class_to_register |
return class_to_register |
@@ -77,37 +88,44 @@ class NoiseGenerator(object): |
return self._noisy_signal_filepaths |
@property |
- def output_paths(self): |
- return self._output_paths |
+ def apm_output_paths(self): |
+ return self._apm_output_paths |
@property |
def reference_signal_filepaths(self): |
return self._reference_signal_filepaths |
- def generate( |
+ def Generate( |
self, input_signal_filepath, input_noise_cache_path, base_output_path): |
- """Generate a set of noisy input and reference audiotrack file pairs. |
+ """Generates a set of noisy input and reference audiotrack file pairs. |
- This method initializes an empty set of pairs and calls the _generate() |
+ This method initializes an empty set of pairs and calls the _Generate() |
method implemented in a concrete class. |
+ |
+ Args: |
+ input_signal_filepath: path to the clean input audio track file. |
+ input_noise_cache_path: path to the cache of noisy audio track files. |
+ base_output_path: base path where output is written. |
""" |
- self.clear() |
- return self._generate( |
+ self.Clear() |
+ self._Generate( |
input_signal_filepath, input_noise_cache_path, base_output_path) |
- def clear(self): |
+ def Clear(self): |
+ """Clears the generated output path dictionaries. |
+ """ |
self._noisy_signal_filepaths = {} |
- self._output_paths = {} |
+ self._apm_output_paths = {} |
self._reference_signal_filepaths = {} |
- def _generate( |
+ def _Generate( |
self, input_signal_filepath, input_noise_cache_path, base_output_path): |
- """This is an abstract method to be implemented in each concrete class. |
+ """Abstract method to be implemented in each concrete class. |
""" |
raise NotImplementedError() |
- def _add_noise_snr_pairs(self, base_output_path, noisy_mix_filepaths, |
- snr_value_pairs): |
+ def _AddNoiseSnrPairs(self, base_output_path, noisy_mix_filepaths, |
+ snr_value_pairs): |
"""Adds noisy-reference signal pairs. |
Args: |
@@ -120,8 +138,8 @@ class NoiseGenerator(object): |
for snr_noisy, snr_refence in snr_value_pairs: |
config_name = '{0}_{1:d}_{2:d}_SNR'.format( |
noise_track_name, snr_noisy, snr_refence) |
- output_path = self._make_dir(base_output_path, config_name) |
- self._add_noise_reference_files_pair( |
+ output_path = self._MakeDir(base_output_path, config_name) |
+ self._AddNoiseReferenceFilesPair( |
config_name=config_name, |
noisy_signal_filepath=noisy_mix_filepaths[ |
noise_track_name][snr_noisy], |
@@ -129,30 +147,38 @@ class NoiseGenerator(object): |
noise_track_name][snr_refence], |
output_path=output_path) |
- def _add_noise_reference_files_pair(self, config_name, noisy_signal_filepath, |
- reference_signal_filepath, output_path): |
+ def _AddNoiseReferenceFilesPair(self, config_name, noisy_signal_filepath, |
+ reference_signal_filepath, output_path): |
+ """Adds one noisy-reference signal pair. |
+ |
+ Args: |
+ config_name: name of the APM configuration. |
+ noisy_signal_filepath: path to noisy audio track file. |
+ reference_signal_filepath: path to reference audio track file. |
+ output_path: APM output path. |
+ """ |
assert config_name not in self._noisy_signal_filepaths |
self._noisy_signal_filepaths[config_name] = os.path.abspath( |
noisy_signal_filepath) |
- self._output_paths[config_name] = os.path.abspath(output_path) |
+ self._apm_output_paths[config_name] = os.path.abspath(output_path) |
self._reference_signal_filepaths[config_name] = os.path.abspath( |
reference_signal_filepath) |
# Save noisy and reference file paths. |
- data_access.Metadata.save_audio_in_ref_paths( |
+ data_access.Metadata.SaveAudioInRefPaths( |
output_path=output_path, |
audio_in_filepath=self._noisy_signal_filepaths[config_name], |
audio_ref_filepath=self._reference_signal_filepaths[config_name]) |
@classmethod |
- def _make_dir(cls, base_output_path, noise_generator_config_name): |
+ def _MakeDir(cls, base_output_path, noise_generator_config_name): |
output_path = os.path.join(base_output_path, noise_generator_config_name) |
- data_access.make_directory(output_path) |
+ data_access.MakeDirectory(output_path) |
return output_path |
# Identity generator. |
-@NoiseGenerator.register_class |
+@NoiseGenerator.RegisterClass |
class IdentityGenerator(NoiseGenerator): |
"""Generator that adds no noise. |
@@ -164,18 +190,18 @@ class IdentityGenerator(NoiseGenerator): |
def __init__(self): |
NoiseGenerator.__init__(self) |
- def _generate( |
+ def _Generate( |
self, input_signal_filepath, input_noise_cache_path, base_output_path): |
CONFIG_NAME = 'default' |
- output_path = self._make_dir(base_output_path, CONFIG_NAME) |
- self._add_noise_reference_files_pair( |
+ output_path = self._MakeDir(base_output_path, CONFIG_NAME) |
+ self._AddNoiseReferenceFilesPair( |
config_name=CONFIG_NAME, |
noisy_signal_filepath=input_signal_filepath, |
reference_signal_filepath=input_signal_filepath, |
output_path=output_path) |
-@NoiseGenerator.register_class |
+@NoiseGenerator.RegisterClass |
class WhiteNoiseGenerator(NoiseGenerator): |
"""Additive white noise generator. |
""" |
@@ -197,18 +223,18 @@ class WhiteNoiseGenerator(NoiseGenerator): |
def __init__(self): |
NoiseGenerator.__init__(self) |
- def _generate( |
+ def _Generate( |
self, input_signal_filepath, input_noise_cache_path, base_output_path): |
# Load the input signal. |
- input_signal = signal_processing.SignalProcessingUtils.load_wav( |
+ input_signal = signal_processing.SignalProcessingUtils.LoadWav( |
input_signal_filepath) |
- input_signal = signal_processing.SignalProcessingUtils.normalize( |
+ input_signal = signal_processing.SignalProcessingUtils.Normalize( |
input_signal) |
# Create the noise track. |
- noise_signal = signal_processing.SignalProcessingUtils.generate_white_noise( |
+ noise_signal = signal_processing.SignalProcessingUtils.GenerateWhiteNoise( |
input_signal) |
- noise_signal = signal_processing.SignalProcessingUtils.normalize( |
+ noise_signal = signal_processing.SignalProcessingUtils.Normalize( |
noise_signal) |
# Create the noisy mixes (once for each unique SNR value). |
@@ -222,11 +248,11 @@ class WhiteNoiseGenerator(NoiseGenerator): |
# Create and save if not done. |
if not os.path.exists(noisy_signal_filepath): |
# Create noisy signal. |
- noisy_signal = signal_processing.SignalProcessingUtils.mix_signals( |
+ noisy_signal = signal_processing.SignalProcessingUtils.MixSignals( |
input_signal, noise_signal, snr) |
# Save. |
- signal_processing.SignalProcessingUtils.save_wav( |
+ signal_processing.SignalProcessingUtils.SaveWav( |
noisy_signal_filepath, noisy_signal) |
# Add file to the collection of mixes. |
@@ -235,8 +261,8 @@ class WhiteNoiseGenerator(NoiseGenerator): |
# Add all the noisy-reference signal pairs. |
for snr_noisy, snr_refence in self._SNR_VALUE_PAIRS: |
config_name = '{0:d}_{1:d}_SNR'.format(snr_noisy, snr_refence) |
- output_path = self._make_dir(base_output_path, config_name) |
- self._add_noise_reference_files_pair( |
+ output_path = self._MakeDir(base_output_path, config_name) |
+ self._AddNoiseReferenceFilesPair( |
config_name=config_name, |
noisy_signal_filepath=noisy_mix_filepaths[snr_noisy], |
reference_signal_filepath=noisy_mix_filepaths[snr_refence], |
@@ -244,7 +270,7 @@ class WhiteNoiseGenerator(NoiseGenerator): |
# TODO(alessiob): remove comment when class implemented. |
-# @NoiseGenerator.register_class |
+# @NoiseGenerator.RegisterClass |
class NarrowBandNoiseGenerator(NoiseGenerator): |
"""Additive narrow-band noise generator. |
""" |
@@ -254,13 +280,13 @@ class NarrowBandNoiseGenerator(NoiseGenerator): |
def __init__(self): |
NoiseGenerator.__init__(self) |
- def _generate( |
+ def _Generate( |
self, input_signal_filepath, input_noise_cache_path, base_output_path): |
# TODO(alessiob): implement. |
pass |
-@NoiseGenerator.register_class |
+@NoiseGenerator.RegisterClass |
class EnvironmentalNoiseGenerator(NoiseGenerator): |
"""Additive environmental noise generator. |
""" |
@@ -290,27 +316,22 @@ class EnvironmentalNoiseGenerator(NoiseGenerator): |
def __init__(self): |
NoiseGenerator.__init__(self) |
- def _generate( |
+ def _Generate( |
self, input_signal_filepath, input_noise_cache_path, base_output_path): |
- """Generate environmental noise. |
+ """Generates environmental noise. |
- For each noise track and pair of SNR values, the following 2 audio tracks |
+ For each noise track and pair of SNR values, the following two audio tracks |
are created: the noisy signal and the reference signal. The former is |
obtained by mixing the (clean) input signal to the corresponding noise |
track enforcing the target SNR. |
- |
- Args: |
- input_signal_filepath: (clean) input signal file path. |
- input_noise_cache_path: path for the cached noise track files. |
- base_output_path: base output path. |
""" |
# Init. |
snr_values = set([snr for pair in self._SNR_VALUE_PAIRS for snr in pair]) |
# Load the input signal. |
- input_signal = signal_processing.SignalProcessingUtils.load_wav( |
+ input_signal = signal_processing.SignalProcessingUtils.LoadWav( |
input_signal_filepath) |
- input_signal = signal_processing.SignalProcessingUtils.normalize( |
+ input_signal = signal_processing.SignalProcessingUtils.Normalize( |
input_signal) |
noisy_mix_filepaths = {} |
@@ -323,9 +344,9 @@ class EnvironmentalNoiseGenerator(NoiseGenerator): |
logging.error('cannot find the <%s> noise track', noise_track_filename) |
raise exceptions.FileNotFoundError() |
- noise_signal = signal_processing.SignalProcessingUtils.load_wav( |
+ noise_signal = signal_processing.SignalProcessingUtils.LoadWav( |
noise_track_filepath) |
- noise_signal = signal_processing.SignalProcessingUtils.normalize( |
+ noise_signal = signal_processing.SignalProcessingUtils.Normalize( |
noise_signal) |
# Create the noisy mixes (once for each unique SNR value). |
@@ -338,24 +359,26 @@ class EnvironmentalNoiseGenerator(NoiseGenerator): |
# Create and save if not done. |
if not os.path.exists(noisy_signal_filepath): |
# Create noisy signal. |
- noisy_signal = signal_processing.SignalProcessingUtils.mix_signals( |
+ noisy_signal = signal_processing.SignalProcessingUtils.MixSignals( |
input_signal, noise_signal, snr) |
# Save. |
- signal_processing.SignalProcessingUtils.save_wav( |
+ signal_processing.SignalProcessingUtils.SaveWav( |
noisy_signal_filepath, noisy_signal) |
# Add file to the collection of mixes. |
noisy_mix_filepaths[noise_track_name][snr] = noisy_signal_filepath |
# Add all the noise-SNR pairs. |
- self._add_noise_snr_pairs( |
+ self._AddNoiseSnrPairs( |
base_output_path, noisy_mix_filepaths, self._SNR_VALUE_PAIRS) |
-@NoiseGenerator.register_class |
+@NoiseGenerator.RegisterClass |
class EchoNoiseGenerator(NoiseGenerator): |
"""Echo noise generator. |
+ |
+ TODO(alessiob): Rename from echo to reverberation. |
""" |
NAME = 'echo' |
@@ -381,7 +404,7 @@ class EchoNoiseGenerator(NoiseGenerator): |
NoiseGenerator.__init__(self) |
self._aechen_ir_database_path = aechen_ir_database_path |
- def _generate( |
+ def _Generate( |
self, input_signal_filepath, input_noise_cache_path, base_output_path): |
"""Generates echo noise. |
@@ -390,17 +413,12 @@ class EchoNoiseGenerator(NoiseGenerator): |
created: the noisy signal and the reference signal. The former is |
obtained by mixing the (clean) input signal to the corresponding noise |
track enforcing the target SNR. |
- |
- Args: |
- input_signal_filepath: (clean) input signal file path. |
- input_noise_cache_path: path for the cached noise track files. |
- base_output_path: base output path. |
""" |
# Init. |
snr_values = set([snr for pair in self._SNR_VALUE_PAIRS for snr in pair]) |
# Load the input signal. |
- input_signal = signal_processing.SignalProcessingUtils.load_wav( |
+ input_signal = signal_processing.SignalProcessingUtils.LoadWav( |
input_signal_filepath) |
noisy_mix_filepaths = {} |
@@ -412,14 +430,14 @@ class EchoNoiseGenerator(NoiseGenerator): |
noise_signal = None |
try: |
# Load noise track. |
- noise_signal = signal_processing.SignalProcessingUtils.load_wav( |
+ noise_signal = signal_processing.SignalProcessingUtils.LoadWav( |
noise_track_filepath) |
except IOError: # File not found. |
# Generate noise track by applying the impulse response. |
impulse_response_filepath = os.path.join( |
self._aechen_ir_database_path, |
self._IMPULSE_RESPONSES[impulse_response_name]) |
- noise_signal = self._generate_noise_track( |
+ noise_signal = self._GenerateNoiseTrack( |
noise_track_filepath, input_signal, impulse_response_filepath) |
assert noise_signal is not None |
@@ -434,21 +452,21 @@ class EchoNoiseGenerator(NoiseGenerator): |
# Create and save if not done. |
if not os.path.exists(noisy_signal_filepath): |
# Create noisy signal. |
- noisy_signal = signal_processing.SignalProcessingUtils.mix_signals( |
+ noisy_signal = signal_processing.SignalProcessingUtils.MixSignals( |
input_signal, noise_signal, snr, bln_pad_shortest=True) |
# Save. |
- signal_processing.SignalProcessingUtils.save_wav( |
+ signal_processing.SignalProcessingUtils.SaveWav( |
noisy_signal_filepath, noisy_signal) |
# Add file to the collection of mixes. |
noisy_mix_filepaths[impulse_response_name][snr] = noisy_signal_filepath |
# Add all the noise-SNR pairs. |
- self._add_noise_snr_pairs(base_output_path, noisy_mix_filepaths, |
- self._SNR_VALUE_PAIRS) |
+ self._AddNoiseSnrPairs(base_output_path, noisy_mix_filepaths, |
+ self._SNR_VALUE_PAIRS) |
- def _generate_noise_track(self, noise_track_filepath, input_signal, |
+ def _GenerateNoiseTrack(self, noise_track_filepath, input_signal, |
impulse_response_filepath): |
"""Generates noise track. |
@@ -459,6 +477,9 @@ class EchoNoiseGenerator(NoiseGenerator): |
noise_track_filepath: output file path for the noise track. |
input_signal: (clean) input signal samples. |
impulse_response_filepath: impulse response file path. |
+ |
+ Returns: |
+ AudioSegment instance. |
""" |
# Load impulse response. |
data = scipy.io.loadmat(impulse_response_filepath) |
@@ -470,11 +491,11 @@ class EchoNoiseGenerator(NoiseGenerator): |
# Apply impulse response. |
processed_signal = ( |
- signal_processing.SignalProcessingUtils.apply_impulse_response( |
+ signal_processing.SignalProcessingUtils.ApplyImpulseResponse( |
input_signal, impulse_response)) |
# Save. |
- signal_processing.SignalProcessingUtils.save_wav( |
+ signal_processing.SignalProcessingUtils.SaveWav( |
noise_track_filepath, processed_signal) |
return processed_signal |