1 /*
2 * Copyright (C) 2014 Michal Ratajsky <michal.ratajsky@gmail.com>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the licence, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include <glib.h>
19 #include <glib-object.h>
20
21 #include "matemixer-enums.h"
22 #include "matemixer-enum-types.h"
23 #include "matemixer-stream.h"
24 #include "matemixer-stream-control.h"
25 #include "matemixer-stream-control-private.h"
26
27 /**
28 * SECTION:matemixer-stream-control
29 * @include: libmatemixer/matemixer.h
30 */
31
32 struct _MateMixerStreamControlPrivate
33 {
34 gchar *name;
35 gchar *label;
36 gboolean mute;
37 gfloat balance;
38 gfloat fade;
39 MateMixerStream *stream;
40 MateMixerStreamControlFlags flags;
41 MateMixerStreamControlRole role;
42 MateMixerStreamControlMediaRole media_role;
43 };
44
45 enum {
46 PROP_0,
47 PROP_NAME,
48 PROP_LABEL,
49 PROP_FLAGS,
50 PROP_ROLE,
51 PROP_MEDIA_ROLE,
52 PROP_STREAM,
53 PROP_MUTE,
54 PROP_VOLUME,
55 PROP_BALANCE,
56 PROP_FADE,
57 N_PROPERTIES
58 };
59
60 static GParamSpec *properties[N_PROPERTIES] = { NULL, };
61
62 enum {
63 MONITOR_VALUE,
64 N_SIGNALS
65 };
66
67 static guint signals[N_SIGNALS] = { 0, };
68
69 static void mate_mixer_stream_control_get_property (GObject *object,
70 guint param_id,
71 GValue *value,
72 GParamSpec *pspec);
73 static void mate_mixer_stream_control_set_property (GObject *object,
74 guint param_id,
75 const GValue *value,
76 GParamSpec *pspec);
77
78 static void mate_mixer_stream_control_finalize (GObject *object);
79
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(MateMixerStreamControl,mate_mixer_stream_control,G_TYPE_OBJECT)80 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MateMixerStreamControl, mate_mixer_stream_control, G_TYPE_OBJECT)
81
82 static void
83 mate_mixer_stream_control_class_init (MateMixerStreamControlClass *klass)
84 {
85 GObjectClass *object_class;
86
87 object_class = G_OBJECT_CLASS (klass);
88 object_class->finalize = mate_mixer_stream_control_finalize;
89 object_class->get_property = mate_mixer_stream_control_get_property;
90 object_class->set_property = mate_mixer_stream_control_set_property;
91
92 properties[PROP_NAME] =
93 g_param_spec_string ("name",
94 "Name",
95 "Name of the stream control",
96 NULL,
97 G_PARAM_READWRITE |
98 G_PARAM_CONSTRUCT_ONLY |
99 G_PARAM_STATIC_STRINGS);
100
101 properties[PROP_LABEL] =
102 g_param_spec_string ("label",
103 "Label",
104 "Label of the stream control",
105 NULL,
106 G_PARAM_READWRITE |
107 G_PARAM_CONSTRUCT_ONLY |
108 G_PARAM_STATIC_STRINGS);
109
110 properties[PROP_FLAGS] =
111 g_param_spec_flags ("flags",
112 "Flags",
113 "Capability flags of the stream control",
114 MATE_MIXER_TYPE_STREAM_CONTROL_FLAGS,
115 MATE_MIXER_STREAM_CONTROL_NO_FLAGS,
116 G_PARAM_READWRITE |
117 G_PARAM_CONSTRUCT_ONLY |
118 G_PARAM_STATIC_STRINGS);
119
120 properties[PROP_ROLE] =
121 g_param_spec_enum ("role",
122 "Role",
123 "Role of the stream control",
124 MATE_MIXER_TYPE_STREAM_CONTROL_ROLE,
125 MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN,
126 G_PARAM_READWRITE |
127 G_PARAM_CONSTRUCT_ONLY |
128 G_PARAM_STATIC_STRINGS);
129
130 properties[PROP_MEDIA_ROLE] =
131 g_param_spec_enum ("media-role",
132 "Media role",
133 "Media role of the stream control",
134 MATE_MIXER_TYPE_STREAM_CONTROL_MEDIA_ROLE,
135 MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_UNKNOWN,
136 G_PARAM_READWRITE |
137 G_PARAM_CONSTRUCT_ONLY |
138 G_PARAM_STATIC_STRINGS);
139
140 properties[PROP_STREAM] =
141 g_param_spec_object ("stream",
142 "Stream",
143 "Stream which owns the control",
144 MATE_MIXER_TYPE_STREAM,
145 G_PARAM_READWRITE |
146 G_PARAM_CONSTRUCT_ONLY |
147 G_PARAM_STATIC_STRINGS);
148
149 properties[PROP_MUTE] =
150 g_param_spec_boolean ("mute",
151 "Mute",
152 "Mute state of the stream control",
153 FALSE,
154 G_PARAM_READABLE |
155 G_PARAM_STATIC_STRINGS);
156
157 properties[PROP_VOLUME] =
158 g_param_spec_uint ("volume",
159 "Volume",
160 "Volume of the stream control",
161 0,
162 G_MAXUINT,
163 0,
164 G_PARAM_READABLE |
165 G_PARAM_STATIC_STRINGS);
166
167 properties[PROP_BALANCE] =
168 g_param_spec_float ("balance",
169 "Balance",
170 "Balance value of the stream control",
171 -1.0f,
172 1.0f,
173 0.0f,
174 G_PARAM_READABLE |
175 G_PARAM_STATIC_STRINGS);
176
177 properties[PROP_FADE] =
178 g_param_spec_float ("fade",
179 "Fade",
180 "Fade value of the stream control",
181 -1.0f,
182 1.0f,
183 0.0f,
184 G_PARAM_READABLE |
185 G_PARAM_STATIC_STRINGS);
186
187 g_object_class_install_properties (object_class, N_PROPERTIES, properties);
188
189 signals[MONITOR_VALUE] =
190 g_signal_new ("monitor-value",
191 G_TYPE_FROM_CLASS (klass),
192 G_SIGNAL_RUN_FIRST,
193 G_STRUCT_OFFSET (MateMixerStreamControlClass, monitor_value),
194 NULL,
195 NULL,
196 g_cclosure_marshal_VOID__DOUBLE,
197 G_TYPE_NONE,
198 1,
199 G_TYPE_DOUBLE);
200 }
201
202 static void
mate_mixer_stream_control_get_property(GObject * object,guint param_id,GValue * value,GParamSpec * pspec)203 mate_mixer_stream_control_get_property (GObject *object,
204 guint param_id,
205 GValue *value,
206 GParamSpec *pspec)
207 {
208 MateMixerStreamControl *control;
209
210 control = MATE_MIXER_STREAM_CONTROL (object);
211
212 switch (param_id) {
213 case PROP_NAME:
214 g_value_set_string (value, control->priv->name);
215 break;
216 case PROP_LABEL:
217 g_value_set_string (value, control->priv->label);
218 break;
219 case PROP_FLAGS:
220 g_value_set_flags (value, control->priv->flags);
221 break;
222 case PROP_ROLE:
223 g_value_set_enum (value, control->priv->role);
224 break;
225 case PROP_MEDIA_ROLE:
226 g_value_set_enum (value, control->priv->media_role);
227 break;
228 case PROP_STREAM:
229 g_value_set_object (value, control->priv->stream);
230 break;
231
232 default:
233 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
234 break;
235 }
236 }
237
238 static void
mate_mixer_stream_control_set_property(GObject * object,guint param_id,const GValue * value,GParamSpec * pspec)239 mate_mixer_stream_control_set_property (GObject *object,
240 guint param_id,
241 const GValue *value,
242 GParamSpec *pspec)
243 {
244 MateMixerStreamControl *control;
245
246 control = MATE_MIXER_STREAM_CONTROL (object);
247
248 switch (param_id) {
249 case PROP_NAME:
250 /* Construct-only string */
251 control->priv->name = g_value_dup_string (value);
252 break;
253 case PROP_LABEL:
254 /* Construct-only string */
255 control->priv->label = g_value_dup_string (value);
256 break;
257 case PROP_FLAGS:
258 control->priv->flags = g_value_get_flags (value);
259 break;
260 case PROP_ROLE:
261 control->priv->role = g_value_get_enum (value);
262 break;
263 case PROP_MEDIA_ROLE:
264 control->priv->media_role = g_value_get_enum (value);
265 break;
266 case PROP_STREAM:
267 /* Construct-only object */
268 control->priv->stream = g_value_get_object (value);
269
270 if (control->priv->stream != NULL)
271 g_object_add_weak_pointer (G_OBJECT (control->priv->stream),
272 (gpointer *) &control->priv->stream);
273 break;
274
275 default:
276 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
277 break;
278 }
279 }
280
281 static void
mate_mixer_stream_control_init(MateMixerStreamControl * control)282 mate_mixer_stream_control_init (MateMixerStreamControl *control)
283 {
284 control->priv = mate_mixer_stream_control_get_instance_private (control);
285 }
286
287 static void
mate_mixer_stream_control_finalize(GObject * object)288 mate_mixer_stream_control_finalize (GObject *object)
289 {
290 MateMixerStreamControl *control;
291
292 control = MATE_MIXER_STREAM_CONTROL (object);
293
294 g_free (control->priv->name);
295 g_free (control->priv->label);
296
297 G_OBJECT_CLASS (mate_mixer_stream_control_parent_class)->finalize (object);
298 }
299
300 /**
301 * mate_mixer_stream_control_get_name:
302 * @control: a #MateMixerStreamControl
303 */
304 const gchar *
mate_mixer_stream_control_get_name(MateMixerStreamControl * control)305 mate_mixer_stream_control_get_name (MateMixerStreamControl *control)
306 {
307 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), NULL);
308
309 return control->priv->name;
310 }
311
312 /**
313 * mate_mixer_stream_control_get_label:
314 * @control: a #MateMixerStreamControl
315 */
316 const gchar *
mate_mixer_stream_control_get_label(MateMixerStreamControl * control)317 mate_mixer_stream_control_get_label (MateMixerStreamControl *control)
318 {
319 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), NULL);
320
321 return control->priv->label;
322 }
323
324 /**
325 * mate_mixer_stream_control_get_flags:
326 * @control: a #MateMixerStreamControl
327 */
328 MateMixerStreamControlFlags
mate_mixer_stream_control_get_flags(MateMixerStreamControl * control)329 mate_mixer_stream_control_get_flags (MateMixerStreamControl *control)
330 {
331 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), MATE_MIXER_STREAM_CONTROL_NO_FLAGS);
332
333 return control->priv->flags;
334 }
335
336 /**
337 * mate_mixer_stream_control_get_role:
338 * @control: a #MateMixerStreamControl
339 */
340 MateMixerStreamControlRole
mate_mixer_stream_control_get_role(MateMixerStreamControl * control)341 mate_mixer_stream_control_get_role (MateMixerStreamControl *control)
342 {
343 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN);
344
345 return control->priv->role;
346 }
347
348 /**
349 * mate_mixer_stream_control_get_media_role:
350 * @control: a #MateMixerStreamControl
351 */
352 MateMixerStreamControlMediaRole
mate_mixer_stream_control_get_media_role(MateMixerStreamControl * control)353 mate_mixer_stream_control_get_media_role (MateMixerStreamControl *control)
354 {
355 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_UNKNOWN);
356
357 return control->priv->media_role;
358 }
359
360 /**
361 * mate_mixer_stream_control_get_app_info:
362 * @control: a #MateMixerStreamControl
363 */
364 MateMixerAppInfo *
mate_mixer_stream_control_get_app_info(MateMixerStreamControl * control)365 mate_mixer_stream_control_get_app_info (MateMixerStreamControl *control)
366 {
367 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), NULL);
368
369 if (control->priv->role == MATE_MIXER_STREAM_CONTROL_ROLE_APPLICATION) {
370 MateMixerStreamControlClass *klass =
371 MATE_MIXER_STREAM_CONTROL_GET_CLASS (control);
372
373 /* Implementation required for application role controls */
374 return klass->get_app_info (control);
375 }
376 return NULL;
377 }
378
379 /**
380 * mate_mixer_stream_control_get_stream:
381 * @control: a #MateMixerStreamControl
382 */
383 MateMixerStream *
mate_mixer_stream_control_get_stream(MateMixerStreamControl * control)384 mate_mixer_stream_control_get_stream (MateMixerStreamControl *control)
385 {
386 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), NULL);
387
388 return control->priv->stream;
389 }
390
391 /**
392 * mate_mixer_stream_control_set_stream:
393 * @control: a #MateMixerStreamControl
394 * @stream: a #MateMixerStream
395 */
396 gboolean
mate_mixer_stream_control_set_stream(MateMixerStreamControl * control,MateMixerStream * stream)397 mate_mixer_stream_control_set_stream (MateMixerStreamControl *control,
398 MateMixerStream *stream)
399 {
400 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE);
401 g_return_val_if_fail (stream == NULL || MATE_MIXER_IS_STREAM (stream), FALSE);
402
403 if ((control->priv->flags & MATE_MIXER_STREAM_CONTROL_MOVABLE) == 0)
404 return FALSE;
405
406 if (control->priv->stream != stream) {
407 MateMixerStreamControlClass *klass =
408 MATE_MIXER_STREAM_CONTROL_GET_CLASS (control);
409
410 /* Implementation required when the flag is available */
411 if (klass->set_stream (control, stream) == FALSE)
412 return FALSE;
413
414 _mate_mixer_stream_control_set_stream (control, stream);
415 }
416 return TRUE;
417 }
418
419 /**
420 * mate_mixer_stream_control_get_mute:
421 * @control: a #MateMixerStreamControl
422 */
423 gboolean
mate_mixer_stream_control_get_mute(MateMixerStreamControl * control)424 mate_mixer_stream_control_get_mute (MateMixerStreamControl *control)
425 {
426 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE);
427
428 return control->priv->mute;
429 }
430
431 /**
432 * mate_mixer_stream_control_set_mute:
433 * @control: a #MateMixerStreamControl
434 * @mute: the mute toggle state to set
435 */
436 gboolean
mate_mixer_stream_control_set_mute(MateMixerStreamControl * control,gboolean mute)437 mate_mixer_stream_control_set_mute (MateMixerStreamControl *control, gboolean mute)
438 {
439 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE);
440
441 if ((control->priv->flags & MATE_MIXER_STREAM_CONTROL_MUTE_WRITABLE) == 0)
442 return FALSE;
443
444 if (control->priv->mute != mute) {
445 MateMixerStreamControlClass *klass =
446 MATE_MIXER_STREAM_CONTROL_GET_CLASS (control);
447
448 /* Implementation required when the flag is available */
449 if (klass->set_mute (control, mute) == FALSE)
450 return FALSE;
451
452 _mate_mixer_stream_control_set_mute (control, mute);
453 }
454 return TRUE;
455 }
456
457 /**
458 * mate_mixer_stream_control_get_num_channels:
459 * @control: a #MateMixerStreamControl
460 */
461 guint
mate_mixer_stream_control_get_num_channels(MateMixerStreamControl * control)462 mate_mixer_stream_control_get_num_channels (MateMixerStreamControl *control)
463 {
464 MateMixerStreamControlClass *klass;
465
466 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), 0);
467
468 klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control);
469
470 if (klass->get_num_channels != NULL)
471 return klass->get_num_channels (control);
472
473 return 0;
474 }
475
476 /**
477 * mate_mixer_stream_control_get_volume:
478 * @control: a #MateMixerStreamControl
479 */
480 guint
mate_mixer_stream_control_get_volume(MateMixerStreamControl * control)481 mate_mixer_stream_control_get_volume (MateMixerStreamControl *control)
482 {
483 MateMixerStreamControlClass *klass;
484
485 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), 0);
486
487 klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control);
488
489 if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_VOLUME_READABLE) {
490 /* Implementation required when the flag is available */
491 return klass->get_volume (control);
492 }
493 return klass->get_min_volume (control);
494 }
495
496 /**
497 * mate_mixer_stream_control_set_volume:
498 * @control: a #MateMixerStreamControl
499 * @volume: the volume to set
500 */
501 gboolean
mate_mixer_stream_control_set_volume(MateMixerStreamControl * control,guint volume)502 mate_mixer_stream_control_set_volume (MateMixerStreamControl *control, guint volume)
503 {
504 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE);
505
506 if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_VOLUME_WRITABLE) {
507 MateMixerStreamControlClass *klass =
508 MATE_MIXER_STREAM_CONTROL_GET_CLASS (control);
509
510 /* Implementation required when the flag is available */
511 return klass->set_volume (control, volume);
512 }
513 return FALSE;
514 }
515
516 /**
517 * mate_mixer_stream_control_get_decibel:
518 * @control: a #MateMixerStreamControl
519 */
520 gdouble
mate_mixer_stream_control_get_decibel(MateMixerStreamControl * control)521 mate_mixer_stream_control_get_decibel (MateMixerStreamControl *control)
522 {
523 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), -MATE_MIXER_INFINITY);
524
525 if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_HAS_DECIBEL &&
526 control->priv->flags & MATE_MIXER_STREAM_CONTROL_VOLUME_READABLE) {
527 MateMixerStreamControlClass *klass =
528 MATE_MIXER_STREAM_CONTROL_GET_CLASS (control);
529
530 /* Implementation required when the flags are available */
531 return klass->get_decibel (control);
532 }
533 return -MATE_MIXER_INFINITY;
534 }
535
536 /**
537 * mate_mixer_stream_control_set_decibel:
538 * @control: a #MateMixerStreamControl
539 * @decibel: the volume to set in decibels
540 */
541 gboolean
mate_mixer_stream_control_set_decibel(MateMixerStreamControl * control,gdouble decibel)542 mate_mixer_stream_control_set_decibel (MateMixerStreamControl *control, gdouble decibel)
543 {
544 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE);
545
546 if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_HAS_DECIBEL &&
547 control->priv->flags & MATE_MIXER_STREAM_CONTROL_VOLUME_WRITABLE) {
548 MateMixerStreamControlClass *klass =
549 MATE_MIXER_STREAM_CONTROL_GET_CLASS (control);
550
551 /* Implementation required when the flags are available */
552 return klass->set_decibel (control, decibel);
553 }
554 return FALSE;
555 }
556
557 /**
558 * mate_mixer_stream_control_has_channel_position:
559 * @control: a #MateMixerStreamControl
560 * @position: to channel position to check
561 */
562 gboolean
mate_mixer_stream_control_has_channel_position(MateMixerStreamControl * control,MateMixerChannelPosition position)563 mate_mixer_stream_control_has_channel_position (MateMixerStreamControl *control,
564 MateMixerChannelPosition position)
565 {
566 MateMixerStreamControlClass *klass;
567
568 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE);
569
570 klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control);
571
572 if (klass->has_channel_position != NULL)
573 return klass->has_channel_position (control, position);
574
575 return FALSE;
576 }
577
578 /**
579 * mate_mixer_stream_control_get_channel_position:
580 * @control: a #MateMixerStreamControl
581 * @channel: a channel index
582 */
583 MateMixerChannelPosition
mate_mixer_stream_control_get_channel_position(MateMixerStreamControl * control,guint channel)584 mate_mixer_stream_control_get_channel_position (MateMixerStreamControl *control, guint channel)
585 {
586 MateMixerStreamControlClass *klass;
587
588 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), MATE_MIXER_CHANNEL_UNKNOWN);
589
590 klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control);
591
592 if (klass->get_channel_position != NULL)
593 return klass->get_channel_position (control, channel);
594
595 return MATE_MIXER_CHANNEL_UNKNOWN;
596 }
597
598 /**
599 * mate_mixer_stream_control_get_channel_volume:
600 * @control: a #MateMixerStreamControl
601 * @channel: a channel index
602 */
603 guint
mate_mixer_stream_control_get_channel_volume(MateMixerStreamControl * control,guint channel)604 mate_mixer_stream_control_get_channel_volume (MateMixerStreamControl *control, guint channel)
605 {
606 MateMixerStreamControlClass *klass;
607
608 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), 0);
609
610 klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control);
611
612 if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_VOLUME_READABLE) {
613 /* Implementation required when the flag is available */
614 return klass->get_channel_volume (control, channel);
615 }
616 return klass->get_min_volume (control);
617 }
618
619 /**
620 * mate_mixer_stream_control_set_channel_volume:
621 * @control: a #MateMixerStreamControl
622 * @channel: a channel index
623 * @volume: the volume to set
624 */
625 gboolean
mate_mixer_stream_control_set_channel_volume(MateMixerStreamControl * control,guint channel,guint volume)626 mate_mixer_stream_control_set_channel_volume (MateMixerStreamControl *control,
627 guint channel,
628 guint volume)
629 {
630 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE);
631
632 if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_VOLUME_WRITABLE) {
633 MateMixerStreamControlClass *klass =
634 MATE_MIXER_STREAM_CONTROL_GET_CLASS (control);
635
636 /* Implementation required when the flag is available */
637 return klass->set_channel_volume (control, channel, volume);
638 }
639 return FALSE;
640 }
641
642 /**
643 * mate_mixer_stream_control_get_channel_decibel:
644 * @control: a #MateMixerStreamControl
645 * @channel: a channel index
646 */
647 gdouble
mate_mixer_stream_control_get_channel_decibel(MateMixerStreamControl * control,guint channel)648 mate_mixer_stream_control_get_channel_decibel (MateMixerStreamControl *control, guint channel)
649 {
650 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), -MATE_MIXER_INFINITY);
651
652 if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_HAS_DECIBEL &&
653 control->priv->flags & MATE_MIXER_STREAM_CONTROL_VOLUME_READABLE) {
654 MateMixerStreamControlClass *klass =
655 MATE_MIXER_STREAM_CONTROL_GET_CLASS (control);
656
657 /* Implementation required when the flags are available */
658 return klass->get_channel_decibel (control, channel);
659 }
660 return -MATE_MIXER_INFINITY;
661 }
662
663 /**
664 * mate_mixer_stream_control_set_channel_decibel:
665 * @control: a #MateMixerStreamControl
666 * @channel: a channel index
667 * @decibel: the volume to set in decibels
668 */
669 gboolean
mate_mixer_stream_control_set_channel_decibel(MateMixerStreamControl * control,guint channel,gdouble decibel)670 mate_mixer_stream_control_set_channel_decibel (MateMixerStreamControl *control,
671 guint channel,
672 gdouble decibel)
673 {
674 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE);
675
676 if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_HAS_DECIBEL &&
677 control->priv->flags & MATE_MIXER_STREAM_CONTROL_VOLUME_WRITABLE) {
678 MateMixerStreamControlClass *klass =
679 MATE_MIXER_STREAM_CONTROL_GET_CLASS (control);
680
681 /* Implementation required when the flags are available */
682 return klass->set_channel_decibel (control, channel, decibel);
683 }
684 return FALSE;
685 }
686
687 /**
688 * mate_mixer_stream_control_get_balance:
689 * @control: a #MateMixerStreamControl
690 */
691 gfloat
mate_mixer_stream_control_get_balance(MateMixerStreamControl * control)692 mate_mixer_stream_control_get_balance (MateMixerStreamControl *control)
693 {
694 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), 0.0f);
695
696 if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_CAN_BALANCE)
697 return control->priv->balance;
698 else
699 return 0.0f;
700 }
701
702 /**
703 * mate_mixer_stream_control_set_balance:
704 * @control: a #MateMixerStreamControl
705 * @balance: the balance value
706 */
707 gboolean
mate_mixer_stream_control_set_balance(MateMixerStreamControl * control,gfloat balance)708 mate_mixer_stream_control_set_balance (MateMixerStreamControl *control, gfloat balance)
709 {
710 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE);
711 g_return_val_if_fail (balance >= -1.0f && balance <= 1.0f, FALSE);
712
713 if ((control->priv->flags & MATE_MIXER_STREAM_CONTROL_CAN_BALANCE) == 0)
714 return FALSE;
715
716 if (control->priv->balance != balance) {
717 MateMixerStreamControlClass *klass =
718 MATE_MIXER_STREAM_CONTROL_GET_CLASS (control);
719
720 /* Implementation required when the flag is available */
721 if (klass->set_balance (control, balance) == FALSE)
722 return FALSE;
723
724 _mate_mixer_stream_control_set_balance (control, balance);
725 }
726 return TRUE;
727 }
728
729 /**
730 * mate_mixer_stream_control_get_fade:
731 * @control: a #MateMixerStreamControl
732 */
733 gfloat
mate_mixer_stream_control_get_fade(MateMixerStreamControl * control)734 mate_mixer_stream_control_get_fade (MateMixerStreamControl *control)
735 {
736 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), 0.0f);
737
738 if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_CAN_FADE)
739 return control->priv->fade;
740 else
741 return 0.0f;
742 }
743
744 /**
745 * mate_mixer_stream_control_set_fade:
746 * @control: a #MateMixerStreamControl
747 * @fade: the fade value
748 */
749 gboolean
mate_mixer_stream_control_set_fade(MateMixerStreamControl * control,gfloat fade)750 mate_mixer_stream_control_set_fade (MateMixerStreamControl *control, gfloat fade)
751 {
752 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE);
753 g_return_val_if_fail (fade >= -1.0f && fade <= 1.0f, FALSE);
754
755 if ((control->priv->flags & MATE_MIXER_STREAM_CONTROL_CAN_FADE) == 0)
756 return FALSE;
757
758 if (control->priv->fade != fade) {
759 MateMixerStreamControlClass *klass =
760 MATE_MIXER_STREAM_CONTROL_GET_CLASS (control);
761
762 /* Implementation required when the flag is available */
763 if (klass->set_fade (control, fade) == FALSE)
764 return FALSE;
765
766 _mate_mixer_stream_control_set_fade (control, fade);
767 }
768 return TRUE;
769 }
770
771 /**
772 * mate_mixer_stream_control_get_monitor_enabled:
773 * @control: a #MateMixerStreamControl
774 */
775 gboolean
mate_mixer_stream_control_get_monitor_enabled(MateMixerStreamControl * control)776 mate_mixer_stream_control_get_monitor_enabled (MateMixerStreamControl *control)
777 {
778 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE);
779
780 if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_HAS_MONITOR) {
781 MateMixerStreamControlClass *klass =
782 MATE_MIXER_STREAM_CONTROL_GET_CLASS (control);
783
784 /* Implementation required when the flag is available */
785 return klass->get_monitor_enabled (control);
786 }
787 return FALSE;
788 }
789
790 /**
791 * mate_mixer_stream_control_set_monitor_enabled:
792 * @control: a #MateMixerStreamControl
793 * @enabled: a boolean value
794 */
795 gboolean
mate_mixer_stream_control_set_monitor_enabled(MateMixerStreamControl * control,gboolean enabled)796 mate_mixer_stream_control_set_monitor_enabled (MateMixerStreamControl *control, gboolean enabled)
797 {
798 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE);
799
800 if ((control->priv->flags & MATE_MIXER_STREAM_CONTROL_HAS_MONITOR) == 0)
801 return FALSE;
802
803 /* Implementation required when the flag is available */
804 return MATE_MIXER_STREAM_CONTROL_GET_CLASS (control)->set_monitor_enabled (control, enabled);
805 }
806
807 /**
808 * mate_mixer_stream_control_get_min_volume:
809 * @control: a #MateMixerStreamControl
810 */
811 guint
mate_mixer_stream_control_get_min_volume(MateMixerStreamControl * control)812 mate_mixer_stream_control_get_min_volume (MateMixerStreamControl *control)
813 {
814 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), 0);
815
816 /* Implementation required */
817 return MATE_MIXER_STREAM_CONTROL_GET_CLASS (control)->get_min_volume (control);
818 }
819
820 /**
821 * mate_mixer_stream_control_get_max_volume:
822 * @control: a #MateMixerStreamControl
823 */
824 guint
mate_mixer_stream_control_get_max_volume(MateMixerStreamControl * control)825 mate_mixer_stream_control_get_max_volume (MateMixerStreamControl *control)
826 {
827 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), 0);
828
829 /* Implementation required */
830 return MATE_MIXER_STREAM_CONTROL_GET_CLASS (control)->get_max_volume (control);
831 }
832
833 /**
834 * mate_mixer_stream_control_get_normal_volume:
835 * @control: a #MateMixerStreamControl
836 */
837 guint
mate_mixer_stream_control_get_normal_volume(MateMixerStreamControl * control)838 mate_mixer_stream_control_get_normal_volume (MateMixerStreamControl *control)
839 {
840 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), 0);
841
842 /* Implementation required */
843 return MATE_MIXER_STREAM_CONTROL_GET_CLASS (control)->get_normal_volume (control);
844 }
845
846 /**
847 * mate_mixer_stream_control_get_base_volume:
848 * @control: a #MateMixerStreamControl
849 */
850 guint
mate_mixer_stream_control_get_base_volume(MateMixerStreamControl * control)851 mate_mixer_stream_control_get_base_volume (MateMixerStreamControl *control)
852 {
853 g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), 0);
854
855 /* Implementation required */
856 return MATE_MIXER_STREAM_CONTROL_GET_CLASS (control)->get_base_volume (control);
857 }
858
859 /* Protected functions */
860 void
_mate_mixer_stream_control_set_flags(MateMixerStreamControl * control,MateMixerStreamControlFlags flags)861 _mate_mixer_stream_control_set_flags (MateMixerStreamControl *control,
862 MateMixerStreamControlFlags flags)
863 {
864 g_return_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control));
865
866 if (control->priv->flags == flags)
867 return;
868
869 control->priv->flags = flags;
870
871 g_object_notify_by_pspec (G_OBJECT (control), properties[PROP_FLAGS]);
872 }
873
874 void
_mate_mixer_stream_control_set_stream(MateMixerStreamControl * control,MateMixerStream * stream)875 _mate_mixer_stream_control_set_stream (MateMixerStreamControl *control,
876 MateMixerStream *stream)
877 {
878 g_return_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control));
879 g_return_if_fail (stream == NULL || MATE_MIXER_IS_STREAM (stream));
880
881 if (control->priv->stream == stream)
882 return;
883
884 if (control->priv->stream != NULL)
885 g_object_remove_weak_pointer (G_OBJECT (control->priv->stream),
886 (gpointer *) &control->priv->stream);
887
888 if (stream != NULL) {
889 control->priv->stream = stream;
890 g_object_add_weak_pointer (G_OBJECT (control->priv->stream),
891 (gpointer *) &control->priv->stream);
892 } else
893 control->priv->stream = NULL;
894
895 g_object_notify_by_pspec (G_OBJECT (control), properties[PROP_STREAM]);
896 }
897
898 void
_mate_mixer_stream_control_set_mute(MateMixerStreamControl * control,gboolean mute)899 _mate_mixer_stream_control_set_mute (MateMixerStreamControl *control, gboolean mute)
900 {
901 g_return_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control));
902
903 if (control->priv->mute == mute)
904 return;
905
906 control->priv->mute = mute;
907
908 g_object_notify_by_pspec (G_OBJECT (control), properties[PROP_MUTE]);
909 }
910
911 void
_mate_mixer_stream_control_set_balance(MateMixerStreamControl * control,gfloat balance)912 _mate_mixer_stream_control_set_balance (MateMixerStreamControl *control, gfloat balance)
913 {
914 g_return_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control));
915
916 if (control->priv->balance == balance)
917 return;
918
919 control->priv->balance = balance;
920
921 g_object_notify_by_pspec (G_OBJECT (control), properties[PROP_BALANCE]);
922 }
923
924 void
_mate_mixer_stream_control_set_fade(MateMixerStreamControl * control,gfloat fade)925 _mate_mixer_stream_control_set_fade (MateMixerStreamControl *control, gfloat fade)
926 {
927 g_return_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control));
928
929 if (control->priv->fade == fade)
930 return;
931
932 control->priv->fade = fade;
933
934 g_object_notify_by_pspec (G_OBJECT (control), properties[PROP_FADE]);
935 }
936