Skip site navigation (1)Skip section navigation (2)
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>