1# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
2#
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
5# tree. An additional intellectual property rights grant can be found
6# in the file PATENTS.  All contributing project authors may
7# be found in the AUTHORS file in the root of the source tree.
8"""Unit tests for the echo path simulation module.
9"""
10
11import shutil
12import os
13import tempfile
14import unittest
15
16import pydub
17
18from . import echo_path_simulation
19from . import echo_path_simulation_factory
20from . import signal_processing
21
22
23class TestEchoPathSimulators(unittest.TestCase):
24    """Unit tests for the eval_scores module.
25  """
26
27    def setUp(self):
28        """Creates temporary data."""
29        self._tmp_path = tempfile.mkdtemp()
30
31        # Create and save white noise.
32        silence = pydub.AudioSegment.silent(duration=1000, frame_rate=48000)
33        white_noise = signal_processing.SignalProcessingUtils.GenerateWhiteNoise(
34            silence)
35        self._audio_track_num_samples = (
36            signal_processing.SignalProcessingUtils.CountSamples(white_noise))
37        self._audio_track_filepath = os.path.join(self._tmp_path,
38                                                  'white_noise.wav')
39        signal_processing.SignalProcessingUtils.SaveWav(
40            self._audio_track_filepath, white_noise)
41
42        # Make a copy the white noise audio track file; it will be used by
43        # echo_path_simulation.RecordedEchoPathSimulator.
44        shutil.copy(self._audio_track_filepath,
45                    os.path.join(self._tmp_path, 'white_noise_echo.wav'))
46
47    def tearDown(self):
48        """Recursively deletes temporary folders."""
49        shutil.rmtree(self._tmp_path)
50
51    def testRegisteredClasses(self):
52        # Check that there is at least one registered echo path simulator.
53        registered_classes = (
54            echo_path_simulation.EchoPathSimulator.REGISTERED_CLASSES)
55        self.assertIsInstance(registered_classes, dict)
56        self.assertGreater(len(registered_classes), 0)
57
58        # Instance factory.
59        factory = echo_path_simulation_factory.EchoPathSimulatorFactory()
60
61        # Try each registered echo path simulator.
62        for echo_path_simulator_name in registered_classes:
63            simulator = factory.GetInstance(
64                echo_path_simulator_class=registered_classes[
65                    echo_path_simulator_name],
66                render_input_filepath=self._audio_track_filepath)
67
68            echo_filepath = simulator.Simulate(self._tmp_path)
69            if echo_filepath is None:
70                self.assertEqual(echo_path_simulation.NoEchoPathSimulator.NAME,
71                                 echo_path_simulator_name)
72                # No other tests in this case.
73                continue
74
75            # Check that the echo audio track file exists and its length is greater or
76            # equal to that of the render audio track.
77            self.assertTrue(os.path.exists(echo_filepath))
78            echo = signal_processing.SignalProcessingUtils.LoadWav(
79                echo_filepath)
80            self.assertGreaterEqual(
81                signal_processing.SignalProcessingUtils.CountSamples(echo),
82                self._audio_track_num_samples)
83