22 #include "../../SDL_internal.h"
24 #if SDL_AUDIO_DRIVER_JACK
29 #include "../SDL_audio_c.h"
32 #include "../../thread/SDL_systhread.h"
35 static jack_client_t * (*JACK_jack_client_open) (
const char *, jack_options_t, jack_status_t *, ...);
36 static int (*JACK_jack_client_close) (jack_client_t *);
37 static void (*JACK_jack_on_shutdown) (jack_client_t *, JackShutdownCallback,
void *);
38 static int (*JACK_jack_activate) (jack_client_t *);
39 static int (*JACK_jack_deactivate) (jack_client_t *);
40 static void * (*JACK_jack_port_get_buffer) (jack_port_t *, jack_nframes_t);
41 static int (*JACK_jack_port_unregister) (jack_client_t *, jack_port_t *);
42 static void (*JACK_jack_free) (
void *);
43 static const char ** (*JACK_jack_get_ports) (jack_client_t *,
const char *,
const char *,
unsigned long);
44 static jack_nframes_t (*JACK_jack_get_sample_rate) (jack_client_t *);
45 static jack_nframes_t (*JACK_jack_get_buffer_size) (jack_client_t *);
46 static jack_port_t * (*JACK_jack_port_register) (jack_client_t *,
const char *,
const char *,
unsigned long,
unsigned long);
47 static jack_port_t * (*JACK_jack_port_by_name) (jack_client_t *,
const char *);
48 static const char * (*JACK_jack_port_name) (
const jack_port_t *);
49 static const char * (*JACK_jack_port_type) (
const jack_port_t *);
50 static int (*JACK_jack_connect) (jack_client_t *,
const char *,
const char *);
51 static int (*JACK_jack_set_process_callback) (jack_client_t *, JackProcessCallback,
void *);
53 static int load_jack_syms(
void);
56 #ifdef SDL_AUDIO_DRIVER_JACK_DYNAMIC
59 static void *jack_handle =
NULL;
63 load_jack_sym(
const char *fn,
void **
addr)
75 #define SDL_JACK_SYM(x) \
76 if (!load_jack_sym(#x, (void **) (char *) &JACK_##x)) return -1
79 UnloadJackLibrary(
void)
81 if (jack_handle !=
NULL) {
91 if (jack_handle ==
NULL) {
93 if (jack_handle ==
NULL) {
108 #define SDL_JACK_SYM(x) JACK_##x = x
111 UnloadJackLibrary(
void)
116 LoadJackLibrary(
void)
128 SDL_JACK_SYM(jack_client_open);
129 SDL_JACK_SYM(jack_client_close);
130 SDL_JACK_SYM(jack_on_shutdown);
131 SDL_JACK_SYM(jack_activate);
132 SDL_JACK_SYM(jack_deactivate);
133 SDL_JACK_SYM(jack_port_get_buffer);
134 SDL_JACK_SYM(jack_port_unregister);
135 SDL_JACK_SYM(jack_free);
136 SDL_JACK_SYM(jack_get_ports);
137 SDL_JACK_SYM(jack_get_sample_rate);
138 SDL_JACK_SYM(jack_get_buffer_size);
139 SDL_JACK_SYM(jack_port_register);
140 SDL_JACK_SYM(jack_port_by_name);
141 SDL_JACK_SYM(jack_port_name);
142 SDL_JACK_SYM(jack_port_type);
143 SDL_JACK_SYM(jack_connect);
144 SDL_JACK_SYM(jack_set_process_callback);
150 jackShutdownCallback(
void *arg)
162 jackProcessPlaybackCallback(jack_nframes_t nframes,
void *arg)
165 jack_port_t **
ports = this->hidden->sdlports;
172 SDL_memset(this->hidden->iobuffer,
'\0', this->spec.size);
175 for (channelsi = 0; channelsi < total_channels; channelsi++) {
176 float *
dst = (
float *) JACK_jack_port_get_buffer(
ports[channelsi], nframes);
178 const float *
src = ((
float *) this->hidden->iobuffer) + channelsi;
180 for (framesi = 0; framesi < total_frames; framesi++) {
182 src += total_channels;
194 JACK_WaitDevice(
_THIS)
204 JACK_GetDeviceBuf(
_THIS)
206 return (
Uint8 *) this->hidden->iobuffer;
211 jackProcessCaptureCallback(jack_nframes_t nframes,
void *arg)
215 jack_port_t **
ports = this->hidden->sdlports;
220 for (channelsi = 0; channelsi < total_channels; channelsi++) {
221 const float *
src = (
const float *) JACK_jack_port_get_buffer(
ports[channelsi], nframes);
223 float *
dst = ((
float *) this->hidden->iobuffer) + channelsi;
225 for (framesi = 0; framesi < total_frames; framesi++) {
227 dst += total_channels;
238 JACK_CaptureFromDevice(
_THIS,
void *
buffer,
int buflen)
252 JACK_FlushCapture(
_THIS)
259 JACK_CloseDevice(
_THIS)
261 if (this->hidden->client) {
262 JACK_jack_deactivate(this->hidden->client);
264 if (this->hidden->sdlports) {
267 for (i = 0;
i < channels;
i++) {
268 JACK_jack_port_unregister(this->hidden->client, this->hidden->sdlports[
i]);
273 JACK_jack_client_close(this->hidden->client);
276 if (this->hidden->iosem) {
284 JACK_OpenDevice(
_THIS,
void *
handle,
const char *devname,
int iscapture)
290 const unsigned long sysportflags = iscapture ? JackPortIsOutput : JackPortIsInput;
291 const unsigned long sdlportflags = iscapture ? JackPortIsInput : JackPortIsOutput;
292 const JackProcessCallback
callback = iscapture ? jackProcessCaptureCallback : jackProcessPlaybackCallback;
293 const char *sdlportstr = iscapture ?
"input" :
"output";
294 const char **devports =
NULL;
296 jack_client_t *client =
NULL;
297 jack_status_t status;
304 if (this->hidden ==
NULL) {
309 client = JACK_jack_client_open(
"SDL", JackNoStartServer, &status,
NULL);
310 this->hidden->client =
client;
315 devports = JACK_jack_get_ports(
client,
NULL,
NULL, JackPortIsPhysical | sysportflags);
316 if (!devports || !devports[0]) {
317 return SDL_SetError(
"No physical JACK ports available");
320 while (devports[++
ports]) {
327 const jack_port_t *dport = JACK_jack_port_by_name(
client, devports[
i]);
328 const char *
type = JACK_jack_port_type(dport);
332 audio_ports[channels++] =
i;
336 return SDL_SetError(
"No physical JACK ports available");
351 if (!this->hidden->iosem) {
356 if (!this->hidden->iobuffer) {
361 this->hidden->sdlports = (jack_port_t **)
SDL_calloc(channels,
sizeof (jack_port_t *));
362 if (this->hidden->sdlports ==
NULL) {
366 for (
i = 0;
i < channels;
i++) {
368 SDL_snprintf(portname,
sizeof (portname),
"sdl_jack_%s_%d", sdlportstr,
i);
369 this->hidden->sdlports[
i] = JACK_jack_port_register(
client, portname, JACK_DEFAULT_AUDIO_TYPE, sdlportflags, 0);
370 if (this->hidden->sdlports[
i] ==
NULL) {
375 if (JACK_jack_set_process_callback(
client,
callback,
this) != 0) {
376 return SDL_SetError(
"JACK: Couldn't set process callback");
379 JACK_jack_on_shutdown(
client, jackShutdownCallback,
this);
381 if (JACK_jack_activate(
client) != 0) {
386 for (
i = 0;
i < channels;
i++) {
387 const char *sdlport = JACK_jack_port_name(this->hidden->sdlports[
i]);
388 const char *srcport =
iscapture ? devports[audio_ports[
i]] : sdlport;
389 const char *dstport =
iscapture ? sdlport : devports[audio_ports[
i]];
390 if (JACK_jack_connect(
client, srcport, dstport) != 0) {
391 return SDL_SetError(
"Couldn't connect JACK ports: %s => %s", srcport, dstport);
396 JACK_jack_free(devports);
404 JACK_Deinitialize(
void)
412 if (LoadJackLibrary() < 0) {
416 jack_status_t status;
417 jack_client_t *
client = JACK_jack_client_open(
"SDL", JackNoStartServer, &status,
NULL);
422 JACK_jack_client_close(
client);
441 "jack",
"JACK Audio Connection Kit", JACK_Init, 0