• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2016 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import common
6import logging
7import math
8import numpy
9import unittest
10
11from autotest_lib.client.cros.audio import audio_data
12from autotest_lib.client.cros.audio import audio_quality_measurement
13
14class NoiseLevelTest(unittest.TestCase):
15    def setUp(self):
16        """Uses the same seed to generate noise for each test."""
17        numpy.random.seed(0)
18
19
20    def testNoiseLevel(self):
21        # Generates the standard sin wave with standard_noise portion of noise.
22        rate = 48000
23        length_in_secs = 2
24        frequency = 440
25        amplitude = 1
26        standard_noise = 0.05
27
28        wave = []
29        for index in xrange(0, rate * length_in_secs):
30            phase = 2.0 * math.pi * frequency * float(index) / float(rate)
31            sine_wave = math.sin(phase)
32            noise = standard_noise * numpy.random.standard_normal()
33            wave.append(float(amplitude) * (sine_wave + noise))
34
35        # Calculates the average value after applying teager operator.
36        teager_value_of_wave, length = 0, len(wave)
37        for i in range(1, length-1):
38            ith_teager_value = abs(wave[i] * wave[i] - wave[i - 1] * wave[i + 1])
39            ith_teager_value *= max(1, abs(wave[i]))
40            teager_value_of_wave += ith_teager_value
41        teager_value_of_wave /= float(length * (amplitude ** 2))
42
43        noise = audio_quality_measurement.noise_level(amplitude, frequency,
44                                                      rate,
45                                                      teager_value_of_wave)
46
47        self.assertTrue(abs(noise - standard_noise) < 0.01)
48
49
50class ErrorTest(unittest.TestCase):
51    def testError(self):
52        value1 = [0.2, 0.4, 0.1, 0.01, 0.01, 0.01]
53        value2 = [0.3, 0.3, 0.08, 0.0095, 0.0098, 0.0099]
54        error  = [0.5, 0.25, 0.2, 0.05, 0.02, 0.01]
55        for i in xrange( len(value1) ):
56          ret = audio_quality_measurement.error(value1[i], value2[i])
57          self.assertTrue(abs(ret - error[i]) < 0.001)
58
59
60class QualityMeasurementTest(unittest.TestCase):
61    def setUp(self):
62        """Creates a test signal of sine wave."""
63        numpy.random.seed(0)
64
65        self.rate = 48000
66        self.freq = 440
67        self.amplitude = 1
68        length_in_secs = 2
69        self.samples = length_in_secs * self.rate
70        self.y = []
71        for index in xrange(self.samples):
72            phase = 2.0 * math.pi * self.freq * float(index) / float(self.rate)
73            sine_wave = math.sin(phase)
74            self.y.append(float(self.amplitude) * sine_wave)
75
76
77    def add_noise(self):
78        """Adds noise to the test signal."""
79        noise_amplitude = 0.01 * self.amplitude
80        for index in xrange(self.samples):
81            noise = noise_amplitude * numpy.random.standard_normal()
82            self.y[index] += noise
83
84
85    def generate_delay(self):
86        """Generates some delays during playing."""
87        self.delay_start_time = [0.200, 0.375, 0.513, 0.814, 1.000, 1.300]
88        self.delay_end_time   = [0.201, 0.377, 0.516, 0.824, 1.100, 1.600]
89
90        for i in xrange(len(self.delay_start_time)):
91            start_index = int(self.delay_start_time[i] * self.rate)
92            end_index   = int(self.delay_end_time[i]   * self.rate)
93            for j in xrange(start_index,end_index):
94                self.y[j] = 0
95
96
97    def generate_artifacts_before_playback(self):
98        """Generates artifacts before playing."""
99        silence_before_playback_end_time = 0.2
100        end_index = int(silence_before_playback_end_time * self.rate)
101        for i in xrange(0, end_index):
102            self.y[i] = 0
103        noise_start_index = int(0.1 * self.rate)
104        noise_end_index = int(0.1005 * self.rate)
105        for i in xrange(noise_start_index, noise_end_index):
106            self.y[i] = 3 * self.amplitude
107
108
109    def generate_artifacts_after_playback(self):
110        """Generates artifacts after playing."""
111        silence_after_playback_start_time = int(1.9 * self.rate)
112        noise_start_index = int(1.95 * self.rate)
113        noise_end_index = int((1.95 + 0.02) * self.rate)
114
115        for i in xrange(silence_after_playback_start_time, self.samples):
116            self.y[i] = 0
117        for i in xrange(noise_start_index, noise_end_index):
118            self.y[i] = self.amplitude
119
120
121    def generate_burst_during_playback(self):
122        """Generates bursts during playing."""
123        self.burst_start_time = [0.300, 0.475, 0.613, 0.814, 1.300]
124        self.burst_end_time   = [0.301, 0.476, 0.614, 0.815, 1.301]
125
126        for i in xrange(len(self.burst_start_time)):
127            start_index = int(self.burst_start_time[i] * self.rate)
128            end_index   = int(self.burst_end_time[i]   * self.rate)
129            for j in xrange(start_index, end_index):
130                self.y[j] = self.amplitude * (3 + numpy.random.uniform(-1, 1))
131
132
133    def generate_volume_changing(self):
134        "Generates volume changing during playing."
135        start_time = [0.300, 1.400]
136        end_time   = [0.600, 1.700]
137        for i in xrange(len(start_time)):
138            start_index = int(start_time[i] * self.rate)
139            end_index   = int(end_time[i]   * self.rate)
140            for j in xrange(start_index,end_index):
141                self.y[j] *= 1.4
142        self.volume_changing = [+1, -1, +1, -1]
143        self.volume_changing_time = [0.3, 0.6, 1.4, 1.7]
144
145
146    def testGoodSignal(self):
147        """Sine wave signal with no noise or artifacts."""
148        result = audio_quality_measurement.quality_measurement(self.y,
149                                                               self.rate)
150        self.assertTrue(len(result['artifacts']['noise_before_playback']) == 0)
151        self.assertTrue(len(result['artifacts']['noise_after_playback']) == 0)
152        self.assertTrue(len(result['artifacts']['delay_during_playback']) == 0)
153        self.assertTrue(len(result['artifacts']['burst_during_playback']) == 0)
154        self.assertTrue(len(result['volume_changes']) == 0)
155        self.assertTrue(result['equivalent_noise_level'] < 0.005)
156
157
158    def testGoodSignalNoise(self):
159        """Sine wave signal with noise."""
160        self.add_noise();
161        result = audio_quality_measurement.quality_measurement(self.y,
162                                                               self.rate)
163        self.assertTrue(len(result['artifacts']['noise_before_playback']) == 0)
164        self.assertTrue(len(result['artifacts']['noise_after_playback']) == 0)
165        self.assertTrue(len(result['artifacts']['delay_during_playback']) == 0)
166        self.assertTrue(len(result['artifacts']['burst_during_playback']) == 0)
167        self.assertTrue(len(result['volume_changes']) == 0)
168        self.assertTrue(0.009 < result['equivalent_noise_level'] and
169                                result['equivalent_noise_level'] < 0.011)
170
171
172    def testDelay(self):
173        """Sine wave with delay during playing."""
174        self.generate_delay()
175        result = audio_quality_measurement.quality_measurement(self.y,
176                                                               self.rate)
177        self.assertTrue(len(result['artifacts']['noise_before_playback']) == 0)
178        self.assertTrue(len(result['artifacts']['noise_after_playback']) == 0)
179        self.assertTrue(len(result['volume_changes']) ==
180                        2 * len(self.delay_start_time))
181        self.assertTrue(result['equivalent_noise_level'] < 0.005)
182
183        self.assertTrue(len(result['artifacts']['delay_during_playback']) ==
184                        len(self.delay_start_time))
185        for i in xrange(len(result['artifacts']['delay_during_playback'])):
186            delta = abs(result['artifacts']['delay_during_playback'][i][0] -
187                        self.delay_start_time[i])
188            self.assertTrue(delta < 0.001)
189            duration = self.delay_end_time[i] - self.delay_start_time[i]
190            delta = abs(result['artifacts']['delay_during_playback'][i][1] -
191                        duration)
192            self.assertTrue(delta < 0.001)
193
194
195    def testArtifactsBeforePlayback(self):
196        """Sine wave with artifacts before playback."""
197        self.generate_artifacts_before_playback()
198        result = audio_quality_measurement.quality_measurement(self.y,
199                                                               self.rate)
200        self.assertTrue(len(result['artifacts']['noise_before_playback']) == 1)
201        delta = abs(result['artifacts']['noise_before_playback'][0][0] - 0.1)
202        self.assertTrue(delta < 0.01)
203        delta = abs(result['artifacts']['noise_before_playback'][0][1] - 0.005)
204        self.assertTrue(delta < 0.004)
205        self.assertTrue(len(result['artifacts']['noise_after_playback']) == 0)
206        self.assertTrue(len(result['artifacts']['delay_during_playback']) == 0)
207        self.assertTrue(len(result['artifacts']['burst_during_playback']) == 0)
208        self.assertTrue(len(result['volume_changes']) == 0)
209        self.assertTrue(result['equivalent_noise_level'] < 0.005)
210
211
212    def testArtifactsAfterPlayback(self):
213        """Sine wave with artifacts after playback."""
214        self.generate_artifacts_after_playback()
215        result = audio_quality_measurement.quality_measurement(self.y,
216                                                               self.rate)
217        self.assertTrue(len(result['artifacts']['noise_before_playback']) == 0)
218        self.assertTrue(len(result['artifacts']['noise_after_playback']) == 1)
219        delta = abs(result['artifacts']['noise_after_playback'][0][0] - 1.95)
220        self.assertTrue(delta < 0.01)
221        delta = abs(result['artifacts']['noise_after_playback'][0][1] - 0.02)
222        self.assertTrue(delta < 0.001)
223        self.assertTrue(len(result['artifacts']['delay_during_playback']) == 0)
224        self.assertTrue(len(result['artifacts']['burst_during_playback'] ) == 0)
225        self.assertTrue(len(result['volume_changes']) == 0)
226        self.assertTrue(result['equivalent_noise_level'] < 0.005)
227
228
229    def testBurstDuringPlayback(self):
230        """Sine wave with burst during playback."""
231        self.generate_burst_during_playback()
232        result = audio_quality_measurement.quality_measurement(self.y,
233                                                               self.rate)
234        self.assertTrue(len(result['artifacts']['noise_before_playback']) == 0)
235        self.assertTrue(len(result['artifacts']['noise_after_playback']) == 0)
236        self.assertTrue(len(result['artifacts']['delay_during_playback']) == 0)
237        self.assertTrue(len(result['artifacts']['burst_during_playback']) == 5)
238        self.assertTrue(len(result['volume_changes']) == 10)
239        self.assertTrue(result['equivalent_noise_level'] > 0.02)
240        for i in xrange(len(result['artifacts']['burst_during_playback'])):
241            delta = abs(self.burst_start_time[i] -
242                        result['artifacts']['burst_during_playback'][i])
243            self.assertTrue(delta < 0.002)
244
245
246    def testVolumeChanging(self):
247        """Sine wave with volume changing during playback."""
248        self.generate_volume_changing()
249        result = audio_quality_measurement.quality_measurement(self.y,
250                                                               self.rate)
251        self.assertTrue(len(result['artifacts']['noise_before_playback']) == 0)
252        self.assertTrue(len(result['artifacts']['noise_after_playback']) == 0)
253        self.assertTrue(len(result['artifacts']['delay_during_playback']) == 0)
254        self.assertTrue(len(result['artifacts']['burst_during_playback']) == 0)
255        self.assertTrue(result['equivalent_noise_level'] < 0.005)
256        self.assertTrue(len(result['volume_changes']) ==
257                        len(self.volume_changing))
258        for i in xrange(len(self.volume_changing)):
259            self.assertTrue(abs(self.volume_changing_time[i] -
260                                result['volume_changes'][i][0]) < 0.01)
261            self.assertTrue(self.volume_changing[i] ==
262                            result['volume_changes'][i][1])
263
264if __name__ == '__main__':
265    unittest.main()
266