Commit | Line | Data |
---|---|---|
920dae64 AT |
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 | ||
44 | def play_sound_file(data, rate, ssize, nchannels): | |
45 | try: | |
46 | dsp = ossaudiodev.open('w') | |
47 | except IOError, msg: | |
48 | if msg[0] in (errno.EACCES, errno.ENODEV, errno.EBUSY): | |
49 | raise TestSkipped, msg | |
50 | raise TestFailed, msg | |
51 | ||
52 | # at least check that these methods can be invoked | |
53 | dsp.bufsize() | |
54 | dsp.obufcount() | |
55 | dsp.obuffree() | |
56 | dsp.getptr() | |
57 | dsp.fileno() | |
58 | ||
59 | # set parameters based on .au file headers | |
60 | dsp.setparameters(AFMT_S16_NE, nchannels, rate) | |
61 | t1 = time.time() | |
62 | print "playing test sound file..." | |
63 | dsp.write(data) | |
64 | dsp.close() | |
65 | t2 = time.time() | |
66 | print "elapsed time: %.1f sec" % (t2-t1) | |
67 | ||
68 | def test_setparameters(dsp): | |
69 | # Two configurations for testing: | |
70 | # config1 (8-bit, mono, 8 kHz) should work on even the most | |
71 | # ancient and crufty sound card, but maybe not on special- | |
72 | # purpose high-end hardware | |
73 | # config2 (16-bit, stereo, 44.1kHz) should work on all but the | |
74 | # most ancient and crufty hardware | |
75 | config1 = (ossaudiodev.AFMT_U8, 1, 8000) | |
76 | config2 = (AFMT_S16_NE, 2, 44100) | |
77 | ||
78 | for config in [config1, config2]: | |
79 | (fmt, channels, rate) = config | |
80 | if (dsp.setfmt(fmt) == fmt and | |
81 | dsp.channels(channels) == channels and | |
82 | dsp.speed(rate) == rate): | |
83 | break | |
84 | else: | |
85 | raise RuntimeError("unable to set audio sampling parameters: " | |
86 | "you must have really weird audio hardware") | |
87 | ||
88 | # setparameters() should be able to set this configuration in | |
89 | # either strict or non-strict mode. | |
90 | result = dsp.setparameters(fmt, channels, rate, False) | |
91 | assert result == (fmt, channels, rate), \ | |
92 | "setparameters%r: returned %r" % (config + result) | |
93 | result = dsp.setparameters(fmt, channels, rate, True) | |
94 | assert result == (fmt, channels, rate), \ | |
95 | "setparameters%r: returned %r" % (config + result) | |
96 | ||
97 | def test_bad_setparameters(dsp): | |
98 | ||
99 | # Now try some configurations that are presumably bogus: eg. 300 | |
100 | # channels currently exceeds even Hollywood's ambitions, and | |
101 | # negative sampling rate is utter nonsense. setparameters() should | |
102 | # accept these in non-strict mode, returning something other than | |
103 | # was requested, but should barf in strict mode. | |
104 | fmt = AFMT_S16_NE | |
105 | rate = 44100 | |
106 | channels = 2 | |
107 | for config in [(fmt, 300, rate), # ridiculous nchannels | |
108 | (fmt, -5, rate), # impossible nchannels | |
109 | (fmt, channels, -50), # impossible rate | |
110 | ]: | |
111 | (fmt, channels, rate) = config | |
112 | result = dsp.setparameters(fmt, channels, rate, False) | |
113 | assert result != config, \ | |
114 | "setparameters: unexpectedly got requested configuration" | |
115 | ||
116 | try: | |
117 | result = dsp.setparameters(fmt, channels, rate, True) | |
118 | raise AssertionError("setparameters: expected OSSAudioError") | |
119 | except ossaudiodev.OSSAudioError, err: | |
120 | print "setparameters: got OSSAudioError as expected" | |
121 | ||
122 | def test(): | |
123 | (data, rate, ssize, nchannels) = read_sound_file(findfile('audiotest.au')) | |
124 | play_sound_file(data, rate, ssize, nchannels) | |
125 | ||
126 | dsp = ossaudiodev.open("w") | |
127 | try: | |
128 | test_setparameters(dsp) | |
129 | ||
130 | # Disabled because it fails under Linux 2.6 with ALSA's OSS | |
131 | # emulation layer. | |
132 | #test_bad_setparameters(dsp) | |
133 | finally: | |
134 | dsp.close() | |
135 | ||
136 | test() |