Home | History | Annotate | Download | only in tests
      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 import logging
     18 import math
     19 import numpy
     20 import unittest
     21 
     22 import acts.test_utils.audio_analysis_lib.audio_data as audio_data
     23 import acts.test_utils.audio_analysis_lib.audio_analysis as audio_analysis
     24 import acts.test_utils.audio_analysis_lib.audio_quality_measurement as \
     25     audio_quality_measurement
     26 
     27 
     28 class 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 
     63 class 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 
     73 class 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 
    267 if __name__ == '__main__':
    268     unittest.main()
    269