From: Takashi Sakamoto Date: Mon, 18 Nov 2019 04:22:44 +0000 (+0900) Subject: rawmidi: stream_pair: add APIs to open ALSA Rawmidi character device X-Git-Tag: v0.1.0~183 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=909ff54d5265d01da04f9ddabfa2f00240971762;p=alsa-gobject.git rawmidi: stream_pair: add APIs to open ALSA Rawmidi character device Signed-off-by: Takashi Sakamoto --- diff --git a/src/rawmidi/alsarawmidi.map b/src/rawmidi/alsarawmidi.map index 1c68baa..6aace36 100644 --- a/src/rawmidi/alsarawmidi.map +++ b/src/rawmidi/alsarawmidi.map @@ -13,6 +13,7 @@ ALSA_GOBJECT_0_0_0 { "alsarawmidi_stream_pair_get_type"; "alsarawmidi_stream_pair_new"; + "alsarawmidi_stream_pair_open"; local: *; }; diff --git a/src/rawmidi/privates.h b/src/rawmidi/privates.h index 9d901ca..b0f2674 100644 --- a/src/rawmidi/privates.h +++ b/src/rawmidi/privates.h @@ -22,6 +22,8 @@ GQuark alsarawmidi_error_quark(void); 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); + G_END_DECLS #endif diff --git a/src/rawmidi/query.c b/src/rawmidi/query.c index 7ef4363..b5670e9 100644 --- a/src/rawmidi/query.c +++ b/src/rawmidi/query.c @@ -429,3 +429,10 @@ void alsarawmidi_get_substream_info(guint card_id, guint device_id, if (*error != NULL) g_object_unref(*substream_info); } + +void rawmidi_select_subdevice(guint card_id, guint subdevice_id, GError **error) +{ + guint data = subdevice_id; + rawmidi_perform_ctl_ioctl(card_id, SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE, + &data, error); +} diff --git a/src/rawmidi/stream-pair.c b/src/rawmidi/stream-pair.c index 4ce38ff..bc00c29 100644 --- a/src/rawmidi/stream-pair.c +++ b/src/rawmidi/stream-pair.c @@ -1,16 +1,45 @@ // SPDX-License-Identifier: LGPL-3.0-or-later #include "stream-pair.h" +#include "query.h" +#include "privates.h" -G_DEFINE_TYPE(ALSARawmidiStreamPair, alsarawmidi_stream_pair, G_TYPE_OBJECT) +#include +#include +#include +#include +#include +#include + +struct _ALSARawmidiStreamPairPrivate { + int fd; +}; +G_DEFINE_TYPE_WITH_PRIVATE(ALSARawmidiStreamPair, alsarawmidi_stream_pair, G_TYPE_OBJECT) + +static void rawmidi_stream_pair_finalize(GObject *obj) +{ + ALSARawmidiStreamPair *self = ALSARAWMIDI_STREAM_PAIR(obj); + ALSARawmidiStreamPairPrivate *priv = + alsarawmidi_stream_pair_get_instance_private(self); + + if (priv->fd >= 0) + close(priv->fd); + + G_OBJECT_CLASS(alsarawmidi_stream_pair_parent_class)->finalize(obj); +} static void alsarawmidi_stream_pair_class_init(ALSARawmidiStreamPairClass *klass) { - return; + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->finalize = rawmidi_stream_pair_finalize; } static void alsarawmidi_stream_pair_init(ALSARawmidiStreamPair *self) { - return; + ALSARawmidiStreamPairPrivate *priv = + alsarawmidi_stream_pair_get_instance_private(self); + + priv->fd = -1; } /** @@ -22,3 +51,64 @@ ALSARawmidiStreamPair *alsarawmidi_stream_pair_new() { return g_object_new(ALSARAWMIDI_TYPE_STREAM_PAIR, NULL); } + +/** + * alsarawmidi_stream_pair_open: + * @self: A #ALSARawmidiStreamPair. + * @card_id: The numerical ID of sound card. + * @device_id: The numerical ID of rawmidi device for the sound card. + * @subdevice_id: The numerical ID of subdevice for the rawmidi device. + * @access_modes: Access flags for stream direction. + * @open_flag: The flag of open(2) system call. O_RDWR, O_WRONLY and O_RDONLY + * are forced to fulfil internally according to the access_modes. + * @error: A #GError. + * + * Open file descriptor for a pair of streams to attach input/output substreams + * corresponding to the given subdevice. + */ +void alsarawmidi_stream_pair_open(ALSARawmidiStreamPair *self, guint card_id, + guint device_id, guint subdevice_id, + ALSARawmidiStreamPairInfoFlag access_modes, + gint open_flag, GError **error) +{ + ALSARawmidiStreamPairPrivate *priv; + char *devnode; + + g_return_if_fail(ALSARAWMIDI_IS_STREAM_PAIR(self)); + priv = alsarawmidi_stream_pair_get_instance_private(self); + + // The flag is used to attach substreams for each direction. + if (access_modes & ~(ALSARAWMIDI_STREAM_PAIR_INFO_FLAG_OUTPUT | + ALSARAWMIDI_STREAM_PAIR_INFO_FLAG_INPUT)) { + generate_error(error, EINVAL); + return; + } + + if ((access_modes & ALSARAWMIDI_STREAM_PAIR_INFO_FLAG_OUTPUT) && + (access_modes & ALSARAWMIDI_STREAM_PAIR_INFO_FLAG_INPUT)) { + open_flag = O_RDWR; + } else if (access_modes & ALSARAWMIDI_STREAM_PAIR_INFO_FLAG_OUTPUT) { + open_flag = O_WRONLY; + } else if (access_modes & ALSARAWMIDI_STREAM_PAIR_INFO_FLAG_INPUT) { + open_flag = O_RDONLY; + } else { + generate_error(error, EINVAL); + return; + } + + alsarawmidi_get_rawmidi_devnode(card_id, device_id, &devnode, error); + if (*error != NULL) + return; + + rawmidi_select_subdevice(card_id, subdevice_id, error); + if (*error != NULL) { + g_free(devnode); + return; + } + + priv->fd = open(devnode, open_flag); + if (priv->fd < 0) + generate_error(error, errno); + + g_free(devnode); +} diff --git a/src/rawmidi/stream-pair.h b/src/rawmidi/stream-pair.h index 248d62c..46c4080 100644 --- a/src/rawmidi/stream-pair.h +++ b/src/rawmidi/stream-pair.h @@ -5,6 +5,8 @@ #include #include +#include + G_BEGIN_DECLS #define ALSARAWMIDI_TYPE_STREAM_PAIR (alsarawmidi_stream_pair_get_type()) @@ -31,9 +33,12 @@ G_BEGIN_DECLS typedef struct _ALSARawmidiStreamPair ALSARawmidiStreamPair; typedef struct _ALSARawmidiStreamPairClass ALSARawmidiStreamPairClass; +typedef struct _ALSARawmidiStreamPairPrivate ALSARawmidiStreamPairPrivate; struct _ALSARawmidiStreamPair { GObject parent_instance; + + ALSARawmidiStreamPairPrivate *priv; }; struct _ALSARawmidiStreamPairClass { @@ -44,6 +49,11 @@ GType alsarawmidi_stream_pair_get_type(void) G_GNUC_CONST; ALSARawmidiStreamPair *alsarawmidi_stream_pair_new(); +void alsarawmidi_stream_pair_open(ALSARawmidiStreamPair *self, guint card_id, + guint device_id, guint subdevice_id, + ALSARawmidiStreamPairInfoFlag access_modes, + gint open_flag, GError **error); + G_END_DECLS #endif diff --git a/tests/alsarawmidi-stream-pair b/tests/alsarawmidi-stream-pair index cdf1983..f785617 100644 --- a/tests/alsarawmidi-stream-pair +++ b/tests/alsarawmidi-stream-pair @@ -13,6 +13,7 @@ target = ALSARawmidi.StreamPair() props = () methods = ( 'new', + 'open', ) signals = ()