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