• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2#
3#   Copyright 2017 - The Android Open Source Project
4#
5#   Licensed under the Apache License, Version 2.0 (the "License");
6#   you may not use this file except in compliance with the License.
7#   You may obtain a copy of the License at
8#
9#       http://www.apache.org/licenses/LICENSE-2.0
10#
11#   Unless required by applicable law or agreed to in writing, software
12#   distributed under the License is distributed on an "AS IS" BASIS,
13#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14#   See the License for the specific language governing permissions and
15#   limitations under the License.
16
17# Note: This test has been labelled as an integration test due to its use of
18# real data, and the 12+ second execution time. It also generates sine waves
19# during the test, rather than using data that has been pre-calculated.
20
21import math
22import numpy
23import unittest
24
25import acts_contrib.test_utils.audio_analysis_lib.audio_quality_measurement as audio_quality_measurement
26
27
28class NoiseLevelTest(unittest.TestCase):
29    def setUp(self):
30        """Uses the same seed to generate noise for each test."""
31        numpy.random.seed(0)
32
33    def test_noise_level(self):
34        # Generates the standard sin wave with standard_noise portion of noise.
35        rate = 48000
36        length_in_secs = 2
37        frequency = 440
38        amplitude = 1
39        standard_noise = 0.05
40
41        wave = []
42        for index in range(0, rate * length_in_secs):
43            phase = 2.0 * math.pi * frequency * float(index) / float(rate)
44            sine_wave = math.sin(phase)
45            noise = standard_noise * numpy.random.standard_normal()
46            wave.append(float(amplitude) * (sine_wave + noise))
47
48        # Calculates the average value after applying teager operator.
49        teager_value_of_wave, length = 0, len(wave)
50        for i in range(1, length - 1):
51            ith_teager_value = abs(wave[i] * wave[i] - wave[i - 1] * wave[i +
52                                                                          1])
53            ith_teager_value *= max(1, abs(wave[i]))
54            teager_value_of_wave += ith_teager_value
55        teager_value_of_wave /= float(length * (amplitude**2))
56
57        noise = audio_quality_measurement.noise_level(
58            amplitude, frequency, rate, teager_value_of_wave)
59
60        self.assertTrue(abs(noise - standard_noise) < 0.01)
61
62
63class ErrorTest(unittest.TestCase):
64    def test_error(self):
65        value1 = [0.2, 0.4, 0.1, 0.01, 0.01, 0.01]
66        value2 = [0.3, 0.3, 0.08, 0.0095, 0.0098, 0.0099]
67        error = [0.5, 0.25, 0.2, 0.05, 0.02, 0.01]
68        for i in range(len(value1)):
69            ret = audio_quality_measurement.error(value1[i], value2[i])
70            self.assertTrue(abs(ret - error[i]) < 0.001)
71
72
73class QualityMeasurementTest(unittest.TestCase):
74    def setUp(self):
75        """Creates a test signal of sine wave."""
76        numpy.random.seed(0)
77
78        self.rate = 48000
79        self.freq = 440
80        self.amplitude = 1
81        length_in_secs = 2
82        self.samples = length_in_secs * self.rate
83        self.y = []
84        for index in range(self.samples):
85            phase = 2.0 * math.pi * self.freq * float(index) / float(self.rate)
86            sine_wave = math.sin(phase)
87            self.y.append(float(self.amplitude) * sine_wave)
88
89    def add_noise(self):
90        """Adds noise to the test signal."""
91        noise_amplitude = 0.01 * self.amplitude
92        for index in range(self.samples):
93            noise = noise_amplitude * numpy.random.standard_normal()
94            self.y[index] += noise
95
96    def generate_delay(self):
97        """Generates some delays during playing."""
98        self.delay_start_time = [0.200, 0.375, 0.513, 0.814, 1.000, 1.300]
99        self.delay_end_time = [0.201, 0.377, 0.516, 0.824, 1.100, 1.600]
100
101        for i in range(len(self.delay_start_time)):
102            start_index = int(self.delay_start_time[i] * self.rate)
103            end_index = int(self.delay_end_time[i] * self.rate)
104            for j in range(start_index, end_index):
105                self.y[j] = 0
106
107    def generate_artifacts_before_playback(self):
108        """Generates artifacts before playing."""
109        silence_before_playback_end_time = 0.2
110        end_index = int(silence_before_playback_end_time * self.rate)
111        for i in range(0, end_index):
112            self.y[i] = 0
113        noise_start_index = int(0.1 * self.rate)
114        noise_end_index = int(0.1005 * self.rate)
115        for i in range(noise_start_index, noise_end_index):
116            self.y[i] = 3 * self.amplitude
117
118    def generate_artifacts_after_playback(self):
119        """Generates artifacts after playing."""
120        silence_after_playback_start_time = int(1.9 * self.rate)
121        noise_start_index = int(1.95 * self.rate)
122        noise_end_index = int((1.95 + 0.02) * self.rate)
123
124        for i in range(silence_after_playback_start_time, self.samples):
125            self.y[i] = 0
126        for i in range(noise_start_index, noise_end_index):
127            self.y[i] = self.amplitude
128
129    def generate_burst_during_playback(self):
130        """Generates bursts during playing."""
131        self.burst_start_time = [0.300, 0.475, 0.613, 0.814, 1.300]
132        self.burst_end_time = [0.301, 0.476, 0.614, 0.815, 1.301]
133
134        for i in range(len(self.burst_start_time)):
135            start_index = int(self.burst_start_time[i] * self.rate)
136            end_index = int(self.burst_end_time[i] * self.rate)
137            for j in range(start_index, end_index):
138                self.y[j] = self.amplitude * (3 + numpy.random.uniform(-1, 1))
139
140    def generate_volume_changing(self):
141        """Generates volume changing during playing."""
142        start_time = [0.300, 1.400]
143        end_time = [0.600, 1.700]
144        for i in range(len(start_time)):
145            start_index = int(start_time[i] * self.rate)
146            end_index = int(end_time[i] * self.rate)
147            for j in range(start_index, end_index):
148                self.y[j] *= 1.4
149        self.volume_changing = [+1, -1, +1, -1]
150        self.volume_changing_time = [0.3, 0.6, 1.4, 1.7]
151
152    def test_good_signal(self):
153        """Sine wave signal with no noise or artifacts."""
154        result = audio_quality_measurement.quality_measurement(self.y,
155                                                               self.rate)
156        self.assertTrue(len(result['artifacts']['noise_before_playback']) == 0)
157        self.assertTrue(len(result['artifacts']['noise_after_playback']) == 0)
158        self.assertTrue(len(result['artifacts']['delay_during_playback']) == 0)
159        self.assertTrue(len(result['artifacts']['burst_during_playback']) == 0)
160        self.assertTrue(len(result['volume_changes']) == 0)
161        self.assertTrue(result['equivalent_noise_level'] < 0.005)
162
163    def test_good_signal_with_noise(self):
164        """Sine wave signal with noise."""
165        self.add_noise()
166        result = audio_quality_measurement.quality_measurement(self.y,
167                                                               self.rate)
168        self.assertTrue(len(result['artifacts']['noise_before_playback']) == 0)
169        self.assertTrue(len(result['artifacts']['noise_after_playback']) == 0)
170        self.assertTrue(len(result['artifacts']['delay_during_playback']) == 0)
171        self.assertTrue(len(result['artifacts']['burst_during_playback']) == 0)
172        self.assertTrue(len(result['volume_changes']) == 0)
173        self.assertTrue(0.009 < result['equivalent_noise_level'] < 0.011)
174
175    def test_delay(self):
176        """Sine wave with delay during playing."""
177        self.generate_delay()
178        result = audio_quality_measurement.quality_measurement(self.y,
179                                                               self.rate)
180        self.assertTrue(len(result['artifacts']['noise_before_playback']) == 0)
181        self.assertTrue(len(result['artifacts']['noise_after_playback']) == 0)
182        self.assertTrue(
183            len(result['volume_changes']) == 2 * len(self.delay_start_time))
184        self.assertTrue(result['equivalent_noise_level'] < 0.005)
185
186        self.assertTrue(
187            len(result['artifacts']['delay_during_playback']) ==
188            len(self.delay_start_time))
189        for i in range(len(result['artifacts']['delay_during_playback'])):
190            delta = abs(result['artifacts']['delay_during_playback'][i][0] -
191                        self.delay_start_time[i])
192            self.assertTrue(delta < 0.001)
193            duration = self.delay_end_time[i] - self.delay_start_time[i]
194            delta = abs(result['artifacts']['delay_during_playback'][i][1] -
195                        duration)
196            self.assertTrue(delta < 0.001)
197
198    def test_artifacts_before_playback(self):
199        """Sine wave with artifacts before playback."""
200        self.generate_artifacts_before_playback()
201        result = audio_quality_measurement.quality_measurement(self.y,
202                                                               self.rate)
203        self.assertTrue(len(result['artifacts']['noise_before_playback']) == 1)
204        delta = abs(result['artifacts']['noise_before_playback'][0][0] - 0.1)
205        self.assertTrue(delta < 0.01)
206        delta = abs(result['artifacts']['noise_before_playback'][0][1] - 0.005)
207        self.assertTrue(delta < 0.004)
208        self.assertTrue(len(result['artifacts']['noise_after_playback']) == 0)
209        self.assertTrue(len(result['artifacts']['delay_during_playback']) == 0)
210        self.assertTrue(len(result['artifacts']['burst_during_playback']) == 0)
211        self.assertTrue(len(result['volume_changes']) == 0)
212        self.assertTrue(result['equivalent_noise_level'] < 0.005)
213
214    def test_artifacts_after_playback(self):
215        """Sine wave with artifacts after playback."""
216        self.generate_artifacts_after_playback()
217        result = audio_quality_measurement.quality_measurement(self.y,
218                                                               self.rate)
219        self.assertTrue(len(result['artifacts']['noise_before_playback']) == 0)
220        self.assertTrue(len(result['artifacts']['noise_after_playback']) == 1)
221        delta = abs(result['artifacts']['noise_after_playback'][0][0] - 1.95)
222        self.assertTrue(delta < 0.01)
223        delta = abs(result['artifacts']['noise_after_playback'][0][1] - 0.02)
224        self.assertTrue(delta < 0.001)
225        self.assertTrue(len(result['artifacts']['delay_during_playback']) == 0)
226        self.assertTrue(len(result['artifacts']['burst_during_playback']) == 0)
227        self.assertTrue(len(result['volume_changes']) == 0)
228        self.assertTrue(result['equivalent_noise_level'] < 0.005)
229
230    def test_burst_during_playback(self):
231        """Sine wave with burst during playback."""
232        self.generate_burst_during_playback()
233        result = audio_quality_measurement.quality_measurement(self.y,
234                                                               self.rate)
235        self.assertTrue(len(result['artifacts']['noise_before_playback']) == 0)
236        self.assertTrue(len(result['artifacts']['noise_after_playback']) == 0)
237        self.assertTrue(len(result['artifacts']['delay_during_playback']) == 0)
238        self.assertTrue(len(result['artifacts']['burst_during_playback']) == 5)
239        self.assertTrue(len(result['volume_changes']) == 10)
240        self.assertTrue(result['equivalent_noise_level'] > 0.02)
241        for i in range(len(result['artifacts']['burst_during_playback'])):
242            delta = abs(self.burst_start_time[i] - result['artifacts'][
243                'burst_during_playback'][i])
244            self.assertTrue(delta < 0.002)
245
246    def test_volume_changing(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(
257            len(result['volume_changes']) == len(self.volume_changing))
258        for i in range(len(self.volume_changing)):
259            self.assertTrue(
260                abs(self.volume_changing_time[i] - result['volume_changes'][i][
261                    0]) < 0.01)
262            self.assertTrue(
263                self.volume_changing[i] == result['volume_changes'][i][1])
264
265
266if __name__ == '__main__':
267    unittest.main()
268