Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-3.0-or-later
2 : : // SPDX-FileCopyrightText: Andy Holmes <andrew.g.r.holmes@gmail.com>
3 : :
4 : : #define G_LOG_DOMAIN "valent-mixer-stream"
5 : :
6 : : #include "config.h"
7 : :
8 : : #include <libvalent-core.h>
9 : :
10 : : #include "valent-mixer-enums.h"
11 : : #include "valent-mixer-stream.h"
12 : :
13 : :
14 : : /**
15 : : * ValentMixerStream:
16 : : *
17 : : * A base class for mixer streams.
18 : : *
19 : : * `ValentMixerStream` is a base class for mixer streams, intended for use by
20 : : * implementations of [class@Valent.MixerAdapter].
21 : : *
22 : : * Since: 1.0
23 : : */
24 : :
25 : : typedef struct
26 : : {
27 : : char *name;
28 : : char *description;
29 : : ValentMixerDirection direction;
30 : : unsigned int level;
31 : : unsigned int muted : 1;
32 : : } ValentMixerStreamPrivate;
33 : :
34 [ + + + - ]: 1110 : G_DEFINE_TYPE_WITH_PRIVATE (ValentMixerStream, valent_mixer_stream, VALENT_TYPE_RESOURCE)
35 : :
36 : : typedef enum {
37 : : PROP_DESCRIPTION = 1,
38 : : PROP_DIRECTION,
39 : : PROP_LEVEL,
40 : : PROP_MUTED,
41 : : PROP_NAME,
42 : : } ValentMixerStreamProperty;
43 : :
44 : : static GParamSpec *properties[PROP_NAME + 1] = { NULL, };
45 : :
46 : : /* LCOV_EXCL_START */
47 : : static const char *
48 : : valent_mixer_stream_real_get_name (ValentMixerStream *stream)
49 : : {
50 : : ValentMixerStreamPrivate *priv = valent_mixer_stream_get_instance_private (stream);
51 : :
52 : : if (priv->name == NULL)
53 : : priv->name = g_uuid_string_random ();
54 : :
55 : : return priv->name;
56 : : }
57 : :
58 : : static const char *
59 : : valent_mixer_stream_real_get_description (ValentMixerStream *stream)
60 : : {
61 : : ValentMixerStreamPrivate *priv = valent_mixer_stream_get_instance_private (stream);
62 : :
63 : : if (priv->description == NULL)
64 : : return "Unnamed Stream";
65 : :
66 : : return priv->description;
67 : : }
68 : :
69 : : ValentMixerDirection
70 : : valent_mixer_stream_real_get_direction (ValentMixerStream *stream)
71 : : {
72 : : ValentMixerStreamPrivate *priv = valent_mixer_stream_get_instance_private (stream);
73 : :
74 : : return priv->direction;
75 : : }
76 : :
77 : : static unsigned int
78 : : valent_mixer_stream_real_get_level (ValentMixerStream *stream)
79 : : {
80 : : ValentMixerStreamPrivate *priv = valent_mixer_stream_get_instance_private (stream);
81 : :
82 : : return priv->level;
83 : : }
84 : :
85 : : static void
86 : : valent_mixer_stream_real_set_level (ValentMixerStream *stream,
87 : : unsigned int level)
88 : : {
89 : : ValentMixerStreamPrivate *priv = valent_mixer_stream_get_instance_private (stream);
90 : :
91 : : if (priv->level == level)
92 : : return;
93 : :
94 : : priv->level = level;
95 : : g_object_notify_by_pspec (G_OBJECT (stream), properties [PROP_LEVEL]);
96 : : }
97 : :
98 : : static gboolean
99 : : valent_mixer_stream_real_get_muted (ValentMixerStream *stream)
100 : : {
101 : : ValentMixerStreamPrivate *priv = valent_mixer_stream_get_instance_private (stream);
102 : :
103 : : return priv->muted;
104 : : }
105 : :
106 : : static void
107 : : valent_mixer_stream_real_set_muted (ValentMixerStream *stream,
108 : : gboolean mute)
109 : : {
110 : : ValentMixerStreamPrivate *priv = valent_mixer_stream_get_instance_private (stream);
111 : :
112 : : if (priv->muted == mute)
113 : : return;
114 : :
115 : : priv->muted = mute;
116 : : g_object_notify_by_pspec (G_OBJECT (stream), properties [PROP_MUTED]);
117 : : }
118 : : /* LCOV_EXCL_STOP */
119 : :
120 : : /*
121 : : * GObject
122 : : */
123 : : static void
124 : 37 : valent_mixer_stream_finalize (GObject *object)
125 : : {
126 : 37 : ValentMixerStream *self = VALENT_MIXER_STREAM (object);
127 : 37 : ValentMixerStreamPrivate *priv = valent_mixer_stream_get_instance_private (self);
128 : :
129 [ + - ]: 37 : g_clear_pointer (&priv->name, g_free);
130 [ + - ]: 37 : g_clear_pointer (&priv->description, g_free);
131 : :
132 : 37 : G_OBJECT_CLASS (valent_mixer_stream_parent_class)->finalize (object);
133 : 37 : }
134 : :
135 : : static void
136 : 5 : valent_mixer_stream_get_property (GObject *object,
137 : : guint prop_id,
138 : : GValue *value,
139 : : GParamSpec *pspec)
140 : : {
141 : 5 : ValentMixerStream *self = VALENT_MIXER_STREAM (object);
142 : :
143 [ + + + + : 5 : switch ((ValentMixerStreamProperty)prop_id)
+ - ]
144 : : {
145 : 1 : case PROP_DESCRIPTION:
146 : 1 : g_value_set_string (value, valent_mixer_stream_get_description (self));
147 : 1 : break;
148 : :
149 : 1 : case PROP_DIRECTION:
150 : 1 : g_value_set_enum (value, valent_mixer_stream_get_direction (self));
151 : 1 : break;
152 : :
153 : 1 : case PROP_LEVEL:
154 : 1 : g_value_set_uint (value, valent_mixer_stream_get_level (self));
155 : 1 : break;
156 : :
157 : 1 : case PROP_MUTED:
158 : 1 : g_value_set_boolean (value, valent_mixer_stream_get_muted (self));
159 : 1 : break;
160 : :
161 : 1 : case PROP_NAME:
162 : 1 : g_value_set_string (value, valent_mixer_stream_get_name (self));
163 : 1 : break;
164 : :
165 : 0 : default:
166 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
167 : : }
168 : 5 : }
169 : :
170 : : static void
171 : 153 : valent_mixer_stream_set_property (GObject *object,
172 : : guint prop_id,
173 : : const GValue *value,
174 : : GParamSpec *pspec)
175 : : {
176 : 153 : ValentMixerStream *self = VALENT_MIXER_STREAM (object);
177 : 153 : ValentMixerStreamPrivate *priv = valent_mixer_stream_get_instance_private (self);
178 : :
179 [ + + + + : 153 : switch ((ValentMixerStreamProperty)prop_id)
+ - ]
180 : : {
181 : 37 : case PROP_DESCRIPTION:
182 : 37 : priv->description = g_value_dup_string (value);
183 : 37 : break;
184 : :
185 : 37 : case PROP_DIRECTION:
186 : 37 : priv->direction = g_value_get_enum (value);
187 : 37 : break;
188 : :
189 : 30 : case PROP_LEVEL:
190 : 30 : valent_mixer_stream_set_level (self, g_value_get_uint (value));
191 : 30 : break;
192 : :
193 : 12 : case PROP_MUTED:
194 : 12 : valent_mixer_stream_set_muted (self, g_value_get_boolean (value));
195 : 12 : break;
196 : :
197 : 37 : case PROP_NAME:
198 : 37 : priv->name = g_value_dup_string (value);
199 : 37 : break;
200 : :
201 : 0 : default:
202 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
203 : : }
204 : 153 : }
205 : :
206 : : static void
207 : 4 : valent_mixer_stream_class_init (ValentMixerStreamClass *klass)
208 : : {
209 : 4 : GObjectClass *object_class = G_OBJECT_CLASS (klass);
210 : 4 : ValentMixerStreamClass *stream_class = VALENT_MIXER_STREAM_CLASS (klass);
211 : :
212 : 4 : object_class->finalize = valent_mixer_stream_finalize;
213 : 4 : object_class->get_property = valent_mixer_stream_get_property;
214 : 4 : object_class->set_property = valent_mixer_stream_set_property;
215 : :
216 : 4 : stream_class->get_name = valent_mixer_stream_real_get_name;
217 : 4 : stream_class->get_description = valent_mixer_stream_real_get_description;
218 : 4 : stream_class->get_direction = valent_mixer_stream_real_get_direction;
219 : 4 : stream_class->get_level = valent_mixer_stream_real_get_level;
220 : 4 : stream_class->set_level = valent_mixer_stream_real_set_level;
221 : 4 : stream_class->get_muted = valent_mixer_stream_real_get_muted;
222 : 4 : stream_class->set_muted = valent_mixer_stream_real_set_muted;
223 : :
224 : : /**
225 : : * ValentMixerStream:description: (getter get_description)
226 : : *
227 : : * The human-readable label of the stream.
228 : : *
229 : : * Implementation may emit [signal@GObject.Object::notify] for this property
230 : : * if it changes.
231 : : *
232 : : * Since: 1.0
233 : : */
234 : 8 : properties [PROP_DESCRIPTION] =
235 : 4 : g_param_spec_string ("description", NULL, NULL,
236 : : NULL,
237 : : (G_PARAM_READWRITE |
238 : : G_PARAM_CONSTRUCT_ONLY |
239 : : G_PARAM_EXPLICIT_NOTIFY |
240 : : G_PARAM_STATIC_STRINGS));
241 : :
242 : : /**
243 : : * ValentMixerStream:direction: (getter get_direction)
244 : : *
245 : : * The port direction of the stream.
246 : : *
247 : : * Since: 1.0
248 : : */
249 : 8 : properties [PROP_DIRECTION] =
250 : 4 : g_param_spec_enum ("direction", NULL, NULL,
251 : : VALENT_TYPE_MIXER_DIRECTION,
252 : : VALENT_MIXER_INPUT,
253 : : (G_PARAM_CONSTRUCT_ONLY |
254 : : G_PARAM_READWRITE |
255 : : G_PARAM_EXPLICIT_NOTIFY |
256 : : G_PARAM_STATIC_STRINGS));
257 : :
258 : : /**
259 : : * ValentMixerStream:level: (getter get_level) (setter set_level)
260 : : *
261 : : * The input or output level of the stream.
262 : : *
263 : : * Since: 1.0
264 : : */
265 : 8 : properties [PROP_LEVEL] =
266 : 4 : g_param_spec_uint ("level", NULL, NULL,
267 : : 0, 100,
268 : : 0,
269 : : (G_PARAM_READWRITE |
270 : : G_PARAM_EXPLICIT_NOTIFY |
271 : : G_PARAM_STATIC_STRINGS));
272 : :
273 : : /**
274 : : * ValentMixerStream:muted: (getter get_muted) (setter set_muted)
275 : : *
276 : : * Whether the stream is muted.
277 : : *
278 : : * Since: 1.0
279 : : */
280 : 8 : properties [PROP_MUTED] =
281 : 4 : g_param_spec_boolean ("muted", NULL, NULL,
282 : : FALSE,
283 : : (G_PARAM_READWRITE |
284 : : G_PARAM_EXPLICIT_NOTIFY |
285 : : G_PARAM_STATIC_STRINGS));
286 : :
287 : : /**
288 : : * ValentMixerStream:name: (getter get_name)
289 : : *
290 : : * The unique name of the stream.
291 : : *
292 : : * Since: 1.0
293 : : */
294 : 8 : properties [PROP_NAME] =
295 : 4 : g_param_spec_string ("name", NULL, NULL,
296 : : NULL,
297 : : (G_PARAM_READWRITE |
298 : : G_PARAM_CONSTRUCT_ONLY |
299 : : G_PARAM_EXPLICIT_NOTIFY |
300 : : G_PARAM_STATIC_STRINGS));
301 : :
302 : 4 : g_object_class_install_properties (object_class, G_N_ELEMENTS (properties), properties);
303 : 4 : }
304 : :
305 : : static void
306 : 37 : valent_mixer_stream_init (ValentMixerStream *stream)
307 : : {
308 : 37 : }
309 : :
310 : : /**
311 : : * valent_mixer_stream_get_name: (get-property name) (virtual get_name)
312 : : * @stream: a `ValentMixerStream`
313 : : *
314 : : * Get the unique name of @stream.
315 : : *
316 : : * Returns: (transfer none): a unique name
317 : : *
318 : : * Since: 1.0
319 : : */
320 : : const char *
321 : 16 : valent_mixer_stream_get_name (ValentMixerStream *stream)
322 : : {
323 : 16 : const char *ret;
324 : :
325 : 16 : VALENT_ENTRY;
326 : :
327 [ + - ]: 16 : g_return_val_if_fail (VALENT_IS_MIXER_STREAM (stream), NULL);
328 : :
329 : 16 : ret = VALENT_MIXER_STREAM_GET_CLASS (stream)->get_name (stream);
330 : :
331 : 16 : VALENT_RETURN (ret);
332 : : }
333 : :
334 : : /**
335 : : * valent_mixer_stream_get_description: (get-property description) (virtual get_description)
336 : : * @stream: a `ValentMixerStream`
337 : : *
338 : : * Get the human-readable label of @stream.
339 : : *
340 : : * Returns: (transfer none): a stream description
341 : : *
342 : : * Since: 1.0
343 : : */
344 : : const char *
345 : 13 : valent_mixer_stream_get_description (ValentMixerStream *stream)
346 : : {
347 : 13 : const char *ret;
348 : :
349 : 13 : VALENT_ENTRY;
350 : :
351 [ + - ]: 13 : g_return_val_if_fail (VALENT_IS_MIXER_STREAM (stream), NULL);
352 : :
353 : 13 : ret = VALENT_MIXER_STREAM_GET_CLASS (stream)->get_description (stream);
354 : :
355 : 13 : VALENT_RETURN (ret);
356 : : }
357 : :
358 : : /**
359 : : * valent_mixer_stream_get_direction: (get-property direction) (virtual get_direction)
360 : : * @stream: a `ValentMixerStream`
361 : : *
362 : : * Get the port direction of @stream.
363 : : *
364 : : * Returns: the `ValentMixerDirection` of @stream
365 : : *
366 : : * Since: 1.0
367 : : */
368 : : ValentMixerDirection
369 : 44 : valent_mixer_stream_get_direction (ValentMixerStream *stream)
370 : : {
371 : 44 : ValentMixerStreamPrivate *priv = valent_mixer_stream_get_instance_private (stream);
372 : :
373 [ + - ]: 44 : g_return_val_if_fail (VALENT_IS_MIXER_STREAM (stream), VALENT_MIXER_INPUT);
374 : :
375 : 44 : return priv->direction;
376 : : }
377 : :
378 : : /**
379 : : * valent_mixer_stream_get_level: (get-property level) (virtual get_level)
380 : : * @stream: a `ValentMixerStream`
381 : : *
382 : : * Get the level of @stream (eg. speaker volume, microphone sensitivity).
383 : : *
384 : : * Implementations that override this method should also override
385 : : * [vfunc@Valent.MixerStream.set_level].
386 : : *
387 : : * Returns: a volume level between `0` and `100`
388 : : *
389 : : * Since: 1.0
390 : : */
391 : : unsigned int
392 : 64 : valent_mixer_stream_get_level (ValentMixerStream *stream)
393 : : {
394 : 64 : unsigned int ret;
395 : :
396 : 64 : VALENT_ENTRY;
397 : :
398 [ + - ]: 64 : g_return_val_if_fail (VALENT_IS_MIXER_STREAM (stream), 0);
399 : :
400 : 64 : ret = VALENT_MIXER_STREAM_GET_CLASS (stream)->get_level (stream);
401 : :
402 : 64 : VALENT_RETURN (ret);
403 : : }
404 : :
405 : : /**
406 : : * valent_mixer_stream_set_level: (set-property level) (virtual set_level)
407 : : * @stream: a `ValentMixerStream`
408 : : * @level: a volume level between `0` and `100`
409 : : *
410 : : * Set the level of @stream (eg. speaker volume, microphone sensitivity).
411 : : *
412 : : * Implementations that override this method should also override
413 : : * [vfunc@Valent.MixerStream.get_level].
414 : : *
415 : : * Since: 1.0
416 : : */
417 : : void
418 : 45 : valent_mixer_stream_set_level (ValentMixerStream *stream,
419 : : unsigned int level)
420 : : {
421 : 45 : VALENT_ENTRY;
422 : :
423 [ + - ]: 45 : g_return_if_fail (VALENT_IS_MIXER_STREAM (stream));
424 [ - + ]: 45 : g_return_if_fail (level <= 100);
425 : :
426 : 45 : VALENT_MIXER_STREAM_GET_CLASS (stream)->set_level (stream, level);
427 : :
428 : 45 : VALENT_EXIT;
429 : : }
430 : :
431 : : /**
432 : : * valent_mixer_stream_get_muted: (get-property muted) (virtual get_muted)
433 : : * @stream: a `ValentMixerStream`
434 : : *
435 : : * Get the muted state of @stream.
436 : : *
437 : : * Implementations that override this method should also override
438 : : * [vfunc@Valent.MixerStream.set_muted].
439 : : *
440 : : * Returns: %TRUE if the stream is muted, or %FALSE if not
441 : : *
442 : : * Since: 1.0
443 : : */
444 : : gboolean
445 : 64 : valent_mixer_stream_get_muted (ValentMixerStream *stream)
446 : : {
447 : 64 : gboolean ret;
448 : :
449 : 64 : VALENT_ENTRY;
450 : :
451 [ + - ]: 64 : g_return_val_if_fail (VALENT_IS_MIXER_STREAM (stream), FALSE);
452 : :
453 : 64 : ret = VALENT_MIXER_STREAM_GET_CLASS (stream)->get_muted (stream);
454 : :
455 : 64 : VALENT_RETURN (ret);
456 : : }
457 : :
458 : : /**
459 : : * valent_mixer_stream_set_muted: (set-property muted) (virtual set_muted)
460 : : * @stream: a `ValentMixerStream`
461 : : * @state: whether the stream should be muted
462 : : *
463 : : * Set the muted state of @stream.
464 : : *
465 : : * Implementations that override this method should also override
466 : : * [vfunc@Valent.MixerStream.get_muted].
467 : : *
468 : : * Since: 1.0
469 : : */
470 : : void
471 : 27 : valent_mixer_stream_set_muted (ValentMixerStream *stream,
472 : : gboolean state)
473 : : {
474 : 27 : VALENT_ENTRY;
475 : :
476 [ + - ]: 27 : g_return_if_fail (VALENT_IS_MIXER_STREAM (stream));
477 : :
478 : 27 : VALENT_MIXER_STREAM_GET_CLASS (stream)->set_muted (stream, state);
479 : :
480 : 27 : VALENT_EXIT;
481 : : }
482 : :
|