Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(330)

Side by Side Diff: webrtc/modules/audio_processing/test/py_quality_assessment/quality_assessment/simulation.py

Issue 2813883002: APM QA refactoring: render stream support, echo path simulation, new export engine (Closed)
Patch Set: removing details about the experiment Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 data_access 15 from . import data_access
16 from . import echo_path_simulation
16 from . import eval_scores 17 from . import eval_scores
17 from . import eval_scores_factory 18 from . import eval_scores_factory
18 from . import test_data_generation 19 from . import test_data_generation
19 from . import test_data_generation_factory 20 from . import test_data_generation_factory
20 21
21 22
22 class ApmModuleSimulator(object): 23 class ApmModuleSimulator(object):
23 """APM module simulator class. 24 """Audio processing module (APM) simulator class.
24 """ 25 """
25 26
26 _TEST_DATA_GENERATOR_CLASSES = ( 27 _TEST_DATA_GENERATOR_CLASSES = (
27 test_data_generation.TestDataGenerator.REGISTERED_CLASSES) 28 test_data_generation.TestDataGenerator.REGISTERED_CLASSES)
28 _EVAL_SCORE_WORKER_CLASSES = eval_scores.EvaluationScore.REGISTERED_CLASSES 29 _EVAL_SCORE_WORKER_CLASSES = eval_scores.EvaluationScore.REGISTERED_CLASSES
29 30
30 def __init__(self, aechen_ir_database_path, polqa_tool_bin_path, 31 def __init__(self, aechen_ir_database_path, polqa_tool_bin_path,
31 ap_wrapper, evaluator): 32 ap_wrapper, evaluator):
32 # Init. 33 # Init.
33 self._audioproc_wrapper = ap_wrapper 34 self._audioproc_wrapper = ap_wrapper
34 self._evaluator = evaluator 35 self._evaluator = evaluator
35 36
36 # Instance factory objects. 37 # Instance factory objects.
37 self._test_data_generator_factory = ( 38 self._test_data_generator_factory = (
38 test_data_generation_factory.TestDataGeneratorFactory( 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_bin_path=polqa_tool_bin_path)) 43 polqa_tool_bin_path=polqa_tool_bin_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._test_data_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
51 self._reverse_input_filepaths = None
50 52
51 def Run(self, config_filepaths, input_filepaths, test_data_generator_names, 53 def Run(self, config_filepaths, input_filepaths, test_data_generator_names,
52 eval_score_names, output_dir): 54 eval_score_names, output_dir, reverse_input_filepaths=None,
55 echo_path_simulator_name=None):
53 """Runs the APM simulation. 56 """Runs the APM simulation.
54 57
55 Initializes paths and required instances, then runs all the simulations. 58 Initializes paths and required instances, then runs all the simulations.
59 Reverse input can be optionally added. If added, the number of input audio
60 tracks and reverse input audio tracks has to equal. The two lists are used
peah-webrtc 2017/04/21 05:28:45 have?
AleBzk 2017/04/24 14:30:42 Done.
61 to form pairs of input and reverse input.
56 62
57 Args: 63 Args:
58 config_filepaths: set of APM configuration files to test. 64 config_filepaths: set of APM configuration files to test.
59 input_filepaths: set of input audio track files to test. 65 input_filepaths: set of input audio track files to test.
60 test_data_generator_names: set of test data generator names to test. 66 test_data_generator_names: set of test data generator names to test.
61 eval_score_names: set of evaluation score names to test. 67 eval_score_names: set of evaluation score names to test.
62 output_dir: base path to the output directory for wav files and outcomes. 68 output_dir: base path to the output directory for wav files and outcomes.
69 reverse_input_filepaths: set of revert input audio track files to test.
70 echo_path_simulator_name: name of the echo path simulator to use when
71 reverse input is provided.
63 """ 72 """
73 assert reverse_input_filepaths is None or len(input_filepaths) == len(
74 reverse_input_filepaths), ('reverse input set size not matching input '
75 'set size')
76 assert reverse_input_filepaths is None or echo_path_simulator_name in (
77 echo_path_simulation.EchoPathSimulator.REGISTERED_CLASSES), (
78 'reverse input ')
64 self._base_output_path = os.path.abspath(output_dir) 79 self._base_output_path = os.path.abspath(output_dir)
65 80
66 # Instance test data generators. 81 # Instance test data generators.
67 self._test_data_generators = [self._test_data_generator_factory.GetInstance( 82 self._test_data_generators = [self._test_data_generator_factory.GetInstance(
68 test_data_generators_class=( 83 test_data_generators_class=(
69 self._TEST_DATA_GENERATOR_CLASSES[name])) for name in ( 84 self._TEST_DATA_GENERATOR_CLASSES[name])) for name in (
70 test_data_generator_names)] 85 test_data_generator_names)]
71 86
72 # Instance evaluation score workers. 87 # Instance evaluation score workers.
73 self._evaluation_score_workers = [ 88 self._evaluation_score_workers = [
74 self._evaluation_score_factory.GetInstance( 89 self._evaluation_score_factory.GetInstance(
75 evaluation_score_class=self._EVAL_SCORE_WORKER_CLASSES[name]) for ( 90 evaluation_score_class=self._EVAL_SCORE_WORKER_CLASSES[name]) for (
76 name) in eval_score_names] 91 name) in eval_score_names]
77 92
78 # Set APM configuration file paths. 93 # Set APM configuration file paths.
79 self._config_filepaths = self._CreatePathsCollection(config_filepaths) 94 self._config_filepaths = self._CreatePathsCollection(config_filepaths)
80 95
81 # Set probing signal file paths. 96 # Set probing signal file paths.
82 self._input_filepaths = self._CreatePathsCollection(input_filepaths) 97 if reverse_input_filepaths is None:
98 # Forward input only.
99 self._input_filepaths = self._CreatePathsCollection(input_filepaths)
100 self._reverse_input_filepaths = None
101 else:
102 # Set both forward and reverse input signals.
103 self._SetProbingSignalFilePaths(input_filepaths, reverse_input_filepaths)
104
105 # TODO(alessiob): Instance EchoPathSimulator through factory.
peah-webrtc 2017/04/21 05:28:45 Instantiate ?
AleBzk 2017/04/24 14:30:41 Done.
83 106
84 self._SimulateAll() 107 self._SimulateAll()
85 108
86 def _SimulateAll(self): 109 def _SimulateAll(self):
87 """Runs all the simulations. 110 """Runs all the simulations.
88 111
89 Iterates over the combinations of APM configurations, probing signals, and 112 Iterates over the combinations of APM configurations, probing signals, and
90 test data generators. 113 test data generators.
91 """ 114 """
115 without_reverse_input = self._reverse_input_filepaths is None
116
92 # Try different APM config files. 117 # Try different APM config files.
93 for config_name in self._config_filepaths: 118 for config_name in self._config_filepaths:
94 config_filepath = self._config_filepaths[config_name] 119 config_filepath = self._config_filepaths[config_name]
95 120
96 # Try different probing signal files. 121 # Try different probing signal files.
97 for input_name in self._input_filepaths: 122 for input_name in self._input_filepaths:
98 input_filepath = self._input_filepaths[input_name] 123 input_filepath = self._input_filepaths[input_name]
124 reverse_input_filepath = None if without_reverse_input else (
125 self._reverse_input_filepaths[input_name])
99 126
100 # Try different test data generators. 127 # Try different test data generators.
101 for test_data_generators in self._test_data_generators: 128 for test_data_generators in self._test_data_generators:
102 logging.info('config: <%s>, input: <%s>, noise: <%s>', 129 logging.info('config: <%s>, input: <%s>, noise: <%s>',
103 config_name, input_name, test_data_generators.NAME) 130 config_name, input_name, test_data_generators.NAME)
104 131
105 # Output path for the input-noise pairs. It is used to cache the noisy 132 # Output path for the input-noise pairs. It is used to cache the noisy
106 # copies of the probing signals (shared across some simulations). 133 # copies of the probing signals (shared across some simulations).
107 input_noise_cache_path = os.path.join( 134 input_noise_cache_path = os.path.join(
108 self._base_output_path, 135 self._base_output_path,
109 '_cache', 136 '_cache',
110 'input_{}-noise_{}'.format(input_name, test_data_generators.NAME)) 137 'input_{}-noise_{}'.format(input_name, test_data_generators.NAME))
111 data_access.MakeDirectory(input_noise_cache_path) 138 data_access.MakeDirectory(input_noise_cache_path)
112 logging.debug('input-noise cache path: <%s>', input_noise_cache_path) 139 logging.debug('input-noise cache path: <%s>', input_noise_cache_path)
113 140
114 # Full output path. 141 # Full output path.
142 input_dir_suffix = input_name if without_reverse_input else (
143 '{}-{}'.format(input_name, self._ExtractFileName(
144 reverse_input_filepath)))
115 output_path = os.path.join( 145 output_path = os.path.join(
116 self._base_output_path, 146 self._base_output_path,
117 'cfg-{}'.format(config_name), 147 'cfg-{}'.format(config_name),
118 'input-{}'.format(input_name), 148 'input-{}'.format(input_dir_suffix),
119 'gen-{}'.format(test_data_generators.NAME)) 149 'gen-{}'.format(test_data_generators.NAME))
120 data_access.MakeDirectory(output_path) 150 data_access.MakeDirectory(output_path)
121 logging.debug('output path: <%s>', output_path) 151 logging.debug('output path: <%s>', output_path)
122 152
123 self._Simulate(test_data_generators, input_filepath, 153 self._Simulate(test_data_generators, input_filepath,
124 input_noise_cache_path, output_path, config_filepath) 154 reverse_input_filepath, input_noise_cache_path,
155 output_path, config_filepath,)
125 156
126 def _Simulate(self, test_data_generators, input_filepath, 157 def _Simulate(self, test_data_generators, input_filepath,
127 input_noise_cache_path, output_path, config_filepath): 158 reverse_input_filepath, input_noise_cache_path, output_path,
159 config_filepath):
128 """Runs a single set of simulation. 160 """Runs a single set of simulation.
129 161
130 Simulates a given combination of APM configuration, probing signal, and 162 Simulates a given combination of APM configuration, probing signal, and
131 test data generator. It iterates over the test data generator 163 test data generator. It iterates over the test data generator
132 internal configurations. 164 internal configurations.
133 165
134 Args: 166 Args:
135 test_data_generators: TestDataGenerator instance. 167 test_data_generators: TestDataGenerator instance.
136 input_filepath: input audio track file to test. 168 input_filepath: input audio track file to test.
169 reverse_input_filepath: reverse input audio track file to test.
137 input_noise_cache_path: path for the noisy audio track files. 170 input_noise_cache_path: path for the noisy audio track files.
138 output_path: base output path for the test data generator. 171 output_path: base output path for the test data generator.
139 config_filepath: APM configuration file to test. 172 config_filepath: APM configuration file to test.
140 """ 173 """
141 # Generate pairs of noisy input and reference signal files. 174 # Generate pairs of noisy input and reference signal files.
142 test_data_generators.Generate( 175 test_data_generators.Generate(
143 input_signal_filepath=input_filepath, 176 input_signal_filepath=input_filepath,
144 input_noise_cache_path=input_noise_cache_path, 177 input_noise_cache_path=input_noise_cache_path,
145 base_output_path=output_path) 178 base_output_path=output_path)
146 179
147 # For each test data pair, simulate a call and evaluate. 180 # For each test data pair, simulate a call and evaluate.
148 for test_data_generators_config_name in test_data_generators.config_names: 181 for test_data_generators_config_name in test_data_generators.config_names:
149 logging.info(' - test data generator config: <%s>', 182 logging.info(' - test data generator config: <%s>',
150 test_data_generators_config_name) 183 test_data_generators_config_name)
151 184
152 # APM input and output signal paths. 185 # Paths to the test data generator output.
186 # Note that the reference signal does not depend on the reverse input
187 # which is optional.
153 noisy_signal_filepath = test_data_generators.noisy_signal_filepaths[ 188 noisy_signal_filepath = test_data_generators.noisy_signal_filepaths[
154 test_data_generators_config_name] 189 test_data_generators_config_name]
155 evaluation_output_path = test_data_generators.apm_output_paths[
156 test_data_generators_config_name]
157
158 # Simulate a call using the audio processing module.
159 self._audioproc_wrapper.Run(
160 config_filepath=config_filepath,
161 input_filepath=noisy_signal_filepath,
162 output_path=evaluation_output_path)
163
164 # Reference signal path for the evaluation step.
165 reference_signal_filepath = ( 190 reference_signal_filepath = (
166 test_data_generators.reference_signal_filepaths[ 191 test_data_generators.reference_signal_filepaths[
167 test_data_generators_config_name]) 192 test_data_generators_config_name])
168 193
194 # Path to the APM input signal.
195 apm_input_filepath = noisy_signal_filepath
196 if reverse_input_filepath is not None:
197 logging.info(' - reverse input filepath: <%s>', reverse_input_filepath)
198 # TODO(alessiob): Simulate echo path using the EchoPathSimulator
199 # instance with which |apm_input_filepath| is updated.
200
201 # Path for the APM output file.
202 evaluation_output_path = test_data_generators.apm_output_paths[
203 test_data_generators_config_name]
204
205 # Simulate a call using APM.
206 self._audioproc_wrapper.Run(
207 config_filepath=config_filepath,
208 input_filepath=apm_input_filepath,
209 reverse_input_filepath=reverse_input_filepath,
210 output_path=evaluation_output_path)
211
169 # Evaluate. 212 # Evaluate.
170 self._evaluator.Run( 213 self._evaluator.Run(
171 evaluation_score_workers=self._evaluation_score_workers, 214 evaluation_score_workers=self._evaluation_score_workers,
172 apm_output_filepath=self._audioproc_wrapper.output_filepath, 215 apm_output_filepath=self._audioproc_wrapper.output_filepath,
173 reference_input_filepath=reference_signal_filepath, 216 reference_input_filepath=reference_signal_filepath,
174 output_path=evaluation_output_path) 217 output_path=evaluation_output_path)
175 218
219 def _SetProbingSignalFilePaths(self, input_filepaths,
peah-webrtc 2017/04/21 05:28:45 The naming of this method does not seem intuitive
AleBzk 2017/04/24 14:30:42 Renamed to _SetTestInputSignalFilePaths().
220 reverse_input_filepaths):
221 """Sets input and revers input file paths collections.
222
223 Pairs the input and rever input files by storing the file paths into two
peah-webrtc 2017/04/21 05:28:45 reverse ?
AleBzk 2017/04/24 14:30:42 Done.
224 collections. The key is the file name of the input file.
225
226 Args:
227 input_filepaths: list of file paths.
228 reverse_input_filepaths: list of file paths.
229 """
230 self._input_filepaths = {}
231 self._reverse_input_filepaths = {}
232 assert len(input_filepaths) == len(reverse_input_filepaths)
233 for input_filepath, reverse_input_filepath in zip(
234 input_filepaths, reverse_input_filepaths):
235 name = self._ExtractFileName(input_filepath)
236 self._input_filepaths[name] = os.path.abspath(input_filepath)
237 self._reverse_input_filepaths[name] = os.path.abspath(
238 reverse_input_filepath)
239
176 @classmethod 240 @classmethod
177 def _CreatePathsCollection(cls, filepaths): 241 def _CreatePathsCollection(cls, filepaths):
178 """Creates a collection of file paths. 242 """Creates a collection of file paths.
179 243
180 Given a list of file paths, makes a collection with one item for each file 244 Given a list of file paths, makes a collection with one item for each file
181 path. The value is absolute path, the key is the file name without 245 path. The value is absolute path, the key is the file name without
182 extenstion. 246 extenstion.
183 247
184 Args: 248 Args:
185 filepaths: list of file paths. 249 filepaths: list of file paths.
186 250
187 Returns: 251 Returns:
188 A dict. 252 A dict.
189 """ 253 """
190 filepaths_collection = {} 254 filepaths_collection = {}
191 for filepath in filepaths: 255 for filepath in filepaths:
192 name = os.path.splitext(os.path.split(filepath)[1])[0] 256 name = cls._ExtractFileName(filepath)
193 filepaths_collection[name] = os.path.abspath(filepath) 257 filepaths_collection[name] = os.path.abspath(filepath)
194 return filepaths_collection 258 return filepaths_collection
259
260 @classmethod
261 def _ExtractFileName(cls, filepath):
262 return os.path.splitext(os.path.split(filepath)[1])[0]
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698