Mailing List Archive

Test results of linuxaudiodev.c
Hi --

here are results from testing linuxaudiodev from the latest CVS Python
1.6. This is on a Dell Dimension with on-board audio hardware: the
Yamaha YMF724 chipset. I'm using the ALSA 0.5.8a driver (the latest as
of a week or two ago, and the only one that supports the YMF724).

Bottom line: the test sound plays, but it sounds horrible when played by
linuxaudiodev. If I do this:

$ play Lib/test/audiotest.au

then Cardinal Fang comes through loud and clear. ("play" is a shell
script wrapper for "sox", writing to /dev/dsp.) But if I do this:

$ ./python Lib/test/regrtest.py test_linuxaudiodev

he's still audible (and at the same volume), but very scratchy. Sounds
kind of like a very over-driven amp, or like a cheap car radio that
somebody attacked with a knife.

[...some time passes...]

OK, I just tried it on another machine, also a Dell but with a different
sound chip: the Crystal CS4232. I'm pretty sure this one is using the
OSS drivers included with the kernel, which is probably the second most
important difference after the chipset itself. Bottom line: it also
sounds horrible.

Greg
--
Greg Ward - software developer gward@mems-exchange.org
MEMS Exchange / CNRI voice: +1-703-262-5376
Reston, Virginia, USA fax: +1-703-262-5367
Re: Test results of linuxaudiodev.c [ In reply to ]
>>>>> "GW" == Greg Ward <gward@mems-exchange.org> writes:

GW> then Cardinal Fang comes through loud and clear. ("play" is a
GW> shell script wrapper for "sox", writing to /dev/dsp.) But if
GW> I do this:

GW> $ ./python Lib/test/regrtest.py test_linuxaudiodev

GW> he's still audible (and at the same volume), but very
GW> scratchy. Sounds kind of like a very over-driven amp, or like
GW> a cheap car radio that somebody attacked with a knife.

I don't even get that. play works fine for me too, but on this Dell
Optiplex GX110 with unknown sound chip set, test_linuxaudiodev gives
me nothing.

-Barry
Re: Test results of linuxaudiodev.c [ In reply to ]
Greg Ward <gward@mems-exchange.org> writes:

> Hi --
>
> here are results from testing linuxaudiodev from the latest CVS Python
> 1.6. This is on a Dell Dimension with on-board audio hardware: the
> Yamaha YMF724 chipset. I'm using the ALSA 0.5.8a driver (the latest as
> of a week or two ago, and the only one that supports the YMF724).
>
> Bottom line: the test sound plays, but it sounds horrible when played by
> linuxaudiodev. If I do this:
>
> $ play Lib/test/audiotest.au
>
> then Cardinal Fang comes through loud and clear. ("play" is a shell
> script wrapper for "sox", writing to /dev/dsp.) But if I do this:
>
> $ ./python Lib/test/regrtest.py test_linuxaudiodev
>
> he's still audible (and at the same volume), but very scratchy. Sounds
> kind of like a very over-driven amp, or like a cheap car radio that
> somebody attacked with a knife.
>
> [...some time passes...]
>
> OK, I just tried it on another machine, also a Dell but with a different
> sound chip: the Crystal CS4232. I'm pretty sure this one is using the
> OSS drivers included with the kernel, which is probably the second most
> important difference after the chipset itself. Bottom line: it also
> sounds horrible.

Just tried that here; ouch. I have a Dell Dimension XPS D233 (which
has an on-board Yamaha chipset - the OPL2, I believe). I use the
sound driver that comes with the redhat built kernel (which is the OSS
one I think).

$ play audiotest.au

sounds fine,

$ ../../../build/python regrtest.py test_linuxaudiodev.py \
test_linuxaudiodev

sounds horrible; it sounds like it's being rammed through at far too
high a volume, but playing with the PCM or volume sliders in gmix has
no appreciable effect on the quality. This suggests somewhat that the
problem lies in linuxaudiodev.c, doesn't it?

Is this stuff, like, documented anywhere? I can't find any helpful
manpages...

I presume this module must work better than this for some people?

Cheers,
M.
Re: Test results of linuxaudiodev.c [ In reply to ]
On 29 Jun 2000, Michael Hudson wrote:
> $ play audiotest.au
>
> sounds fine,
>
> $ ../../../build/python regrtest.py test_linuxaudiodev.py \
> test_linuxaudiodev
>
> sounds horrible; it sounds like it's being rammed through at far too
> high a volume

Sounds like u-law to me. linuxaudiodev.c selects /dev/dsp by
default, which accepts raw data, not .au format.

Try setting the environment variable AUDIODEV to /dev/audio
before running the test script. Does that work any better?


-- ?!ng
Re: Test results of linuxaudiodev.c [ In reply to ]
Ka-Ping Yee <pingster@ilm.com> writes:

> On 29 Jun 2000, Michael Hudson wrote:
> > $ play audiotest.au
> >
> > sounds fine,
> >
> > $ ../../../build/python regrtest.py test_linuxaudiodev.py \
> > test_linuxaudiodev
> >
> > sounds horrible; it sounds like it's being rammed through at far too
> > high a volume
>
> Sounds like u-law to me. linuxaudiodev.c selects /dev/dsp by
> default, which accepts raw data, not .au format.
>
> Try setting the environment variable AUDIODEV to /dev/audio
> before running the test script. Does that work any better?

That's the ticket. "play" and the test now sound identical, modulo
some pops & cracks at the start and end of the test. I presume what
follows is thus a good idea?

Index: test_linuxaudiodev.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/test/test_linuxaudiodev.py,v
retrieving revision 1.1
diff -u -r1.1 test_linuxaudiodev.py
--- test_linuxaudiodev.py 2000/06/10 04:22:57 1.1
+++ test_linuxaudiodev.py 2000/06/29 23:32:55
@@ -17,4 +17,6 @@
def test():
play_sound_file(findfile('audiotest.au'))

+os.environ["AUDIODEV"] = "/dev/audio"
+
test()

Cheers,
M.
Re: Test results of linuxaudiodev.c [ In reply to ]
On Thu, 29 Jun 2000, Ka-Ping Yee wrote:
> Try setting the environment variable AUDIODEV to /dev/audio
> before running the test script. Does that work any better?

Even if that works, i realize that's not the way the interface
was intended to be used. To play an AU file, the routine should
look something like this (not tested, as i don't have a working
Linux box)...

def play_au_file(path):

fp = open(path, "r")

# Read the .au file header.
header = fp.read(24)
hdrsize, length, encoding, rate, channels = \
struct.unpack(">xxxxiiiii", header)
fp.read(hdrsize - 24)

data = fp.read()
fp.close()

# Set the data format according to the code in the .au header.
if encoding == 1:
size, fmt = 8, linuxaudiodev.AFMT_MU_LAW
elif encoding == 2:
size, fmt = 8, linuxaudiodev.AFMT_S8
elif encoding == 3:
size, fmt = 16, linuxaudiodev.AFMT_S16_BE
else:
raise "audio format not supported"

dsp = linuxaudiodev.open("w")
dsp.setparameters(rate, size, channels, fmt)
dsp.write(data)
dsp.close()


-- ?!ng

Explicit hoc totum; This completes the whole;
Pro Christo da mihi potum. For Christ's sake give me a drink.
-- from the colophon of a 12th-century copyist
Re: Test results of linuxaudiodev.c [ In reply to ]
Ka-Ping Yee <pingster@ilm.com> writes:

> On Thu, 29 Jun 2000, Ka-Ping Yee wrote:
> > Try setting the environment variable AUDIODEV to /dev/audio
> > before running the test script. Does that work any better?
>
> Even if that works, i realize that's not the way the interface
> was intended to be used. To play an AU file, the routine should
> look something like this (not tested, as i don't have a working
> Linux box)...
[snip]

Yup, that works fine. Don't understand the details - and as I have my
graduation ceremony tomorrow I'm going to go to bed and leave learning
them until some other occasion!

Cheers,
M.

PS: my Lib/test/test_linuxaudiodev.py is now this:

from test_support import verbose, findfile, TestFailed
import linuxaudiodev
import os,struct

def play_au_file(path):

fp = open(path, "r")

# Read the .au file header.
header = fp.read(24)
hdrsize, length, encoding, rate, channels = \
struct.unpack(">xxxxiiiii", header)
fp.read(hdrsize - 24)

data = fp.read()
fp.close()

# Set the data format according to the code in the .au header.
if encoding == 1:
size, fmt = 8, linuxaudiodev.AFMT_MU_LAW
elif encoding == 2:
size, fmt = 8, linuxaudiodev.AFMT_S8
elif encoding == 3:
size, fmt = 16, linuxaudiodev.AFMT_S16_BE
else:
raise "audio format not supported"

dsp = linuxaudiodev.open("w")
dsp.setparameters(rate, size, channels, fmt)
dsp.write(data)
dsp.close()


def test():
play_au_file(findfile('audiotest.au'))

test()

... which is an improvement on what's there now.
Re: Test results of linuxaudiodev.c [ In reply to ]
On 30 Jun 2000, Michael Hudson wrote:
> Yup, that works fine. Don't understand the details - and as I have my
> graduation ceremony tomorrow I'm going to go to bed and leave learning
> them until some other occasion!

Cool.

Okay, i just discovered sunau.py. Here's my real shot at
test_linuxaudiodev.py. Can you give this a try?


---- test_linuxaudiodev.py ----
from test_support import verbose, findfile, TestFailed
import linuxaudiodev
import os, sunau

formats = {("ULAW", 1): linuxaudiodev.AFMT_MU_LAW,
("NONE", 1): linuxaudiodev.AFMT_S8,
("NONE", 2): linuxaudiodev.AFMT_S16_BE}

def play_au_file(path):
au = sunau.open(path, "r")
data = au.readframes(sunau.AUDIO_UNKNOWN_SIZE)
au.close()

spec = (au.getcomptype(), au.getsampwidth())
if not has_key(formats, spec):
raise "audio format not supported by linuxaudiodev"

dsp = linuxaudiodev.open("w")
dsp.setparameters(au.getframerate(), au.getsampwidth() * 8,
au.getnchannels(), formats[spec])
dsp.write(data)
dsp.close()

def test():
play_au_file(findfile('audiotest.au'))

test()
---- test_linuxaudiodev.py ----



-- ?!ng
Re: Test results of linuxaudiodev.c [ In reply to ]
To python-dev: Sorry for the hiatus.

To python-list: does someone who knows about audio and can run linux
want to play with this (Ping and I fall into just one of these
categories each!).

Ka-Ping Yee <pingster@ilm.com> writes:

> On 30 Jun 2000, Michael Hudson wrote:
> > Yup, that works fine. Don't understand the details - and as I have my
> > graduation ceremony tomorrow I'm going to go to bed and leave learning
> > them until some other occasion!
>
> Cool.
>
> Okay, i just discovered sunau.py. Here's my real shot at
> test_linuxaudiodev.py. Can you give this a try?
>
>
> ---- test_linuxaudiodev.py ----
> from test_support import verbose, findfile, TestFailed
> import linuxaudiodev
> import os, sunau
>
> formats = {("ULAW", 1): linuxaudiodev.AFMT_MU_LAW,
> ("NONE", 1): linuxaudiodev.AFMT_S8,
> ("NONE", 2): linuxaudiodev.AFMT_S16_BE}
>
> def play_au_file(path):
> au = sunau.open(path, "r")
> data = au.readframes(sunau.AUDIO_UNKNOWN_SIZE)
> au.close()
>
> spec = (au.getcomptype(), au.getsampwidth())
> if not has_key(formats, spec):
^^^^^^^
Oops?

> raise "audio format not supported by linuxaudiodev"

Maybe you mean:

raise TestFailed, "audio format not supported by linuxaudiodev"

? I thought string exceptions were deprecated...

> dsp = linuxaudiodev.open("w")
> dsp.setparameters(au.getframerate(), au.getsampwidth() * 8,
> au.getnchannels(), formats[spec])
> dsp.write(data)
> dsp.close()
>
> def test():
> play_au_file(findfile('audiotest.au'))
>
> test()

This doesn't work. I don't really understand why.

For audiotest.au, |spec| is ("ULAW",2), which I don't think is right;
file(1) says

audiotest.au: Sun/NeXT audio data: 8-bit ISDN u-law, mono, 8000 Hz

So I think this could be a bug in sunau.

The other data (au.getframerate(), au.getnchannels()) agrees with
file(1).

Anybody have a better idea?

Cheers,
Michael Hudson, BA (as of today! woohoo!)
Re: Test results of linuxaudiodev.c [ In reply to ]
Ka-Ping Yee wrote:
>
> On 30 Jun 2000, Michael Hudson wrote:
> > Yup, that works fine. Don't understand the details - and as I have my
> > graduation ceremony tomorrow I'm going to go to bed and leave learning
> > them until some other occasion!
>
> Cool.
>
> Okay, i just discovered sunau.py. Here's my real shot at
> test_linuxaudiodev.py. Can you give this a try?
>
>
> ---- test_linuxaudiodev.py ----
> from test_support import verbose, findfile, TestFailed
> import linuxaudiodev
> import os, sunau

Yes, but this uses sunau which assumes the audioop.c module is enabled
(imported by readframes(), sunau.py line 259) which might not be the case.
Besides, Michael reported that it doesn't work quite right.

So I'd blindly vote for Michael Hudson's improved version which uses
only linuxaudiodev and plays the test sound without noise:

----------[ test_linuxaudiodev.py posted by Michael Hudson ]-----------

from test_support import verbose, findfile, TestFailed
import linuxaudiodev
import os,struct

def play_au_file(path):

fp = open(path, "r")

# Read the .au file header.
header = fp.read(24)
hdrsize, length, encoding, rate, channels = \
struct.unpack(">xxxxiiiii", header)
fp.read(hdrsize - 24)

data = fp.read()
fp.close()

# Set the data format according to the code in the .au header.
if encoding == 1:
size, fmt = 8, linuxaudiodev.AFMT_MU_LAW
elif encoding == 2:
size, fmt = 8, linuxaudiodev.AFMT_S8
elif encoding == 3:
size, fmt = 16, linuxaudiodev.AFMT_S16_BE
else:
raise "audio format not supported"

dsp = linuxaudiodev.open("w")
dsp.setparameters(rate, size, channels, fmt)
dsp.write(data)
dsp.close()


def test():
play_au_file(findfile('audiotest.au'))

test()

----------------------------------------------------------------------

--
Vladimir MARANGOZOV | Vladimir.Marangozov@inrialpes.fr
http://sirac.inrialpes.fr/~marangoz | tel:(+33-4)76615277 fax:76615252
Re: Test results of linuxaudiodev.c [ In reply to ]
[Ping]
> Okay, i just discovered sunau.py. Here's my real shot at
> test_linuxaudiodev.py. Can you give this a try?

Didn't work -- even after I changed has_key(formats, ...) to
formats.has_key(...). Here's what I get:

Traceback (most recent call last):
File "test_linuxaudiodev-ping.py", line 37, in ?
test()
File "test_linuxaudiodev-ping.py", line 35, in test
play_au_file(findfile('audiotest.au'))
File "test_linuxaudiodev-ping.py", line 26, in play_au_file
raise "audio format not supported by linuxaudiodev"
audio format not supported by linuxaudiodev

Sheesh, you'd think that plain old "Sun/NeXT audio data: 8-bit ISDN
u-law, mono, 8000 Hz" (this is what "file" reports on "audiotest.au")
would be supported. ;-)

So I tried Michael Hudson's version. It also failed, but in a more
interesting way. There mere traceback is not enough, but it's a start:

Traceback (most recent call last):
File "test_linuxaudiodev-hudson.py", line 62, in ?
test()
File "test_linuxaudiodev-hudson.py", line 60, in test
play_au_file(findfile('audiotest.au'))
File "test_linuxaudiodev-hudson.py", line 55, in play_au_file
dsp.write(data)
linuxaudiodev.error: (11, 'Resource temporarily unavailable')

Here's the sequence of events I get:

* run Michael's version of test_linuxaudiodev.py
* it *immediately* dumps the above traceback, but does not return
me to my shell prompt
* Cardinal Fang *does* start his famous proclamation, and it
sounds right (same as I get from "play audiotest.au")
* but it's truncated about 3/4 of the way through: "Nobody expects
the Spani----"
* and then Python terminates with exit status 1 (presumably due to
the traceback)

Very curious! I know next-to-nothing about both Python's exception
handling, sound drivers on Linux, and PC audio hardware. Any
speculation I might offer would probably be useless, so I will merely
comment that this is indeed curious.

Greg
--
Greg Ward - software developer gward@mems-exchange.org
MEMS Exchange / CNRI voice: +1-703-262-5376
Reston, Virginia, USA fax: +1-703-262-5367