Bug Summary

File:build-analysis/../src/plugins/jack/jack.c
Warning:line 421, column 26
Assigned value is garbage or undefined

Annotated Source Code

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
38typedef 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
58static gboolean xmms_jack_plugin_setup (xmms_output_plugin_t *plugin);
59static gboolean xmms_jack_new (xmms_output_t *output);
60static void xmms_jack_destroy (xmms_output_t *output);
61static gboolean xmms_jack_status (xmms_output_t *output, xmms_playback_status_t status);
62static void xmms_jack_flush (xmms_output_t *output);
63static gboolean xmms_jack_volume_set (xmms_output_t *output, const gchar *channel, guint volume);
64static gboolean xmms_jack_volume_get (xmms_output_t *output, const gchar **names, guint *values, guint *num_channels);
65static int xmms_jack_process (jack_nframes_t frames, void *arg);
66static void xmms_jack_shutdown (void *arg);
67static void xmms_jack_error (const gchar *desc);
68static gboolean xmms_jack_ports_connected (xmms_output_t *output);
69static gboolean xmms_jack_connect_ports (xmms_output_t *output);
70static gboolean xmms_jack_connect (xmms_output_t *output);
71
72/*
73 * Plugin header
74 */
75
76XMMS_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
80static gboolean
81xmms_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
122static gboolean
123xmms_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
169static gboolean
170xmms_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
226static void
227xmms_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
246static gboolean
247xmms_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
265static gboolean
266xmms_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
306static gboolean
307xmms_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
325static void
326xmms_jack_flush (xmms_output_t *output)
327{
328 /* do nothing... */
329}
330
331
332static int
333xmms_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;
1
'sign' declared without an initial value
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++) {
2
Loop condition is true. Entering loop body
3
Loop condition is true. Entering loop body
4
Loop condition is false. Execution continues on line 349
346 buf[i] = jack_port_get_buffer (data->ports[i], frames);
347 }
348
349 toread = frames;
350
351 if (data->running) {
5
Assuming the condition is true
6
Taking true branch
352 while (toread) {
7
Loop condition is true. Entering loop body
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) {
8
Assuming 'avail' is >= 't'
9
Taking false branch
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) {
10
Assuming 'res' is > 0
11
Taking false branch
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) {
12
Assuming 'res' is >= 't'
13
Taking false branch
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++) {
14
Loop condition is true. Entering loop body
380 if (data->new_volume_actual[j] == data->volume_actual[j]) {
15
Taking false branch
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) {
16
Assuming the condition is false
17
Taking false branch
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++) {
18
Assuming 'i' is >= 'res'
19
Loop condition is false. Execution continues on line 420
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) {
20
Taking true branch
421 data->last_sign[j] = sign;
21
Assigned value is garbage or undefined
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
448static gboolean
449xmms_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
494static gboolean
495xmms_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
526static void
527xmms_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
543static void
544xmms_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}