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