From: Jaroslav Kysela Date: Mon, 30 Oct 2000 12:15:18 +0000 (+0000) Subject: Added functions: X-Git-Tag: v1.0.3~1087 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=0e561770c6fedb025a3446d8149dfdcc3fa71b77;p=alsa-lib.git Added functions: snd_ctl_rawmidi_prefer_subdevice snd_rawmidi_open_subdevice Fixed functions: snd_pcm_hw_open - fixed prefer subdevice code --- diff --git a/aserver/aserver.c b/aserver/aserver.c index 84d71099..5e54d0b0 100644 --- a/aserver/aserver.c +++ b/aserver/aserver.c @@ -627,6 +627,9 @@ int ctl_shm_cmd(client_t *client) case SND_CTL_IOCTL_RAWMIDI_INFO: ctrl->result = snd_ctl_rawmidi_info(ctl, &ctrl->u.rawmidi_info); break; + case SND_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE: + ctrl->result = snd_ctl_rawmidi_prefer_subdevice(ctl, ctrl->u.rawmidi_prefer_subdevice); + break; case SND_CTL_IOCTL_READ: ctrl->result = snd_ctl_read1(ctl, &ctrl->u.read); break; diff --git a/include/aserver.h b/include/aserver.h index 3469b043..85823fd8 100644 --- a/include/aserver.h +++ b/include/aserver.h @@ -92,6 +92,7 @@ typedef struct { snd_pcm_info_t pcm_info; int pcm_prefer_subdevice; snd_rawmidi_info_t rawmidi_info; + int rawmidi_prefer_subdevice; snd_ctl_event_t read; } u; char data[0]; diff --git a/include/control.h b/include/control.h index e1221a76..864a39e4 100644 --- a/include/control.h +++ b/include/control.h @@ -55,6 +55,7 @@ int snd_ctl_hwdep_info(snd_ctl_t *handle, snd_hwdep_info_t * info); int snd_ctl_pcm_info(snd_ctl_t *handle, snd_pcm_info_t * info); int snd_ctl_pcm_prefer_subdevice(snd_ctl_t *handle, int subdev); int snd_ctl_rawmidi_info(snd_ctl_t *handle, snd_rawmidi_info_t * info); +int snd_ctl_rawmidi_prefer_subdevice(snd_ctl_t *handle, int subdev); int snd_ctl_read(snd_ctl_t *handle, snd_ctl_callbacks_t * callbacks); diff --git a/include/rawmidi.h b/include/rawmidi.h index b69c2703..4fbce8e6 100644 --- a/include/rawmidi.h +++ b/include/rawmidi.h @@ -18,6 +18,7 @@ extern "C" { typedef struct snd_rawmidi snd_rawmidi_t; +int snd_rawmidi_open_subdevice(snd_rawmidi_t **handle, int card, int device, int subdevice, int mode); int snd_rawmidi_open(snd_rawmidi_t **handle, int card, int device, int mode); int snd_rawmidi_close(snd_rawmidi_t *handle); int snd_rawmidi_poll_descriptor(snd_rawmidi_t *handle); diff --git a/src/control/control.c b/src/control/control.c index 341af124..40c90075 100644 --- a/src/control/control.c +++ b/src/control/control.c @@ -104,6 +104,12 @@ int snd_ctl_rawmidi_info(snd_ctl_t *ctl, snd_rawmidi_info_t * info) return ctl->ops->rawmidi_info(ctl, info); } +int snd_ctl_rawmidi_prefer_subdevice(snd_ctl_t *ctl, int subdev) +{ + assert(ctl); + return ctl->ops->rawmidi_prefer_subdevice(ctl, subdev); +} + int snd_ctl_read1(snd_ctl_t *ctl, snd_ctl_event_t *event) { assert(ctl && event); diff --git a/src/control/control_hw.c b/src/control/control_hw.c index 5d58ab12..eb805ae9 100644 --- a/src/control/control_hw.c +++ b/src/control/control_hw.c @@ -126,6 +126,14 @@ static int snd_ctl_hw_rawmidi_info(snd_ctl_t *handle, snd_rawmidi_info_t * info) return 0; } +static int snd_ctl_hw_rawmidi_prefer_subdevice(snd_ctl_t *handle, int subdev) +{ + snd_ctl_hw_t *hw = handle->private; + if (ioctl(hw->fd, SND_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE, &subdev) < 0) + return -errno; + return 0; +} + static int snd_ctl_hw_read(snd_ctl_t *handle, snd_ctl_event_t *event) { snd_ctl_hw_t *hw = handle->private; @@ -144,6 +152,7 @@ struct snd_ctl_ops snd_ctl_hw_ops = { pcm_info: snd_ctl_hw_pcm_info, pcm_prefer_subdevice: snd_ctl_hw_pcm_prefer_subdevice, rawmidi_info: snd_ctl_hw_rawmidi_info, + rawmidi_prefer_subdevice: snd_ctl_hw_rawmidi_prefer_subdevice, read: snd_ctl_hw_read, }; diff --git a/src/control/control_local.h b/src/control/control_local.h index 34f302d4..8f912ccb 100644 --- a/src/control/control_local.h +++ b/src/control/control_local.h @@ -35,6 +35,7 @@ struct snd_ctl_ops { int (*pcm_info)(snd_ctl_t *handle, snd_pcm_info_t * info); int (*pcm_prefer_subdevice)(snd_ctl_t *handle, int subdev); int (*rawmidi_info)(snd_ctl_t *handle, snd_rawmidi_info_t * info); + int (*rawmidi_prefer_subdevice)(snd_ctl_t *handle, int subdev); int (*read)(snd_ctl_t *handle, snd_ctl_event_t *event); }; diff --git a/src/control/control_shm.c b/src/control/control_shm.c index 968e1461..02210c74 100644 --- a/src/control/control_shm.c +++ b/src/control/control_shm.c @@ -239,6 +239,19 @@ static int snd_ctl_shm_rawmidi_info(snd_ctl_t *ctl, snd_rawmidi_info_t * info) return err; } +static int snd_ctl_shm_rawmidi_prefer_subdevice(snd_ctl_t *ctl, int subdev) +{ + snd_ctl_shm_t *shm = ctl->private; + snd_ctl_shm_ctrl_t *ctrl = shm->ctrl; + int err; + ctrl->u.rawmidi_prefer_subdevice = subdev; + ctrl->cmd = SND_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE; + err = snd_ctl_shm_action(ctl); + if (err < 0) + return err; + return err; +} + static int snd_ctl_shm_read(snd_ctl_t *ctl, snd_ctl_event_t *event) { snd_ctl_shm_t *shm = ctl->private; @@ -265,6 +278,7 @@ struct snd_ctl_ops snd_ctl_shm_ops = { pcm_info: snd_ctl_shm_pcm_info, pcm_prefer_subdevice: snd_ctl_shm_pcm_prefer_subdevice, rawmidi_info: snd_ctl_shm_rawmidi_info, + rawmidi_prefer_subdevice: snd_ctl_shm_rawmidi_prefer_subdevice, read: snd_ctl_shm_read, }; diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c index fb6356b1..63eb82bb 100644 --- a/src/pcm/pcm_hw.c +++ b/src/pcm/pcm_hw.c @@ -579,15 +579,18 @@ int snd_pcm_hw_open_subdevice(snd_pcm_t **pcmp, int card, int device, int subdev default: assert(0); } - ret = snd_ctl_pcm_prefer_subdevice(ctl, subdevice); - snd_ctl_close(ctl); - if (ret < 0) - return ret; sprintf(filename, filefmt, card, device); __again: - if (attempt++ > 3) + if (attempt++ > 3) { + snd_ctl_close(ctl); return -EBUSY; + } + ret = snd_ctl_pcm_prefer_subdevice(ctl, subdevice); + if (ret < 0) { + snd_ctl_close(ctl); + return ret; + } fmode = O_RDWR; if (mode & SND_PCM_NONBLOCK) fmode |= O_NONBLOCK; @@ -595,6 +598,7 @@ int snd_pcm_hw_open_subdevice(snd_pcm_t **pcmp, int card, int device, int subdev fmode |= O_ASYNC; if ((fd = open(filename, fmode)) < 0) { SYSERR("open %s failed", filename); + snd_ctl_close(ctl); return -errno; } if (ioctl(fd, SND_PCM_IOCTL_PVERSION, &ver) < 0) { @@ -646,11 +650,13 @@ int snd_pcm_hw_open_subdevice(snd_pcm_t **pcmp, int card, int device, int subdev ret = snd_pcm_hw_mmap_status(pcm); if (ret < 0) { snd_pcm_close(pcm); + snd_ctl_close(ctl); return ret; } ret = snd_pcm_hw_mmap_control(pcm); if (ret < 0) { snd_pcm_close(pcm); + snd_ctl_close(ctl); return ret; } return 0; @@ -661,6 +667,7 @@ int snd_pcm_hw_open_subdevice(snd_pcm_t **pcmp, int card, int device, int subdev if (pcm) free(pcm); close(fd); + snd_ctl_close(ctl); return ret; } diff --git a/src/rawmidi/rawmidi.c b/src/rawmidi/rawmidi.c index 9845776b..a89ea2d6 100644 --- a/src/rawmidi/rawmidi.c +++ b/src/rawmidi/rawmidi.c @@ -38,33 +38,69 @@ struct snd_rawmidi { int mode; }; -int snd_rawmidi_open(snd_rawmidi_t **handle, int card, int device, int mode) +int snd_rawmidi_open_subdevice(snd_rawmidi_t **handle, int card, int device, int subdevice, int mode) { - int fd, ver; + int fd, ver, ret; + int attempt = 0; char filename[32]; + snd_ctl_t *ctl; snd_rawmidi_t *rmidi; + snd_rawmidi_info_t info; *handle = NULL; if (card < 0 || card >= SND_CARDS) return -EINVAL; + + if ((ret = snd_ctl_hw_open(&ctl, NULL, card)) < 0) + return ret; sprintf(filename, SND_FILE_RAWMIDI, card, device); + + __again: + if (attempt++ > 3) { + snd_ctl_close(ctl); + return -EBUSY; + } + ret = snd_ctl_rawmidi_prefer_subdevice(ctl, subdevice); + if (ret < 0) { + snd_ctl_close(ctl); + return ret; + } if ((fd = open(filename, mode)) < 0) { snd_card_load(card); - if ((fd = open(filename, mode)) < 0) + if ((fd = open(filename, mode)) < 0) { + snd_ctl_close(ctl); return -errno; + } } if (ioctl(fd, SND_RAWMIDI_IOCTL_PVERSION, &ver) < 0) { + ret = -errno; close(fd); - return -errno; + snd_ctl_close(ctl); + return ret; } if (SND_PROTOCOL_INCOMPATIBLE(ver, SND_RAWMIDI_VERSION_MAX)) { close(fd); + snd_ctl_close(ctl); return -SND_ERROR_INCOMPATIBLE_VERSION; } + if (subdevice >= 0) { + memset(&info, 0, sizeof(info)); + if (ioctl(fd, SND_RAWMIDI_IOCTL_INFO, &info) < 0) { + ret = -errno; + close(fd); + snd_ctl_close(ctl); + return ret; + } + if (info.subdevice != subdevice) { + close(fd); + goto __again; + } + } rmidi = (snd_rawmidi_t *) calloc(1, sizeof(snd_rawmidi_t)); if (rmidi == NULL) { close(fd); + snd_ctl_close(ctl); return -ENOMEM; } rmidi->card = card; @@ -75,6 +111,11 @@ int snd_rawmidi_open(snd_rawmidi_t **handle, int card, int device, int mode) return 0; } +int snd_rawmidi_open(snd_rawmidi_t **handle, int card, int device, int mode) +{ + return snd_rawmidi_open_subdevice(handle, card, device, -1, mode); +} + int snd_rawmidi_close(snd_rawmidi_t *rmidi) { int res;