From: Takashi Sakamoto Date: Mon, 16 Nov 2020 13:27:54 +0000 (+0900) Subject: rawmidi: stream_pair: fix to select substream X-Git-Tag: v0.1.99~11 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=9c1f5f3af766156f7d22c46c2d08a3fae4da2dd0;p=alsa-gobject.git rawmidi: stream_pair: fix to select substream 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 --- diff --git a/src/rawmidi/privates.h b/src/rawmidi/privates.h index 8a78d54..394f0d3 100644 --- a/src/rawmidi/privates.h +++ b/src/rawmidi/privates.h @@ -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); diff --git a/src/rawmidi/query.c b/src/rawmidi/query.c index 1acd0ab..a717166 100644 --- a/src/rawmidi/query.c +++ b/src/rawmidi/query.c @@ -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); } diff --git a/src/rawmidi/stream-pair.c b/src/rawmidi/stream-pair.c index 3e62dc1..d043524 100644 --- a/src/rawmidi/stream-pair.c +++ b/src/rawmidi/stream-pair.c @@ -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);