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-pa-stream"
5 : :
6 : : #include "config.h"
7 : :
8 : : #include <math.h>
9 : :
10 : : #include <gvc-mixer-stream.h>
11 : : #include <valent.h>
12 : :
13 : : #include "valent-pa-stream.h"
14 : :
15 : :
16 : : struct _ValentPaStream
17 : : {
18 : : ValentMixerStream parent_instance;
19 : :
20 : : GvcMixerStream *stream;
21 : : char *description;
22 : : unsigned int vol_max;
23 : : };
24 : :
25 : 0 : G_DEFINE_FINAL_TYPE (ValentPaStream, valent_pa_stream, VALENT_TYPE_MIXER_STREAM)
26 : :
27 : : enum {
28 : : PROP_0,
29 : : PROP_BASE_STREAM,
30 : : PROP_VOL_MAX,
31 : : N_PROPERTIES
32 : : };
33 : :
34 : : static GParamSpec *properties[N_PROPERTIES] = { NULL, };
35 : :
36 : :
37 : : static void
38 : 0 : on_port_changed (GvcMixerStream *stream,
39 : : GParamSpec *pspec,
40 : : ValentPaStream *self)
41 : : {
42 : 0 : const GvcMixerStreamPort *port;
43 : :
44 : 0 : g_assert (VALENT_IS_PA_STREAM (self));
45 : :
46 : 0 : g_clear_pointer (&self->description, g_free);
47 : :
48 : 0 : if ((port = gvc_mixer_stream_get_port (self->stream)) != NULL)
49 : : {
50 : 0 : const char *description;
51 : :
52 : 0 : description = gvc_mixer_stream_get_description (self->stream);
53 : 0 : self->description = g_strdup_printf ("%s (%s)",
54 : 0 : port->human_port,
55 : : description);
56 : : }
57 : :
58 : 0 : g_object_notify (G_OBJECT (self), "description");
59 : 0 : }
60 : :
61 : : /*
62 : : * ValentMixerStream
63 : : */
64 : : static const char *
65 : 0 : valent_pa_stream_get_description (ValentMixerStream *stream)
66 : : {
67 : 0 : ValentPaStream *self = VALENT_PA_STREAM (stream);
68 : :
69 : 0 : g_assert (VALENT_IS_PA_STREAM (self));
70 : :
71 : 0 : if (self->description == NULL)
72 : 0 : return gvc_mixer_stream_get_description (self->stream);
73 : :
74 : : return self->description;
75 : : }
76 : :
77 : : static unsigned int
78 : 0 : valent_pa_stream_get_level (ValentMixerStream *stream)
79 : : {
80 : 0 : ValentPaStream *self = VALENT_PA_STREAM (stream);
81 : 0 : unsigned int volume;
82 : 0 : double percent;
83 : 0 : unsigned int level;
84 : :
85 : 0 : g_assert (VALENT_IS_PA_STREAM (self));
86 : 0 : g_assert (GVC_IS_MIXER_STREAM (self->stream));
87 : :
88 : 0 : volume = gvc_mixer_stream_get_volume (self->stream);
89 : 0 : percent = (double)volume / (double)self->vol_max;
90 : 0 : level = floor (percent * 100);
91 : :
92 : 0 : return (unsigned int)level;
93 : : }
94 : :
95 : : static void
96 : 0 : valent_pa_stream_set_level (ValentMixerStream *stream,
97 : : unsigned int level)
98 : : {
99 : 0 : ValentPaStream *self = VALENT_PA_STREAM (stream);
100 : 0 : double percent;
101 : 0 : unsigned int volume;
102 : :
103 : 0 : g_assert (VALENT_IS_PA_STREAM (self));
104 : 0 : g_assert (GVC_IS_MIXER_STREAM (self->stream));
105 : :
106 : 0 : percent = (double)level / (double)100;
107 : 0 : volume = floor (percent * (double)self->vol_max);
108 : :
109 : 0 : gvc_mixer_stream_set_volume (self->stream, (uint32_t)volume);
110 : 0 : gvc_mixer_stream_push_volume (self->stream);
111 : 0 : g_object_notify (G_OBJECT (stream), "level");
112 : 0 : }
113 : :
114 : : static gboolean
115 : 0 : valent_pa_stream_get_muted (ValentMixerStream *stream)
116 : : {
117 : 0 : ValentPaStream *self = VALENT_PA_STREAM (stream);
118 : :
119 : 0 : g_assert (VALENT_IS_PA_STREAM (self));
120 : 0 : g_assert (GVC_IS_MIXER_STREAM (self->stream));
121 : :
122 : 0 : return gvc_mixer_stream_get_is_muted (self->stream);
123 : : }
124 : :
125 : : static void
126 : 0 : valent_pa_stream_set_muted (ValentMixerStream *stream,
127 : : gboolean state)
128 : : {
129 : 0 : ValentPaStream *self = VALENT_PA_STREAM (stream);
130 : :
131 : 0 : g_assert (VALENT_IS_PA_STREAM (self));
132 : 0 : g_assert (GVC_IS_MIXER_STREAM (self->stream));
133 : :
134 : 0 : gvc_mixer_stream_change_is_muted (self->stream, state);
135 : 0 : g_object_notify (G_OBJECT (stream), "muted");
136 : 0 : }
137 : :
138 : : static const char *
139 : 0 : valent_pa_stream_get_name (ValentMixerStream *stream)
140 : : {
141 : 0 : ValentPaStream *self = VALENT_PA_STREAM (stream);
142 : :
143 : 0 : g_assert (VALENT_IS_PA_STREAM (self));
144 : 0 : g_assert (GVC_IS_MIXER_STREAM (self->stream));
145 : :
146 : 0 : return gvc_mixer_stream_get_name (self->stream);
147 : : }
148 : :
149 : : /*
150 : : * GObject
151 : : */
152 : : static void
153 : 0 : valent_pa_stream_get_property (GObject *object,
154 : : guint prop_id,
155 : : GValue *value,
156 : : GParamSpec *pspec)
157 : : {
158 : 0 : ValentPaStream *self = VALENT_PA_STREAM (object);
159 : :
160 : 0 : switch (prop_id)
161 : : {
162 : 0 : case PROP_BASE_STREAM:
163 : 0 : g_value_set_object (value, self->stream);
164 : 0 : break;
165 : :
166 : 0 : case PROP_VOL_MAX:
167 : 0 : g_value_set_uint (value, self->vol_max);
168 : 0 : break;
169 : :
170 : 0 : default:
171 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
172 : : }
173 : 0 : }
174 : :
175 : : static void
176 : 0 : valent_pa_stream_set_property (GObject *object,
177 : : guint prop_id,
178 : : const GValue *value,
179 : : GParamSpec *pspec)
180 : : {
181 : 0 : ValentPaStream *self = VALENT_PA_STREAM (object);
182 : :
183 : 0 : switch (prop_id)
184 : : {
185 : 0 : case PROP_BASE_STREAM:
186 : 0 : self->stream = g_value_dup_object (value);
187 : 0 : break;
188 : :
189 : 0 : case PROP_VOL_MAX:
190 : 0 : self->vol_max = g_value_get_uint (value);
191 : 0 : break;
192 : :
193 : 0 : default:
194 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
195 : : }
196 : 0 : }
197 : :
198 : : static void
199 : 0 : valent_pa_stream_constructed (GObject *object)
200 : : {
201 : 0 : ValentPaStream *self = VALENT_PA_STREAM (object);
202 : :
203 : 0 : g_assert (self->stream != NULL);
204 : :
205 : 0 : g_signal_connect_object (self->stream,
206 : : "notify::port",
207 : : G_CALLBACK (on_port_changed),
208 : : self, 0);
209 : 0 : on_port_changed (self->stream, NULL, self);
210 : :
211 : 0 : G_OBJECT_CLASS (valent_pa_stream_parent_class)->constructed (object);
212 : 0 : }
213 : :
214 : : static void
215 : 0 : valent_pa_stream_finalize (GObject *object)
216 : : {
217 : 0 : ValentPaStream *self = VALENT_PA_STREAM (object);
218 : :
219 : 0 : g_signal_handlers_disconnect_by_data (self->stream, self);
220 : 0 : g_clear_object (&self->stream);
221 : :
222 : 0 : G_OBJECT_CLASS (valent_pa_stream_parent_class)->finalize (object);
223 : 0 : }
224 : :
225 : : static void
226 : 0 : valent_pa_stream_class_init (ValentPaStreamClass *klass)
227 : : {
228 : 0 : GObjectClass *object_class = G_OBJECT_CLASS (klass);
229 : 0 : ValentMixerStreamClass *stream_class = VALENT_MIXER_STREAM_CLASS (klass);
230 : :
231 : 0 : object_class->constructed = valent_pa_stream_constructed;
232 : 0 : object_class->finalize = valent_pa_stream_finalize;
233 : 0 : object_class->get_property = valent_pa_stream_get_property;
234 : 0 : object_class->set_property = valent_pa_stream_set_property;
235 : :
236 : 0 : stream_class->get_name = valent_pa_stream_get_name;
237 : 0 : stream_class->get_description = valent_pa_stream_get_description;
238 : 0 : stream_class->get_level = valent_pa_stream_get_level;
239 : 0 : stream_class->set_level = valent_pa_stream_set_level;
240 : 0 : stream_class->get_muted = valent_pa_stream_get_muted;
241 : 0 : stream_class->set_muted = valent_pa_stream_set_muted;
242 : :
243 : : /**
244 : : * ValentPaStream:base-stream:
245 : : *
246 : : * The `GvcMixerStream` this stream wraps.
247 : : */
248 : 0 : properties [PROP_BASE_STREAM] =
249 : 0 : g_param_spec_object ("base-stream", NULL, NULL,
250 : : GVC_TYPE_MIXER_STREAM,
251 : : (G_PARAM_READWRITE |
252 : : G_PARAM_CONSTRUCT_ONLY |
253 : : G_PARAM_EXPLICIT_NOTIFY |
254 : : G_PARAM_STATIC_STRINGS));
255 : :
256 : : /**
257 : : * ValentPaStream:vol-max:
258 : : *
259 : : * The maximum volume.
260 : : */
261 : 0 : properties [PROP_VOL_MAX] =
262 : 0 : g_param_spec_uint ("vol-max", NULL, NULL,
263 : : 0, G_MAXUINT32,
264 : : G_MAXUINT32,
265 : : (G_PARAM_READWRITE |
266 : : G_PARAM_CONSTRUCT_ONLY |
267 : : G_PARAM_EXPLICIT_NOTIFY |
268 : : G_PARAM_STATIC_STRINGS));
269 : :
270 : 0 : g_object_class_install_properties (object_class, N_PROPERTIES, properties);
271 : 0 : }
272 : :
273 : : static void
274 : 0 : valent_pa_stream_init (ValentPaStream *self)
275 : : {
276 : 0 : }
277 : :
|