21 #include "../../SDL_internal.h"
23 #if SDL_AUDIO_DRIVER_JACK
27 #include "../SDL_audio_c.h"
30 #include "../../thread/SDL_systhread.h"
33 static jack_client_t * (*JACK_jack_client_open) (
const char *, jack_options_t, jack_status_t *, ...);
34 static int (*JACK_jack_client_close) (jack_client_t *);
35 static void (*JACK_jack_on_shutdown) (jack_client_t *, JackShutdownCallback,
void *);
36 static int (*JACK_jack_activate) (jack_client_t *);
37 static int (*JACK_jack_deactivate) (jack_client_t *);
38 static void * (*JACK_jack_port_get_buffer) (jack_port_t *, jack_nframes_t);
39 static int (*JACK_jack_port_unregister) (jack_client_t *, jack_port_t *);
40 static void (*JACK_jack_free) (
void *);
41 static const char ** (*JACK_jack_get_ports) (jack_client_t *,
const char *,
const char *,
unsigned long);
42 static jack_nframes_t (*JACK_jack_get_sample_rate) (jack_client_t *);
43 static jack_nframes_t (*JACK_jack_get_buffer_size) (jack_client_t *);
44 static jack_port_t * (*JACK_jack_port_register) (jack_client_t *,
const char *,
const char *,
unsigned long,
unsigned long);
45 static jack_port_t * (*JACK_jack_port_by_name) (jack_client_t *,
const char *);
46 static const char * (*JACK_jack_port_name) (
const jack_port_t *);
47 static const char * (*JACK_jack_port_type) (
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) {
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_by_name);
139 SDL_JACK_SYM(jack_port_name);
140 SDL_JACK_SYM(jack_port_type);
141 SDL_JACK_SYM(jack_connect);
142 SDL_JACK_SYM(jack_set_process_callback);
148 jackShutdownCallback(
void *arg)
160 jackProcessPlaybackCallback(jack_nframes_t nframes,
void *arg)
163 jack_port_t **
ports = this->hidden->sdlports;
170 SDL_memset(this->hidden->iobuffer,
'\0', this->spec.size);
173 for (channelsi = 0; channelsi < total_channels; channelsi++) {
174 float *
dst = (
float *) JACK_jack_port_get_buffer(
ports[channelsi], nframes);
176 const float *
src = ((
float *) this->hidden->iobuffer) + channelsi;
178 for (framesi = 0; framesi < total_frames; framesi++) {
180 src += total_channels;
192 JACK_WaitDevice(
_THIS)
202 JACK_GetDeviceBuf(
_THIS)
204 return (
Uint8 *) this->hidden->iobuffer;
209 jackProcessCaptureCallback(jack_nframes_t nframes,
void *arg)
213 jack_port_t **
ports = this->hidden->sdlports;
218 for (channelsi = 0; channelsi < total_channels; channelsi++) {
219 const float *
src = (
const float *) JACK_jack_port_get_buffer(
ports[channelsi], nframes);
221 float *
dst = ((
float *) this->hidden->iobuffer) + channelsi;
223 for (framesi = 0; framesi < total_frames; framesi++) {
225 dst += total_channels;
236 JACK_CaptureFromDevice(
_THIS,
void *
buffer,
int buflen)
250 JACK_FlushCapture(
_THIS)
257 JACK_CloseDevice(
_THIS)
259 if (this->hidden->client) {
260 JACK_jack_deactivate(this->hidden->client);
262 if (this->hidden->sdlports) {
265 for (i = 0;
i < channels;
i++) {
266 JACK_jack_port_unregister(this->hidden->client, this->hidden->sdlports[
i]);
271 JACK_jack_client_close(this->hidden->client);
274 if (this->hidden->iosem) {
283 JACK_OpenDevice(
_THIS,
void *
handle,
const char *devname,
int iscapture)
289 const unsigned long sysportflags = iscapture ? JackPortIsOutput : JackPortIsInput;
290 const unsigned long sdlportflags = iscapture ? JackPortIsInput : JackPortIsOutput;
291 const JackProcessCallback
callback = iscapture ? jackProcessCaptureCallback : jackProcessPlaybackCallback;
292 const char *sdlportstr = iscapture ?
"input" :
"output";
293 const char **devports =
NULL;
295 jack_client_t *client =
NULL;
296 jack_status_t status;
303 if (this->hidden ==
NULL) {
308 client = JACK_jack_client_open(
"SDL", JackNoStartServer, &status,
NULL);
309 this->hidden->client =
client;
314 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[++
ports]) {
326 const jack_port_t *dport = JACK_jack_port_by_name(
client, devports[
i]);
327 const char *
type = JACK_jack_port_type(dport);
331 audio_ports[channels++] =
i;
335 return SDL_SetError(
"No physical JACK ports available");
350 if (!this->hidden->iosem) {
355 if (!this->hidden->iobuffer) {
360 this->hidden->sdlports = (jack_port_t **)
SDL_calloc(channels,
sizeof (jack_port_t *));
361 if (this->hidden->sdlports ==
NULL) {
365 for (
i = 0;
i < channels;
i++) {
367 SDL_snprintf(portname,
sizeof (portname),
"sdl_jack_%s_%d", sdlportstr,
i);
368 this->hidden->sdlports[
i] = JACK_jack_port_register(
client, portname, JACK_DEFAULT_AUDIO_TYPE, sdlportflags, 0);
369 if (this->hidden->sdlports[
i] ==
NULL) {
374 if (JACK_jack_set_process_callback(
client,
callback,
this) != 0) {
375 return SDL_SetError(
"JACK: Couldn't set process callback");
378 JACK_jack_on_shutdown(
client, jackShutdownCallback,
this);
380 if (JACK_jack_activate(
client) != 0) {
385 for (
i = 0;
i < channels;
i++) {
386 const char *sdlport = JACK_jack_port_name(this->hidden->sdlports[
i]);
387 const char *srcport =
iscapture ? devports[audio_ports[
i]] : sdlport;
388 const char *dstport =
iscapture ? sdlport : devports[audio_ports[
i]];
389 if (JACK_jack_connect(
client, srcport, dstport) != 0) {
390 return SDL_SetError(
"Couldn't connect JACK ports: %s => %s", srcport, dstport);
395 JACK_jack_free(devports);
403 JACK_Deinitialize(
void)
411 if (LoadJackLibrary() < 0) {
415 jack_status_t status;
416 jack_client_t *
client = JACK_jack_client_open(
"SDL", JackNoStartServer, &status,
NULL);
421 JACK_jack_client_close(
client);
440 "jack",
"JACK Audio Connection Kit", JACK_Init, 0
#define SDL_assert(condition)
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device)
#define SDL_DestroySemaphore
#define SDL_CreateSemaphore
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_OutOfMemory()
void * SDL_LoadFunction(void *handle, const char *name)
GLuint GLuint GLsizei GLenum type
GLenum GLenum GLsizei const GLuint GLboolean enabled
AudioBootStrap JACK_bootstrap
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)
EGLImageKHR EGLint EGLint * handle
const EGLAttrib EGLOutputPortEXT * ports
void(* WaitDevice)(_THIS)
void(* CloseDevice)(_THIS)
void(* FlushCapture)(_THIS)
int OnlyHasDefaultCaptureDevice
int OnlyHasDefaultOutputDevice
Uint8 *(* GetDeviceBuf)(_THIS)
void(* Deinitialize)(void)
int(* CaptureFromDevice)(_THIS, void *buffer, int buflen)
int(* OpenDevice)(_THIS, void *handle, const char *devname, int iscapture)
static Uint32 callback(Uint32 interval, void *param)
typedef int(__stdcall *FARPROC)()