]> git.alsa-project.org Git - alsa-gobject.git/commitdiff
rawmidi: stream_pair: fix to select substream topic/fix-rawmidi-substream
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Mon, 16 Nov 2020 13:27:54 +0000 (22:27 +0900)
committerTakashi Sakamoto <o-takashi@sakamocchi.jp>
Mon, 16 Nov 2020 13:29:20 +0000 (22:29 +0900)
ALSARawmidi.StreamPair.open() has subdevice_id to select one of
substreams supported by the Rawmidi device. However, this parameter is
ignored and the first substream is always selected.

In ALSA rawmidi core, private structure associated to file descriptor
to control character device assists selection of rawmidi substream.
It requires to keep the file descriptor until the selected substream
is actually attached by open rawmidi character device.

Current implementation of libalsarawmidi is to close the file descriptor
before opening rawmidi character device. This is the cause of the issue.

This commit fixes the bug by keeping the file descriptor till opening
rawmidi character device.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
src/rawmidi/privates.h
src/rawmidi/query.c
src/rawmidi/stream-pair.c

index 8a78d54b68c1ef834fe62189ab850b692cfafbfe..394f0d315791b42136f9db37a845725cc4e3d864 100644 (file)
@@ -18,7 +18,7 @@ G_BEGIN_DECLS
 void rawmidi_substream_info_refer_private(ALSARawmidiSubstreamInfo *self,
                                           struct snd_rawmidi_info **info);
 
-void rawmidi_select_subdevice(guint card_id, guint subdevice_id, GError **error);
+void rawmidi_select_subdevice(guint card_id, guint subdevice_id, int *ctl_fd, GError **error);
 
 void rawmidi_substream_params_refer_private(ALSARawmidiSubstreamParams *self,
                                             struct snd_rawmidi_params **params);
index 1acd0ab41448ad0ce05b170c8f54fb0417e04105..a717166a1c6d261d9be9b784d35c462ea161c581 100644 (file)
@@ -445,9 +445,9 @@ void alsarawmidi_get_substream_info(guint card_id, guint device_id,
         g_object_unref(*substream_info);
 }
 
-void rawmidi_select_subdevice(guint card_id, guint subdevice_id, GError **error)
+void rawmidi_select_subdevice(guint card_id, guint subdevice_id, int *ctl_fd, GError **error)
 {
     guint data = subdevice_id;
     rawmidi_perform_ctl_ioctl(card_id, SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE,
-                              &data, "RAWMIDI_PREFER_SUBDEVICE", NULL, error);
+                              &data, "RAWMIDI_PREFER_SUBDEVICE", ctl_fd, error);
 }
index 3e62dc185916044378cf51e66012988b120c7357..d0435247bc2efc8df0a3773858b84db8299fd3cf 100644 (file)
@@ -208,6 +208,7 @@ void alsarawmidi_stream_pair_open(ALSARawmidiStreamPair *self, guint card_id,
 {
     ALSARawmidiStreamPairPrivate *priv;
     char *devnode;
+    int ctl_fd;
     int proto_ver;
 
     g_return_if_fail(ALSARAWMIDI_IS_STREAM_PAIR(self));
@@ -232,13 +233,14 @@ void alsarawmidi_stream_pair_open(ALSARawmidiStreamPair *self, guint card_id,
     if (*error != NULL)
         return;
 
-    rawmidi_select_subdevice(card_id, subdevice_id, error);
+    rawmidi_select_subdevice(card_id, subdevice_id, &ctl_fd, error);
     if (*error != NULL) {
         g_free(devnode);
         return;
     }
 
     priv->fd = open(devnode, open_flag);
+    close(ctl_fd);
     if (priv->fd < 0) {
         if (errno == ENODEV) {
             generate_local_error(error, ALSARAWMIDI_STREAM_PAIR_ERROR_DISCONNECTED);