python-2.5.2/win32/Lib/test/test_ossaudiodev.py
changeset 0 ae805ac0140d
equal deleted inserted replaced
-1:000000000000 0:ae805ac0140d
       
     1 from test import test_support
       
     2 test_support.requires('audio')
       
     3 
       
     4 from test.test_support import verbose, findfile, TestFailed, TestSkipped
       
     5 
       
     6 import errno
       
     7 import fcntl
       
     8 import ossaudiodev
       
     9 import os
       
    10 import sys
       
    11 import select
       
    12 import sunaudio
       
    13 import time
       
    14 import audioop
       
    15 
       
    16 # Arggh, AFMT_S16_NE not defined on all platforms -- seems to be a
       
    17 # fairly recent addition to OSS.
       
    18 try:
       
    19     from ossaudiodev import AFMT_S16_NE
       
    20 except ImportError:
       
    21     if sys.byteorder == "little":
       
    22         AFMT_S16_NE = ossaudiodev.AFMT_S16_LE
       
    23     else:
       
    24         AFMT_S16_NE = ossaudiodev.AFMT_S16_BE
       
    25 
       
    26 
       
    27 SND_FORMAT_MULAW_8 = 1
       
    28 
       
    29 def read_sound_file(path):
       
    30     fp = open(path, 'rb')
       
    31     size, enc, rate, nchannels, extra = sunaudio.gethdr(fp)
       
    32     data = fp.read()
       
    33     fp.close()
       
    34 
       
    35     if enc != SND_FORMAT_MULAW_8:
       
    36         print "Expect .au file with 8-bit mu-law samples"
       
    37         return
       
    38 
       
    39     # Convert the data to 16-bit signed.
       
    40     data = audioop.ulaw2lin(data, 2)
       
    41     return (data, rate, 16, nchannels)
       
    42 
       
    43 # version of assert that still works with -O
       
    44 def _assert(expr, message=None):
       
    45     if not expr:
       
    46         raise AssertionError(message or "assertion failed")
       
    47 
       
    48 def play_sound_file(data, rate, ssize, nchannels):
       
    49     try:
       
    50         dsp = ossaudiodev.open('w')
       
    51     except IOError, msg:
       
    52         if msg[0] in (errno.EACCES, errno.ENOENT, errno.ENODEV, errno.EBUSY):
       
    53             raise TestSkipped, msg
       
    54         raise TestFailed, msg
       
    55 
       
    56     # at least check that these methods can be invoked
       
    57     dsp.bufsize()
       
    58     dsp.obufcount()
       
    59     dsp.obuffree()
       
    60     dsp.getptr()
       
    61     dsp.fileno()
       
    62 
       
    63     # Make sure the read-only attributes work.
       
    64     _assert(dsp.closed is False, "dsp.closed is not False")
       
    65     _assert(dsp.name == "/dev/dsp")
       
    66     _assert(dsp.mode == 'w', "bad dsp.mode: %r" % dsp.mode)
       
    67 
       
    68     # And make sure they're really read-only.
       
    69     for attr in ('closed', 'name', 'mode'):
       
    70         try:
       
    71             setattr(dsp, attr, 42)
       
    72             raise RuntimeError("dsp.%s not read-only" % attr)
       
    73         except TypeError:
       
    74             pass
       
    75 
       
    76     # Compute expected running time of sound sample (in seconds).
       
    77     expected_time = float(len(data)) / (ssize/8) / nchannels / rate
       
    78 
       
    79     # set parameters based on .au file headers
       
    80     dsp.setparameters(AFMT_S16_NE, nchannels, rate)
       
    81     print ("playing test sound file (expected running time: %.2f sec)"
       
    82            % expected_time)
       
    83     t1 = time.time()
       
    84     dsp.write(data)
       
    85     dsp.close()
       
    86     t2 = time.time()
       
    87     elapsed_time = t2 - t1
       
    88 
       
    89     percent_diff = (abs(elapsed_time - expected_time) / expected_time) * 100
       
    90     _assert(percent_diff <= 10.0, \
       
    91             ("elapsed time (%.2f sec) > 10%% off of expected time (%.2f sec)"
       
    92              % (elapsed_time, expected_time)))
       
    93 
       
    94 def test_setparameters(dsp):
       
    95     # Two configurations for testing:
       
    96     #   config1 (8-bit, mono, 8 kHz) should work on even the most
       
    97     #      ancient and crufty sound card, but maybe not on special-
       
    98     #      purpose high-end hardware
       
    99     #   config2 (16-bit, stereo, 44.1kHz) should work on all but the
       
   100     #      most ancient and crufty hardware
       
   101     config1 = (ossaudiodev.AFMT_U8, 1, 8000)
       
   102     config2 = (AFMT_S16_NE, 2, 44100)
       
   103 
       
   104     for config in [config1, config2]:
       
   105         (fmt, channels, rate) = config
       
   106         if (dsp.setfmt(fmt) == fmt and
       
   107             dsp.channels(channels) == channels and
       
   108             dsp.speed(rate) == rate):
       
   109             break
       
   110     else:
       
   111         raise RuntimeError("unable to set audio sampling parameters: "
       
   112                            "you must have really weird audio hardware")
       
   113 
       
   114     # setparameters() should be able to set this configuration in
       
   115     # either strict or non-strict mode.
       
   116     result = dsp.setparameters(fmt, channels, rate, False)
       
   117     _assert(result == (fmt, channels, rate),
       
   118             "setparameters%r: returned %r" % (config, result))
       
   119     result = dsp.setparameters(fmt, channels, rate, True)
       
   120     _assert(result == (fmt, channels, rate),
       
   121             "setparameters%r: returned %r" % (config, result))
       
   122 
       
   123 def test_bad_setparameters(dsp):
       
   124 
       
   125     # Now try some configurations that are presumably bogus: eg. 300
       
   126     # channels currently exceeds even Hollywood's ambitions, and
       
   127     # negative sampling rate is utter nonsense.  setparameters() should
       
   128     # accept these in non-strict mode, returning something other than
       
   129     # was requested, but should barf in strict mode.
       
   130     fmt = AFMT_S16_NE
       
   131     rate = 44100
       
   132     channels = 2
       
   133     for config in [(fmt, 300, rate),       # ridiculous nchannels
       
   134                    (fmt, -5, rate),        # impossible nchannels
       
   135                    (fmt, channels, -50),   # impossible rate
       
   136                   ]:
       
   137         (fmt, channels, rate) = config
       
   138         result = dsp.setparameters(fmt, channels, rate, False)
       
   139         _assert(result != config,
       
   140                 "setparameters: unexpectedly got requested configuration")
       
   141 
       
   142         try:
       
   143             result = dsp.setparameters(fmt, channels, rate, True)
       
   144             raise AssertionError("setparameters: expected OSSAudioError")
       
   145         except ossaudiodev.OSSAudioError, err:
       
   146             print "setparameters: got OSSAudioError as expected"
       
   147 
       
   148 def test():
       
   149     (data, rate, ssize, nchannels) = read_sound_file(findfile('audiotest.au'))
       
   150     play_sound_file(data, rate, ssize, nchannels)
       
   151 
       
   152     dsp = ossaudiodev.open("w")
       
   153     try:
       
   154         test_setparameters(dsp)
       
   155 
       
   156         # Disabled because it fails under Linux 2.6 with ALSA's OSS
       
   157         # emulation layer.
       
   158         #test_bad_setparameters(dsp)
       
   159     finally:
       
   160         dsp.close()
       
   161         _assert(dsp.closed is True, "dsp.closed is not True")
       
   162 
       
   163 test()