1import unittest 2 3from ctypes import sizeof 4from io import BytesIO 5 6from pyglet.media.synthesis import * 7 8 9local_dir = os.path.dirname(__file__) 10test_data_path = os.path.abspath(os.path.join(local_dir, '..', '..', 'data')) 11del local_dir 12 13 14def get_test_data_file(*file_parts): 15 """Get a file from the test data directory in an OS independent way. 16 17 Supply relative file name as you would in os.path.join(). 18 """ 19 return os.path.join(test_data_path, *file_parts) 20 21 22class SynthesisSourceTest: 23 """Simple test to check if synthesized sources provide data.""" 24 source_class = None 25 26 def test_default(self): 27 source = self.source_class(1.) 28 self._test_total_duration(source) 29 if self.source_class is not WhiteNoise: 30 self._test_generated_bytes(source) 31 32 def test_sample_size_8(self): 33 source = self.source_class(1., sample_size=8) 34 self._test_total_duration(source) 35 if self.source_class is not WhiteNoise: 36 self._test_generated_bytes(source, sample_size=8) 37 38 def test_sample_rate_11025(self): 39 source = self.source_class(1., sample_rate=11025) 40 self._test_total_duration(source) 41 if self.source_class is not WhiteNoise: 42 self._test_generated_bytes(source, sample_rate=11025) 43 44 def _test_total_duration(self, source): 45 total_bytes = source.audio_format.bytes_per_second 46 self._check_audio_data(source, total_bytes, 1.) 47 48 def _check_audio_data(self, source, expected_bytes, expected_duration): 49 data = source.get_audio_data(expected_bytes + 100) 50 self.assertIsNotNone(data) 51 self.assertAlmostEqual(expected_bytes, data.length, delta=20) 52 self.assertAlmostEqual(expected_duration, data.duration) 53 54 self.assertIsNotNone(data.data) 55 if isinstance(data.data, (bytes, str)): 56 self.assertAlmostEqual(expected_bytes, len(data.data), delta=20) 57 else: 58 self.assertAlmostEqual(expected_bytes, sizeof(data.data), delta=20) 59 60 # Should now be out of data 61 last_data = source.get_audio_data(100) 62 self.assertIsNone(last_data) 63 64 def test_seek_default(self): 65 source = self.source_class(1.) 66 self._test_seek(source) 67 68 def test_seek_sample_size_8(self): 69 source = self.source_class(1., sample_size=8) 70 self._test_seek(source) 71 72 def _test_seek(self, source): 73 seek_time = .5 74 bytes_left = source.audio_format.bytes_per_second * .5 75 source.seek(seek_time) 76 self._check_audio_data(source, bytes_left, .5) 77 78 def _test_generated_bytes(self, source, sample_rate=44800, sample_size=16): 79 source_name = self.source_class.__name__.lower() 80 filename = "synthesis_{0}_{1}_{2}_1ch.wav".format(source_name, sample_size, sample_rate) 81 82 with open(get_test_data_file('media', filename), 'rb') as f: 83 # discard the wave header: 84 loaded_bytes = f.read()[44:] 85 source.seek(0) 86 generated_data = source.get_audio_data(source._max_offset) 87 bytes_buffer = BytesIO(generated_data.data).getvalue() 88 # Compare a small chunk, to avoid hanging on mismatch: 89 assert bytes_buffer[:1000] == loaded_bytes[:1000],\ 90 "Generated bytes do not match sample wave file." 91 92 93class SilenceTest(SynthesisSourceTest, unittest.TestCase): 94 source_class = Silence 95 96 97class WhiteNoiseTest(SynthesisSourceTest, unittest.TestCase): 98 source_class = WhiteNoise 99 100 101class SineTest(SynthesisSourceTest, unittest.TestCase): 102 source_class = Sine 103 104 105class TriangleTest(SynthesisSourceTest, unittest.TestCase): 106 source_class = Triangle 107 108 109class SawtoothTest(SynthesisSourceTest, unittest.TestCase): 110 source_class = Sawtooth 111 112 113class SquareTest(SynthesisSourceTest, unittest.TestCase): 114 source_class = Square 115 116 117class FMTest(SynthesisSourceTest, unittest.TestCase): 118 source_class = FM 119 120 121class DigitarTest(SynthesisSourceTest, unittest.TestCase): 122 source_class = Digitar 123