From c1c1903a03b38b20fc74dd5ca2513eec739eca0c Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Tue, 14 Jun 2022 19:23:21 +0900 Subject: [PATCH] seq: event-cntr/event-data-queue: obsolete timestamp functions by adding alternatives In UAPI of ALSA Sequencer, time stamp is defined as union which has tick time member and real time member. There is no tag to select two members, thus user applications should judge which member is used. In this meaning, exposing the union is not necessarily useful. This commit is a preparation to obsolete the union. The methods to retrieve the union are rewrite to retrieve either tick time or real time explicitly. Signed-off-by: Takashi Sakamoto --- samples/seq | 9 +- src/seq/alsaseq.map | 20 ++-- src/seq/event-cntr.c | 195 +++++++++++++++++++++++++++++++------ src/seq/event-cntr.h | 26 +++-- src/seq/event-data-queue.c | 52 +++++++--- src/seq/event-data-queue.h | 13 ++- tests/alsaseq-event-cntr | 12 ++- 7 files changed, 260 insertions(+), 67 deletions(-) diff --git a/samples/seq b/samples/seq index 0cbb5e7..fefb0a0 100755 --- a/samples/seq +++ b/samples/seq @@ -113,11 +113,12 @@ def handle_event(client, ev_cntr): print(' tag:', tag) _, queue_id = ev_cntr.get_queue_id(i) print(' queue-id:', queue_id) - _, tstamp = ev_cntr.get_tstamp(i) - if ev_cntr.get_tstamp_mode(i) == ALSASeq.EventTimestampMode.TICK: - print(' tstamp:', tstamp.get_tick_time()) + if tstamp_mode == ALSASeq.EventTimestampMode.TICK: + _, tick_time = ev_cntr.get_tick_time(i) + print(' tick-time:', tick_time) else: - print(' tstamp:', tstamp.get_real_time()) + _, real_time = ev_cntr.get_real_time(i) + print(' real-time:', real_time) _, dst = ev_cntr.get_dst(i) print(' dst:', dst.get_client_id(), dst.get_port_id()) _, src = ev_cntr.get_src(i) diff --git a/src/seq/alsaseq.map b/src/seq/alsaseq.map index f14f35e..35cde92 100644 --- a/src/seq/alsaseq.map +++ b/src/seq/alsaseq.map @@ -76,8 +76,6 @@ ALSA_GOBJECT_0_0_0 { "alsaseq_event_data_queue_set_queue_id"; "alsaseq_event_data_queue_get_value_param"; "alsaseq_event_data_queue_set_value_param"; - "alsaseq_event_data_queue_get_tstamp_param"; - "alsaseq_event_data_queue_set_tstamp_param"; "alsaseq_event_data_queue_get_position_param"; "alsaseq_event_data_queue_set_position_param"; "alsaseq_event_data_queue_get_skew_param"; @@ -187,8 +185,6 @@ ALSA_GOBJECT_0_3_0 { "alsaseq_event_cntr_set_tag"; "alsaseq_event_cntr_get_queue_id"; "alsaseq_event_cntr_set_queue_id"; - "alsaseq_event_cntr_get_tstamp"; - "alsaseq_event_cntr_set_tstamp"; "alsaseq_event_cntr_get_dst"; "alsaseq_event_cntr_set_dst"; "alsaseq_event_cntr_get_src"; @@ -205,8 +201,6 @@ ALSA_GOBJECT_0_3_0 { "alsaseq_event_cntr_set_blob_data"; "alsaseq_event_cntr_get_queue_data"; "alsaseq_event_cntr_set_queue_data"; - "alsaseq_event_cntr_get_tstamp_data"; - "alsaseq_event_cntr_set_tstamp_data"; "alsaseq_event_cntr_get_addr_data"; "alsaseq_event_cntr_set_addr_data"; "alsaseq_event_cntr_get_connect_data"; @@ -218,4 +212,18 @@ ALSA_GOBJECT_0_3_0 { "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"; + "alsaseq_event_data_queue_set_real_time_param"; } ALSA_GOBJECT_0_2_0; diff --git a/src/seq/event-cntr.c b/src/seq/event-cntr.c index e47f4ef..0e3327c 100644 --- a/src/seq/event-cntr.c +++ b/src/seq/event-cntr.c @@ -689,19 +689,18 @@ gboolean alsaseq_event_cntr_set_queue_id(ALSASeqEventCntr *self, gsize index, gu } /** - * alsaseq_event_cntr_get_tstamp: + * alsaseq_event_cntr_get_tick_time: * @self: A [class@EventCntr]. * @index: The index of event to set. - * @tstamp: (out)(transfer none): The timestamp for the event. The content is affected by the mode - * of tstamping. + * @tick_time: (out): The value of MIDI ticks. * @error: A [struct@GLib.Error]. * - * Get the timestamp of event pointed by index. + * Get event time as MIDI ticks. * * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. */ -gboolean alsaseq_event_cntr_get_tstamp(ALSASeqEventCntr *self, gsize index, - const ALSASeqTstamp **tstamp, GError **error) +gboolean alsaseq_event_cntr_get_tick_time(ALSASeqEventCntr *self, gsize index, + guint *tick_time, GError **error) { ALSASeqEventCntrPrivate *priv; struct event_iterator iter; @@ -710,32 +709,64 @@ gboolean alsaseq_event_cntr_get_tstamp(ALSASeqEventCntr *self, gsize index, g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); priv = alsaseq_event_cntr_get_instance_private(self); - g_return_val_if_fail(tstamp != NULL, FALSE); + 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); - *tstamp = (const ALSASeqTstamp *)&ev->time; + ev->data.time.tick = tick_time; return TRUE; } /** - * alsaseq_event_cntr_set_tstamp: + * alsaseq_event_cntr_get_real_time: * @self: A [class@EventCntr]. * @index: The index of event to set. - * @tstamp: The timestamp for the event. The content is affected by the mode of tstamping. + * @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]. * - * Set the timestamp for the event pointed by index. + * Refer to the time as wall-clock event time. * * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. */ -gboolean alsaseq_event_cntr_set_tstamp(ALSASeqEventCntr *self, gsize index, - const ALSASeqTstamp *tstamp, GError **error) +gboolean alsaseq_event_cntr_get_real_time(ALSASeqEventCntr *self, gsize index, + const guint32 *real_time[2], GError **error) { ALSASeqEventCntrPrivate *priv; struct event_iterator iter; @@ -744,15 +775,49 @@ gboolean alsaseq_event_cntr_set_tstamp(ALSASeqEventCntr *self, gsize index, g_return_val_if_fail(ALSASEQ_IS_EVENT_CNTR(self), FALSE); priv = alsaseq_event_cntr_get_instance_private(self); - g_return_val_if_fail(tstamp != NULL, FALSE); + 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->time = *tstamp; + ev->data.time.time.tv_sec = real_time[0]; + ev->data.time.time.tv_nsec = real_time[1]; return TRUE; } @@ -1400,18 +1465,18 @@ gboolean alsaseq_event_cntr_set_queue_data(ALSASeqEventCntr *self, gsize index, } /** - * alsaseq_event_cntr_get_tstamp_data: + * alsaseq_event_cntr_get_tick_time_data: * @self: A [class@EventCntr]. * @index: The index of event to set. - * @data: (out)(transfer none): The timestamp data of event. + * @tick_time: (out): The value of MIDI ticks. * @error: A [struct@GLib.Error]. * - * Get the timestamp data of event pointed by the index. + * Get time data as MIDI ticks. * * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. */ -gboolean alsaseq_event_cntr_get_tstamp_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqTstamp **data, GError **error) +gboolean alsaseq_event_cntr_get_tick_time_data(ALSASeqEventCntr *self, gsize index, + guint *tick_time, GError **error) { ALSASeqEventCntrPrivate *priv; struct event_iterator iter; @@ -1420,31 +1485,31 @@ gboolean alsaseq_event_cntr_get_tstamp_data(ALSASeqEventCntr *self, gsize index, 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(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); - *data = (const ALSASeqTstamp *)&ev->data.time; + *tick_time = ev->data.time.tick; return TRUE; } /** - * alsaseq_event_cntr_set_tstamp_data: + * alsaseq_event_cntr_set_tick_time_data: * @self: A [class@EventCntr]. * @index: The index of event to set. - * @data: The timestamp data of event. + * @tick_time: The value of MIDI ticks. * @error: A [struct@GLib.Error]. * - * Copy the timestamp data to the event pointed by the index. + * Set time data as MIDI ticks. * * Returns: %TRUE when the overall operation finishes successfully, else %FALSE. */ -gboolean alsaseq_event_cntr_set_tstamp_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqTstamp *data, GError **error) +gboolean alsaseq_event_cntr_set_tick_time_data(ALSASeqEventCntr *self, gsize index, + const guint tick_time, GError **error) { ALSASeqEventCntrPrivate *priv; struct event_iterator iter; @@ -1453,7 +1518,6 @@ gboolean alsaseq_event_cntr_set_tstamp_data(ALSASeqEventCntr *self, gsize index, 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); @@ -1463,7 +1527,80 @@ gboolean alsaseq_event_cntr_set_tstamp_data(ALSASeqEventCntr *self, gsize index, if (!ensure_fixed_length_event(priv, ev, error)) return FALSE; - ev->data.time = *(union snd_seq_timestamp *)data; + 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; } diff --git a/src/seq/event-cntr.h b/src/seq/event-cntr.h index 8fbf7a0..ceb2e95 100644 --- a/src/seq/event-cntr.h +++ b/src/seq/event-cntr.h @@ -53,10 +53,15 @@ gboolean alsaseq_event_cntr_get_queue_id(ALSASeqEventCntr *self, gsize index, gu gboolean alsaseq_event_cntr_set_queue_id(ALSASeqEventCntr *self, gsize index, guint8 queue_id, GError **error); -gboolean alsaseq_event_cntr_get_tstamp(ALSASeqEventCntr *self, gsize index, - const ALSASeqTstamp **tstamp, GError **error); -gboolean alsaseq_event_cntr_set_tstamp(ALSASeqEventCntr *self, gsize index, - const ALSASeqTstamp *tstamp, 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); @@ -98,10 +103,15 @@ gboolean alsaseq_event_cntr_get_queue_data(ALSASeqEventCntr *self, gsize index, gboolean alsaseq_event_cntr_set_queue_data(ALSASeqEventCntr *self, gsize index, const ALSASeqEventDataQueue *data, GError **error); -gboolean alsaseq_event_cntr_get_tstamp_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqTstamp **data, GError **error); -gboolean alsaseq_event_cntr_set_tstamp_data(ALSASeqEventCntr *self, gsize index, - const ALSASeqTstamp *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); diff --git a/src/seq/event-data-queue.c b/src/seq/event-data-queue.c index a30578d..01a7081 100644 --- a/src/seq/event-data-queue.c +++ b/src/seq/event-data-queue.c @@ -78,29 +78,57 @@ void alsaseq_event_data_queue_set_value_param(ALSASeqEventDataQueue *self, } /** - * alsaseq_event_data_queue_get_tstamp_param: + * alsaseq_event_data_queue_get_tick_time_param: * @self: A [struct@EventDataQueue]. - * @tstamp: (out)(transfer none): The timestamp as param of the queue event. + * @tick_time: (out): The tick time as param of the queue event. * - * Get the timestamp as param of the queue event. + * Get the tick time as param of the queue event. */ -void alsaseq_event_data_queue_get_tstamp_param(const ALSASeqEventDataQueue *self, - const ALSASeqTstamp **tstamp) +void alsaseq_event_data_queue_get_tick_time_param(const ALSASeqEventDataQueue *self, + guint *tick_time) { - *tstamp = &self->param.time; + *tick_time = self->param.time.tick; } /** - * alsaseq_event_data_queue_set_tstamp_param: + * alsaseq_event_data_queue_set_tick_time_param: * @self: A [struct@EventDataQueue]. - * @tstamp: (transfer none): The timestamp as param of the queue event. + * @tick_time: The tick time as param of the queue event. * - * Set the timestamp as param of the queue event. + * Set the tick time as param of the queue event. */ -void alsaseq_event_data_queue_set_tstamp_param(ALSASeqEventDataQueue *self, - const ALSASeqTstamp *tstamp) +void alsaseq_event_data_queue_set_tick_time_param(ALSASeqEventDataQueue *self, + const guint tick_time) { - self->param.time = *tstamp; + self->param.time.tick = tick_time; +} + +/** + * alsaseq_event_data_queue_get_real_time_param: + * @self: A [struct@EventDataQueue]. + * @real_time: (array fixed-size=2) (out) (transfer none): The real time as param of the queue + * event. + * + * Get the real time as parameter of the queue event. + */ +void alsaseq_event_data_queue_get_real_time_param(const ALSASeqEventDataQueue *self, + const guint32 *real_time[2]) +{ + *real_time = (guint32 *)&self->param.time.time; +} + +/** + * alsaseq_event_data_queue_set_real_time_param: + * @self: A [struct@EventDataQueue]. + * @real_time: (array fixed-size=2): The real time as param of the queue event. + * + * Set the real time as parameter of the queue event. + */ +void alsaseq_event_data_queue_set_real_time_param(ALSASeqEventDataQueue *self, + const guint32 real_time[2]) +{ + self->param.time.time.tv_sec = real_time[0]; + self->param.time.time.tv_nsec = real_time[1]; } /** diff --git a/src/seq/event-data-queue.h b/src/seq/event-data-queue.h index 42ec66a..fad050a 100644 --- a/src/seq/event-data-queue.h +++ b/src/seq/event-data-queue.h @@ -22,10 +22,15 @@ void alsaseq_event_data_queue_get_value_param(const ALSASeqEventDataQueue *self, void alsaseq_event_data_queue_set_value_param(ALSASeqEventDataQueue *self, gint value); -void alsaseq_event_data_queue_get_tstamp_param(const ALSASeqEventDataQueue *self, - const ALSASeqTstamp **tstamp); -void alsaseq_event_data_queue_set_tstamp_param(ALSASeqEventDataQueue *self, - const ALSASeqTstamp *tstamp); +void alsaseq_event_data_queue_get_tick_time_param(const ALSASeqEventDataQueue *self, + guint *tick_time); +void alsaseq_event_data_queue_set_tick_time_param(ALSASeqEventDataQueue *self, + const guint tick_time); + +void alsaseq_event_data_queue_get_real_time_param(const ALSASeqEventDataQueue *self, + const guint32 *real_time[2]); +void alsaseq_event_data_queue_set_real_time_param(ALSASeqEventDataQueue *self, + const guint32 real_time[2]); void alsaseq_event_data_queue_get_position_param(const ALSASeqEventDataQueue *self, guint *position); diff --git a/tests/alsaseq-event-cntr b/tests/alsaseq-event-cntr index a6be590..0b90901 100644 --- a/tests/alsaseq-event-cntr +++ b/tests/alsaseq-event-cntr @@ -28,8 +28,10 @@ methods = ( 'set_tag', 'get_queue_id', 'set_queue_id', - 'get_tstamp', - 'set_tstamp', + "get_tick_time", + "set_tick_time", + "get_real_time", + "set_real_time", 'get_dst', 'set_dst', 'get_src', @@ -46,8 +48,10 @@ methods = ( 'set_blob_data', 'get_queue_data', 'set_queue_data', - 'get_tstamp_data', - 'set_tstamp_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', -- 2.47.3