From dd4aab8c41feb56440c87827b15b20a532aa826e Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Wed, 20 Nov 2019 19:41:46 +0900 Subject: [PATCH] seq: queue_tempo: add properties Signed-off-by: Takashi Sakamoto --- src/seq/alsaseq.map | 3 + src/seq/queue-tempo.c | 144 +++++++++++++++++++++++++++++++++++++- src/seq/queue-tempo.h | 8 +++ tests/alsaseq-queue-tempo | 12 +++- 4 files changed, 163 insertions(+), 4 deletions(-) diff --git a/src/seq/alsaseq.map b/src/seq/alsaseq.map index 2c20f6d..319b234 100644 --- a/src/seq/alsaseq.map +++ b/src/seq/alsaseq.map @@ -147,6 +147,9 @@ ALSA_GOBJECT_0_0_0 { "alsaseq_queue_status_get_real_time"; "alsaseq_queue_tempo_get_type"; + "alsaseq_queue_tempo_new"; + "alsaseq_queue_tempo_get_skew"; + "alsaseq_queue_tempo_set_skew"; local: *; }; diff --git a/src/seq/queue-tempo.c b/src/seq/queue-tempo.c index d060f44..ac93a7b 100644 --- a/src/seq/queue-tempo.c +++ b/src/seq/queue-tempo.c @@ -1,14 +1,154 @@ // SPDX-License-Identifier: LGPL-3.0-or-later #include "queue-tempo.h" -G_DEFINE_TYPE(ALSASeqQueueTempo, alsaseq_queue_tempo, G_TYPE_OBJECT) +#include + +struct _ALSASeqQueueTempoPrivate { + struct snd_seq_queue_tempo tempo; +}; +G_DEFINE_TYPE_WITH_PRIVATE(ALSASeqQueueTempo, alsaseq_queue_tempo, G_TYPE_OBJECT) + +enum seq_queue_tempo_prop_type { + SEQ_QUEUE_TEMPO_PROP_QUEUE_ID = 1, + SEQ_QUEUE_TEMPO_PROP_TEMPO, + SEQ_QUEUE_TEMPO_PROP_RESOLUTION, + SEQ_QUEUE_TEMPO_PROP_COUNT, +}; +static GParamSpec *seq_queue_tempo_props[SEQ_QUEUE_TEMPO_PROP_COUNT] = { NULL, }; + +static void seq_queue_tempo_set_property(GObject *obj, guint id, + const GValue *val, GParamSpec *spec) +{ + ALSASeqQueueTempo *self = ALSASEQ_QUEUE_TEMPO(obj); + ALSASeqQueueTempoPrivate *priv = + alsaseq_queue_tempo_get_instance_private(self); + + switch (id) { + case SEQ_QUEUE_TEMPO_PROP_QUEUE_ID: + priv->tempo.queue = g_value_get_int(val); + break; + case SEQ_QUEUE_TEMPO_PROP_TEMPO: + priv->tempo.tempo = g_value_get_int(val); + break; + case SEQ_QUEUE_TEMPO_PROP_RESOLUTION: + priv->tempo.ppq = g_value_get_int(val); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, id, spec); + break; + } +} + +static void seq_queue_tempo_get_property(GObject *obj, guint id, GValue *val, + GParamSpec *spec) +{ + ALSASeqQueueTempo *self = ALSASEQ_QUEUE_TEMPO(obj); + ALSASeqQueueTempoPrivate *priv = + alsaseq_queue_tempo_get_instance_private(self); + + switch (id) { + case SEQ_QUEUE_TEMPO_PROP_QUEUE_ID: + g_value_set_int(val, priv->tempo.queue); + break; + case SEQ_QUEUE_TEMPO_PROP_TEMPO: + g_value_set_uint(val, priv->tempo.tempo); + break; + case SEQ_QUEUE_TEMPO_PROP_RESOLUTION: + g_value_set_int(val, priv->tempo.ppq); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, id, spec); + break; + } +} static void alsaseq_queue_tempo_class_init(ALSASeqQueueTempoClass *klass) { - return; + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->set_property = seq_queue_tempo_set_property; + gobject_class->get_property = seq_queue_tempo_get_property; + + seq_queue_tempo_props[SEQ_QUEUE_TEMPO_PROP_QUEUE_ID] = + g_param_spec_int("queue-id", "queue-id", + "The numerical ID of queue, except for one of " + "ALSASeqSpecificClientId.", + G_MININT, G_MAXINT, + -1, + G_PARAM_READWRITE); + + seq_queue_tempo_props[SEQ_QUEUE_TEMPO_PROP_TEMPO] = + g_param_spec_uint("tempo", "tempo", + "The number of micro second per tick as tempo.", + 0, G_MAXUINT, + 0, + G_PARAM_READWRITE); + + seq_queue_tempo_props[SEQ_QUEUE_TEMPO_PROP_RESOLUTION] = + g_param_spec_int("resolution", "resolution", + "The number of pulse per quarter as resolution.", + 0, G_MAXINT, + 0, + G_PARAM_READWRITE); + + g_object_class_install_properties(gobject_class, + SEQ_QUEUE_TEMPO_PROP_COUNT, + seq_queue_tempo_props); } static void alsaseq_queue_tempo_init(ALSASeqQueueTempo *self) { return; } + +/** + * alsaseq_queue_tempo_new: + * + * Allocate and return an instance of ALSASeqQueueTempo. + * + * Returns: A #ALSASeqQueueTempo. + */ +ALSASeqQueueTempo *alsaseq_queue_tempo_new() +{ + return g_object_new(ALSASEQ_TYPE_QUEUE_TEMPO, NULL); +} + +/** + * alsaseq_queue_tempo_get_skew: + * @self: A #ALSASeqQueueTempo. + * @skew: (array fixed-size=2)(out)(transfer none): The array with two elements + * for numerator and denominator of fraction for skew. + * + * Refer to numerator and denominator of skew. + */ +void alsaseq_queue_tempo_get_skew(ALSASeqQueueTempo *self, const guint32 **skew) +{ + ALSASeqQueueTempoPrivate *priv; + + g_return_if_fail(ALSASEQ_IS_QUEUE_TEMPO(self)); + priv = alsaseq_queue_tempo_get_instance_private(self); + + // MEMO: I wish 32-bit storage size is aligned to 32 bit offset in all of + // supported ABIs. + *skew = (guint32 *)&priv->tempo.skew_value; +} + + +/** + * alsaseq_queue_tempo_set_skew: + * @self: A #ALSASeqQueueTempo. + * @skew: (array fixed-size=2)(transfer none): The array with two elements for + * numerator and denominator of fraction for skew. + * + * Copy numerator and denominator of skew. + */ +void alsaseq_queue_tempo_set_skew(ALSASeqQueueTempo *self, const guint32 skew[2]) +{ + ALSASeqQueueTempoPrivate *priv; + + g_return_if_fail(ALSASEQ_IS_QUEUE_TEMPO(self)); + priv = alsaseq_queue_tempo_get_instance_private(self); + + priv->tempo.skew_value = skew[0]; + priv->tempo.skew_base = skew[1]; +} diff --git a/src/seq/queue-tempo.h b/src/seq/queue-tempo.h index 6d13bed..c6fbf05 100644 --- a/src/seq/queue-tempo.h +++ b/src/seq/queue-tempo.h @@ -31,9 +31,12 @@ G_BEGIN_DECLS typedef struct _ALSASeqQueueTempo ALSASeqQueueTempo; typedef struct _ALSASeqQueueTempoClass ALSASeqQueueTempoClass; +typedef struct _ALSASeqQueueTempoPrivate ALSASeqQueueTempoPrivate; struct _ALSASeqQueueTempo { GObject parent_instance; + + ALSASeqQueueTempoPrivate *priv; }; struct _ALSASeqQueueTempoClass { @@ -42,6 +45,11 @@ struct _ALSASeqQueueTempoClass { GType alsaseq_queue_tempo_get_type() G_GNUC_CONST; +ALSASeqQueueTempo *alsaseq_queue_tempo_new(); + +void alsaseq_queue_tempo_get_skew(ALSASeqQueueTempo *self, const guint32 **skew); +void alsaseq_queue_tempo_set_skew(ALSASeqQueueTempo *self, const guint32 skew[2]); + G_END_DECLS #endif diff --git a/tests/alsaseq-queue-tempo b/tests/alsaseq-queue-tempo index 13ccbf4..6cf80e4 100644 --- a/tests/alsaseq-queue-tempo +++ b/tests/alsaseq-queue-tempo @@ -10,8 +10,16 @@ gi.require_version('ALSASeq', '0.0') from gi.repository import ALSASeq target = ALSASeq.QueueTempo() -props = () -methods = () +props = ( + 'queue-id', + 'tempo', + 'resolution', +) +methods = ( + 'new', + 'get_skew', + 'set_skew', +) signals = () if not test(target, props, methods, signals): -- 2.47.3