update sdl Merge commit '4d48f9d23713d94b861da7b5d41baf2a41334994'

This commit is contained in:
2023-08-12 20:17:29 +02:00
215 changed files with 12672 additions and 17114 deletions

View File

@@ -135,9 +135,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_PostSemaphore(_this->hidden->iosem); /* unblock the SDL thread. */
SDL_AudioDeviceDisconnected((SDL_AudioDevice *)arg);
}
// !!! FIXME: implement and register these!
@@ -146,124 +144,117 @@ static void jackShutdownCallback(void *arg) /* JACK went away; device is lost. *
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;
int channelsi;
SDL_assert(nframes == ((SDL_AudioDevice *)arg)->sample_frames);
SDL_OutputAudioThreadIterate((SDL_AudioDevice *)arg);
return 0;
}
if (!SDL_AtomicGet(&_this->enabled)) {
/* silence the buffer to avoid repeats and corruption. */
SDL_memset(_this->hidden->iobuffer, '\0', _this->spec.size);
}
static void JACK_PlayDevice(SDL_AudioDevice *device, const Uint8 *ui8buffer, int buflen)
{
const float *buffer = (float *) ui8buffer;
jack_port_t **ports = device->hidden->sdlports;
const int total_channels = device->spec.channels;
const int total_frames = device->sample_frames;
const jack_nframes_t nframes = (jack_nframes_t) device->sample_frames;
for (channelsi = 0; channelsi < total_channels; channelsi++) {
for (int channelsi = 0; channelsi < total_channels; channelsi++) {
float *dst = (float *)JACK_jack_port_get_buffer(ports[channelsi], nframes);
if (dst) {
const float *src = _this->hidden->iobuffer + channelsi;
int framesi;
for (framesi = 0; framesi < total_frames; framesi++) {
const float *src = buffer + channelsi;
for (int framesi = 0; framesi < total_frames; framesi++) {
*(dst++) = *src;
src += total_channels;
}
}
}
SDL_PostSemaphore(_this->hidden->iosem); /* tell SDL thread we're done; refill the buffer. */
return 0;
}
/* This function waits until it is possible to write a full sound buffer */
static void JACK_WaitDevice(SDL_AudioDevice *_this)
static Uint8 *JACK_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size)
{
if (SDL_AtomicGet(&_this->enabled)) {
if (SDL_WaitSemaphore(_this->hidden->iosem) == -1) {
SDL_OpenedAudioDeviceDisconnected(_this);
}
}
}
static Uint8 *JACK_GetDeviceBuf(SDL_AudioDevice *_this)
{
return (Uint8 *)_this->hidden->iobuffer;
return (Uint8 *)device->hidden->iobuffer;
}
static int jackProcessCaptureCallback(jack_nframes_t nframes, void *arg)
{
SDL_AudioDevice *_this = (SDL_AudioDevice *)arg;
if (SDL_AtomicGet(&_this->enabled)) {
jack_port_t **ports = _this->hidden->sdlports;
const int total_channels = _this->spec.channels;
const int total_frames = _this->spec.samples;
int channelsi;
for (channelsi = 0; channelsi < total_channels; channelsi++) {
const float *src = (const float *)JACK_jack_port_get_buffer(ports[channelsi], nframes);
if (src) {
float *dst = _this->hidden->iobuffer + channelsi;
int framesi;
for (framesi = 0; framesi < total_frames; framesi++) {
*dst = *(src++);
dst += total_channels;
}
}
}
}
SDL_PostSemaphore(_this->hidden->iosem); /* tell SDL thread we're done; new buffer is ready! */
SDL_assert(nframes == ((SDL_AudioDevice *)arg)->sample_frames);
SDL_CaptureAudioThreadIterate((SDL_AudioDevice *)arg);
return 0;
}
static int JACK_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen)
static int JACK_CaptureFromDevice(SDL_AudioDevice *device, void *vbuffer, int buflen)
{
SDL_assert(buflen == _this->spec.size); /* we always fill a full buffer. */
float *buffer = (float *) vbuffer;
jack_port_t **ports = device->hidden->sdlports;
const int total_channels = device->spec.channels;
const int total_frames = device->sample_frames;
const jack_nframes_t nframes = (jack_nframes_t) device->sample_frames;
/* Wait for JACK to fill the iobuffer */
if (SDL_WaitSemaphore(_this->hidden->iosem) == -1) {
return -1;
for (int channelsi = 0; channelsi < total_channels; channelsi++) {
const float *src = (const float *)JACK_jack_port_get_buffer(ports[channelsi], nframes);
if (src) {
float *dst = buffer + channelsi;
for (int framesi = 0; framesi < total_frames; framesi++) {
*dst = *(src++);
dst += total_channels;
}
}
}
SDL_memcpy(buffer, _this->hidden->iobuffer, buflen);
return buflen;
}
static void JACK_FlushCapture(SDL_AudioDevice *_this)
static void JACK_FlushCapture(SDL_AudioDevice *device)
{
SDL_WaitSemaphore(_this->hidden->iosem);
// do nothing, the data will just be replaced next callback.
}
static void JACK_CloseDevice(SDL_AudioDevice *_this)
static void JACK_CloseDevice(SDL_AudioDevice *device)
{
if (_this->hidden->client) {
JACK_jack_deactivate(_this->hidden->client);
if (device->hidden) {
if (device->hidden->client) {
JACK_jack_deactivate(device->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 (device->hidden->sdlports) {
const int channels = device->spec.channels;
int i;
for (i = 0; i < channels; i++) {
JACK_jack_port_unregister(device->hidden->client, device->hidden->sdlports[i]);
}
SDL_free(device->hidden->sdlports);
}
SDL_free(_this->hidden->sdlports);
JACK_jack_client_close(device->hidden->client);
}
JACK_jack_client_close(_this->hidden->client);
}
SDL_free(device->hidden->iobuffer);
SDL_free(device->hidden);
device->hidden = NULL;
if (_this->hidden->iosem) {
SDL_DestroySemaphore(_this->hidden->iosem);
SDL_AudioThreadFinalize(device);
}
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 *device)
{
/* Note that JACK uses "output" for capture devices (they output audio
data to us) and "input" for playback (we input audio data to them).
Likewise, SDL's playback port will be "output" (we write data out)
and capture will be "input" (we read data in). */
SDL_bool iscapture = _this->iscapture;
SDL_bool iscapture = device->iscapture;
const unsigned long sysportflags = iscapture ? JackPortIsOutput : JackPortIsInput;
const unsigned long sdlportflags = iscapture ? JackPortIsInput : JackPortIsOutput;
const JackProcessCallback callback = iscapture ? jackProcessCaptureCallback : jackProcessPlaybackCallback;
@@ -277,14 +268,13 @@ static int JACK_OpenDevice(SDL_AudioDevice *_this, const char *devname)
int i;
/* Initialize all variables that we clean on shutdown */
_this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*_this->hidden));
if (_this->hidden == NULL) {
device->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*device->hidden));
if (device->hidden == NULL) {
return SDL_OutOfMemory();
}
/* !!! FIXME: we _still_ need an API to specify an app name */
client = JACK_jack_client_open("SDL", JackNoStartServer, &status, NULL);
_this->hidden->client = client;
client = JACK_jack_client_open(GetJackAppName(), JackNoStartServer, &status, NULL);
device->hidden->client = client;
if (client == NULL) {
return SDL_SetError("Can't open JACK client");
}
@@ -317,28 +307,24 @@ static int JACK_OpenDevice(SDL_AudioDevice *_this, const char *devname)
/* !!! FIXME: docs say about buffer size: "This size may change, clients that depend on it must register a bufsize_callback so they will be notified if it does." */
/* Jack pretty much demands what it wants. */
_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);
device->spec.format = SDL_AUDIO_F32SYS;
device->spec.freq = JACK_jack_get_sample_rate(client);
device->spec.channels = channels;
device->sample_frames = JACK_jack_get_buffer_size(client);
SDL_CalculateAudioSpec(&_this->spec);
SDL_UpdatedAudioDeviceFormat(device);
_this->hidden->iosem = SDL_CreateSemaphore(0);
if (!_this->hidden->iosem) {
SDL_free(audio_ports);
return -1; /* error was set by SDL_CreateSemaphore */
}
_this->hidden->iobuffer = (float *)SDL_calloc(1, _this->spec.size);
if (!_this->hidden->iobuffer) {
SDL_free(audio_ports);
return SDL_OutOfMemory();
if (!device->iscapture) {
device->hidden->iobuffer = (float *)SDL_calloc(1, device->buffer_size);
if (!device->hidden->iobuffer) {
SDL_free(audio_ports);
return SDL_OutOfMemory();
}
}
/* Build SDL's ports, which we will connect to the device ports. */
_this->hidden->sdlports = (jack_port_t **)SDL_calloc(channels, sizeof(jack_port_t *));
if (_this->hidden->sdlports == NULL) {
device->hidden->sdlports = (jack_port_t **)SDL_calloc(channels, sizeof(jack_port_t *));
if (device->hidden->sdlports == NULL) {
SDL_free(audio_ports);
return SDL_OutOfMemory();
}
@@ -346,19 +332,19 @@ static int JACK_OpenDevice(SDL_AudioDevice *_this, const char *devname)
for (i = 0; i < channels; i++) {
char portname[32];
(void)SDL_snprintf(portname, sizeof(portname), "sdl_jack_%s_%d", sdlportstr, i);
_this->hidden->sdlports[i] = JACK_jack_port_register(client, portname, JACK_DEFAULT_AUDIO_TYPE, sdlportflags, 0);
if (_this->hidden->sdlports[i] == NULL) {
device->hidden->sdlports[i] = JACK_jack_port_register(client, portname, JACK_DEFAULT_AUDIO_TYPE, sdlportflags, 0);
if (device->hidden->sdlports[i] == NULL) {
SDL_free(audio_ports);
return SDL_SetError("jack_port_register failed");
}
}
if (JACK_jack_set_process_callback(client, callback, _this) != 0) {
if (JACK_jack_set_process_callback(client, callback, device) != 0) {
SDL_free(audio_ports);
return SDL_SetError("JACK: Couldn't set process callback");
}
JACK_jack_on_shutdown(client, jackShutdownCallback, _this);
JACK_jack_on_shutdown(client, jackShutdownCallback, device);
if (JACK_jack_activate(client) != 0) {
SDL_free(audio_ports);
@@ -367,7 +353,7 @@ static int JACK_OpenDevice(SDL_AudioDevice *_this, const char *devname)
/* once activated, we can connect all the ports. */
for (i = 0; i < channels; i++) {
const char *sdlport = JACK_jack_port_name(_this->hidden->sdlports[i]);
const char *sdlport = JACK_jack_port_name(device->hidden->sdlports[i]);
const char *srcport = iscapture ? devports[audio_ports[i]] : sdlport;
const char *dstport = iscapture ? sdlport : devports[audio_ports[i]];
if (JACK_jack_connect(client, srcport, dstport) != 0) {
@@ -406,8 +392,8 @@ static SDL_bool JACK_Init(SDL_AudioDriverImpl *impl)
/* Set the function pointers */
impl->OpenDevice = JACK_OpenDevice;
impl->WaitDevice = JACK_WaitDevice;
impl->GetDeviceBuf = JACK_GetDeviceBuf;
impl->PlayDevice = JACK_PlayDevice;
impl->CloseDevice = JACK_CloseDevice;
impl->Deinitialize = JACK_Deinitialize;
impl->CaptureFromDevice = JACK_CaptureFromDevice;
@@ -415,6 +401,7 @@ static SDL_bool JACK_Init(SDL_AudioDriverImpl *impl)
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
impl->HasCaptureSupport = SDL_TRUE;
impl->ProvidesOwnCallbackThread = SDL_TRUE;
return SDL_TRUE; /* this audio target is available. */
}

View File

@@ -28,9 +28,8 @@
struct SDL_PrivateAudioData
{
jack_client_t *client;
SDL_Semaphore *iosem;
float *iobuffer;
jack_port_t **sdlports;
float *iobuffer;
};
#endif /* SDL_jackaudio_h_ */