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