From 51dacc8e0e15c4e4f5169e52ace0258b66686086 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Sun, 26 Dec 1999 17:27:43 +0000 Subject: [PATCH] MMAP changes (/dev/snd/pcmcontrol). Removed unregister callback from snd_minor_t. --- include/pcm.h | 5 +--- src/pcm/pcm.c | 72 ++++++++++++++++++++++++++++++++++------------------- src/pcm/pcm_local.h | 2 ++ 3 files changed, 50 insertions(+), 29 deletions(-) diff --git a/include/pcm.h b/include/pcm.h index 32566e0b..e6ffb772 100644 --- a/include/pcm.h +++ b/include/pcm.h @@ -8,10 +8,7 @@ #define SND_PCM_OPEN_PLAYBACK 0x0001 #define SND_PCM_OPEN_CAPTURE 0x0002 #define SND_PCM_OPEN_DUPLEX 0x0003 -#define SND_PCM_OPEN_STREAM 0x1000 -#define SND_PCM_OPEN_STREAM_PLAYBACK 0x1001 -#define SND_PCM_OPEN_STREAM_CAPTURE 0x1002 -#define SND_PCM_OPEN_STREAM_DUPLEX 0x1003 +#define SND_PCM_OPEN_NONBLOCK 0x1000 #ifdef __cplusplus extern "C" { diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index 87e6a3d2..dd91f5b6 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -30,6 +30,7 @@ #include "pcm_local.h" #define SND_FILE_PCM "/dev/snd/pcmC%iD%i" +#define SND_FILE_PCM_CONTROL "/dev/snd/pcmcontrol" #define SND_PCM_VERSION_MAX SND_PROTOCOL_VERSION(1, 0, 0) int snd_pcm_open(snd_pcm_t **handle, int card, int device, int mode) @@ -37,13 +38,6 @@ int snd_pcm_open(snd_pcm_t **handle, int card, int device, int mode) return snd_pcm_open_subdevice(handle, card, device, -1, mode); } -#ifndef O_WRITEFLG -#define O_WRITEFLG 0x10000000 -#endif -#ifndef O_READFLG -#define O_READFLG 0x20000000 -#endif - int snd_pcm_open_subdevice(snd_pcm_t **handle, int card, int device, int subdevice, int mode) { int fd, fmode, ver, err, attempt = 0; @@ -58,16 +52,18 @@ int snd_pcm_open_subdevice(snd_pcm_t **handle, int card, int device, int subdevi return -EINVAL; if ((err = snd_ctl_open(&ctl, card)) < 0) return err; - fmode = O_RDWR; - if (mode & SND_PCM_OPEN_PLAYBACK) - fmode |= O_WRITEFLG; - if (mode & SND_PCM_OPEN_CAPTURE) - fmode |= O_READFLG; - if (fmode == O_RDWR) { + if ((mode & (SND_PCM_OPEN_PLAYBACK|SND_PCM_OPEN_CAPTURE)) == + (SND_PCM_OPEN_PLAYBACK|SND_PCM_OPEN_CAPTURE)) { + fmode = O_RDWR; + } else if (mode & SND_PCM_OPEN_PLAYBACK) { + fmode = O_WRONLY; + } else if (mode & SND_PCM_OPEN_CAPTURE) { + fmode = O_RDONLY; + } else { snd_ctl_close(ctl); return -EINVAL; } - if (mode & SND_PCM_OPEN_STREAM) + if (mode & SND_PCM_OPEN_NONBLOCK) fmode |= O_NONBLOCK; __again: if (attempt++ > 3) { @@ -133,6 +129,8 @@ int snd_pcm_open_subdevice(snd_pcm_t **handle, int card, int device, int subdevi pcm->device = device; pcm->fd = fd; pcm->mode = mode; + pcm->ver = ver; + pcm->mmap_ctrl_fd[0] = pcm->mmap_ctrl_fd[1] = -1; *handle = pcm; return 0; } @@ -394,9 +392,9 @@ ssize_t snd_pcm_read(snd_pcm_t *pcm, void *buffer, size_t size) int snd_pcm_mmap(snd_pcm_t *pcm, int channel, snd_pcm_mmap_control_t **control, void **buffer) { snd_pcm_channel_info_t info; - int err; + snd_pcm_mmap_select_t sel; + int err, ctrl_fd, ver, prot; void *caddr, *daddr; - off_t offset; if (control) *control = NULL; @@ -408,24 +406,44 @@ int snd_pcm_mmap(snd_pcm_t *pcm, int channel, snd_pcm_mmap_control_t **control, info.channel = channel; if ((err = snd_pcm_channel_info(pcm, &info))<0) return err; - offset = channel == SND_PCM_CHANNEL_PLAYBACK ? - SND_PCM_MMAP_OFFSET_PLAYBACK_CONTROL : - SND_PCM_MMAP_OFFSET_CAPTURE_CONTROL; - caddr = mmap(NULL, sizeof(snd_pcm_mmap_control_t), PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, pcm->fd, offset); - if (caddr == (caddr_t)-1 || caddr == NULL) + ctrl_fd = open(SND_FILE_PCM_CONTROL, O_RDWR); + if (ctrl_fd < 0) + return -errno; + if (ioctl(ctrl_fd, SND_PCM_CTRL_IOCTL_PVERSION, &ver) < 0) { + err = -errno; + close(ctrl_fd); + return err; + } + if (pcm->ver != ver) { + close(ctrl_fd); + return -SND_ERROR_INCOMPATIBLE_VERSION; + } + sel.card = pcm->card; + sel.device = pcm->device; + sel.subdevice = info.subdevice; + sel.channel = channel; + if (ioctl(ctrl_fd, SND_PCM_CTRL_IOCTL_SELECT, &sel) < 0) { + err = -errno; + close(ctrl_fd); + return err; + } + caddr = mmap(NULL, sizeof(snd_pcm_mmap_control_t), PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, ctrl_fd, SND_PCM_MMAP_OFFSET_CONTROL); + if (caddr == (caddr_t)-1 || caddr == NULL) { + close(ctrl_fd); return -errno; - offset = channel == SND_PCM_CHANNEL_PLAYBACK ? - SND_PCM_MMAP_OFFSET_PLAYBACK : - SND_PCM_MMAP_OFFSET_CAPTURE; - daddr = mmap(NULL, info.mmap_size, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, pcm->fd, offset); + } + prot = channel == SND_PCM_CHANNEL_PLAYBACK ? PROT_WRITE : PROT_READ; + daddr = mmap(NULL, info.mmap_size, prot, MAP_FILE|MAP_SHARED, ctrl_fd, SND_PCM_MMAP_OFFSET_DATA); if (daddr == (caddr_t)-1 || daddr == NULL) { err = -errno; munmap(caddr, sizeof(snd_pcm_mmap_control_t)); + close(ctrl_fd); return err; } *control = pcm->mmap_caddr[channel] = caddr; *buffer = pcm->mmap_daddr[channel] = daddr; pcm->mmap_size[channel] = info.mmap_size; + pcm->mmap_ctrl_fd[channel] = ctrl_fd; return 0; } @@ -442,5 +460,9 @@ int snd_pcm_munmap(snd_pcm_t *pcm, int channel) pcm->mmap_daddr[channel] = NULL; pcm->mmap_size[channel] = 0; } + if (pcm->mmap_ctrl_fd[channel] >= 0) { + close(pcm->mmap_ctrl_fd[channel]); + pcm->mmap_ctrl_fd[channel] = -1; + } return 0; } diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h index 271a1769..7fd9714a 100644 --- a/src/pcm/pcm_local.h +++ b/src/pcm/pcm_local.h @@ -26,8 +26,10 @@ struct snd_pcm { int device; int fd; int mode; + int ver; int setup_is_valid[2]; snd_pcm_channel_setup_t setup[2]; + int mmap_ctrl_fd[2]; snd_pcm_mmap_control_t *mmap_caddr[2]; char *mmap_daddr[2]; long mmap_size[2]; -- 2.11.0