blob: 0166ce9ef50a246044aeb6d76954242c346c8d01 [file] [log] [blame]
markdrdd1893d2018-02-05 17:13:47 -08001#!/usr/bin/env python3
tturney91191de2017-11-16 15:07:17 -08002#
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
17import logging
18import math
19import numpy
20import unittest
21
22import acts.test_utils.audio_analysis_lib.audio_data as audio_data
23import acts.test_utils.audio_analysis_lib.audio_analysis as audio_analysis
24import acts.test_utils.audio_analysis_lib.audio_quality_measurement as \
25 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 testNoiseLevel(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 testError(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 testGoodSignal(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 testGoodSignalNoise(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'] and
174 result['equivalent_noise_level'] < 0.011)
175
176 def testDelay(self):
177 """Sine wave with delay during playing."""
178 self.generate_delay()
179 result = audio_quality_measurement.quality_measurement(self.y,
180 self.rate)
181 self.assertTrue(len(result['artifacts']['noise_before_playback']) == 0)
182 self.assertTrue(len(result['artifacts']['noise_after_playback']) == 0)
183 self.assertTrue(
184 len(result['volume_changes']) == 2 * len(self.delay_start_time))
185 self.assertTrue(result['equivalent_noise_level'] < 0.005)
186
187 self.assertTrue(
188 len(result['artifacts']['delay_during_playback']) ==
189 len(self.delay_start_time))
190 for i in range(len(result['artifacts']['delay_during_playback'])):
191 delta = abs(result['artifacts']['delay_during_playback'][i][0] -
192 self.delay_start_time[i])
193 self.assertTrue(delta < 0.001)
194 duration = self.delay_end_time[i] - self.delay_start_time[i]
195 delta = abs(result['artifacts']['delay_during_playback'][i][1] -
196 duration)
197 self.assertTrue(delta < 0.001)
198
199 def testArtifactsBeforePlayback(self):
200 """Sine wave with artifacts before playback."""
201 self.generate_artifacts_before_playback()
202 result = audio_quality_measurement.quality_measurement(self.y,
203 self.rate)
204 self.assertTrue(len(result['artifacts']['noise_before_playback']) == 1)
205 delta = abs(result['artifacts']['noise_before_playback'][0][0] - 0.1)
206 self.assertTrue(delta < 0.01)
207 delta = abs(result['artifacts']['noise_before_playback'][0][1] - 0.005)
208 self.assertTrue(delta < 0.004)
209 self.assertTrue(len(result['artifacts']['noise_after_playback']) == 0)
210 self.assertTrue(len(result['artifacts']['delay_during_playback']) == 0)
211 self.assertTrue(len(result['artifacts']['burst_during_playback']) == 0)
212 self.assertTrue(len(result['volume_changes']) == 0)
213 self.assertTrue(result['equivalent_noise_level'] < 0.005)
214
215 def testArtifactsAfterPlayback(self):
216 """Sine wave with artifacts after playback."""
217 self.generate_artifacts_after_playback()
218 result = audio_quality_measurement.quality_measurement(self.y,
219 self.rate)
220 self.assertTrue(len(result['artifacts']['noise_before_playback']) == 0)
221 self.assertTrue(len(result['artifacts']['noise_after_playback']) == 1)
222 delta = abs(result['artifacts']['noise_after_playback'][0][0] - 1.95)
223 self.assertTrue(delta < 0.01)
224 delta = abs(result['artifacts']['noise_after_playback'][0][1] - 0.02)
225 self.assertTrue(delta < 0.001)
226 self.assertTrue(len(result['artifacts']['delay_during_playback']) == 0)
227 self.assertTrue(len(result['artifacts']['burst_during_playback']) == 0)
228 self.assertTrue(len(result['volume_changes']) == 0)
229 self.assertTrue(result['equivalent_noise_level'] < 0.005)
230
231 def testBurstDuringPlayback(self):
232 """Sine wave with burst during playback."""
233 self.generate_burst_during_playback()
234 result = audio_quality_measurement.quality_measurement(self.y,
235 self.rate)
236 self.assertTrue(len(result['artifacts']['noise_before_playback']) == 0)
237 self.assertTrue(len(result['artifacts']['noise_after_playback']) == 0)
238 self.assertTrue(len(result['artifacts']['delay_during_playback']) == 0)
239 self.assertTrue(len(result['artifacts']['burst_during_playback']) == 5)
240 self.assertTrue(len(result['volume_changes']) == 10)
241 self.assertTrue(result['equivalent_noise_level'] > 0.02)
242 for i in range(len(result['artifacts']['burst_during_playback'])):
243 delta = abs(self.burst_start_time[i] - result['artifacts'][
244 'burst_during_playback'][i])
245 self.assertTrue(delta < 0.002)
246
247 def testVolumeChanging(self):
248 """Sine wave with volume changing during playback."""
249 self.generate_volume_changing()
250 result = audio_quality_measurement.quality_measurement(self.y,
251 self.rate)
252 self.assertTrue(len(result['artifacts']['noise_before_playback']) == 0)
253 self.assertTrue(len(result['artifacts']['noise_after_playback']) == 0)
254 self.assertTrue(len(result['artifacts']['delay_during_playback']) == 0)
255 self.assertTrue(len(result['artifacts']['burst_during_playback']) == 0)
256 self.assertTrue(result['equivalent_noise_level'] < 0.005)
257 self.assertTrue(
258 len(result['volume_changes']) == len(self.volume_changing))
259 for i in range(len(self.volume_changing)):
260 self.assertTrue(
261 abs(self.volume_changing_time[i] - result['volume_changes'][i][
262 0]) < 0.01)
263 self.assertTrue(
264 self.volume_changing[i] == result['volume_changes'][i][1])
265
266
267if __name__ == '__main__':
268 unittest.main()