File: | build-analysis/../src/plugins/jack/jack.c |
Warning: | line 421, column 26 Assigned value is garbage or undefined |
1 | /* XMMS2 - X Music Multiplexer System | |||
2 | * Copyright (C) 2003-2017 XMMS2 Team | |||
3 | * | |||
4 | * PLUGINS ARE NOT CONSIDERED TO BE DERIVED WORK !!! | |||
5 | * | |||
6 | * This library is free software; you can redistribute it and/or | |||
7 | * modify it under the terms of the GNU Lesser General Public | |||
8 | * License as published by the Free Software Foundation; either | |||
9 | * version 2.1 of the License, or (at your option) any later version. | |||
10 | * | |||
11 | * This library is distributed in the hope that it will be useful, | |||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
14 | * Lesser General Public License for more details. | |||
15 | */ | |||
16 | ||||
17 | #include <xmms/xmms_outputplugin.h> | |||
18 | #include <xmms/xmms_log.h> | |||
19 | ||||
20 | #include <stdio.h> | |||
21 | ||||
22 | #include <glib.h> | |||
23 | #include <jack/jack.h> | |||
24 | ||||
25 | ||||
26 | /* | |||
27 | * Defines | |||
28 | */ | |||
29 | ||||
30 | /* this isn't really what we want... */ | |||
31 | #define CHANNELS2 2 | |||
32 | ||||
33 | ||||
34 | /* | |||
35 | * Type definitions | |||
36 | */ | |||
37 | ||||
38 | typedef struct xmms_jack_data_St { | |||
39 | jack_client_t *jack; | |||
40 | jack_port_t *ports[CHANNELS2]; | |||
41 | /* ports */ | |||
42 | gint chunksiz; | |||
43 | gboolean error; | |||
44 | gboolean running; | |||
45 | guint underruns; | |||
46 | guint volume[CHANNELS2]; | |||
47 | gfloat volume_actual[CHANNELS2]; | |||
48 | gfloat new_volume_actual[CHANNELS2]; | |||
49 | gint last_sign[CHANNELS2]; | |||
50 | GMutex volume_change; /* This should not be needed once the server doesn't allow multiple clients to set the volume at the same time */ | |||
51 | } xmms_jack_data_t; | |||
52 | ||||
53 | ||||
54 | /* | |||
55 | * Function prototypes | |||
56 | */ | |||
57 | ||||
58 | static gboolean xmms_jack_plugin_setup (xmms_output_plugin_t *plugin); | |||
59 | static gboolean xmms_jack_new (xmms_output_t *output); | |||
60 | static void xmms_jack_destroy (xmms_output_t *output); | |||
61 | static gboolean xmms_jack_status (xmms_output_t *output, xmms_playback_status_t status); | |||
62 | static void xmms_jack_flush (xmms_output_t *output); | |||
63 | static gboolean xmms_jack_volume_set (xmms_output_t *output, const gchar *channel, guint volume); | |||
64 | static gboolean xmms_jack_volume_get (xmms_output_t *output, const gchar **names, guint *values, guint *num_channels); | |||
65 | static int xmms_jack_process (jack_nframes_t frames, void *arg); | |||
66 | static void xmms_jack_shutdown (void *arg); | |||
67 | static void xmms_jack_error (const gchar *desc); | |||
68 | static gboolean xmms_jack_ports_connected (xmms_output_t *output); | |||
69 | static gboolean xmms_jack_connect_ports (xmms_output_t *output); | |||
70 | static gboolean xmms_jack_connect (xmms_output_t *output); | |||
71 | ||||
72 | /* | |||
73 | * Plugin header | |||
74 | */ | |||
75 | ||||
76 | XMMS_OUTPUT_PLUGIN_DEFINE ("jack", "Jack Output", XMMS_VERSION,xmms_plugin_desc_t __attribute__((visibility ("default"))) XMMS_PLUGIN_DESC = { XMMS_PLUGIN_TYPE_OUTPUT, 8, "jack", "Jack Output", "clang-analysis" , "Jack audio server output plugin", (gboolean (*)(gpointer)) xmms_jack_plugin_setup }; | |||
77 | "Jack audio server output plugin",xmms_plugin_desc_t __attribute__((visibility ("default"))) XMMS_PLUGIN_DESC = { XMMS_PLUGIN_TYPE_OUTPUT, 8, "jack", "Jack Output", "clang-analysis" , "Jack audio server output plugin", (gboolean (*)(gpointer)) xmms_jack_plugin_setup }; | |||
78 | xmms_jack_plugin_setup)xmms_plugin_desc_t __attribute__((visibility ("default"))) XMMS_PLUGIN_DESC = { XMMS_PLUGIN_TYPE_OUTPUT, 8, "jack", "Jack Output", "clang-analysis" , "Jack audio server output plugin", (gboolean (*)(gpointer)) xmms_jack_plugin_setup };; | |||
79 | ||||
80 | static gboolean | |||
81 | xmms_jack_plugin_setup (xmms_output_plugin_t *plugin) | |||
82 | { | |||
83 | xmms_output_methods_t methods; | |||
84 | ||||
85 | XMMS_OUTPUT_METHODS_INIT (methods)memset (&methods, 0, sizeof (xmms_output_methods_t)); | |||
86 | ||||
87 | methods.new = xmms_jack_new; | |||
88 | methods.destroy = xmms_jack_destroy; | |||
89 | methods.status = xmms_jack_status; | |||
90 | methods.flush = xmms_jack_flush; | |||
91 | methods.volume_get = xmms_jack_volume_get; | |||
92 | methods.volume_set = xmms_jack_volume_set; | |||
93 | ||||
94 | xmms_output_plugin_methods_set (plugin, &methods); | |||
95 | ||||
96 | xmms_output_plugin_config_property_register (plugin, "clientname", "XMMS2", | |||
97 | NULL((void*)0), NULL((void*)0)); | |||
98 | ||||
99 | xmms_output_plugin_config_property_register (plugin, "connect_ports", "1", | |||
100 | NULL((void*)0), NULL((void*)0)); | |||
101 | ||||
102 | xmms_output_plugin_config_property_register (plugin, "connect_to_ports", "physical", | |||
103 | NULL((void*)0), NULL((void*)0)); | |||
104 | ||||
105 | xmms_output_plugin_config_property_register (plugin, "volume.left", "100", | |||
106 | NULL((void*)0), NULL((void*)0)); | |||
107 | ||||
108 | xmms_output_plugin_config_property_register (plugin, "volume.right", "100", | |||
109 | NULL((void*)0), NULL((void*)0)); | |||
110 | ||||
111 | jack_set_error_function (xmms_jack_error); | |||
112 | ||||
113 | return TRUE(!(0)); | |||
114 | } | |||
115 | ||||
116 | ||||
117 | /* | |||
118 | * Member functions | |||
119 | */ | |||
120 | ||||
121 | ||||
122 | static gboolean | |||
123 | xmms_jack_connect (xmms_output_t *output) | |||
124 | { | |||
125 | int i; | |||
126 | const xmms_config_property_t *cv; | |||
127 | const gchar *clientname; | |||
128 | xmms_jack_data_t *data; | |||
129 | ||||
130 | g_return_val_if_fail (output, FALSE)do{ if (output) { } else { g_return_if_fail_warning (((gchar* ) 0), ((const char*) (__func__)), "output"); return ((0)); }; }while (0); | |||
131 | data = xmms_output_private_data_get (output); | |||
132 | g_return_val_if_fail (data, FALSE)do{ if (data) { } else { g_return_if_fail_warning (((gchar*) 0 ), ((const char*) (__func__)), "data"); return ((0)); }; }while (0); | |||
133 | ||||
134 | cv = xmms_output_config_lookup (output, "clientname"); | |||
135 | clientname = xmms_config_property_get_string (cv); | |||
136 | ||||
137 | data->jack = jack_client_open (clientname, JackNullOption, NULL((void*)0)); | |||
138 | if (!data->jack) { | |||
139 | return FALSE(0); | |||
140 | } | |||
141 | ||||
142 | jack_set_process_callback (data->jack, xmms_jack_process, output); | |||
143 | jack_on_shutdown (data->jack, xmms_jack_shutdown, output); | |||
144 | ||||
145 | ||||
146 | for (i = 0; i < CHANNELS2; i++) { | |||
147 | gchar name[16]; | |||
148 | g_snprintf (name, sizeof (name), "out_%d", i + 1); | |||
149 | data->ports[i] = jack_port_register (data->jack, name, | |||
150 | JACK_DEFAULT_AUDIO_TYPE"32 bit float mono audio", | |||
151 | (JackPortIsOutput | | |||
152 | JackPortIsTerminal), 0); | |||
153 | } | |||
154 | ||||
155 | data->chunksiz = jack_get_buffer_size (data->jack); | |||
156 | ||||
157 | if (jack_activate (data->jack)) { | |||
158 | /* jadda jadda */ | |||
159 | jack_client_close (data->jack); | |||
160 | return FALSE(0); | |||
161 | } | |||
162 | ||||
163 | data->error = FALSE(0); | |||
164 | ||||
165 | return TRUE(!(0)); | |||
166 | } | |||
167 | ||||
168 | ||||
169 | static gboolean | |||
170 | xmms_jack_new (xmms_output_t *output) | |||
171 | { | |||
172 | xmms_jack_data_t *data; | |||
173 | xmms_config_property_t *cv; | |||
174 | int connect; | |||
175 | ||||
176 | g_return_val_if_fail (output, FALSE)do{ if (output) { } else { g_return_if_fail_warning (((gchar* ) 0), ((const char*) (__func__)), "output"); return ((0)); }; }while (0); | |||
177 | ||||
178 | data = g_new0 (xmms_jack_data_t, 1)((xmms_jack_data_t *) g_malloc0_n ((1), sizeof (xmms_jack_data_t ))); | |||
179 | ||||
180 | data->underruns = 0; | |||
181 | ||||
182 | cv = xmms_output_config_lookup (output, "volume.left"); | |||
183 | data->volume[0] = xmms_config_property_get_int (cv); | |||
184 | ||||
185 | cv = xmms_output_config_lookup (output, "volume.right"); | |||
186 | data->volume[1] = xmms_config_property_get_int (cv); | |||
187 | ||||
188 | data->volume_actual[0] = (gfloat)(data->volume[0] / 100.0); | |||
189 | data->volume_actual[0] *= data->volume_actual[0]; | |||
190 | data->new_volume_actual[0] = data->volume_actual[0]; | |||
191 | data->volume_actual[1] = (gfloat)(data->volume[1] / 100.0); | |||
192 | data->volume_actual[1] *= data->volume_actual[1]; | |||
193 | data->new_volume_actual[1] = data->volume_actual[1]; | |||
194 | ||||
195 | g_mutex_init (&data->volume_change); | |||
196 | ||||
197 | ||||
198 | xmms_output_private_data_set (output, data); | |||
199 | ||||
200 | if (!xmms_jack_connect (output)) { | |||
201 | g_mutex_clear (&data->volume_change); | |||
202 | g_free (data); | |||
203 | return FALSE(0); | |||
204 | } | |||
205 | ||||
206 | xmms_output_format_add (output, XMMS_SAMPLE_FORMAT_FLOAT, CHANNELS,xmms_output_stream_type_add (output, XMMS_STREAM_TYPE_MIMETYPE , "audio/pcm", XMMS_STREAM_TYPE_FMT_FORMAT, XMMS_SAMPLE_FORMAT_FLOAT , XMMS_STREAM_TYPE_FMT_CHANNELS, 2, XMMS_STREAM_TYPE_FMT_SAMPLERATE , jack_get_sample_rate (data->jack), XMMS_STREAM_TYPE_END) | |||
207 | jack_get_sample_rate (data->jack))xmms_output_stream_type_add (output, XMMS_STREAM_TYPE_MIMETYPE , "audio/pcm", XMMS_STREAM_TYPE_FMT_FORMAT, XMMS_SAMPLE_FORMAT_FLOAT , XMMS_STREAM_TYPE_FMT_CHANNELS, 2, XMMS_STREAM_TYPE_FMT_SAMPLERATE , jack_get_sample_rate (data->jack), XMMS_STREAM_TYPE_END); | |||
208 | ||||
209 | cv = xmms_output_config_lookup (output, "connect_ports"); | |||
210 | connect = xmms_config_property_get_int (cv); | |||
211 | ||||
212 | if (connect == 1) { | |||
213 | ||||
214 | if (!xmms_jack_ports_connected (output) && !xmms_jack_connect_ports (output)) { | |||
215 | g_mutex_clear (&data->volume_change); | |||
216 | g_free (data); | |||
217 | return FALSE(0); | |||
218 | } | |||
219 | ||||
220 | } | |||
221 | ||||
222 | return TRUE(!(0)); | |||
223 | } | |||
224 | ||||
225 | ||||
226 | static void | |||
227 | xmms_jack_destroy (xmms_output_t *output) | |||
228 | { | |||
229 | xmms_jack_data_t *data; | |||
230 | ||||
231 | g_return_if_fail (output)do{ if (output) { } else { g_return_if_fail_warning (((gchar* ) 0), ((const char*) (__func__)), "output"); return; }; }while (0); | |||
232 | data = xmms_output_private_data_get (output); | |||
233 | g_return_if_fail (data)do{ if (data) { } else { g_return_if_fail_warning (((gchar*) 0 ), ((const char*) (__func__)), "data"); return; }; }while (0); | |||
234 | ||||
235 | g_mutex_clear (&data->volume_change); | |||
236 | ||||
237 | if (data->jack) { | |||
238 | jack_deactivate (data->jack); | |||
239 | jack_client_close (data->jack); | |||
240 | } | |||
241 | ||||
242 | g_free (data); | |||
243 | } | |||
244 | ||||
245 | ||||
246 | static gboolean | |||
247 | xmms_jack_ports_connected (xmms_output_t *output) | |||
248 | { | |||
249 | xmms_jack_data_t *data; | |||
250 | ||||
251 | g_return_val_if_fail (output, FALSE)do{ if (output) { } else { g_return_if_fail_warning (((gchar* ) 0), ((const char*) (__func__)), "output"); return ((0)); }; }while (0); | |||
252 | data = xmms_output_private_data_get (output); | |||
253 | g_return_val_if_fail (data, FALSE)do{ if (data) { } else { g_return_if_fail_warning (((gchar*) 0 ), ((const char*) (__func__)), "data"); return ((0)); }; }while (0); | |||
254 | ||||
255 | gint is_connected = 0; | |||
256 | gint i; | |||
257 | ||||
258 | for (i = 0; i < CHANNELS2; i++) { | |||
259 | is_connected += jack_port_connected (data->ports[i]); | |||
260 | } | |||
261 | ||||
262 | return (is_connected > 0); | |||
263 | } | |||
264 | ||||
265 | static gboolean | |||
266 | xmms_jack_connect_ports (xmms_output_t *output) | |||
267 | { | |||
268 | const gchar *ports; | |||
269 | const gchar **remote_ports; | |||
270 | gboolean ret = TRUE(!(0)); | |||
271 | gint i, err; | |||
272 | xmms_config_property_t *cv; | |||
273 | xmms_jack_data_t *data; | |||
274 | ||||
275 | g_return_val_if_fail (output, FALSE)do{ if (output) { } else { g_return_if_fail_warning (((gchar* ) 0), ((const char*) (__func__)), "output"); return ((0)); }; }while (0); | |||
276 | data = xmms_output_private_data_get (output); | |||
277 | g_return_val_if_fail (data, FALSE)do{ if (data) { } else { g_return_if_fail_warning (((gchar*) 0 ), ((const char*) (__func__)), "data"); return ((0)); }; }while (0); | |||
278 | ||||
279 | cv = xmms_output_config_lookup (output, "connect_to_ports"); | |||
280 | ports = xmms_config_property_get_string (cv); | |||
281 | ||||
282 | if ((strlen(ports) == 0) || ((strncmp(ports, "physical", 8) == 0))) { | |||
283 | ||||
284 | remote_ports = jack_get_ports (data->jack, NULL((void*)0), NULL((void*)0), | |||
285 | JackPortIsInput | JackPortIsPhysical); | |||
286 | ||||
287 | } else { | |||
288 | ||||
289 | remote_ports = jack_get_ports (data->jack, ports, NULL((void*)0), JackPortIsInput); | |||
290 | ||||
291 | } | |||
292 | ||||
293 | for (i = 0; i < CHANNELS2 && remote_ports && remote_ports[i]; i++) { | |||
294 | const gchar *src_port = jack_port_name (data->ports[i]); | |||
295 | ||||
296 | err = jack_connect (data->jack, src_port, remote_ports[i]); | |||
297 | if (err < 0) { | |||
298 | ret = FALSE(0); | |||
299 | break; | |||
300 | } | |||
301 | } | |||
302 | ||||
303 | return ret; | |||
304 | } | |||
305 | ||||
306 | static gboolean | |||
307 | xmms_jack_status (xmms_output_t *output, xmms_playback_status_t status) | |||
308 | { | |||
309 | xmms_jack_data_t *data; | |||
310 | ||||
311 | g_return_val_if_fail (output, FALSE)do{ if (output) { } else { g_return_if_fail_warning (((gchar* ) 0), ((const char*) (__func__)), "output"); return ((0)); }; }while (0); | |||
312 | data = xmms_output_private_data_get (output); | |||
313 | g_return_val_if_fail (data, FALSE)do{ if (data) { } else { g_return_if_fail_warning (((gchar*) 0 ), ((const char*) (__func__)), "data"); return ((0)); }; }while (0); | |||
314 | ||||
315 | if (status == XMMS_PLAYBACK_STATUS_PLAY) { | |||
316 | data->running = TRUE(!(0)); | |||
317 | } else { | |||
318 | data->running = FALSE(0); | |||
319 | } | |||
320 | ||||
321 | return TRUE(!(0)); | |||
322 | } | |||
323 | ||||
324 | ||||
325 | static void | |||
326 | xmms_jack_flush (xmms_output_t *output) | |||
327 | { | |||
328 | /* do nothing... */ | |||
329 | } | |||
330 | ||||
331 | ||||
332 | static int | |||
333 | xmms_jack_process (jack_nframes_t frames, void *arg) | |||
334 | { | |||
335 | xmms_output_t *output = (xmms_output_t*) arg; | |||
336 | xmms_jack_data_t *data; | |||
337 | xmms_samplefloat_t *buf[CHANNELS2]; | |||
338 | xmms_samplefloat_t tbuf[CHANNELS2*4096]; | |||
339 | gint i, j, res, toread, sign; | |||
| ||||
340 | ||||
341 | g_return_val_if_fail (output, -1)do{ if (output) { } else { g_return_if_fail_warning (((gchar* ) 0), ((const char*) (__func__)), "output"); return (-1); }; } while (0); | |||
342 | data = xmms_output_private_data_get (output); | |||
343 | g_return_val_if_fail (data, -1)do{ if (data) { } else { g_return_if_fail_warning (((gchar*) 0 ), ((const char*) (__func__)), "data"); return (-1); }; }while (0); | |||
344 | ||||
345 | for (i = 0; i < CHANNELS2; i++) { | |||
346 | buf[i] = jack_port_get_buffer (data->ports[i], frames); | |||
347 | } | |||
348 | ||||
349 | toread = frames; | |||
350 | ||||
351 | if (data->running) { | |||
352 | while (toread) { | |||
353 | gint t, avail; | |||
354 | ||||
355 | t = MIN (toread * CHANNELS * sizeof (xmms_samplefloat_t),(((toread * 2 * sizeof (xmms_samplefloat_t)) < (sizeof (tbuf ))) ? (toread * 2 * sizeof (xmms_samplefloat_t)) : (sizeof (tbuf ))) | |||
356 | sizeof (tbuf))(((toread * 2 * sizeof (xmms_samplefloat_t)) < (sizeof (tbuf ))) ? (toread * 2 * sizeof (xmms_samplefloat_t)) : (sizeof (tbuf ))); | |||
357 | ||||
358 | avail = xmms_output_bytes_available (output); | |||
359 | ||||
360 | if (avail < t) { | |||
361 | data->underruns++; | |||
362 | XMMS_DBG ("jack output underun number %d! Not enough bytes available. Wanted: %d Available: %d", data->underruns, t, avail)g_debug ("../src/plugins/jack/jack.c" ":" "362" ": " "jack output underun number %d! Not enough bytes available. Wanted: %d Available: %d" , data->underruns, t, avail); | |||
363 | break; | |||
364 | } | |||
365 | ||||
366 | res = xmms_output_read (output, (gchar *)tbuf, t); | |||
367 | ||||
368 | if (res <= 0) { | |||
369 | XMMS_DBG ("Output read returned %d unexpectedly", res)g_debug ("../src/plugins/jack/jack.c" ":" "369" ": " "Output read returned %d unexpectedly" , res); | |||
370 | break; | |||
371 | } | |||
372 | ||||
373 | if (res < t) { | |||
374 | XMMS_DBG ("Less bytes read than expected. (Probably a ringbuffer hotspot)")g_debug ("../src/plugins/jack/jack.c" ":" "374" ": " "Less bytes read than expected. (Probably a ringbuffer hotspot)" ); | |||
375 | } | |||
376 | ||||
377 | res /= CHANNELS2 * sizeof (xmms_samplefloat_t); | |||
378 | ||||
379 | for (j = 0; j < CHANNELS2; j++) { | |||
380 | if (data->new_volume_actual[j] == data->volume_actual[j]) { | |||
381 | for (i = 0; i < res; i++) { | |||
382 | buf[j][i] = (tbuf[i * CHANNELS2 + j] * data->volume_actual[j]); | |||
383 | } | |||
384 | } else { | |||
385 | ||||
386 | /* The way the volume change is set up here, the volume can only change once per callback, but thats | |||
387 | allways plenty of times per second */ | |||
388 | ||||
389 | /* last_sign: 0 = unset, -1 neg, +1 pos */ | |||
390 | ||||
391 | if (data->last_sign[j] == 0) { | |||
392 | if (tbuf[j] > 0.0f) { | |||
393 | data->last_sign[j] = 1; | |||
394 | } else { | |||
395 | /* Zero counts as negative here, but its moot */ | |||
396 | data->last_sign[j] = -1; | |||
397 | } | |||
398 | } | |||
399 | ||||
400 | for (i = 0; i < res; i++) { | |||
401 | ||||
402 | if (data->last_sign[j] != 0) { | |||
403 | if (tbuf[i*CHANNELS2 + j] > 0.0f) { | |||
404 | sign = 1; | |||
405 | } else { | |||
406 | sign = -1; | |||
407 | } | |||
408 | ||||
409 | if ((sign != data->last_sign[j]) || (tbuf[i * CHANNELS2 + j] == 0.0f)) { | |||
410 | ||||
411 | data->volume_actual[j] = data->new_volume_actual[j]; | |||
412 | data->last_sign[j] = 0; | |||
413 | } | |||
414 | } | |||
415 | ||||
416 | buf[j][i] = (tbuf[i * CHANNELS2 + j] * data->volume_actual[j]); | |||
417 | ||||
418 | } | |||
419 | ||||
420 | if (data->last_sign[j] != 0) { | |||
421 | data->last_sign[j] = sign; | |||
| ||||
422 | } | |||
423 | } | |||
424 | } | |||
425 | ||||
426 | toread -= res; | |||
427 | } | |||
428 | } | |||
429 | ||||
430 | if ((!data->running) || ((frames - toread) != frames)) { | |||
431 | /* fill rest of buffer with silence */ | |||
432 | if (data->running) { | |||
433 | XMMS_DBG ("Silence for %d frames", toread)g_debug ("../src/plugins/jack/jack.c" ":" "433" ": " "Silence for %d frames" , toread); | |||
434 | } | |||
435 | for (j = 0; j < CHANNELS2; j++) { | |||
436 | if (data->new_volume_actual[j] != data->volume_actual[j]) { | |||
437 | data->volume_actual[j] = data->new_volume_actual[j]; | |||
438 | } | |||
439 | for (i = frames - toread; i < frames; i++) { | |||
440 | buf[j][i] = 0.0f; | |||
441 | } | |||
442 | } | |||
443 | } | |||
444 | ||||
445 | return 0; | |||
446 | } | |||
447 | ||||
448 | static gboolean | |||
449 | xmms_jack_volume_set (xmms_output_t *output, | |||
450 | const gchar *channel_name, guint volume) | |||
451 | { | |||
452 | xmms_jack_data_t *data; | |||
453 | xmms_config_property_t *cv; | |||
454 | gchar *volume_strp; | |||
455 | gchar volume_str[4]; | |||
456 | gfloat new_volume; /* For atomicness with zero crossing respect */ | |||
457 | ||||
458 | g_return_val_if_fail (output, FALSE)do{ if (output) { } else { g_return_if_fail_warning (((gchar* ) 0), ((const char*) (__func__)), "output"); return ((0)); }; }while (0); | |||
459 | g_return_val_if_fail (channel_name, FALSE)do{ if (channel_name) { } else { g_return_if_fail_warning ((( gchar*) 0), ((const char*) (__func__)), "channel_name"); return ((0)); }; }while (0); | |||
460 | g_return_val_if_fail (volume <= 100, FALSE)do{ if (volume <= 100) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "volume <= 100" ); return ((0)); }; }while (0); | |||
461 | ||||
462 | volume_strp = volume_str; | |||
463 | ||||
464 | data = xmms_output_private_data_get (output); | |||
465 | ||||
466 | g_mutex_lock (&data->volume_change); | |||
467 | ||||
468 | g_return_val_if_fail (data, FALSE)do{ if (data) { } else { g_return_if_fail_warning (((gchar*) 0 ), ((const char*) (__func__)), "data"); return ((0)); }; }while (0); | |||
469 | ||||
470 | if (g_ascii_strcasecmp (channel_name, "Left") == 0) { | |||
471 | data->volume[0] = volume; | |||
472 | new_volume = (gfloat)(volume / 100.0); | |||
473 | new_volume *= new_volume; | |||
474 | data->new_volume_actual[0] = new_volume; | |||
475 | cv = xmms_output_config_lookup (output, "volume.left"); | |||
476 | sprintf (volume_str, "%d", data->volume[0]); | |||
477 | xmms_config_property_set_data (cv, volume_strp); | |||
478 | } else { | |||
479 | /* If its not left, its right */ | |||
480 | data->volume[1] = volume; | |||
481 | new_volume = (gfloat)(volume / 100.0); | |||
482 | new_volume *= new_volume; | |||
483 | data->new_volume_actual[1] = new_volume; | |||
484 | cv = xmms_output_config_lookup (output, "volume.right"); | |||
485 | sprintf (volume_str, "%d", data->volume[1]); | |||
486 | xmms_config_property_set_data (cv, volume_strp); | |||
487 | } | |||
488 | ||||
489 | g_mutex_unlock (&data->volume_change); | |||
490 | ||||
491 | return TRUE(!(0)); | |||
492 | } | |||
493 | ||||
494 | static gboolean | |||
495 | xmms_jack_volume_get (xmms_output_t *output, const gchar **names, | |||
496 | guint *values, guint *num_channels) | |||
497 | { | |||
498 | xmms_jack_data_t *data; | |||
499 | ||||
500 | g_return_val_if_fail (output, FALSE)do{ if (output) { } else { g_return_if_fail_warning (((gchar* ) 0), ((const char*) (__func__)), "output"); return ((0)); }; }while (0); | |||
501 | ||||
502 | data = xmms_output_private_data_get (output); | |||
503 | ||||
504 | g_return_val_if_fail (data, FALSE)do{ if (data) { } else { g_return_if_fail_warning (((gchar*) 0 ), ((const char*) (__func__)), "data"); return ((0)); }; }while (0); | |||
505 | g_return_val_if_fail (num_channels, FALSE)do{ if (num_channels) { } else { g_return_if_fail_warning ((( gchar*) 0), ((const char*) (__func__)), "num_channels"); return ((0)); }; }while (0); | |||
506 | ||||
507 | if (!*num_channels) { | |||
508 | *num_channels = 2; | |||
509 | return TRUE(!(0)); | |||
510 | } | |||
511 | ||||
512 | g_return_val_if_fail (*num_channels == 2, FALSE)do{ if (*num_channels == 2) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "*num_channels == 2" ); return ((0)); }; }while (0); | |||
513 | g_return_val_if_fail (names, FALSE)do{ if (names) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "names"); return ((0)); }; } while (0); | |||
514 | g_return_val_if_fail (values, FALSE)do{ if (values) { } else { g_return_if_fail_warning (((gchar* ) 0), ((const char*) (__func__)), "values"); return ((0)); }; }while (0); | |||
515 | ||||
516 | values[0] = data->volume[0]; | |||
517 | names[0] = "Left"; | |||
518 | ||||
519 | values[1] = data->volume[1]; | |||
520 | names[1] = "Right"; | |||
521 | ||||
522 | return TRUE(!(0)); | |||
523 | } | |||
524 | ||||
525 | ||||
526 | static void | |||
527 | xmms_jack_shutdown (void *arg) | |||
528 | { | |||
529 | xmms_output_t *output = (xmms_output_t*) arg; | |||
530 | xmms_jack_data_t *data; | |||
531 | xmms_error_t err; | |||
532 | ||||
533 | xmms_error_reset (&err); | |||
534 | ||||
535 | data = xmms_output_private_data_get (output); | |||
536 | data->error = TRUE(!(0)); | |||
537 | ||||
538 | xmms_error_set (&err, XMMS_ERROR_GENERIC, "jackd has been shutdown"); | |||
539 | xmms_output_set_error (output, &err); | |||
540 | } | |||
541 | ||||
542 | ||||
543 | static void | |||
544 | xmms_jack_error (const gchar *desc) | |||
545 | { | |||
546 | xmms_log_error ("Jack reported error: %s", desc)g_warning ("../src/plugins/jack/jack.c" ":" "546" ": " "Jack reported error: %s" , desc); | |||
547 | } |