]> git.alsa-project.org Git - alsa-gobject.git/commitdiff
seq: event-cntr: rewrite as boxed structure
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Tue, 14 Jun 2022 10:23:22 +0000 (19:23 +0900)
committer坂本 貴史 <o-takashi@sakamocchi.jp>
Thu, 16 Jun 2022 12:52:00 +0000 (21:52 +0900)
The addition of ALSASeq.Event boxed structure obsoletes many methods of
ALSASeq.EventCntr.

This commit rewrite it for convenience.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
samples/seq
src/seq/alsaseq.h
src/seq/alsaseq.map
src/seq/event-cntr.c
src/seq/event-cntr.h
src/seq/user-client.c
src/seq/user-client.h
tests/alsaseq-event-cntr [deleted file]
tests/meson.build

index d3bef8e883b1292412e0ddc45b40f524d4f0d318..afabde23c39efb95e5f9100450854fb8fd9461b4 100755 (executable)
@@ -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)
 
index d4917f63f7053d4d396e4c4f7806aa1f66b87856..654992c98e1f1f36761a669889c2f89bca1ced43 100644 (file)
@@ -17,6 +17,7 @@
 #include <event-data-connect.h>
 #include <event-data-result.h>
 #include <remove-filter.h>
+#include <event-cntr.h>
 
 #include <queue-timer-common.h>
 
index c624d32122b66bb25d256e4c0771ccd238641bf5..73f9ab137be5f3fa3bd9c1bd15109475857b9934 100644 (file)
@@ -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;
index 7cadc0a73c0a7fbc49ab5f2774d15f19241a604d..d53c43beb90a59168886484e1a8d327f06645c2d 100644 (file)
 // SPDX-License-Identifier: LGPL-3.0-or-later
 #include "privates.h"
 
-#include <errno.h>
-
 /**
  * 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);
     }
 }
index 441f2313a3133a73acdc97dcc8ecb1cf36028d66..063a5c5f36eeea5fc96cc8677beb691ee0bf6ee1 100644 (file)
@@ -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
 
index fdba9a11c3627663d4d97ddd86797381f0c7b8a4..0392f860676e894b396a6c1f59f8dfbc7429fbc9 100644 (file)
@@ -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);
index fce549dd6b3426d259cdf2de868e1d34a23e4573..17bea1a38896f05efaa5286bba535d934bc634d2 100644 (file)
@@ -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 (file)
index 0b90901..0000000
+++ /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)
-
index 0cb8d30122c85525012e67d8bf6fe8b643816273..e7015fda08b5736d570f481b0d3465f50aacdcd8 100644 (file)
@@ -36,7 +36,6 @@ tests = {
     'alsaseq-queue-status',
     'alsaseq-queue-tempo',
     'alsaseq-queue-timer-alsa',
-    'alsaseq-event-cntr',
   ],
   'hwdep': [
     'alsahwdep-enums',