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 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() 269