From 21ec8561cb00f192a28fa267ac7e813e2d21584e Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Mon, 8 Jun 2020 23:10:10 +0900 Subject: [PATCH] seq: event_cntr: add accesor APIs for note data of event pointed by index Signed-off-by: Takashi Sakamoto --- src/seq/alsaseq.map | 2 + src/seq/event-cntr.c | 94 ++++++++++++++++++++++++++++++++++++++++ src/seq/event-cntr.h | 6 +++ tests/alsaseq-event-cntr | 2 + 4 files changed, 104 insertions(+) diff --git a/src/seq/alsaseq.map b/src/seq/alsaseq.map index ef608c0..4c852ef 100644 --- a/src/seq/alsaseq.map +++ b/src/seq/alsaseq.map @@ -194,6 +194,8 @@ ALSA_GOBJECT_0_0_0 { "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"; local: *; }; diff --git a/src/seq/event-cntr.c b/src/seq/event-cntr.c index 86924db..d1a848d 100644 --- a/src/seq/event-cntr.c +++ b/src/seq/event-cntr.c @@ -787,3 +787,97 @@ void alsaseq_event_cntr_set_src(ALSASeqEventCntr *self, gsize index, ev->source = *src; } + +static void ensure_fixed_length_event(ALSASeqEventCntrPrivate *priv, + struct snd_seq_event *ev, GError **error) +{ + if (!priv->allocated) { + generate_error(error, ENOBUFS); + return; + } + + 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; +} + +/** + * alsaseq_event_cntr_get_note_data: + * @self: A #ALSASeqEventCntr. + * @index: The index of event to set. + * @data: (out)(transfer none): The note data of event. + * @error: A #GError. + * + * Get the note data of event pointed by the index. + */ +void 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_if_fail(ALSASEQ_IS_EVENT_CNTR(self)); + priv = alsaseq_event_cntr_get_instance_private(self); + + event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); + ev = event_iterator_find(&iter, index); + if (ev == NULL) { + generate_error(error, EINVAL); + return; + } + + *data = (const ALSASeqEventDataNote *)&ev->data.note; +} + +/** + * alsaseq_event_cntr_set_note_data: + * @self: A #ALSASeqEventCntr. + * @index: The index of event to set. + * @data: The note data of event. + * @error: A #GError. + * + * Copy the note data to the event pointed by the index. + */ +void 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_if_fail(ALSASEQ_IS_EVENT_CNTR(self)); + priv = alsaseq_event_cntr_get_instance_private(self); + + event_iterator_init(&iter, priv->buf, priv->length, priv->allocated); + ev = event_iterator_find(&iter, index); + if (ev == NULL) { + generate_error(error, EINVAL); + return; + } + + ensure_fixed_length_event(priv, ev, error); + if (*error != NULL) + return; + + ev->data.note = *(struct snd_seq_ev_note *)data; +} diff --git a/src/seq/event-cntr.h b/src/seq/event-cntr.h index 46de3df..d485955 100644 --- a/src/seq/event-cntr.h +++ b/src/seq/event-cntr.h @@ -8,6 +8,7 @@ #include #include #include +#include G_BEGIN_DECLS @@ -112,6 +113,11 @@ void alsaseq_event_cntr_get_src(ALSASeqEventCntr *self, gsize index, void alsaseq_event_cntr_set_src(ALSASeqEventCntr *self, gsize index, const ALSASeqAddr *src, GError **error); +void alsaseq_event_cntr_get_note_data(ALSASeqEventCntr *self, gsize index, + const ALSASeqEventDataNote **data, GError **error); +void alsaseq_event_cntr_set_note_data(ALSASeqEventCntr *self, gsize index, + const ALSASeqEventDataNote *data, GError **error); + G_END_DECLS #endif diff --git a/tests/alsaseq-event-cntr b/tests/alsaseq-event-cntr index b6d878e..2a7b791 100644 --- a/tests/alsaseq-event-cntr +++ b/tests/alsaseq-event-cntr @@ -34,6 +34,8 @@ methods = ( 'set_dst', 'get_src', 'set_src', + 'get_note_data', + 'set_note_data', ) signals = () -- 2.47.3