Date: Thu, 6 Apr 2000 17:54:22 -0400 From: Alexander Matey <matey@cis.ohio-state.edu> To: Cameron Grant <gandalf@vilnya.demon.co.uk> Cc: freebsd-hackers@freebsd.org Subject: newpcm - multiple playback channels support Message-ID: <20000406175422.A391@cis.ohio-state.edu>
next in thread | raw e-mail | index | archive | help
Hello Cameron,
I was playing around newpcm quite a bit lately and noticed the
following. All device nodes (dsp%d.%d, ...) which newpcm code registers
if more than a single playback/recording channel is supported by
a sound card driver have same minor number which ultimately points to
channel 0 (I'm wondering how t4dwave.c has been able to support 4
playback channels). DEVFS entries look like this:
lx$kazoo:/sys/kern ll /d/dsp*
crw-rw-rw- 1 root wheel - 30, 3 6 Apr 09:00 /d/dsp0.0
crw-rw-rw- 1 root wheel - 30, 3 6 Apr 09:00 /d/dsp0.1
crw-rw-rw- 1 root wheel - 30, 3 6 Apr 09:00 /d/dsp0.2
crw-rw-rw- 1 root wheel - 30, 3 6 Apr 09:00 /d/dsp0.3
The source of the problem seems to be the code in /sys/dev/sound/pcm/sound.c.
Macros PCMMKMINOR(u, d, c) and PCMCHAN(x) use 2nd byte to store the
channel index in device minor:
#define PCMMINOR(x) (minor(x))
#define PCMCHAN(x) ((PCMMINOR(x) & 0x0000ff00) >> 8)
#define PCMUNIT(x) ((PCMMINOR(x) & 0x000000f0) >> 4)
#define PCMDEV(x) (PCMMINOR(x) & 0x0000000f)
#define PCMMKMINOR(u, d, c) ((((c) & 0xff) << 8) | (((u) & 0x0f) << 4) | ((d) & 0x0f))
And minor() from /sys/kern/kern_conf.c masks out 2nd byte because
it's used by makedev() (also from /sys/kern/kern_conf.c) to store device
major number. We're losing channel index here:
int
minor(dev_t x)
{
if (x == NODEV)
return NOUDEV;
return(x->si_udev & 0xffff00ff);
}
The following patch to sound.c moves audio channel index to 3rd byte of device
minor number:
lx$kazoo:/snd/pcm diff ~/cvs/sys_dev_sound/pcm/sound.c ./sound.c
69c69
< currently minor = (channel << 8) + (unit << 4) + dev
---
> currently minor = (channel << 16) + (unit << 4) + dev
80c80
< minor = (channel << 8) + (unit << 4) + dev
---
> minor = (channel << 16) + (unit << 4) + dev
84c84
< #define PCMCHAN(x) ((PCMMINOR(x) & 0x0000ff00) >> 8)
---
> #define PCMCHAN(x) ((PCMMINOR(x) & 0x00ff0000) >> 16)
87c87
< #define PCMMKMINOR(u, d, c) ((((c) & 0xff) << 8) | (((u) & 0x0f) << 4) | ((d) & 0x0f))
---
> #define PCMMKMINOR(u, d, c) ((((c) & 0xff) << 16) | (((u) & 0x0f) << 4) | ((d) & 0x0f))
After applying this patch:
lx$kazoo:/sys/kern ll /d/dsp*
crw-rw-rw- 1 root wheel - 30, 3 6 Apr 17:14 /d/dsp0.0
crw-rw-rw- 1 root wheel - 30, 0x00010003 6 Apr 17:14 /d/dsp0.1
crw-rw-rw- 1 root wheel - 30, 0x00020003 6 Apr 17:14 /d/dsp0.2
crw-rw-rw- 1 root wheel - 30, 0x00030003 6 Apr 17:14 /d/dsp0.3
I successfully tested this configuration with 4 instances of mpg123
playing 4 different streams thru dsp0.[0-3] simultaneously on my Diamond
MX-300 card. I'm currently in the process of porting Aureal's linux driver
for au88x0 chipsets to FreeBSD (yes, it contains binary only modules,
unfortunately).
If this change isn't breaking anything I think we could consider
incorporating this into /sys/dev/sound/pcm/sound.c. /dev/MAKEDEV does
not need to be updated since it only creates device nodes for channel 0.
Any comments?
--
Alexander Matey
Columbus, OH
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20000406175422.A391>
