OLD | NEW |
1 # Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. | 1 # Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. |
2 # | 2 # |
3 # Use of this source code is governed by a BSD-style license | 3 # Use of this source code is governed by a BSD-style license |
4 # that can be found in the LICENSE file in the root of the source | 4 # that can be found in the LICENSE file in the root of the source |
5 # tree. An additional intellectual property rights grant can be found | 5 # tree. An additional intellectual property rights grant can be found |
6 # in the file PATENTS. All contributing project authors may | 6 # in the file PATENTS. All contributing project authors may |
7 # be found in the AUTHORS file in the root of the source tree. | 7 # be found in the AUTHORS file in the root of the source tree. |
8 | 8 |
9 """APM module simulator. | 9 """APM module simulator. |
10 """ | 10 """ |
11 | 11 |
12 import logging | 12 import logging |
13 import os | 13 import os |
14 | 14 |
15 from . import audioproc_wrapper | 15 from . import audioproc_wrapper |
16 from . import data_access | 16 from . import data_access |
17 from . import eval_scores | 17 from . import eval_scores |
18 from . import eval_scores_factory | 18 from . import eval_scores_factory |
19 from . import evaluation | 19 from . import evaluation |
20 from . import noise_generation | 20 from . import test_data_generation |
21 from . import noise_generation_factory | 21 from . import test_data_generation_factory |
22 | 22 |
23 | 23 |
24 class ApmModuleSimulator(object): | 24 class ApmModuleSimulator(object): |
25 """APM module simulator class. | 25 """APM module simulator class. |
26 """ | 26 """ |
27 | 27 |
28 _NOISE_GENERATOR_CLASSES = noise_generation.NoiseGenerator.REGISTERED_CLASSES | 28 _INREF_GENERATOR_CLASSES = ( |
| 29 test_data_generation.TestDataGenerator.REGISTERED_CLASSES) |
29 _EVAL_SCORE_WORKER_CLASSES = eval_scores.EvaluationScore.REGISTERED_CLASSES | 30 _EVAL_SCORE_WORKER_CLASSES = eval_scores.EvaluationScore.REGISTERED_CLASSES |
30 | 31 |
31 def __init__(self, aechen_ir_database_path, polqa_tool_path): | 32 def __init__(self, aechen_ir_database_path, polqa_tool_path): |
32 # Init. | 33 # Init. |
33 self._audioproc_wrapper = audioproc_wrapper.AudioProcWrapper() | 34 self._audioproc_wrapper = audioproc_wrapper.AudioProcWrapper() |
34 self._evaluator = evaluation.ApmModuleEvaluator() | 35 self._evaluator = evaluation.ApmModuleEvaluator() |
35 | 36 |
36 # Instance factory objects. | 37 # Instance factory objects. |
37 self._noise_generator_factory = ( | 38 self._test_data_generator_factory = ( |
38 noise_generation_factory.NoiseGeneratorFactory( | 39 test_data_generation_factory.TestDataGeneratorFactory( |
39 aechen_ir_database_path=aechen_ir_database_path)) | 40 aechen_ir_database_path=aechen_ir_database_path)) |
40 self._evaluation_score_factory = ( | 41 self._evaluation_score_factory = ( |
41 eval_scores_factory.EvaluationScoreWorkerFactory( | 42 eval_scores_factory.EvaluationScoreWorkerFactory( |
42 polqa_tool_path=polqa_tool_path)) | 43 polqa_tool_path=polqa_tool_path)) |
43 | 44 |
44 # Properties for each run. | 45 # Properties for each run. |
45 self._base_output_path = None | 46 self._base_output_path = None |
46 self._noise_generators = None | 47 self._test_data_generators = None |
47 self._evaluation_score_workers = None | 48 self._evaluation_score_workers = None |
48 self._config_filepaths = None | 49 self._config_filepaths = None |
49 self._input_filepaths = None | 50 self._input_filepaths = None |
50 | 51 |
51 def Run(self, config_filepaths, input_filepaths, noise_generator_names, | 52 def Run(self, config_filepaths, input_filepaths, test_data_generator_names, |
52 eval_score_names, output_dir): | 53 eval_score_names, output_dir): |
53 """Runs the APM simulation. | 54 """Runs the APM simulation. |
54 | 55 |
55 Initializes paths and required instances, then runs all the simulations. | 56 Initializes paths and required instances, then runs all the simulations. |
56 | 57 |
57 Args: | 58 Args: |
58 config_filepaths: set of APM configuration files to test. | 59 config_filepaths: set of APM configuration files to test. |
59 input_filepaths: set of input audio track files to test. | 60 input_filepaths: set of input audio track files to test. |
60 noise_generator_names: set of noise generator names to test. | 61 test_data_generator_names: set of test data generator names to test. |
61 eval_score_names: set of evaluation score names to test. | 62 eval_score_names: set of evaluation score names to test. |
62 output_dir: base path to the output directory for wav files and outcomes. | 63 output_dir: base path to the output directory for wav files and outcomes. |
63 """ | 64 """ |
64 self._base_output_path = os.path.abspath(output_dir) | 65 self._base_output_path = os.path.abspath(output_dir) |
65 | 66 |
66 # Instance noise generators. | 67 # Instance test data generators. |
67 self._noise_generators = [self._noise_generator_factory.GetInstance( | 68 self._test_data_generators = [self._test_data_generator_factory.GetInstance( |
68 noise_generator_class=self._NOISE_GENERATOR_CLASSES[name]) for name in ( | 69 test_data_generators_class=self._INREF_GENERATOR_CLASSES[name]) for ( |
69 noise_generator_names)] | 70 name) in test_data_generator_names] |
70 | 71 |
71 # Instance evaluation score workers. | 72 # Instance evaluation score workers. |
72 self._evaluation_score_workers = [ | 73 self._evaluation_score_workers = [ |
73 self._evaluation_score_factory.GetInstance( | 74 self._evaluation_score_factory.GetInstance( |
74 evaluation_score_class=self._EVAL_SCORE_WORKER_CLASSES[name]) for ( | 75 evaluation_score_class=self._EVAL_SCORE_WORKER_CLASSES[name]) for ( |
75 name) in eval_score_names] | 76 name) in eval_score_names] |
76 | 77 |
77 # Set APM configuration file paths. | 78 # Set APM configuration file paths. |
78 self._config_filepaths = self._CreatePathsCollection(config_filepaths) | 79 self._config_filepaths = self._CreatePathsCollection(config_filepaths) |
79 | 80 |
80 # Set probing signal file paths. | 81 # Set probing signal file paths. |
81 self._input_filepaths = self._CreatePathsCollection(input_filepaths) | 82 self._input_filepaths = self._CreatePathsCollection(input_filepaths) |
82 | 83 |
83 self._SimulateAll() | 84 self._SimulateAll() |
84 | 85 |
85 def _SimulateAll(self): | 86 def _SimulateAll(self): |
86 """Runs all the simulations. | 87 """Runs all the simulations. |
87 | 88 |
88 Iterates over the combinations of APM configurations, probing signals, and | 89 Iterates over the combinations of APM configurations, probing signals, and |
89 noise generators. | 90 test data generators. |
90 """ | 91 """ |
91 # Try different APM config files. | 92 # Try different APM config files. |
92 for config_name in self._config_filepaths: | 93 for config_name in self._config_filepaths: |
93 config_filepath = self._config_filepaths[config_name] | 94 config_filepath = self._config_filepaths[config_name] |
94 | 95 |
95 # Try different probing signal files. | 96 # Try different probing signal files. |
96 for input_name in self._input_filepaths: | 97 for input_name in self._input_filepaths: |
97 input_filepath = self._input_filepaths[input_name] | 98 input_filepath = self._input_filepaths[input_name] |
98 | 99 |
99 # Try different noise generators. | 100 # Try different test data generators. |
100 for noise_generator in self._noise_generators: | 101 for test_data_generators in self._test_data_generators: |
101 logging.info('config: <%s>, input: <%s>, noise: <%s>', | 102 logging.info('config: <%s>, input: <%s>, noise: <%s>', |
102 config_name, input_name, noise_generator.NAME) | 103 config_name, input_name, test_data_generators.NAME) |
103 | 104 |
104 # Output path for the input-noise pairs. It is used to cache the noisy | 105 # Output path for the input-noise pairs. It is used to cache the noisy |
105 # copies of the probing signals (shared across some simulations). | 106 # copies of the probing signals (shared across some simulations). |
106 input_noise_cache_path = os.path.join( | 107 input_noise_cache_path = os.path.join( |
107 self._base_output_path, | 108 self._base_output_path, |
108 '_cache', | 109 '_cache', |
109 'input_{}-noise_{}'.format(input_name, noise_generator.NAME)) | 110 'input_{}-noise_{}'.format(input_name, test_data_generators.NAME)) |
110 data_access.MakeDirectory(input_noise_cache_path) | 111 data_access.MakeDirectory(input_noise_cache_path) |
111 logging.debug('input-noise cache path: <%s>', input_noise_cache_path) | 112 logging.debug('input-noise cache path: <%s>', input_noise_cache_path) |
112 | 113 |
113 # Full output path. | 114 # Full output path. |
114 output_path = os.path.join( | 115 output_path = os.path.join( |
115 self._base_output_path, | 116 self._base_output_path, |
116 'cfg-{}'.format(config_name), | 117 'cfg-{}'.format(config_name), |
117 'input-{}'.format(input_name), | 118 'input-{}'.format(input_name), |
118 'noise-{}'.format(noise_generator.NAME)) | 119 'gen-{}'.format(test_data_generators.NAME)) |
119 data_access.MakeDirectory(output_path) | 120 data_access.MakeDirectory(output_path) |
120 logging.debug('output path: <%s>', output_path) | 121 logging.debug('output path: <%s>', output_path) |
121 | 122 |
122 self._Simulate(noise_generator, input_filepath, | 123 self._Simulate(test_data_generators, input_filepath, |
123 input_noise_cache_path, output_path, config_filepath) | 124 input_noise_cache_path, output_path, config_filepath) |
124 | 125 |
125 def _Simulate(self, noise_generator, input_filepath, input_noise_cache_path, | 126 def _Simulate(self, test_data_generators, input_filepath, |
126 output_path, config_filepath): | 127 input_noise_cache_path, output_path, config_filepath): |
127 """Runs a single set of simulation. | 128 """Runs a single set of simulation. |
128 | 129 |
129 Simulates a given combination of APM configuration, probing signal, and | 130 Simulates a given combination of APM configuration, probing signal, and |
130 noise generator. It iterates over the noise generator internal | 131 test data generator. It iterates over the test data generator |
131 configurations. | 132 internal configurations. |
132 | 133 |
133 Args: | 134 Args: |
134 noise_generator: NoiseGenerator instance. | 135 test_data_generators: TestDataGenerator instance. |
135 input_filepath: input audio track file to test. | 136 input_filepath: input audio track file to test. |
136 input_noise_cache_path: path for the noisy audio track files. | 137 input_noise_cache_path: path for the noisy audio track files. |
137 output_path: base output path for the noise generator. | 138 output_path: base output path for the test data generator. |
138 config_filepath: APM configuration file to test. | 139 config_filepath: APM configuration file to test. |
139 """ | 140 """ |
140 # Generate pairs of noisy input and reference signal files. | 141 # Generate pairs of noisy input and reference signal files. |
141 noise_generator.Generate( | 142 test_data_generators.Generate( |
142 input_signal_filepath=input_filepath, | 143 input_signal_filepath=input_filepath, |
143 input_noise_cache_path=input_noise_cache_path, | 144 input_noise_cache_path=input_noise_cache_path, |
144 base_output_path=output_path) | 145 base_output_path=output_path) |
145 | 146 |
146 # For each input-reference pair, simulate a call and evaluate. | 147 # For each test data pair, simulate a call and evaluate. |
147 for noise_generator_config_name in noise_generator.config_names: | 148 for test_data_generators_config_name in test_data_generators.config_names: |
148 logging.info(' - noise config: <%s>', noise_generator_config_name) | 149 logging.info(' - test data generator config: <%s>', |
| 150 test_data_generators_config_name) |
149 | 151 |
150 # APM input and output signal paths. | 152 # APM input and output signal paths. |
151 noisy_signal_filepath = noise_generator.noisy_signal_filepaths[ | 153 noisy_signal_filepath = test_data_generators.noisy_signal_filepaths[ |
152 noise_generator_config_name] | 154 test_data_generators_config_name] |
153 evaluation_output_path = noise_generator.apm_output_paths[ | 155 evaluation_output_path = test_data_generators.apm_output_paths[ |
154 noise_generator_config_name] | 156 test_data_generators_config_name] |
155 | 157 |
156 # Simulate a call using the audio processing module. | 158 # Simulate a call using the audio processing module. |
157 self._audioproc_wrapper.Run( | 159 self._audioproc_wrapper.Run( |
158 config_filepath=config_filepath, | 160 config_filepath=config_filepath, |
159 input_filepath=noisy_signal_filepath, | 161 input_filepath=noisy_signal_filepath, |
160 output_path=evaluation_output_path) | 162 output_path=evaluation_output_path) |
161 | 163 |
162 # Reference signal path for the evaluation step. | 164 # Reference signal path for the evaluation step. |
163 reference_signal_filepath = noise_generator.reference_signal_filepaths[ | 165 reference_signal_filepath = ( |
164 noise_generator_config_name] | 166 test_data_generators.reference_signal_filepaths[ |
| 167 test_data_generators_config_name]) |
165 | 168 |
166 # Evaluate. | 169 # Evaluate. |
167 self._evaluator.Run( | 170 self._evaluator.Run( |
168 evaluation_score_workers=self._evaluation_score_workers, | 171 evaluation_score_workers=self._evaluation_score_workers, |
169 apm_output_filepath=self._audioproc_wrapper.output_filepath, | 172 apm_output_filepath=self._audioproc_wrapper.output_filepath, |
170 reference_input_filepath=reference_signal_filepath, | 173 reference_input_filepath=reference_signal_filepath, |
171 output_path=evaluation_output_path) | 174 output_path=evaluation_output_path) |
172 | 175 |
173 @classmethod | 176 @classmethod |
174 def _CreatePathsCollection(cls, filepaths): | 177 def _CreatePathsCollection(cls, filepaths): |
175 """Creates a collection of file paths. | 178 """Creates a collection of file paths. |
176 | 179 |
177 Given a list of file paths, makes a collection with one item for each file | 180 Given a list of file paths, makes a collection with one item for each file |
178 path. The value is absolute path, the key is the file name without | 181 path. The value is absolute path, the key is the file name without |
179 extenstion. | 182 extenstion. |
180 | 183 |
181 Args: | 184 Args: |
182 filepaths: list of file paths. | 185 filepaths: list of file paths. |
183 | 186 |
184 Returns: | 187 Returns: |
185 A dict. | 188 A dict. |
186 """ | 189 """ |
187 filepaths_collection = {} | 190 filepaths_collection = {} |
188 for filepath in filepaths: | 191 for filepath in filepaths: |
189 name = os.path.splitext(os.path.split(filepath)[1])[0] | 192 name = os.path.splitext(os.path.split(filepath)[1])[0] |
190 filepaths_collection[name] = os.path.abspath(filepath) | 193 filepaths_collection[name] = os.path.abspath(filepath) |
191 return filepaths_collection | 194 return filepaths_collection |
OLD | NEW |