OSDN Git Service

Added functions:
authorJaroslav Kysela <perex@perex.cz>
Mon, 30 Oct 2000 12:15:18 +0000 (12:15 +0000)
committerJaroslav Kysela <perex@perex.cz>
Mon, 30 Oct 2000 12:15:18 +0000 (12:15 +0000)
snd_ctl_rawmidi_prefer_subdevice
snd_rawmidi_open_subdevice
Fixed functions:
snd_pcm_hw_open - fixed prefer subdevice code

aserver/aserver.c
include/aserver.h
include/control.h
include/rawmidi.h
src/control/control.c
src/control/control_hw.c
src/control/control_local.h
src/control/control_shm.c
src/pcm/pcm_hw.c
src/rawmidi/rawmidi.c

index 84d7109..5e54d0b 100644 (file)
@@ -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;
index 3469b04..85823fd 100644 (file)
@@ -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];
index e1221a7..864a39e 100644 (file)
@@ -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);
 
index b69c270..4fbce8e 100644 (file)
@@ -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);
index 341af12..40c9007 100644 (file)
@@ -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);
index 5d58ab1..eb805ae 100644 (file)
@@ -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,
 };
 
index 34f302d..8f912cc 100644 (file)
@@ -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);
 };
 
index 968e146..02210c7 100644 (file)
@@ -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,
 };
 
index fb6356b..63eb82b 100644 (file)
@@ -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;
 }
 
index 9845776..a89ea2d 100644 (file)
@@ -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;