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
9"""Unit tests for the echo path simulation module.
10"""
11
12import shutil
13import os
14import tempfile
15import unittest
16
17import pydub
18
19from . import echo_path_simulation
20from . import echo_path_simulation_factory
21from . import signal_processing
22
23
24class TestEchoPathSimulators(unittest.TestCase):
25  """Unit tests for the eval_scores module.
26  """
27
28  def setUp(self):
29    """Creates temporary data."""
30    self._tmp_path = tempfile.mkdtemp()
31
32    # Create and save white noise.
33    silence = pydub.AudioSegment.silent(duration=1000, frame_rate=48000)
34    white_noise = signal_processing.SignalProcessingUtils.GenerateWhiteNoise(
35        silence)
36    self._audio_track_num_samples = (
37        signal_processing.SignalProcessingUtils.CountSamples(white_noise))
38    self._audio_track_filepath = os.path.join(self._tmp_path, '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, os.path.join(
45        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(echo_filepath)
79      self.assertGreaterEqual(
80          signal_processing.SignalProcessingUtils.CountSamples(echo),
81          self._audio_track_num_samples)
82