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