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 58 static const char *jack_library = 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) {
97 retval = load_jack_syms();
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)
247 SDL_memcpy(buffer, this->hidden->iobuffer, 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) {
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;
311 if (client ==
NULL) {
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]) {
325 audio_ports =
SDL_calloc(ports,
sizeof *audio_ports);
326 for (i = 0; i <
ports; i++) {
327 const jack_port_t *dport = JACK_jack_port_by_name(client, devports[i]);
328 const char *
type = JACK_jack_port_type(dport);
331 if (len >= 5 && !
SDL_memcmp(type+len-5,
"audio", 5)) {
332 audio_ports[channels++] =
i;
336 return SDL_SetError(
"No physical JACK ports available");
344 this->
spec.
freq = JACK_jack_get_sample_rate(client);
346 this->
spec.
samples = JACK_jack_get_buffer_size(client);
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) {
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) {
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);
418 if (client ==
NULL) {
422 JACK_jack_client_close(client);
441 "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)
GLuint GLuint GLsizei GLenum type
void * SDL_LoadFunction(void *handle, const char *name)
struct @64::@65 channels[NUM_CHANNELS]