From 18906a32b88d213b49816b157ab72a9f14da1532 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 5 Jul 2023 00:22:35 -0400 Subject: [PATCH] jack: First shot at updating for SDL3 audio API. --- CMakeLists.txt | 1 - src/audio/jack/SDL_jackaudio.c | 77 ++++++++++++++++++++-------------- 2 files changed, 46 insertions(+), 32 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0af3be552..c74b19ee5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -353,7 +353,6 @@ set_option(SDL_CLANG_TIDY "Run clang-tidy static analysis" OFF) set(SDL_VENDOR_INFO "" CACHE STRING "Vendor name and/or version to add to SDL_REVISION") -set(SDL_JACK OFF) set(SDL_SNDIO OFF) cmake_dependent_option(SDL_SHARED "Build a shared version of the library" ${SDL_SHARED_DEFAULT} ${SDL_SHARED_AVAILABLE} OFF) diff --git a/src/audio/jack/SDL_jackaudio.c b/src/audio/jack/SDL_jackaudio.c index 60deac3a7..36bfbb8e7 100644 --- a/src/audio/jack/SDL_jackaudio.c +++ b/src/audio/jack/SDL_jackaudio.c @@ -136,7 +136,7 @@ static int load_jack_syms(void) static void jackShutdownCallback(void *arg) /* JACK went away; device is lost. */ { SDL_AudioDevice *_this = (SDL_AudioDevice *)arg; - SDL_OpenedAudioDeviceDisconnected(_this); + SDL_AudioDeviceDisconnected(_this); SDL_PostSemaphore(_this->hidden->iosem); /* unblock the SDL thread. */ } @@ -149,12 +149,12 @@ static int jackProcessPlaybackCallback(jack_nframes_t nframes, void *arg) SDL_AudioDevice *_this = (SDL_AudioDevice *)arg; jack_port_t **ports = _this->hidden->sdlports; const int total_channels = _this->spec.channels; - const int total_frames = _this->spec.samples; + const int total_frames = _this->sample_frames; int channelsi; - if (!SDL_AtomicGet(&_this->enabled)) { + if (SDL_AtomicGet(&_this->shutdown)) { /* silence the buffer to avoid repeats and corruption. */ - SDL_memset(_this->hidden->iobuffer, '\0', _this->spec.size); + SDL_memset(_this->hidden->iobuffer, _this->silence_value, _this->buffer_size); } for (channelsi = 0; channelsi < total_channels; channelsi++) { @@ -176,14 +176,14 @@ static int jackProcessPlaybackCallback(jack_nframes_t nframes, void *arg) /* This function waits until it is possible to write a full sound buffer */ static void JACK_WaitDevice(SDL_AudioDevice *_this) { - if (SDL_AtomicGet(&_this->enabled)) { + if (!SDL_AtomicGet(&_this->shutdown)) { if (SDL_WaitSemaphore(_this->hidden->iosem) == -1) { - SDL_OpenedAudioDeviceDisconnected(_this); + SDL_AudioDeviceDisconnected(_this); } } } -static Uint8 *JACK_GetDeviceBuf(SDL_AudioDevice *_this) +static Uint8 *JACK_GetDeviceBuf(SDL_AudioDevice *_this, int *buffer_size) { return (Uint8 *)_this->hidden->iobuffer; } @@ -191,10 +191,10 @@ static Uint8 *JACK_GetDeviceBuf(SDL_AudioDevice *_this) static int jackProcessCaptureCallback(jack_nframes_t nframes, void *arg) { SDL_AudioDevice *_this = (SDL_AudioDevice *)arg; - if (SDL_AtomicGet(&_this->enabled)) { + if (!SDL_AtomicGet(&_this->shutdown)) { jack_port_t **ports = _this->hidden->sdlports; const int total_channels = _this->spec.channels; - const int total_frames = _this->spec.samples; + const int total_frames = _this->sample_frames; int channelsi; for (channelsi = 0; channelsi < total_channels; channelsi++) { @@ -216,7 +216,7 @@ static int jackProcessCaptureCallback(jack_nframes_t nframes, void *arg) static int JACK_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen) { - SDL_assert(buflen == _this->spec.size); /* we always fill a full buffer. */ + SDL_assert(buflen == _this->buffer_size); /* we always fill a full buffer. */ /* Wait for JACK to fill the iobuffer */ if (SDL_WaitSemaphore(_this->hidden->iosem) == -1) { @@ -234,30 +234,46 @@ static void JACK_FlushCapture(SDL_AudioDevice *_this) static void JACK_CloseDevice(SDL_AudioDevice *_this) { - if (_this->hidden->client) { - JACK_jack_deactivate(_this->hidden->client); + if (_this->hidden) { + if (_this->hidden->client) { + JACK_jack_deactivate(_this->hidden->client); - if (_this->hidden->sdlports) { - const int channels = _this->spec.channels; - int i; - for (i = 0; i < channels; i++) { - JACK_jack_port_unregister(_this->hidden->client, _this->hidden->sdlports[i]); + if (_this->hidden->sdlports) { + const int channels = _this->spec.channels; + int i; + for (i = 0; i < channels; i++) { + JACK_jack_port_unregister(_this->hidden->client, _this->hidden->sdlports[i]); + } + SDL_free(_this->hidden->sdlports); } - SDL_free(_this->hidden->sdlports); + + JACK_jack_client_close(_this->hidden->client); } - JACK_jack_client_close(_this->hidden->client); - } + if (_this->hidden->iosem) { + SDL_DestroySemaphore(_this->hidden->iosem); + } - if (_this->hidden->iosem) { - SDL_DestroySemaphore(_this->hidden->iosem); + SDL_free(_this->hidden->iobuffer); + SDL_free(_this->hidden); } - - SDL_free(_this->hidden->iobuffer); - SDL_free(_this->hidden); } -static int JACK_OpenDevice(SDL_AudioDevice *_this, const char *devname) +// !!! FIXME: unify this (PulseAudio has a getAppName, Pipewire has a thing, etc +static const char *GetJackAppName(void) +{ + const char *retval = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_APP_NAME); + if (retval && *retval) { + return retval; + } + retval = SDL_GetHint(SDL_HINT_APP_NAME); + if (retval && *retval) { + return retval; + } + return "SDL Application"; +} + +static int JACK_OpenDevice(SDL_AudioDevice *_this) { /* Note that JACK uses "output" for capture devices (they output audio data to us) and "input" for playback (we input audio data to them). @@ -282,8 +298,7 @@ static int JACK_OpenDevice(SDL_AudioDevice *_this, const char *devname) return SDL_OutOfMemory(); } - /* !!! FIXME: we _still_ need an API to specify an app name */ - client = JACK_jack_client_open("SDL", JackNoStartServer, &status, NULL); + client = JACK_jack_client_open(GetJackAppName(), JackNoStartServer, &status, NULL); _this->hidden->client = client; if (client == NULL) { return SDL_SetError("Can't open JACK client"); @@ -320,9 +335,9 @@ static int JACK_OpenDevice(SDL_AudioDevice *_this, const char *devname) _this->spec.format = SDL_AUDIO_F32SYS; _this->spec.freq = JACK_jack_get_sample_rate(client); _this->spec.channels = channels; - _this->spec.samples = JACK_jack_get_buffer_size(client); + _this->sample_frames = JACK_jack_get_buffer_size(client); - SDL_CalculateAudioSpec(&_this->spec); + SDL_UpdatedAudioDeviceFormat(_this); _this->hidden->iosem = SDL_CreateSemaphore(0); if (!_this->hidden->iosem) { @@ -330,7 +345,7 @@ static int JACK_OpenDevice(SDL_AudioDevice *_this, const char *devname) return -1; /* error was set by SDL_CreateSemaphore */ } - _this->hidden->iobuffer = (float *)SDL_calloc(1, _this->spec.size); + _this->hidden->iobuffer = (float *)SDL_calloc(1, _this->buffer_size); if (!_this->hidden->iobuffer) { SDL_free(audio_ports); return SDL_OutOfMemory();