Home | History | Annotate | Download | only in audio
      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 
      6 import logging
      7 import math
      8 import numpy
      9 import unittest
     10 
     11 import common
     12 from autotest_lib.client.cros.audio import audio_data
     13 from autotest_lib.client.cros.audio import audio_quality_measurement
     14 
     15 class 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 
     51 class 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 
     61 class 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 
    265 if __name__ == '__main__':
    266     unittest.main()
    267