From: Takashi Sakamoto Date: Tue, 14 Jun 2022 10:23:22 +0000 (+0900) Subject: seq: event-cntr: rewrite as boxed structure X-Git-Tag: v0.3.0~86 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=4bc8ea4b91d2fdc5356bfe45828ad9efa71849ea;p=alsa-gobject.git seq: event-cntr: rewrite as boxed structure The addition of ALSASeq.Event boxed structure obsoletes many methods of ALSASeq.EventCntr. This commit rewrite it for convenience. Signed-off-by: Takashi Sakamoto --- diff --git a/samples/seq b/samples/seq index d3bef8e..afabde2 100755 --- a/samples/seq +++ b/samples/seq @@ -100,33 +100,32 @@ print('scheduled:', count) # Register event handler. def handle_event(client, ev_cntr): - count = ev_cntr.count_events() - print('{} events:'.format(count)) - for i in range(count): + events = ev_cntr.deserialize() + for i, ev in enumerate(events): print(' Event {}:'.format(i)) - _, ev_type = ev_cntr.get_event_type(i) + ev_type = ev.get_event_type() print(' type:', ev_type.value_nick) - _, tstamp_mode = ev_cntr.get_tstamp_mode(i) + tstamp_mode = ev.get_tstamp_mode() print(' tstamp-mode:', tstamp_mode.value_nick) - _, time_mode = ev_cntr.get_time_mode(i) + time_mode = ev.get_time_mode() print(' time-mode:', time_mode.value_nick) - _, length_mode = ev_cntr.get_length_mode(i) + length_mode = ev.get_length_mode() print(' length-mode:', length_mode.value_nick) - _, priority_mode = ev_cntr.get_priority_mode(i) + priority_mode = ev.get_priority_mode() print(' priority-mode:', priority_mode.value_nick) - _, tag = ev_cntr.get_tag(i) + tag = ev.get_tag() print(' tag:', tag) - _, queue_id = ev_cntr.get_queue_id(i) + queue_id = ev.get_queue_id() print(' queue-id:', queue_id) if tstamp_mode == ALSASeq.EventTstampMode.TICK: - _, tick_time = ev_cntr.get_tick_time(i) + _, tick_time = ev.get_tick_time() print(' tick-time:', tick_time) else: - _, real_time = ev_cntr.get_real_time(i) + _, real_time = ev.get_real_time() print(' real-time:', real_time) - _, dst = ev_cntr.get_dst(i) + dst = ev.get_destination() print(' dst:', dst.get_client_id(), dst.get_port_id()) - _, src = ev_cntr.get_src(i) + src = ev.get_source() print(' src:', src.get_client_id(), src.get_port_id()) client.connect('handle-event', handle_event) diff --git a/src/seq/alsaseq.h b/src/seq/alsaseq.h index d4917f6..654992c 100644 --- a/src/seq/alsaseq.h +++ b/src/seq/alsaseq.h @@ -17,6 +17,7 @@ #include #include #include +#include #include diff --git a/src/seq/alsaseq.map b/src/seq/alsaseq.map index c624d32..73f9ab1 100644 --- a/src/seq/alsaseq.map +++ b/src/seq/alsaseq.map @@ -101,10 +101,6 @@ ALSA_GOBJECT_0_0_0 { "alsaseq_queue_tempo_set_skew"; "alsaseq_remove_filter_get_type"; - - "alsaseq_event_cntr_get_type"; - "alsaseq_event_cntr_new"; - "alsaseq_event_cntr_count_events"; local: *; }; @@ -155,58 +151,11 @@ ALSA_GOBJECT_0_3_0 { "alsaseq_client_info_set_event_filter"; "alsaseq_client_info_get_event_filter"; - "alsaseq_event_cntr_calculate_pool_consumption"; - "alsaseq_event_cntr_get_event_type"; - "alsaseq_event_cntr_set_event_type"; - "alsaseq_event_cntr_get_tstamp_mode"; - "alsaseq_event_cntr_set_tstamp_mode"; - "alsaseq_event_cntr_get_time_mode"; - "alsaseq_event_cntr_set_time_mode"; - "alsaseq_event_cntr_get_length_mode"; - "alsaseq_event_cntr_set_length_mode"; - "alsaseq_event_cntr_get_priority_mode"; - "alsaseq_event_cntr_set_priority_mode"; - "alsaseq_event_cntr_get_tag"; - "alsaseq_event_cntr_set_tag"; - "alsaseq_event_cntr_get_queue_id"; - "alsaseq_event_cntr_set_queue_id"; - "alsaseq_event_cntr_get_dst"; - "alsaseq_event_cntr_set_dst"; - "alsaseq_event_cntr_get_src"; - "alsaseq_event_cntr_set_src"; - "alsaseq_event_cntr_get_note_data"; - "alsaseq_event_cntr_set_note_data"; - "alsaseq_event_cntr_get_ctl_data"; - "alsaseq_event_cntr_set_ctl_data"; - "alsaseq_event_cntr_get_byte_data"; - "alsaseq_event_cntr_set_byte_data"; - "alsaseq_event_cntr_get_quadlet_data"; - "alsaseq_event_cntr_set_quadlet_data"; - "alsaseq_event_cntr_get_blob_data"; - "alsaseq_event_cntr_set_blob_data"; - "alsaseq_event_cntr_get_queue_data"; - "alsaseq_event_cntr_set_queue_data"; - "alsaseq_event_cntr_get_addr_data"; - "alsaseq_event_cntr_set_addr_data"; - "alsaseq_event_cntr_get_connect_data"; - "alsaseq_event_cntr_set_connect_data"; - "alsaseq_event_cntr_get_result_data"; - "alsaseq_event_cntr_set_result_data"; - "alsaseq_queue_timer_common_get_type"; "alsaseq_queue_timer_alsa_get_type"; "alsaseq_queue_timer_alsa_new"; - "alsaseq_event_cntr_get_tick_time"; - "alsaseq_event_cntr_set_tick_time"; - "alsaseq_event_cntr_get_real_time"; - "alsaseq_event_cntr_set_real_time"; - "alsaseq_event_cntr_get_tick_time_data"; - "alsaseq_event_cntr_set_tick_time_data"; - "alsaseq_event_cntr_get_real_time_data"; - "alsaseq_event_cntr_set_real_time_data"; - "alsaseq_event_data_queue_get_tick_time_param"; "alsaseq_event_data_queue_set_tick_time_param"; "alsaseq_event_data_queue_get_real_time_param"; @@ -271,4 +220,7 @@ ALSA_GOBJECT_0_3_0 { "alsaseq_user_client_schedule_events"; "alsaseq_user_client_schedule_event"; + + "alsaseq_event_cntr_get_type"; + "alsaseq_event_cntr_deserialize"; } ALSA_GOBJECT_0_2_0; diff --git a/src/seq/event-cntr.c b/src/seq/event-cntr.c index 7cadc0a..d53c43b 100644 --- a/src/seq/event-cntr.c +++ b/src/seq/event-cntr.c @@ -1,1839 +1,90 @@ // SPDX-License-Identifier: LGPL-3.0-or-later #include "privates.h" -#include - /** * ALSASeqEventCntr: - * A GObject-derived object to represent container for a batch of events. - * - * A [class@EventCntr] is a GObject-derived object to represent container for a batch of events. - * The instance of object has accessor methods to properties and data for each events expanded to - * the flat memory space. The object is designed for applications to maintain collections of event - * by the convenient way which each programming language produces. - * - * This is the list of properties for event: - * - the type of event - * - the mode of time stamp - * - the mode of time - * - the mode of length - * - the mode of priority - * - associated tag - * - the numeric ID of associated queue - * - time stamp - * - destination address - * - source address - * - * This is the list of data for event. These data shared the same storage and an event can have the - * sole type of data: - * - note - * - control - * - 12 bytes - * - 3 quadlets - * - blob as variable length of bytes - * - queue control - * - arbitrary time stamp - * - arbitrary address - * - connection with source and destination addresses - * - result + * A boxed structure for container which includes batch of events. * - * The data shares the same storage in event. An event can have the sole type of data. The type of - * data is not associated to the type of event directly. + * For batch of events, [struct@EventCntr] keeps flatten buffer which serialize the events without + * pointing to extra data blob for variable type. */ -typedef struct _ALSASeqEventCntrPrivate { - guint8 *buf; - gsize length; - - gboolean allocated; -} ALSASeqEventCntrPrivate; -G_DEFINE_TYPE_WITH_PRIVATE(ALSASeqEventCntr, alsaseq_event_cntr, G_TYPE_OBJECT) - -static void seq_event_cntr_finaize(GObject *obj) -{ - ALSASeqEventCntr *self = ALSASEQ_EVENT_CNTR(obj); - ALSASeqEventCntrPrivate *priv = - alsaseq_event_cntr_get_instance_private(self); - - if (priv->allocated) - g_free(priv->buf); - - G_OBJECT_CLASS(alsaseq_event_cntr_parent_class)->finalize(obj); -} -static void alsaseq_event_cntr_class_init(ALSASeqEventCntrClass *klass) +static ALSASeqEventCntr *seq_event_cntr_copy(const ALSASeqEventCntr *src) { - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + ALSASeqEventCntr *dst; - gobject_class->finalize = seq_event_cntr_finaize; -} + dst = g_malloc0(sizeof(*dst)); + memcpy(dst, src, sizeof(*dst)); -static void alsaseq_event_cntr_init(ALSASeqEventCntr *self) -{ - ALSASeqEventCntrPrivate *priv = - alsaseq_event_cntr_get_instance_private(self); + dst->buf = g_malloc0(src->length); + memcpy(dst->buf, src->buf, src->length); - priv->buf = NULL; - priv->length = 0; - priv->allocated = FALSE; + return dst; } -/** - * alsaseq_event_cntr_new: - * @count: The number of events going to be allocated. - * @error: A [struct@GLib.Error]. - * - * Allocates and return an instance of [class@EventCntr] to store the count of events. - * - * Returns: A [class@EventCntr]. - */ -ALSASeqEventCntr *alsaseq_event_cntr_new(guint count, GError **error) +static void seq_event_cntr_free(ALSASeqEventCntr *self) { - ALSASeqEventCntr *self; - ALSASeqEventCntrPrivate *priv; - struct snd_seq_event *ev; - int i; - - g_return_val_if_fail(error == NULL || *error == NULL, NULL); - - self = g_object_new(ALSASEQ_TYPE_EVENT_CNTR, NULL); - priv = alsaseq_event_cntr_get_instance_private(self); - - priv->length = sizeof(struct snd_seq_event) * count; - priv->buf = g_malloc0(priv->length); - - priv->allocated = TRUE; - - ev = (struct snd_seq_event *)priv->buf; - for (i = 0; i < count; ++i) { - ev[i].type = SNDRV_SEQ_EVENT_NONE; - ev[i].queue = SNDRV_SEQ_QUEUE_DIRECT; - } - - return self; + g_free(self->buf); + g_free(self); } -static gsize calculate_event_size(struct snd_seq_event *ev, gboolean aligned) -{ - gsize size = sizeof(*ev); - - switch (ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) { - case SNDRV_SEQ_EVENT_LENGTH_VARIABLE: - { - const struct snd_seq_ev_ext *ext = &ev->data.ext; - if (aligned) - size += ext->len; - else - size += (ext->len + sizeof(*ev) - 1) / sizeof(*ev) * sizeof(*ev); - break; - } - default: - break; - } - - return size; -} +G_DEFINE_BOXED_TYPE(ALSASeqEventCntr, alsaseq_event_cntr, seq_event_cntr_copy, seq_event_cntr_free); -struct event_iterator { +struct seq_event_iter { guint8 *buf; gsize length; - gboolean aligned; - gsize offset; + gboolean aligned; }; -static void event_iterator_init(struct event_iterator *iter, guint8 *buf, - gsize length, gboolean aligned) +static void seq_event_iter_init(struct seq_event_iter *iter, guint8 *buf, gsize length, + gboolean aligned) { iter->buf = buf; iter->length = length; - iter->aligned = aligned; - iter->offset = 0; + iter->aligned = aligned; } -static struct snd_seq_event *event_iterator_next(struct event_iterator *iter) +static struct snd_seq_event *seq_event_iter_next(struct seq_event_iter *iter) { - struct snd_seq_event *ev; - gsize ev_size; - - if (iter->offset + sizeof(*ev) > iter->length) - return NULL; - ev = (struct snd_seq_event *)(iter->buf + iter->offset); + gsize length; - ev_size = calculate_event_size(ev, iter->aligned); - if (iter->offset + ev_size > iter->length) + if (iter->buf == NULL) return NULL; - iter->offset += ev_size; - - return ev; -} -static struct snd_seq_event *event_iterator_find(struct event_iterator *iter, - gsize index) -{ - struct snd_seq_event *ev; - gsize count = 0; + if (iter->offset < iter->length) { + struct snd_seq_event *ev = (struct snd_seq_event *)(iter->buf + iter->offset); + length = seq_event_calculate_flattened_length(ev, iter->aligned); - while ((ev = event_iterator_next(iter))) { - if (index == count) + if (iter->offset + length <= iter->length) { + iter->offset += length; return ev; - ++count; + } } return NULL; } /** - * alsaseq_event_cntr_count_events: - * @self: A [class@EventCntr]. - * @count: (out): The count of stored events. - * - * count stored events. - */ -void alsaseq_event_cntr_count_events(ALSASeqEventCntr *self, gsize *count) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_if_fail(ALSASEQ_IS_EVENT_CNTR(self)); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_if_fail(count != NULL); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - - *count = 0; - while ((ev = event_iterator_next(&iter))) - ++(*count); -} - -/** - * alsaseq_event_cntr_calculate_pool_consumption: - * @self: A [class@EventCntr]. - * @count: The amount of events for calculation. - * @cells: (out): The amount of cells to be consumed in pool. - * @error: A [struct@GLib.Error]. - * - * Calculate the amount of cells in client pool to be consumed by a part of events in the container. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_calculate_pool_consumption(ALSASeqEventCntr *self, gsize count, - gsize *cells, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - gsize total; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(cells != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - *cells = 0; - total = 0; - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - while ((ev = event_iterator_next(&iter))) { - gsize size = calculate_event_size(ev, TRUE); - *cells += size /sizeof(*ev); - - if (total == count) - break; - ++total; - } - - return TRUE; -} - -/** - * alsaseq_event_cntr_get_event_type: - * @self: A [class@EventCntr]. - * @index: The index of event to refer to. - * @ev_type: (out): The type of event. - * @error: A [struct@GLib.Error]. - * - * Get the type of event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_get_event_type(ALSASeqEventCntr *self, gsize index, - ALSASeqEventType *ev_type, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(ev_type != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - *ev_type = (ALSASeqEventType)ev->type; - - return TRUE; -} - -/** - * alsaseq_event_cntr_set_event_type: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @ev_type: A [enum@EventType]. - * @error: A [struct@GLib.Error]. - * - * Set the type to event pointed by the index; - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_set_event_type(ALSASeqEventCntr *self, gsize index, - ALSASeqEventType ev_type, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - ev->type = (snd_seq_event_type_t)ev_type; - - return TRUE; -} - -/** - * alsaseq_event_cntr_get_tstamp_mode: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @mode: (out): The mode of timestamping, one of [enum@EventTstampMode]. - * @error: A [struct@GLib.Error]. - * - * Get the mode of timestamping for the event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_get_tstamp_mode(ALSASeqEventCntr *self, gsize index, - ALSASeqEventTstampMode *mode, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(mode != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - *mode = (ALSASeqEventTstampMode)(ev->flags & SNDRV_SEQ_TIME_STAMP_MASK); - - return TRUE; -} - -/** - * alsaseq_event_cntr_set_tstamp_mode: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @mode: The mode of timestamping, one of [enum@EventTstampMode]. - * @error: A [struct@GLib.Error]. - * - * Set the mode of timestamping for the event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_set_tstamp_mode(ALSASeqEventCntr *self, gsize index, - ALSASeqEventTstampMode mode, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - ev->flags &= ~SNDRV_SEQ_TIME_STAMP_MASK; - ev->flags |= (unsigned char)mode; - - return TRUE; -} - -/** - * alsaseq_event_cntr_get_time_mode: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @mode: (out): The mode of time, one of [enum@EventTstampMode]. - * @error: A [struct@GLib.Error]. - * - * Get the mode of time for the event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_get_time_mode(ALSASeqEventCntr *self, gsize index, - ALSASeqEventTimeMode *mode, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(mode != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - *mode = (ALSASeqEventTimeMode)(ev->flags & SNDRV_SEQ_TIME_MODE_MASK); - - return TRUE; -} - -/** - * alsaseq_event_cntr_set_time_mode: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @mode: The mode of time, one of [enum@EventTstampMode]. - * @error: A [struct@GLib.Error]. - * - * Set the mode of time for the event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_set_time_mode(ALSASeqEventCntr *self, gsize index, - ALSASeqEventTimeMode mode, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - ev->flags &= ~SNDRV_SEQ_TIME_MODE_MASK; - ev->flags |= (unsigned char)mode; - - return TRUE; -} - -/** - * alsaseq_event_cntr_get_length_mode: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @mode: (out): The mode of length, one of [enum@EventTstampMode]. - * @error: A [struct@GLib.Error]. - * - * Get the mode of length for the event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_get_length_mode(ALSASeqEventCntr *self, gsize index, - ALSASeqEventLengthMode *mode, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(mode != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - *mode = (ALSASeqEventLengthMode)(ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK); - - return TRUE; -} - -/** - * alsaseq_event_cntr_get_priority_mode: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @mode: (out): The mode of priority, one of [enum@EventTstampMode]. - * @error: A [struct@GLib.Error]. - * - * Get the mode of priority for the event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_get_priority_mode(ALSASeqEventCntr *self, gsize index, - ALSASeqEventPriorityMode *mode, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(mode != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - *mode = (ALSASeqEventPriorityMode)(ev->flags & SNDRV_SEQ_PRIORITY_MASK); - - return TRUE; -} - -/** - * alsaseq_event_cntr_set_priority_mode: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @mode: The mode of priority, one of [enum@EventTstampMode]. - * @error: A [struct@GLib.Error]. - * - * Set the mode of priority for the event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_set_priority_mode(ALSASeqEventCntr *self, gsize index, - ALSASeqEventPriorityMode mode, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - ev->flags &= ~SNDRV_SEQ_PRIORITY_MASK; - ev->flags |= (unsigned char)mode; - - return TRUE; -} - -/** - * alsaseq_event_cntr_get_tag: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @tag: (out): The tag assigned to the event. - * @error: A [struct@GLib.Error]. - * - * Get the tag assignd to the event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_get_tag(ALSASeqEventCntr *self, gsize index, gint8 *tag, - GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(tag != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - *tag = ev->tag; - - return TRUE; -} - -/** - * alsaseq_event_cntr_set_tag: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @tag: The tag going to be assignd to the event. - * @error: A [struct@GLib.Error]. - * - * Get the tag assignd to the event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_set_tag(ALSASeqEventCntr *self, gsize index, gint8 tag, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - ev->tag = tag; - - return TRUE; -} - -/** - * alsaseq_event_cntr_get_queue_id: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @queue_id: (out): The numeric ID of queue to deliver the event. One of [enum@SpecificQueueId] - * is available as well. - * @error: A [struct@GLib.Error]. - * - * Get the numeric ID of queue to deliver the event. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_get_queue_id(ALSASeqEventCntr *self, gsize index, guint8 *queue_id, - GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(queue_id != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - *queue_id = ev->queue; - - return TRUE; -} - -/** - * alsaseq_event_cntr_set_queue_id: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @queue_id: The numeric ID of queue to deliver the event. One of [enum@SpecificQueueId] is - * available as well. - * @error: A [struct@GLib.Error]. - * - * Set the numeric ID of queue to deliver the event. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_set_queue_id(ALSASeqEventCntr *self, gsize index, guint8 queue_id, - GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - ev->queue = queue_id; - - return TRUE; -} - -/** - * alsaseq_event_cntr_get_tick_time: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @tick_time: (out): The value of MIDI ticks. - * @error: A [struct@GLib.Error]. - * - * Get event time as MIDI ticks. + * alsaseq_event_cntr_deserialize: + * @self: A [struct@EventCntr]. + * @events: (element-type ALSASeq.Event) (out) (transfer full): The list of deserialized events. * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. + * Retrieve [struct@GLib.List] including batch of deserialized [struct@Event]. */ -gboolean alsaseq_event_cntr_get_tick_time(ALSASeqEventCntr *self, gsize index, - guint *tick_time, GError **error) +void alsaseq_event_cntr_deserialize(const ALSASeqEventCntr *self, GList **events) { - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; + struct seq_event_iter iter; struct snd_seq_event *ev; - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(tick_time != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - *tick_time = ev->time.tick; - - return TRUE; -} - -/** - * alsaseq_event_cntr_set_tick_time: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @tick_time: The value of MIDI ticks. - * @error: A [struct@GLib.Error]. - * - * Get event time as MIDI ticks. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_set_tick_time(ALSASeqEventCntr *self, gsize index, - const guint tick_time, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - ev->data.time.tick = tick_time; - - return TRUE; -} - -/** - * alsaseq_event_cntr_get_real_time: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @real_time: (array fixed-size=2) (out) (transfer none): The array with two elements for sec part - * and nsec part of real time. - * @error: A [struct@GLib.Error]. - * - * Refer to the time as wall-clock event time. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_get_real_time(ALSASeqEventCntr *self, gsize index, - const guint32 *real_time[2], GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(real_time != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - // MEMO: I expect 32-bit storage size is aligned to 32 bit offset in all of supported ABIs. - *real_time = (guint32 *)&ev->time.time; - - return TRUE; -} - -/** - * alsaseq_event_cntr_set_real_time: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @real_time: (array fixed-size=2) (transfer none): The array with two elements for sec part and - * nsec part of real time. - * @error: A [struct@GLib.Error]. - * - * Copy the time as wall-clock event time. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_set_real_time(ALSASeqEventCntr *self, gsize index, - const guint32 real_time[2], GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - ev->data.time.time.tv_sec = real_time[0]; - ev->data.time.time.tv_nsec = real_time[1]; - - return TRUE; -} - -/** - * alsaseq_event_cntr_get_dst: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @dst: (out)(transfer none): The destination of event. - * @error: A [struct@GLib.Error]. - * - * Get the destination of event pointed by index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_get_dst(ALSASeqEventCntr *self, gsize index, const ALSASeqAddr **dst, - GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(dst != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - *dst = (const ALSASeqAddr *)&ev->dest; - - return TRUE; -} - -/** - * alsaseq_event_cntr_set_dst: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @dst: The destination of event. - * @error: A [struct@GLib.Error]. - * - * Set the destination of event pointed by index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_set_dst(ALSASeqEventCntr *self, gsize index, const ALSASeqAddr *dst, - GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(dst != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - ev->dest = *dst; - - return TRUE; -} - -/** - * alsaseq_event_cntr_get_src: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @src: (out)(transfer none): The source of event. - * @error: A [struct@GLib.Error]. - * - * Get the destination of event pointed by index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_get_src(ALSASeqEventCntr *self, gsize index, const ALSASeqAddr **src, - GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(src != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - *src = (const ALSASeqAddr *)&ev->source; - - return TRUE; -} - -/** - * alsaseq_event_cntr_set_src: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @src: The source of event. - * @error: A [struct@GLib.Error]. - * - * Set the destination of event pointed by index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_set_src(ALSASeqEventCntr *self, gsize index, const ALSASeqAddr *src, - GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(src != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - ev->source = *src; - - return TRUE; -} - -static gboolean ensure_fixed_length_event(ALSASeqEventCntrPrivate *priv, struct snd_seq_event *ev, - GError **error) -{ - if (!priv->allocated) - g_return_val_if_fail(priv->allocated, FALSE); - - switch (ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) { - case SNDRV_SEQ_EVENT_LENGTH_VARIABLE: - { - // Truncate blob area. - guint8 *pos = (guint8 *)ev; - guint8 *next_ev = pos + sizeof(*ev) + ev->data.ext.len; - ptrdiff_t to_tail = priv->length - (next_ev - priv->buf); - - memcpy(pos + sizeof(*ev), next_ev, to_tail); - - priv->length -= ev->data.ext.len; - break; - } - default: - break; - } - - ev->data.ext.ptr = NULL; - ev->data.ext.len = 0; - - ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK; - ev->flags |= SNDRV_SEQ_EVENT_LENGTH_FIXED; - - return TRUE; -} - -static gboolean ensure_variable_length_event(ALSASeqEventCntrPrivate *priv, - struct snd_seq_event *ev, const guint8 *data, - gsize size, GError **error) -{ - guint8 *pos = (guint8 *)ev; - ptrdiff_t from_head = pos + sizeof(*ev) - priv->buf; - ptrdiff_t to_tail; - guint8 *next_ev; - guint8 *new; - - if (!priv->allocated) - g_return_val_if_fail(priv->allocated, FALSE); - - switch (ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) { - case SNDRV_SEQ_EVENT_LENGTH_VARIABLE: - // Expand or shrink total area for new blob. - next_ev = pos + sizeof(*ev) + ev->data.ext.len; - break; - default: - // Expand total area with blob size. - next_ev = pos + sizeof(*ev); - break; - } - - to_tail = priv->length - (next_ev - priv->buf); - - new = g_malloc(from_head + size + to_tail); - - memcpy(new, priv->buf, from_head); - memcpy(new + from_head, data, size); - memcpy(new + from_head + size, next_ev, to_tail); - - g_free(priv->buf); - priv->buf = new; - priv->length = from_head + size + to_tail; - - from_head -= sizeof(*ev); - pos = priv->buf + from_head; - ev = (struct snd_seq_event *)pos; - ev->data.ext.len = size; - - ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK; - ev->flags |= SNDRV_SEQ_EVENT_LENGTH_VARIABLE; - - return TRUE; -} - -/** - * alsaseq_event_cntr_get_note_data: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @data: (out)(transfer none): The note data of event. - * @error: A [struct@GLib.Error]. - * - * Get the note data of event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_get_note_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqEventDataNote **data, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(data != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - *data = (const ALSASeqEventDataNote *)&ev->data.note; - - return TRUE; -} - -/** - * alsaseq_event_cntr_set_note_data: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @data: The note data of event. - * @error: A [struct@GLib.Error]. - * - * Copy the note data to the event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_set_note_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqEventDataNote *data, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(data != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - if (!ensure_fixed_length_event(priv, ev, error)) - return FALSE; - - ev->data.note = *(struct snd_seq_ev_note *)data; - - return TRUE; -} - -/** - * alsaseq_event_cntr_get_ctl_data: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @data: (out)(transfer none): The control data of event. - * @error: A [struct@GLib.Error]. - * - * Get the control data of event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_get_ctl_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqEventDataCtl **data, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(data != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - *data = (const ALSASeqEventDataCtl *)&ev->data.control; - - return TRUE; -} - -/** - * alsaseq_event_cntr_set_ctl_data: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @data: The control data of event. - * @error: A [struct@GLib.Error]. - * - * Copy the control data to the event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_set_ctl_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqEventDataCtl *data, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(data != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - if (!ensure_fixed_length_event(priv, ev, error)) - return FALSE; - - ev->data.control = *(struct snd_seq_ev_ctrl *)data; - - return TRUE; -} - -/** - * alsaseq_event_cntr_get_byte_data: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @data: (array fixed-size=12)(out)(transfer none): The byte data of event. - * @error: A [struct@GLib.Error]. - * - * Get the byte data of event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_get_byte_data(ALSASeqEventCntr *self, gsize index, - const guint8 *data[12], GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(data != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - *data = ev->data.raw8.d; - - return TRUE; -} - -/** - * alsaseq_event_cntr_set_byte_data: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @data: (array fixed-size=12): The byte data of event. - * @error: A [struct@GLib.Error]. - * - * Copy the byte data to the event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_set_byte_data(ALSASeqEventCntr *self, gsize index, - const guint8 data[12], GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(data != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - if (!ensure_fixed_length_event(priv, ev, error)) - return FALSE; - - memcpy(ev->data.raw8.d, data, sizeof(ev->data.raw8.d)); - - return TRUE; -} - -/** - * alsaseq_event_cntr_get_quadlet_data: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @data: (array fixed-size=3)(out)(transfer none): The quadlet data of event. - * @error: A [struct@GLib.Error]. - * - * Get the quadlet data of event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_get_quadlet_data(ALSASeqEventCntr *self, gsize index, - const guint32 *data[3], GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(data != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - *data = ev->data.raw32.d; - - return TRUE; -} - -/** - * alsaseq_event_cntr_set_quadlet_data: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @data: (array fixed-size=3): The quadlet data of event. - * @error: A [struct@GLib.Error]. - * - * Copy the quadlet data to the event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_set_quadlet_data(ALSASeqEventCntr *self, gsize index, - const guint32 data[3], GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(data != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - if (!ensure_fixed_length_event(priv, ev, error)) - return FALSE; - - memcpy(ev->data.raw32.d, data, sizeof(ev->data.raw32.d)); - - return TRUE; -} - -/** - * alsaseq_event_cntr_get_blob_data: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @data: (array length=size)(out)(transfer none): The pointer to blob data. - * @size: The size of data. - * @error: A [struct@GLib.Error]. - * - * Refer to the blob data of event. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_get_blob_data(ALSASeqEventCntr *self, gsize index, - const guint8 **data, gsize *size, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(data != NULL, FALSE); - g_return_val_if_fail(size != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - switch (ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) { - case SNDRV_SEQ_EVENT_LENGTH_VARIABLE: - { - const struct snd_seq_ev_ext *ext = &ev->data.ext; - if (priv->allocated) - *data = ((guint8 *)ev) + sizeof(*ev); - else - *data = ext->ptr; - *size = ext->len; - break; - } - default: - g_return_val_if_reached(FALSE); - } - - return TRUE; -} - -/** - * alsaseq_event_cntr_set_blob_data: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @data: (array length=size): The pointer to blob data for the event. - * @size: The size of data. - * @error: A [struct@GLib.Error]. - * - * Copy the quadlet data to the event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_set_blob_data(ALSASeqEventCntr *self, gsize index, - const guint8 *data, gsize size, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(data != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - return ensure_variable_length_event(priv, ev, data, size, error); -} - -/** - * alsaseq_event_cntr_get_queue_data: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @data: (out)(transfer none): The queue data of event. - * @error: A [struct@GLib.Error]. - * - * Get the queue data of event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_get_queue_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqEventDataQueue **data, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(data != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - *data = (const ALSASeqEventDataQueue *)&ev->data.queue; - - return TRUE; -} - -/** - * alsaseq_event_cntr_set_queue_data: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @data: The queue data of event. - * @error: A [struct@GLib.Error]. - * - * Copy the queue data to the event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_set_queue_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqEventDataQueue *data, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(data != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - if (!ensure_fixed_length_event(priv, ev, error)) - return FALSE; - - ev->data.queue = *(struct snd_seq_ev_queue_control *)data; - - return TRUE; -} - -/** - * alsaseq_event_cntr_get_tick_time_data: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @tick_time: (out): The value of MIDI ticks. - * @error: A [struct@GLib.Error]. - * - * Get time data as MIDI ticks. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_get_tick_time_data(ALSASeqEventCntr *self, gsize index, - guint *tick_time, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(tick_time != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - *tick_time = ev->data.time.tick; - - return TRUE; -} - -/** - * alsaseq_event_cntr_set_tick_time_data: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @tick_time: The value of MIDI ticks. - * @error: A [struct@GLib.Error]. - * - * Set time data as MIDI ticks. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_set_tick_time_data(ALSASeqEventCntr *self, gsize index, - const guint tick_time, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - if (!ensure_fixed_length_event(priv, ev, error)) - return FALSE; - - ev->data.time.tick = tick_time; - - return TRUE; -} - -/** - * alsaseq_event_cntr_get_real_time_data: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @real_time: (array fixed-size=2) (out) (transfer none): The array with two elements for sec part - * and nsec part of real time. - * @error: A [struct@GLib.Error]. - * - * Refer to the time as wall-clock time data. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_get_real_time_data(ALSASeqEventCntr *self, gsize index, - const guint32 *real_time[2], GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(real_time != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - // MEMO: I expect 32-bit storage size is aligned to 32 bit offset in all of supported ABIs. - *real_time = (guint32 *)&ev->data.time.time; - - return TRUE; -} - -/** - * alsaseq_event_cntr_set_real_time_data: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @real_time: (array fixed-size=2) (transfer none): The array with two elements for sec part and - * nsec part of real time. - * @error: A [struct@GLib.Error]. - * - * Copy the time as wall-clock time data. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_set_real_time_data(ALSASeqEventCntr *self, gsize index, - const guint32 real_time[2], GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(real_time != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - if (!ensure_fixed_length_event(priv, ev, error)) - return FALSE; - - ev->data.time.time.tv_nsec = real_time[0]; - ev->data.time.time.tv_nsec = real_time[1]; - - return TRUE; -} - -/** - * alsaseq_event_cntr_get_addr_data: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @data: (out)(transfer none): The address data of event. - * @error: A [struct@GLib.Error]. - * - * Get the address data of event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_get_addr_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqAddr **data, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(data != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - *data = (const ALSASeqAddr *)&ev->data.time; - - return TRUE; -} - -/** - * alsaseq_event_cntr_set_addr_data: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @data: The address data of event. - * @error: A [struct@GLib.Error]. - * - * Copy the address data to the event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_set_addr_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqAddr *data, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(data != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - if (!ensure_fixed_length_event(priv, ev, error)) - return FALSE; - - ev->data.addr = *(struct snd_seq_addr *)data; - - return TRUE; -} - -/** - * alsaseq_event_cntr_get_connect_data: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @data: (out)(transfer none): The connect data of event. - * @error: A [struct@GLib.Error]. - * - * Get the connect data of event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_get_connect_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqEventDataConnect **data, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(data != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - *data = (const ALSASeqEventDataConnect *)&ev->data.connect; - - return TRUE; -} - -/** - * alsaseq_event_cntr_set_connect_data: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @data: The connect data of event. - * @error: A [struct@GLib.Error]. - * - * Copy the connect data to the event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_set_connect_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqEventDataConnect *data, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(data != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - if (!ensure_fixed_length_event(priv, ev, error)) - return FALSE; - - ev->data.connect = *(struct snd_seq_connect *)data; - - return TRUE; -} - -/** - * alsaseq_event_cntr_get_result_data: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @data: (out)(transfer none): The result data of event. - * @error: A [struct@GLib.Error]. - * - * Get the result data of event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_get_result_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqEventDataResult **data, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(data != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - *data = (const ALSASeqEventDataResult *)&ev->data.result; - - return TRUE; -} - -/** - * alsaseq_event_cntr_set_result_data: - * @self: A [class@EventCntr]. - * @index: The index of event to set. - * @data: The result data of event. - * @error: A [struct@GLib.Error]. - * - * Copy the result data to the event pointed by the index. - * - * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. - */ -gboolean alsaseq_event_cntr_set_result_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqEventDataResult *data, GError **error) -{ - ALSASeqEventCntrPrivate *priv; - struct event_iterator iter; - struct snd_seq_event *ev; - - g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); - priv = alsaseq_event_cntr_get_instance_private(self); - - g_return_val_if_fail(data != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - ev = event_iterator_find(&iter, index); - g_return_val_if_fail(ev != NULL, FALSE); - - if (!ensure_fixed_length_event(priv, ev, error)) - return FALSE; - - ev->data.result = *(struct snd_seq_result *)data; - - return TRUE; -} - -void seq_event_cntr_set_buf(ALSASeqEventCntr *self, guint8 *buf, - gsize length) -{ - ALSASeqEventCntrPrivate *priv = - alsaseq_event_cntr_get_instance_private(self); - priv->buf = buf; - priv->length = length; -} - -void seq_event_cntr_get_buf(ALSASeqEventCntr *self, gsize count, - const guint8 **buf, gsize *length) -{ - ALSASeqEventCntrPrivate *priv = - alsaseq_event_cntr_get_instance_private(self); - struct event_iterator iter; + seq_event_iter_init(&iter, self->buf, self->length, self->aligned); + while ((ev = seq_event_iter_next(&iter))) { + struct snd_seq_event *event; - event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); - if (event_iterator_find(&iter, count - 1) != NULL) { - *buf = priv->buf; - *length = iter.offset; - } else { - *buf = NULL; - *length = 0; + // MEMO: For [enum@EventLengthMode].VARIABLE type of event, a memory object is allocated + // for blob data, since the size of boxed structure should have fixed size. + event = g_boxed_copy(ALSASEQ_TYPE_EVENT, ev); + *events = g_list_append(*events, event); } } diff --git a/src/seq/event-cntr.h b/src/seq/event-cntr.h index 441f231..063a5c5 100644 --- a/src/seq/event-cntr.h +++ b/src/seq/event-cntr.h @@ -8,125 +8,16 @@ G_BEGIN_DECLS #define ALSASEQ_TYPE_EVENT_CNTR (alsaseq_event_cntr_get_type()) -G_DECLARE_DERIVABLE_TYPE(ALSASeqEventCntr, alsaseq_event_cntr, ALSASEQ, EVENT_CNTR, GObject); +typedef struct { + /*< private >*/ + guint8 *buf; + gsize length; + gboolean aligned; +} ALSASeqEventCntr; -struct _ALSASeqEventCntrClass { - GObjectClass parent_class; -}; +GType alsaseq_event_cntr_get_type() G_GNUC_CONST; -ALSASeqEventCntr *alsaseq_event_cntr_new(guint count, GError **error); - -void alsaseq_event_cntr_count_events(ALSASeqEventCntr *self, gsize *count); - -gboolean alsaseq_event_cntr_calculate_pool_consumption(ALSASeqEventCntr *self, gsize count, - gsize *cells, GError **error); - -gboolean alsaseq_event_cntr_get_event_type(ALSASeqEventCntr *self, gsize index, - ALSASeqEventType *ev_type, GError **error); -gboolean alsaseq_event_cntr_set_event_type(ALSASeqEventCntr *self, gsize index, - ALSASeqEventType ev_type, GError **error); - -gboolean alsaseq_event_cntr_get_tstamp_mode(ALSASeqEventCntr *self, gsize index, - ALSASeqEventTstampMode *mode, GError **error); -gboolean alsaseq_event_cntr_set_tstamp_mode(ALSASeqEventCntr *self, gsize index, - ALSASeqEventTstampMode mode, GError **error); - -gboolean alsaseq_event_cntr_get_time_mode(ALSASeqEventCntr *self, gsize index, - ALSASeqEventTimeMode *mode, GError **error); -gboolean alsaseq_event_cntr_set_time_mode(ALSASeqEventCntr *self, gsize index, - ALSASeqEventTimeMode mode, GError **error); - -gboolean alsaseq_event_cntr_get_length_mode(ALSASeqEventCntr *self, gsize index, - ALSASeqEventLengthMode *mode, GError **error); - -gboolean alsaseq_event_cntr_get_priority_mode(ALSASeqEventCntr *self, gsize index, - ALSASeqEventPriorityMode *mode, GError **error); -gboolean alsaseq_event_cntr_set_priority_mode(ALSASeqEventCntr *self, gsize index, - ALSASeqEventPriorityMode mode, GError **error); - -gboolean alsaseq_event_cntr_get_tag(ALSASeqEventCntr *self, gsize index, gint8 *tag, - GError **error); -gboolean alsaseq_event_cntr_set_tag(ALSASeqEventCntr *self, gsize index, gint8 tag, GError **error); - -gboolean alsaseq_event_cntr_get_queue_id(ALSASeqEventCntr *self, gsize index, guint8 *queue_id, - GError **error); -gboolean alsaseq_event_cntr_set_queue_id(ALSASeqEventCntr *self, gsize index, guint8 queue_id, - GError **error); - -gboolean alsaseq_event_cntr_get_tick_time(ALSASeqEventCntr *self, gsize index, - guint *tick_time, GError **error); -gboolean alsaseq_event_cntr_set_tick_time(ALSASeqEventCntr *self, gsize index, - const guint tick_time, GError **error); - -gboolean alsaseq_event_cntr_get_real_time(ALSASeqEventCntr *self, gsize index, - const guint32 *real_time[2], GError **error); -gboolean alsaseq_event_cntr_set_real_time(ALSASeqEventCntr *self, gsize index, - const guint32 real_time[2], GError **error); - -gboolean alsaseq_event_cntr_get_dst(ALSASeqEventCntr *self, gsize index, const ALSASeqAddr **dst, - GError **error); -gboolean alsaseq_event_cntr_set_dst(ALSASeqEventCntr *self, gsize index, const ALSASeqAddr *dst, - GError **error); - -gboolean alsaseq_event_cntr_get_src(ALSASeqEventCntr *self, gsize index, const ALSASeqAddr **src, - GError **error); -gboolean alsaseq_event_cntr_set_src(ALSASeqEventCntr *self, gsize index, const ALSASeqAddr *src, - GError **error); - -gboolean alsaseq_event_cntr_get_note_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqEventDataNote **data, GError **error); -gboolean alsaseq_event_cntr_set_note_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqEventDataNote *data, GError **error); - -gboolean alsaseq_event_cntr_get_ctl_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqEventDataCtl **data, GError **error); -gboolean alsaseq_event_cntr_set_ctl_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqEventDataCtl *data, GError **error); - -gboolean alsaseq_event_cntr_get_byte_data(ALSASeqEventCntr *self, gsize index, - const guint8 *data[12], GError **error); -gboolean alsaseq_event_cntr_set_byte_data(ALSASeqEventCntr *self, gsize index, - const guint8 data[12], GError **error); - -gboolean alsaseq_event_cntr_get_quadlet_data(ALSASeqEventCntr *self, gsize index, - const guint32 *data[3], GError **error); -gboolean alsaseq_event_cntr_set_quadlet_data(ALSASeqEventCntr *self, gsize index, - const guint32 data[3], GError **error); - -gboolean alsaseq_event_cntr_get_blob_data(ALSASeqEventCntr *self, gsize index, - const guint8 **data, gsize *size, GError **error); -gboolean alsaseq_event_cntr_set_blob_data(ALSASeqEventCntr *self, gsize index, - const guint8 *data, gsize size, GError **error); - -gboolean alsaseq_event_cntr_get_queue_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqEventDataQueue **data, GError **error); -gboolean alsaseq_event_cntr_set_queue_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqEventDataQueue *data, GError **error); - -gboolean alsaseq_event_cntr_get_tick_time_data(ALSASeqEventCntr *self, gsize index, - guint *tick_time, GError **error); -gboolean alsaseq_event_cntr_set_tick_time_data(ALSASeqEventCntr *self, gsize index, - const guint tick_time, GError **error); - -gboolean alsaseq_event_cntr_get_real_time_data(ALSASeqEventCntr *self, gsize index, - const guint *real_time[2], GError **error); -gboolean alsaseq_event_cntr_set_real_time_data(ALSASeqEventCntr *self, gsize index, - const guint real_time[2], GError **error); - -gboolean alsaseq_event_cntr_get_addr_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqAddr **data, GError **error); -gboolean alsaseq_event_cntr_set_addr_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqAddr *data, GError **error); - -gboolean alsaseq_event_cntr_get_connect_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqEventDataConnect **data, GError **error); -gboolean alsaseq_event_cntr_set_connect_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqEventDataConnect *data, GError **error); - -gboolean alsaseq_event_cntr_get_result_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqEventDataResult **data, GError **error); -gboolean alsaseq_event_cntr_set_result_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqEventDataResult *data, GError **error); +void alsaseq_event_cntr_deserialize(const ALSASeqEventCntr *self, GList **events); G_END_DECLS diff --git a/src/seq/user-client.c b/src/seq/user-client.c index fdba9a1..0392f86 100644 --- a/src/seq/user-client.c +++ b/src/seq/user-client.c @@ -60,7 +60,6 @@ typedef struct { gpointer tag; void *buf; size_t buf_len; - ALSASeqEventCntr *ev_cntr; } UserClientSource; enum seq_user_client_prop_type { @@ -126,12 +125,10 @@ static void alsaseq_user_client_class_init(ALSASeqUserClientClass *klass) /** * ALSASeqUserClient::handle-event: * @self: A [class@UserClient]. - * @ev_cntr: (transfer none): The instance of [class@EventCntr] which points to the batch of - * events. + * @ev_cntr: (transfer none): The instance of [struct@EventCntr] which includes batch of events. * - * When event occurs, this signal is emit with the instance of object which points to a batch - * of events. The instance should not be passed directly to [method@UserClient.schedule_event] - * again because its memory alignment is different for events with blob data. + * When event occurs, this signal is emit with the instance of object which includes batch of + * of events. */ seq_user_client_sigs[SEQ_USER_CLIENT_SIG_TYPE_HANDLE_EVENT] = g_signal_new("handle-event", @@ -139,7 +136,7 @@ static void alsaseq_user_client_class_init(ALSASeqUserClientClass *klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(ALSASeqUserClientClass, handle_event), NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, + g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, ALSASEQ_TYPE_EVENT_CNTR); } @@ -723,6 +720,7 @@ static gboolean seq_user_client_dispatch_src(GSource *gsrc, GSourceFunc cb, ALSASeqUserClient *self = src->self; ALSASeqUserClientPrivate *priv; GIOCondition condition; + ALSASeqEventCntr ev_cntr = { 0 }; int len; priv = alsaseq_user_client_get_instance_private(self); @@ -741,11 +739,12 @@ static gboolean seq_user_client_dispatch_src(GSource *gsrc, GSourceFunc cb, return G_SOURCE_REMOVE; } - seq_event_cntr_set_buf(src->ev_cntr, src->buf, len); + // NOTE: The buffer is flatten layout. + ev_cntr.buf = src->buf; + ev_cntr.length = len; + ev_cntr.aligned = TRUE; - g_signal_emit(self, - seq_user_client_sigs[SEQ_USER_CLIENT_SIG_TYPE_HANDLE_EVENT], - 0, src->ev_cntr); + g_signal_emit(self, seq_user_client_sigs[SEQ_USER_CLIENT_SIG_TYPE_HANDLE_EVENT], 0, &ev_cntr); // Just be sure to continue to process this source. return G_SOURCE_CONTINUE; @@ -755,8 +754,6 @@ static void seq_user_client_finalize_src(GSource *gsrc) { UserClientSource *src = (UserClientSource *)gsrc; - g_object_unref(src->ev_cntr); - g_free(src->buf); g_object_unref(src->self); } @@ -798,8 +795,6 @@ gboolean alsaseq_user_client_create_source(ALSASeqUserClient *self, GSource **gs *gsrc = g_source_new(&funcs, sizeof(*src)); src = (UserClientSource *)(*gsrc); - src->ev_cntr = g_object_new(ALSASEQ_TYPE_EVENT_CNTR, NULL); - g_source_set_name(*gsrc, "ALSASeqUserClient"); g_source_set_priority(*gsrc, G_PRIORITY_HIGH_IDLE); g_source_set_can_recurse(*gsrc, TRUE); diff --git a/src/seq/user-client.h b/src/seq/user-client.h index fce549d..17bea1a 100644 --- a/src/seq/user-client.h +++ b/src/seq/user-client.h @@ -20,16 +20,12 @@ struct _ALSASeqUserClientClass { /** * ALSASeqUserClientClass::handle_event: * @self: A [class@UserClient]. - * @ev_cntr: (transfer none): The instance of [class@EventCntr] which - * points to the batch of events. + * @ev_cntr: (transfer none): The instance of [struct@EventCntr] which includes batch of events. * - * When event occurs, this signal is emit with the instance of object which - * points to a batch of events. The instance should not be passed directly - * to alsaseq_user_client_schedule_event() again because its memory - * alignment is different for events with blob data. + * When event occurs, this signal is emit with the instance of object which includes batch of + * events. */ - void (*handle_event)(ALSASeqUserClient *self, - const ALSASeqEventCntr *ev_cntr); + void (*handle_event)(ALSASeqUserClient *self, const ALSASeqEventCntr *ev_cntr); }; ALSASeqUserClient *alsaseq_user_client_new(); diff --git a/tests/alsaseq-event-cntr b/tests/alsaseq-event-cntr deleted file mode 100644 index 0b90901..0000000 --- a/tests/alsaseq-event-cntr +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env python3 - -from sys import exit -from errno import ENXIO - -from helper import test - -import gi -gi.require_version('ALSASeq', '0.0') -from gi.repository import ALSASeq - -target = ALSASeq.EventCntr() -props = () -methods = ( - 'new', - 'count_events', - 'calculate_pool_consumption', - 'get_event_type', - 'set_event_type', - 'get_tstamp_mode', - 'set_tstamp_mode', - 'get_time_mode', - 'set_time_mode', - 'get_length_mode', - 'get_priority_mode', - 'set_priority_mode', - 'get_tag', - 'set_tag', - 'get_queue_id', - 'set_queue_id', - "get_tick_time", - "set_tick_time", - "get_real_time", - "set_real_time", - 'get_dst', - 'set_dst', - 'get_src', - 'set_src', - 'get_note_data', - 'set_note_data', - 'get_ctl_data', - 'set_ctl_data', - 'get_byte_data', - 'set_byte_data', - 'get_quadlet_data', - 'set_quadlet_data', - 'get_blob_data', - 'set_blob_data', - 'get_queue_data', - 'set_queue_data', - "get_tick_time_data", - "set_tick_time_data", - "get_real_time_data", - "set_real_time_data", - 'get_connect_data', - 'set_connect_data', - 'get_result_data', - 'set_result_data', -) -signals = () - -if not test(target, props, methods, signals): - exit(ENXIO) - diff --git a/tests/meson.build b/tests/meson.build index 0cb8d30..e7015fd 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -36,7 +36,6 @@ tests = { 'alsaseq-queue-status', 'alsaseq-queue-tempo', 'alsaseq-queue-timer-alsa', - 'alsaseq-event-cntr', ], 'hwdep': [ 'alsahwdep-enums',