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