jack: First shot at updating for SDL3 audio API.

This commit is contained in:
Ryan C. Gordon
2023-07-05 00:22:35 -04:00
parent a2b488359e
commit 18906a32b8
2 changed files with 46 additions and 32 deletions

View File

@@ -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)

View File

@@ -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();