Don't try to spawn a JACK server by default
[openal-soft.git] / Alc / backends / jack.c
blobea99a953af1f2b0165eac634ddd3f1297482df45
1 /**
2 * OpenAL cross platform audio library
3 * Copyright (C) 1999-2007 by authors.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
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 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
21 #include "config.h"
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <memory.h>
27 #include "alMain.h"
28 #include "alu.h"
29 #include "threads.h"
30 #include "compat.h"
32 #include "backends/base.h"
34 #include <jack/jack.h>
35 #include <jack/ringbuffer.h>
38 static const ALCchar jackDevice[] = "JACK Default";
41 #ifdef HAVE_DYNLOAD
42 #define JACK_FUNCS(MAGIC) \
43 MAGIC(jack_client_open); \
44 MAGIC(jack_client_close); \
45 MAGIC(jack_client_name_size); \
46 MAGIC(jack_get_client_name); \
47 MAGIC(jack_connect); \
48 MAGIC(jack_activate); \
49 MAGIC(jack_deactivate); \
50 MAGIC(jack_port_register); \
51 MAGIC(jack_port_unregister); \
52 MAGIC(jack_port_get_buffer); \
53 MAGIC(jack_port_name); \
54 MAGIC(jack_get_ports); \
55 MAGIC(jack_free); \
56 MAGIC(jack_get_sample_rate); \
57 MAGIC(jack_set_process_callback); \
58 MAGIC(jack_set_buffer_size_callback); \
59 MAGIC(jack_set_buffer_size); \
60 MAGIC(jack_get_buffer_size);
62 static void *jack_handle;
63 #define MAKE_FUNC(f) static __typeof(f) * p##f
64 JACK_FUNCS(MAKE_FUNC);
65 #undef MAKE_FUNC
67 #define jack_client_open pjack_client_open
68 #define jack_client_close pjack_client_close
69 #define jack_client_name_size pjack_client_name_size
70 #define jack_get_client_name pjack_get_client_name
71 #define jack_connect pjack_connect
72 #define jack_activate pjack_activate
73 #define jack_deactivate pjack_deactivate
74 #define jack_port_register pjack_port_register
75 #define jack_port_unregister pjack_port_unregister
76 #define jack_port_get_buffer pjack_port_get_buffer
77 #define jack_port_name pjack_port_name
78 #define jack_get_ports pjack_get_ports
79 #define jack_free pjack_free
80 #define jack_get_sample_rate pjack_get_sample_rate
81 #define jack_set_process_callback pjack_set_process_callback
82 #define jack_set_buffer_size_callback pjack_set_buffer_size_callback
83 #define jack_set_buffer_size pjack_set_buffer_size
84 #define jack_get_buffer_size pjack_get_buffer_size
85 #endif
88 static jack_options_t ClientOptions = JackNullOption;
90 static ALCboolean jack_load(void)
92 ALCboolean error = ALC_FALSE;
94 #ifdef HAVE_DYNLOAD
95 if(!jack_handle)
97 jack_handle = LoadLib("libjack.so.0");
98 if(!jack_handle)
99 return ALC_FALSE;
101 error = ALC_FALSE;
102 #define LOAD_FUNC(f) do { \
103 p##f = GetSymbol(jack_handle, #f); \
104 if(p##f == NULL) { \
105 error = ALC_TRUE; \
107 } while(0)
108 JACK_FUNCS(LOAD_FUNC);
109 #undef LOAD_FUNC
111 if(error)
113 CloseLib(jack_handle);
114 jack_handle = NULL;
115 return ALC_FALSE;
118 #endif
120 return !error;
124 typedef struct ALCjackPlayback {
125 DERIVE_FROM_TYPE(ALCbackend);
127 jack_client_t *Client;
128 jack_port_t *Port[MAX_OUTPUT_CHANNELS];
130 ll_ringbuffer_t *Ring;
131 alcnd_t Cond;
133 volatile int killNow;
134 althrd_t thread;
135 } ALCjackPlayback;
137 static int ALCjackPlayback_bufferSizeNotify(jack_nframes_t numframes, void *arg);
139 static int ALCjackPlayback_process(jack_nframes_t numframes, void *arg);
140 static int ALCjackPlayback_mixerProc(void *arg);
142 static void ALCjackPlayback_Construct(ALCjackPlayback *self, ALCdevice *device);
143 static void ALCjackPlayback_Destruct(ALCjackPlayback *self);
144 static ALCenum ALCjackPlayback_open(ALCjackPlayback *self, const ALCchar *name);
145 static void ALCjackPlayback_close(ALCjackPlayback *self);
146 static ALCboolean ALCjackPlayback_reset(ALCjackPlayback *self);
147 static ALCboolean ALCjackPlayback_start(ALCjackPlayback *self);
148 static void ALCjackPlayback_stop(ALCjackPlayback *self);
149 static DECLARE_FORWARD2(ALCjackPlayback, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
150 static DECLARE_FORWARD(ALCjackPlayback, ALCbackend, ALCuint, availableSamples)
151 static ALint64 ALCjackPlayback_getLatency(ALCjackPlayback *self);
152 static void ALCjackPlayback_lock(ALCjackPlayback *self);
153 static void ALCjackPlayback_unlock(ALCjackPlayback *self);
154 DECLARE_DEFAULT_ALLOCATORS(ALCjackPlayback)
156 DEFINE_ALCBACKEND_VTABLE(ALCjackPlayback);
159 static void ALCjackPlayback_Construct(ALCjackPlayback *self, ALCdevice *device)
161 ALuint i;
163 ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device);
164 SET_VTABLE2(ALCjackPlayback, ALCbackend, self);
166 alcnd_init(&self->Cond);
168 self->Client = NULL;
169 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
170 self->Port[i] = NULL;
171 self->Ring = NULL;
173 self->killNow = 1;
176 static void ALCjackPlayback_Destruct(ALCjackPlayback *self)
178 ALuint i;
180 if(self->Client)
182 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
184 if(self->Port[i])
185 jack_port_unregister(self->Client, self->Port[i]);
186 self->Port[i] = NULL;
188 jack_client_close(self->Client);
189 self->Client = NULL;
192 alcnd_destroy(&self->Cond);
194 ALCbackend_Destruct(STATIC_CAST(ALCbackend, self));
198 static int ALCjackPlayback_bufferSizeNotify(jack_nframes_t numframes, void *arg)
200 ALCjackPlayback *self = arg;
201 ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice;
202 ALuint bufsize;
204 ALCjackPlayback_lock(self);
205 device->UpdateSize = numframes;
206 device->NumUpdates = 2;
207 TRACE("%u update size x%u\n", device->UpdateSize, device->NumUpdates);
209 bufsize = device->UpdateSize;
210 if(ConfigValueUInt("jack", "buffer-size", &bufsize))
211 bufsize = maxu(NextPowerOf2(bufsize), device->UpdateSize);
212 bufsize += device->UpdateSize;
214 ll_ringbuffer_free(self->Ring);
215 self->Ring = ll_ringbuffer_create(bufsize, FrameSizeFromDevFmt(device->FmtChans, device->FmtType));
216 if(!self->Ring)
218 ERR("Failed to reallocate ringbuffer\n");
219 aluHandleDisconnect(device);
221 ALCjackPlayback_unlock(self);
222 return 0;
226 static int ALCjackPlayback_process(jack_nframes_t numframes, void *arg)
228 ALCjackPlayback *self = arg;
229 jack_default_audio_sample_t *out[MAX_OUTPUT_CHANNELS];
230 ll_ringbuffer_data_t data[2];
231 jack_nframes_t total = 0;
232 jack_nframes_t todo;
233 ALuint i, c, numchans;
235 ll_ringbuffer_get_read_vector(self->Ring, data);
237 for(c = 0;c < MAX_OUTPUT_CHANNELS && self->Port[c];c++)
238 out[c] = jack_port_get_buffer(self->Port[c], numframes);
239 numchans = c;
241 todo = minu(numframes, data[0].len);
242 for(c = 0;c < numchans;c++)
244 for(i = 0;i < todo;i++)
245 out[c][i] = ((ALfloat*)data[0].buf)[i*numchans + c];
246 out[c] += todo;
248 total += todo;
250 todo = minu(numframes-total, data[1].len);
251 if(todo > 0)
253 for(c = 0;c < numchans;c++)
255 for(i = 0;i < todo;i++)
256 out[c][i] = ((ALfloat*)data[1].buf)[i*numchans + c];
257 out[c] += todo;
259 total += todo;
262 ll_ringbuffer_read_advance(self->Ring, total);
263 alcnd_signal(&self->Cond);
265 if(numframes > total)
267 todo = numframes-total;
268 for(c = 0;c < numchans;c++)
270 for(i = 0;i < todo;i++)
271 out[c][i] = 0.0f;
275 return 0;
278 static int ALCjackPlayback_mixerProc(void *arg)
280 ALCjackPlayback *self = arg;
281 ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice;
282 ll_ringbuffer_data_t data[2];
284 SetRTPriority();
285 althrd_setname(althrd_current(), MIXER_THREAD_NAME);
287 ALCjackPlayback_lock(self);
288 while(!self->killNow && device->Connected)
290 ALuint todo, len1, len2;
292 if(ll_ringbuffer_write_space(self->Ring) < device->UpdateSize)
294 alcnd_wait(&self->Cond, &STATIC_CAST(ALCbackend,self)->mMutex);
295 continue;
298 ll_ringbuffer_get_write_vector(self->Ring, data);
299 todo = data[0].len + data[1].len;
300 todo -= todo%device->UpdateSize;
302 len1 = minu(data[0].len, todo);
303 len2 = minu(data[1].len, todo-len1);
305 aluMixData(device, data[0].buf, len1);
306 if(len2 > 0)
307 aluMixData(device, data[1].buf, len2);
308 ll_ringbuffer_write_advance(self->Ring, todo);
310 ALCjackPlayback_unlock(self);
312 return 0;
316 static ALCenum ALCjackPlayback_open(ALCjackPlayback *self, const ALCchar *name)
318 ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
319 const char *client_name = "alsoft";
320 jack_status_t status;
322 if(!name)
323 name = jackDevice;
324 else if(strcmp(name, jackDevice) != 0)
325 return ALC_INVALID_VALUE;
327 self->Client = jack_client_open(client_name, ClientOptions, &status, NULL);
328 if(self->Client == NULL)
330 ERR("jack_client_open() failed, status = 0x%02x\n", status);
331 return ALC_INVALID_VALUE;
333 if((status&JackServerStarted))
334 TRACE("JACK server started\n");
335 if((status&JackNameNotUnique))
337 client_name = jack_get_client_name(self->Client);
338 TRACE("Client name not unique, got `%s' instead\n", client_name);
341 jack_set_process_callback(self->Client, ALCjackPlayback_process, self);
342 jack_set_buffer_size_callback(self->Client, ALCjackPlayback_bufferSizeNotify, self);
344 al_string_copy_cstr(&device->DeviceName, name);
346 return ALC_NO_ERROR;
349 static void ALCjackPlayback_close(ALCjackPlayback *self)
351 ALuint i;
353 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
355 if(self->Port[i])
356 jack_port_unregister(self->Client, self->Port[i]);
357 self->Port[i] = NULL;
359 jack_client_close(self->Client);
360 self->Client = NULL;
363 static ALCboolean ALCjackPlayback_reset(ALCjackPlayback *self)
365 ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
366 ALuint numchans, i;
367 ALuint bufsize;
369 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
371 if(self->Port[i])
372 jack_port_unregister(self->Client, self->Port[i]);
373 self->Port[i] = NULL;
376 /* Ignore the requested buffer metrics and just keep one JACK-sized buffer
377 * ready for when requested. Note that one period's worth of audio in the
378 * ring buffer will always be left unfilled because one element of the ring
379 * buffer will not be writeable, and we only write in period-sized chunks.
381 device->Frequency = jack_get_sample_rate(self->Client);
382 device->UpdateSize = jack_get_buffer_size(self->Client);
383 device->NumUpdates = 2;
385 bufsize = device->UpdateSize;
386 if(ConfigValueUInt("jack", "buffer-size", &bufsize))
387 bufsize = maxu(NextPowerOf2(bufsize), device->UpdateSize);
388 bufsize += device->UpdateSize;
390 /* Force 32-bit float output. */
391 device->FmtType = DevFmtFloat;
393 numchans = ChannelsFromDevFmt(device->FmtChans);
394 for(i = 0;i < numchans;i++)
396 char name[64];
397 snprintf(name, sizeof(name), "channel_%d", i+1);
398 self->Port[i] = jack_port_register(self->Client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
399 if(self->Port[i] == NULL)
401 ERR("Not enough JACK ports available for %s output\n", DevFmtChannelsString(device->FmtChans));
402 if(i == 0) return ALC_FALSE;
403 break;
406 if(i < numchans)
408 if(i == 1)
409 device->FmtChans = DevFmtMono;
410 else
412 for(--i;i >= 2;i--)
414 jack_port_unregister(self->Client, self->Port[i]);
415 self->Port[i] = NULL;
417 device->FmtChans = DevFmtStereo;
421 ll_ringbuffer_free(self->Ring);
422 self->Ring = ll_ringbuffer_create(bufsize, FrameSizeFromDevFmt(device->FmtChans, device->FmtType));
423 if(!self->Ring)
425 ERR("Failed to allocate ringbuffer\n");
426 return ALC_FALSE;
429 SetDefaultChannelOrder(device);
431 return ALC_TRUE;
434 static ALCboolean ALCjackPlayback_start(ALCjackPlayback *self)
436 const char **ports;
437 ALuint i;
439 if(jack_activate(self->Client))
441 ERR("Failed to activate client\n");
442 return ALC_FALSE;
445 ports = jack_get_ports(self->Client, NULL, NULL, JackPortIsPhysical|JackPortIsInput);
446 if(ports == NULL)
448 ERR("No physical playback ports found\n");
449 jack_deactivate(self->Client);
450 return ALC_FALSE;
452 for(i = 0;i < MAX_OUTPUT_CHANNELS && self->Port[i];i++)
454 if(!ports[i])
456 ERR("No physical playback port for \"%s\"\n", jack_port_name(self->Port[i]));
457 break;
459 if(jack_connect(self->Client, jack_port_name(self->Port[i]), ports[i]))
460 ERR("Failed to connect output port \"%s\" to \"%s\"\n", jack_port_name(self->Port[i]), ports[i]);
462 jack_free(ports);
464 self->killNow = 0;
465 if(althrd_create(&self->thread, ALCjackPlayback_mixerProc, self) != althrd_success)
467 jack_deactivate(self->Client);
468 return ALC_FALSE;
471 return ALC_TRUE;
474 static void ALCjackPlayback_stop(ALCjackPlayback *self)
476 int res;
478 if(self->killNow)
479 return;
481 self->killNow = 1;
482 ALCjackPlayback_lock(self);
483 alcnd_signal(&self->Cond);
484 ALCjackPlayback_unlock(self);
485 althrd_join(self->thread, &res);
487 jack_deactivate(self->Client);
491 static ALint64 ALCjackPlayback_getLatency(ALCjackPlayback *self)
493 ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
494 ALint64 latency;
496 ALCjackPlayback_lock(self);
497 latency = ll_ringbuffer_read_space(self->Ring);
498 ALCjackPlayback_unlock(self);
500 return latency * 1000000000 / device->Frequency;
504 static void ALCjackPlayback_lock(ALCjackPlayback *self)
506 almtx_lock(&STATIC_CAST(ALCbackend,self)->mMutex);
509 static void ALCjackPlayback_unlock(ALCjackPlayback *self)
511 almtx_unlock(&STATIC_CAST(ALCbackend,self)->mMutex);
515 typedef struct ALCjackBackendFactory {
516 DERIVE_FROM_TYPE(ALCbackendFactory);
517 } ALCjackBackendFactory;
518 #define ALCJACKBACKENDFACTORY_INITIALIZER { { GET_VTABLE2(ALCjackBackendFactory, ALCbackendFactory) } }
520 static ALCboolean ALCjackBackendFactory_init(ALCjackBackendFactory* UNUSED(self))
522 jack_client_t *client;
523 jack_status_t status;
525 if(!jack_load())
526 return ALC_FALSE;
528 if(!GetConfigValueBool("jack", "spawn-server", 0))
529 ClientOptions |= JackNoStartServer;
530 client = jack_client_open("alsoft", ClientOptions, &status, NULL);
531 if(client == NULL)
533 WARN("jack_client_open() failed, 0x%02x\n", status);
534 if((status&JackServerFailed) && !(ClientOptions&JackNoStartServer))
535 ERR("Unable to connect to JACK server\n");
536 return ALC_FALSE;
539 jack_client_close(client);
540 return ALC_TRUE;
543 static void ALCjackBackendFactory_deinit(ALCjackBackendFactory* UNUSED(self))
545 #ifdef HAVE_DYNLOAD
546 if(jack_handle)
547 CloseLib(jack_handle);
548 jack_handle = NULL;
549 #endif
552 static ALCboolean ALCjackBackendFactory_querySupport(ALCjackBackendFactory* UNUSED(self), ALCbackend_Type type)
554 if(type == ALCbackend_Playback)
555 return ALC_TRUE;
556 return ALC_FALSE;
559 static void ALCjackBackendFactory_probe(ALCjackBackendFactory* UNUSED(self), enum DevProbe type)
561 switch(type)
563 case ALL_DEVICE_PROBE:
564 AppendAllDevicesList(jackDevice);
565 break;
567 case CAPTURE_DEVICE_PROBE:
568 break;
572 static ALCbackend* ALCjackBackendFactory_createBackend(ALCjackBackendFactory* UNUSED(self), ALCdevice *device, ALCbackend_Type type)
574 if(type == ALCbackend_Playback)
576 ALCjackPlayback *backend;
578 backend = ALCjackPlayback_New(sizeof(*backend));
579 if(!backend) return NULL;
580 memset(backend, 0, sizeof(*backend));
582 ALCjackPlayback_Construct(backend, device);
584 return STATIC_CAST(ALCbackend, backend);
587 return NULL;
590 DEFINE_ALCBACKENDFACTORY_VTABLE(ALCjackBackendFactory);
593 ALCbackendFactory *ALCjackBackendFactory_getFactory(void)
595 static ALCjackBackendFactory factory = ALCJACKBACKENDFACTORY_INITIALIZER;
596 return STATIC_CAST(ALCbackendFactory, &factory);