diff options
Diffstat (limited to 'Lib/test/test_ossaudiodev.py')
-rw-r--r-- | Lib/test/test_ossaudiodev.py | 247 |
1 files changed, 130 insertions, 117 deletions
diff --git a/Lib/test/test_ossaudiodev.py b/Lib/test/test_ossaudiodev.py index 6ca1f74..eb15e88 100644 --- a/Lib/test/test_ossaudiodev.py +++ b/Lib/test/test_ossaudiodev.py @@ -1,7 +1,7 @@ from test import test_support test_support.requires('audio') -from test.test_support import verbose, findfile, TestFailed, TestSkipped +from test.test_support import verbose, findfile, TestSkipped import errno import fcntl @@ -12,6 +12,7 @@ import select import sunaudio import time import audioop +import unittest # Arggh, AFMT_S16_NE not defined on all platforms -- seems to be a # fairly recent addition to OSS. @@ -33,131 +34,143 @@ def read_sound_file(path): fp.close() if enc != SND_FORMAT_MULAW_8: - print("Expect .au file with 8-bit mu-law samples") - return + raise RuntimeError("Expect .au file with 8-bit mu-law samples") # Convert the data to 16-bit signed. data = audioop.ulaw2lin(data, 2) return (data, rate, 16, nchannels) -# version of assert that still works with -O -def _assert(expr, message=None): - if not expr: - raise AssertionError(message or "assertion failed") +class OSSAudioDevTests(unittest.TestCase): -def play_sound_file(data, rate, ssize, nchannels): - try: - dsp = ossaudiodev.open('w') - except IOError as msg: - if msg.args[0] in (errno.EACCES, errno.ENOENT, errno.ENODEV, errno.EBUSY): - raise TestSkipped, msg - raise TestFailed, msg - - # at least check that these methods can be invoked - dsp.bufsize() - dsp.obufcount() - dsp.obuffree() - dsp.getptr() - dsp.fileno() - - # Make sure the read-only attributes work. - _assert(dsp.closed is False, "dsp.closed is not False") - _assert(dsp.name == "/dev/dsp") - _assert(dsp.mode == 'w', "bad dsp.mode: %r" % dsp.mode) - - # And make sure they're really read-only. - for attr in ('closed', 'name', 'mode'): + def play_sound_file(self, data, rate, ssize, nchannels): try: - setattr(dsp, attr, 42) - raise RuntimeError("dsp.%s not read-only" % attr) - except TypeError: - pass - - # Compute expected running time of sound sample (in seconds). - expected_time = float(len(data)) / (ssize/8) / nchannels / rate - - # set parameters based on .au file headers - dsp.setparameters(AFMT_S16_NE, nchannels, rate) - print(("playing test sound file (expected running time: %.2f sec)" - % expected_time)) - t1 = time.time() - dsp.write(data) - dsp.close() - t2 = time.time() - elapsed_time = t2 - t1 - - percent_diff = (abs(elapsed_time - expected_time) / expected_time) * 100 - _assert(percent_diff <= 10.0, \ - ("elapsed time (%.2f sec) > 10%% off of expected time (%.2f sec)" - % (elapsed_time, expected_time))) - -def test_setparameters(dsp): - # Two configurations for testing: - # config1 (8-bit, mono, 8 kHz) should work on even the most - # ancient and crufty sound card, but maybe not on special- - # purpose high-end hardware - # config2 (16-bit, stereo, 44.1kHz) should work on all but the - # most ancient and crufty hardware - config1 = (ossaudiodev.AFMT_U8, 1, 8000) - config2 = (AFMT_S16_NE, 2, 44100) - - for config in [config1, config2]: - (fmt, channels, rate) = config - if (dsp.setfmt(fmt) == fmt and - dsp.channels(channels) == channels and - dsp.speed(rate) == rate): - break - else: - raise RuntimeError("unable to set audio sampling parameters: " - "you must have really weird audio hardware") - - # setparameters() should be able to set this configuration in - # either strict or non-strict mode. - result = dsp.setparameters(fmt, channels, rate, False) - _assert(result == (fmt, channels, rate), - "setparameters%r: returned %r" % (config, result)) - result = dsp.setparameters(fmt, channels, rate, True) - _assert(result == (fmt, channels, rate), - "setparameters%r: returned %r" % (config, result)) - -def test_bad_setparameters(dsp): - - # Now try some configurations that are presumably bogus: eg. 300 - # channels currently exceeds even Hollywood's ambitions, and - # negative sampling rate is utter nonsense. setparameters() should - # accept these in non-strict mode, returning something other than - # was requested, but should barf in strict mode. - fmt = AFMT_S16_NE - rate = 44100 - channels = 2 - for config in [(fmt, 300, rate), # ridiculous nchannels - (fmt, -5, rate), # impossible nchannels - (fmt, channels, -50), # impossible rate - ]: - (fmt, channels, rate) = config + dsp = ossaudiodev.open('w') + except IOError as msg: + if msg.args[0] in (errno.EACCES, errno.ENOENT, + errno.ENODEV, errno.EBUSY): + raise TestSkipped(msg) + raise + + # at least check that these methods can be invoked + dsp.bufsize() + dsp.obufcount() + dsp.obuffree() + dsp.getptr() + dsp.fileno() + + # Make sure the read-only attributes work. + self.failUnless(dsp.close) + self.assertEqual(dsp.name, "/dev/dsp") + self.assertEqual(dsp.mode, "w", "bad dsp.mode: %r" % dsp.mode) + + # And make sure they're really read-only. + for attr in ('closed', 'name', 'mode'): + try: + setattr(dsp, attr, 42) + except TypeError: + pass + else: + self.fail("dsp.%s not read-only" % attr) + + # Compute expected running time of sound sample (in seconds). + expected_time = float(len(data)) / (ssize/8) / nchannels / rate + + # set parameters based on .au file headers + dsp.setparameters(AFMT_S16_NE, nchannels, rate) + print ("playing test sound file (expected running time: %.2f sec)" + % expected_time) + t1 = time.time() + dsp.write(data) + dsp.close() + t2 = time.time() + elapsed_time = t2 - t1 + + percent_diff = (abs(elapsed_time - expected_time) / expected_time) * 100 + self.failUnless(percent_diff <= 10.0, + "elapsed time > 10% off of expected time") + + def set_parameters(self, dsp): + # Two configurations for testing: + # config1 (8-bit, mono, 8 kHz) should work on even the most + # ancient and crufty sound card, but maybe not on special- + # purpose high-end hardware + # config2 (16-bit, stereo, 44.1kHz) should work on all but the + # most ancient and crufty hardware + config1 = (ossaudiodev.AFMT_U8, 1, 8000) + config2 = (AFMT_S16_NE, 2, 44100) + + for config in [config1, config2]: + (fmt, channels, rate) = config + if (dsp.setfmt(fmt) == fmt and + dsp.channels(channels) == channels and + dsp.speed(rate) == rate): + break + else: + raise RuntimeError("unable to set audio sampling parameters: " + "you must have really weird audio hardware") + + # setparameters() should be able to set this configuration in + # either strict or non-strict mode. result = dsp.setparameters(fmt, channels, rate, False) - _assert(result != config, - "setparameters: unexpectedly got requested configuration") - + self.assertEqual(result, (fmt, channels, rate), + "setparameters%r: returned %r" % (config, result)) + + result = dsp.setparameters(fmt, channels, rate, True) + self.assertEqual(result, (fmt, channels, rate), + "setparameters%r: returned %r" % (config, result)) + + def set_bad_parameters(self, dsp): + + # Now try some configurations that are presumably bogus: eg. 300 + # channels currently exceeds even Hollywood's ambitions, and + # negative sampling rate is utter nonsense. setparameters() should + # accept these in non-strict mode, returning something other than + # was requested, but should barf in strict mode. + fmt = AFMT_S16_NE + rate = 44100 + channels = 2 + for config in [(fmt, 300, rate), # ridiculous nchannels + (fmt, -5, rate), # impossible nchannels + (fmt, channels, -50), # impossible rate + ]: + (fmt, channels, rate) = config + result = dsp.setparameters(fmt, channels, rate, False) + self.failIfEqual(result, config, + "unexpectedly got requested configuration") + + try: + result = dsp.setparameters(fmt, channels, rate, True) + except ossaudiodev.OSSAudioError as err: + pass + else: + self.fail("expected OSSAudioError") + + def test_playback(self): + sound_info = read_sound_file(findfile('audiotest.au')) + self.play_sound_file(*sound_info) + + def test_set_parameters(self): + dsp = ossaudiodev.open("w") try: - result = dsp.setparameters(fmt, channels, rate, True) - raise AssertionError("setparameters: expected OSSAudioError") - except ossaudiodev.OSSAudioError as err: - print("setparameters: got OSSAudioError as expected") + self.set_parameters(dsp) -def test(): - (data, rate, ssize, nchannels) = read_sound_file(findfile('audiotest.au')) - play_sound_file(data, rate, ssize, nchannels) + # Disabled because it fails under Linux 2.6 with ALSA's OSS + # emulation layer. + #self.set_bad_parameters(dsp) + finally: + dsp.close() + self.failUnless(dsp.closed) - dsp = ossaudiodev.open("w") - try: - test_setparameters(dsp) - - # Disabled because it fails under Linux 2.6 with ALSA's OSS - # emulation layer. - #test_bad_setparameters(dsp) - finally: - dsp.close() - _assert(dsp.closed is True, "dsp.closed is not True") -test() +def test_main(): + try: + dsp = ossaudiodev.open('w') + except IOError as msg: + if msg.args[0] in (errno.EACCES, errno.ENOENT, + errno.ENODEV, errno.EBUSY): + raise TestSkipped(msg) + raise + test_support.run_unittest(__name__) + +if __name__ == "__main__": + test_main() |