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 const char * (*JACK_jack_port_name) (
const jack_port_t *);
48 static int (*JACK_jack_connect) (jack_client_t *,
const char *,
const char *);
49 static int (*JACK_jack_set_process_callback) (jack_client_t *, JackProcessCallback,
void *);
51 static int load_jack_syms(
void);
54 #ifdef SDL_AUDIO_DRIVER_JACK_DYNAMIC 56 static const char *jack_library = SDL_AUDIO_DRIVER_JACK_DYNAMIC;
57 static void *jack_handle =
NULL;
61 load_jack_sym(
const char *fn,
void **
addr)
73 #define SDL_JACK_SYM(x) \ 74 if (!load_jack_sym(#x, (void **) (char *) &JACK_##x)) return -1 77 UnloadJackLibrary(
void)
79 if (jack_handle !=
NULL) {
89 if (jack_handle ==
NULL) {
91 if (jack_handle ==
NULL) {
95 retval = load_jack_syms();
106 #define SDL_JACK_SYM(x) JACK_##x = x 109 UnloadJackLibrary(
void)
114 LoadJackLibrary(
void)
126 SDL_JACK_SYM(jack_client_open);
127 SDL_JACK_SYM(jack_client_close);
128 SDL_JACK_SYM(jack_on_shutdown);
129 SDL_JACK_SYM(jack_activate);
130 SDL_JACK_SYM(jack_deactivate);
131 SDL_JACK_SYM(jack_port_get_buffer);
132 SDL_JACK_SYM(jack_port_unregister);
133 SDL_JACK_SYM(jack_free);
134 SDL_JACK_SYM(jack_get_ports);
135 SDL_JACK_SYM(jack_get_sample_rate);
136 SDL_JACK_SYM(jack_get_buffer_size);
137 SDL_JACK_SYM(jack_port_register);
138 SDL_JACK_SYM(jack_port_name);
139 SDL_JACK_SYM(jack_connect);
140 SDL_JACK_SYM(jack_set_process_callback);
146 jackShutdownCallback(
void *arg)
158 jackProcessPlaybackCallback(jack_nframes_t nframes,
void *arg)
161 jack_port_t **
ports = this->hidden->sdlports;
168 SDL_memset(this->hidden->iobuffer,
'\0', this->spec.size);
171 for (channelsi = 0; channelsi < total_channels; channelsi++) {
172 float *
dst = (
float *) JACK_jack_port_get_buffer(ports[channelsi], nframes);
174 const float *
src = ((
float *) this->hidden->iobuffer) + channelsi;
176 for (framesi = 0; framesi < total_frames; framesi++) {
178 src += total_channels;
190 JACK_WaitDevice(
_THIS)
200 JACK_GetDeviceBuf(
_THIS)
202 return (
Uint8 *) this->hidden->iobuffer;
207 jackProcessCaptureCallback(jack_nframes_t nframes,
void *arg)
211 jack_port_t **ports = this->hidden->sdlports;
216 for (channelsi = 0; channelsi < total_channels; channelsi++) {
217 const float *
src = (
const float *) JACK_jack_port_get_buffer(ports[channelsi], nframes);
219 float *dst = ((
float *) this->hidden->iobuffer) + channelsi;
221 for (framesi = 0; framesi < total_frames; framesi++) {
223 dst += total_channels;
234 JACK_CaptureFromDevice(
_THIS,
void *
buffer,
int buflen)
243 SDL_memcpy(buffer, this->hidden->iobuffer, buflen);
248 JACK_FlushCapture(
_THIS)
255 JACK_CloseDevice(
_THIS)
257 if (this->hidden->client) {
258 JACK_jack_deactivate(this->hidden->client);
260 if (this->hidden->sdlports) {
263 for (i = 0; i < channels; i++) {
264 JACK_jack_port_unregister(this->hidden->client, this->hidden->sdlports[i]);
269 JACK_jack_client_close(this->hidden->client);
272 if (this->hidden->iosem) {
276 if (this->hidden->devports) {
277 JACK_jack_free(this->hidden->devports);
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;
295 jack_client_t *client =
NULL;
296 jack_status_t status;
302 if (this->hidden ==
NULL) {
307 client = JACK_jack_client_open(
"SDL", JackNoStartServer, &status,
NULL);
308 this->hidden->client =
client;
309 if (client ==
NULL) {
313 devports = JACK_jack_get_ports(client,
NULL,
NULL, JackPortIsPhysical | sysportflags);
315 if (!devports || !devports[0]) {
316 return SDL_SetError(
"No physical JACK ports available");
319 while (devports[++channels]) {
327 this->
spec.
freq = JACK_jack_get_sample_rate(client);
329 this->
spec.
samples = JACK_jack_get_buffer_size(client);
334 if (!this->hidden->iosem) {
339 if (!this->hidden->iobuffer) {
344 this->hidden->sdlports = (jack_port_t **)
SDL_calloc(channels,
sizeof (jack_port_t *));
345 if (this->hidden->sdlports ==
NULL) {
349 for (i = 0; i < channels; i++) {
351 SDL_snprintf(portname,
sizeof (portname),
"sdl_jack_%s_%d", sdlportstr, i);
352 this->hidden->sdlports[
i] = JACK_jack_port_register(client, portname, JACK_DEFAULT_AUDIO_TYPE, sdlportflags, 0);
353 if (this->hidden->sdlports[i] ==
NULL) {
358 if (JACK_jack_set_process_callback(client, callback,
this) != 0) {
359 return SDL_SetError(
"JACK: Couldn't set process callback");
362 JACK_jack_on_shutdown(client, jackShutdownCallback,
this);
364 if (JACK_jack_activate(client) != 0) {
369 for (i = 0; i < channels; i++) {
370 const char *sdlport = JACK_jack_port_name(this->hidden->sdlports[i]);
371 const char *srcport = iscapture ? devports[
i] : sdlport;
372 const char *dstport = iscapture ? sdlport : devports[
i];
373 if (JACK_jack_connect(client, srcport, dstport) != 0) {
374 return SDL_SetError(
"Couldn't connect JACK ports: %s => %s", srcport, dstport);
379 this->hidden->devports =
NULL;
380 JACK_jack_free(devports);
387 JACK_Deinitialize(
void)
395 if (LoadJackLibrary() < 0) {
399 jack_status_t status;
400 jack_client_t *client = JACK_jack_client_open(
"SDL", JackNoStartServer, &status,
NULL);
401 if (client ==
NULL) {
405 JACK_jack_client_close(client);
424 "jack",
"JACK Audio Connection Kit", JACK_Init, 0
#define SDL_CreateSemaphore
void(* WaitDevice)(_THIS)
void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device)
const EGLAttrib EGLOutputPortEXT * ports
int OnlyHasDefaultCaptureDevice
int OnlyHasDefaultOutputDevice
EGLImageKHR EGLint EGLint * handle
void(* Deinitialize)(void)
static Uint32 callback(Uint32 interval, void *param)
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
GLenum GLenum GLsizei const GLuint GLboolean enabled
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
#define SDL_assert(condition)
int(* OpenDevice)(_THIS, void *handle, const char *devname, int iscapture)
#define SDL_OutOfMemory()
int(* CaptureFromDevice)(_THIS, void *buffer, int buflen)
void(* CloseDevice)(_THIS)
void(* FlushCapture)(_THIS)
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 void
#define SDL_DestroySemaphore
AudioBootStrap JACK_bootstrap
Uint8 *(* GetDeviceBuf)(_THIS)
void * SDL_LoadFunction(void *handle, const char *name)