alsa: Renamed _this to device

This commit is contained in:
Ryan C. Gordon
2023-07-03 23:49:45 -04:00
parent 0fb9e4baae
commit 4deb2970c9

View File

@@ -225,20 +225,20 @@ static const char *get_audio_device(void *handle, const int channels)
} }
/* This function waits until it is possible to write a full sound buffer */ /* This function waits until it is possible to write a full sound buffer */
static void ALSA_WaitDevice(SDL_AudioDevice *_this) static void ALSA_WaitDevice(SDL_AudioDevice *device)
{ {
#if SDL_ALSA_NON_BLOCKING #if SDL_ALSA_NON_BLOCKING
const snd_pcm_sframes_t needed = (snd_pcm_sframes_t)_this->spec.samples; const snd_pcm_sframes_t needed = (snd_pcm_sframes_t)device->spec.samples;
while (SDL_AtomicGet(&_this->enabled)) { while (SDL_AtomicGet(&device->enabled)) {
const snd_pcm_sframes_t rc = ALSA_snd_pcm_avail(_this->hidden->pcm_handle); const snd_pcm_sframes_t rc = ALSA_snd_pcm_avail(device->hidden->pcm_handle);
if ((rc < 0) && (rc != -EAGAIN)) { if ((rc < 0) && (rc != -EAGAIN)) {
/* Hmm, not much we can do - abort */ /* Hmm, not much we can do - abort */
fprintf(stderr, "ALSA snd_pcm_avail failed (unrecoverable): %s\n", fprintf(stderr, "ALSA snd_pcm_avail failed (unrecoverable): %s\n",
ALSA_snd_strerror(rc)); ALSA_snd_strerror(rc));
SDL_OpenedAudioDeviceDisconnected(_this); SDL_OpenedAudioDeviceDisconnected(device);
return; return;
} else if (rc < needed) { } else if (rc < needed) {
const Uint32 delay = ((needed - (SDL_max(rc, 0))) * 1000) / _this->spec.freq; const Uint32 delay = ((needed - (SDL_max(rc, 0))) * 1000) / device->spec.freq;
SDL_Delay(SDL_max(delay, 10)); SDL_Delay(SDL_max(delay, 10));
} else { } else {
break; /* ready to go! */ break; /* ready to go! */
@@ -311,15 +311,15 @@ CHANNEL_SWIZZLE(SWIZ8)
#undef SWIZ8 #undef SWIZ8
/* /*
* Called right before feeding _this->hidden->mixbuf to the hardware. Swizzle * Called right before feeding device->hidden->mixbuf to the hardware. Swizzle
* channels from Windows/Mac order to the format alsalib will want. * channels from Windows/Mac order to the format alsalib will want.
*/ */
static void swizzle_alsa_channels(SDL_AudioDevice *_this, void *buffer, Uint32 bufferlen) static void swizzle_alsa_channels(SDL_AudioDevice *device, void *buffer, Uint32 bufferlen)
{ {
switch (_this->spec.channels) { switch (device->spec.channels) {
#define CHANSWIZ(chans) \ #define CHANSWIZ(chans) \
case chans: \ case chans: \
switch ((_this->spec.format & (0xFF))) { \ switch ((device->spec.format & (0xFF))) { \
case 8: \ case 8: \
swizzle_alsa_channels_##chans##_Uint8(buffer, bufferlen); \ swizzle_alsa_channels_##chans##_Uint8(buffer, bufferlen); \
break; \ break; \
@@ -348,22 +348,22 @@ static void swizzle_alsa_channels(SDL_AudioDevice *_this, void *buffer, Uint32 b
#ifdef SND_CHMAP_API_VERSION #ifdef SND_CHMAP_API_VERSION
/* Some devices have the right channel map, no swizzling necessary */ /* Some devices have the right channel map, no swizzling necessary */
static void no_swizzle(SDL_AudioDevice *_this, void *buffer, Uint32 bufferlen) static void no_swizzle(SDL_AudioDevice *device, void *buffer, Uint32 bufferlen)
{ {
} }
#endif /* SND_CHMAP_API_VERSION */ #endif /* SND_CHMAP_API_VERSION */
static void ALSA_PlayDevice(SDL_AudioDevice *_this) static void ALSA_PlayDevice(SDL_AudioDevice *device)
{ {
const Uint8 *sample_buf = (const Uint8 *)_this->hidden->mixbuf; const Uint8 *sample_buf = (const Uint8 *)device->hidden->mixbuf;
const int frame_size = ((SDL_AUDIO_BITSIZE(_this->spec.format)) / 8) * const int frame_size = ((SDL_AUDIO_BITSIZE(device->spec.format)) / 8) *
_this->spec.channels; device->spec.channels;
snd_pcm_uframes_t frames_left = ((snd_pcm_uframes_t)_this->spec.samples); snd_pcm_uframes_t frames_left = ((snd_pcm_uframes_t)device->spec.samples);
_this->hidden->swizzle_func(_this, _this->hidden->mixbuf, frames_left); device->hidden->swizzle_func(device, device->hidden->mixbuf, frames_left);
while (frames_left > 0 && SDL_AtomicGet(&_this->enabled)) { while (frames_left > 0 && SDL_AtomicGet(&device->enabled)) {
int status = ALSA_snd_pcm_writei(_this->hidden->pcm_handle, int status = ALSA_snd_pcm_writei(device->hidden->pcm_handle,
sample_buf, frames_left); sample_buf, frames_left);
if (status < 0) { if (status < 0) {
@@ -373,20 +373,20 @@ static void ALSA_PlayDevice(SDL_AudioDevice *_this)
SDL_Delay(1); SDL_Delay(1);
continue; continue;
} }
status = ALSA_snd_pcm_recover(_this->hidden->pcm_handle, status, 0); status = ALSA_snd_pcm_recover(device->hidden->pcm_handle, status, 0);
if (status < 0) { if (status < 0) {
/* Hmm, not much we can do - abort */ /* Hmm, not much we can do - abort */
SDL_LogError(SDL_LOG_CATEGORY_AUDIO, SDL_LogError(SDL_LOG_CATEGORY_AUDIO,
"ALSA write failed (unrecoverable): %s\n", "ALSA write failed (unrecoverable): %s\n",
ALSA_snd_strerror(status)); ALSA_snd_strerror(status));
SDL_OpenedAudioDeviceDisconnected(_this); SDL_OpenedAudioDeviceDisconnected(device);
return; return;
} }
continue; continue;
} else if (status == 0) { } else if (status == 0) {
/* No frames were written (no available space in pcm device). /* No frames were written (no available space in pcm device).
Allow other threads to catch up. */ Allow other threads to catch up. */
Uint32 delay = (frames_left / 2 * 1000) / _this->spec.freq; Uint32 delay = (frames_left / 2 * 1000) / device->spec.freq;
SDL_Delay(delay); SDL_Delay(delay);
} }
@@ -395,34 +395,34 @@ static void ALSA_PlayDevice(SDL_AudioDevice *_this)
} }
} }
static Uint8 *ALSA_GetDeviceBuf(SDL_AudioDevice *_this) static Uint8 *ALSA_GetDeviceBuf(SDL_AudioDevice *device)
{ {
return _this->hidden->mixbuf; return device->hidden->mixbuf;
} }
static int ALSA_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int buflen) static int ALSA_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, int buflen)
{ {
Uint8 *sample_buf = (Uint8 *)buffer; Uint8 *sample_buf = (Uint8 *)buffer;
const int frame_size = ((SDL_AUDIO_BITSIZE(_this->spec.format)) / 8) * const int frame_size = ((SDL_AUDIO_BITSIZE(device->spec.format)) / 8) *
_this->spec.channels; device->spec.channels;
const int total_frames = buflen / frame_size; const int total_frames = buflen / frame_size;
snd_pcm_uframes_t frames_left = total_frames; snd_pcm_uframes_t frames_left = total_frames;
snd_pcm_uframes_t wait_time = frame_size / 2; snd_pcm_uframes_t wait_time = frame_size / 2;
SDL_assert((buflen % frame_size) == 0); SDL_assert((buflen % frame_size) == 0);
while (frames_left > 0 && SDL_AtomicGet(&_this->enabled)) { while (frames_left > 0 && SDL_AtomicGet(&device->enabled)) {
int status; int status;
status = ALSA_snd_pcm_readi(_this->hidden->pcm_handle, status = ALSA_snd_pcm_readi(device->hidden->pcm_handle,
sample_buf, frames_left); sample_buf, frames_left);
if (status == -EAGAIN) { if (status == -EAGAIN) {
ALSA_snd_pcm_wait(_this->hidden->pcm_handle, wait_time); ALSA_snd_pcm_wait(device->hidden->pcm_handle, wait_time);
status = 0; status = 0;
} else if (status < 0) { } else if (status < 0) {
/*printf("ALSA: capture error %d\n", status);*/ /*printf("ALSA: capture error %d\n", status);*/
status = ALSA_snd_pcm_recover(_this->hidden->pcm_handle, status, 0); status = ALSA_snd_pcm_recover(device->hidden->pcm_handle, status, 0);
if (status < 0) { if (status < 0) {
/* Hmm, not much we can do - abort */ /* Hmm, not much we can do - abort */
SDL_LogError(SDL_LOG_CATEGORY_AUDIO, SDL_LogError(SDL_LOG_CATEGORY_AUDIO,
@@ -438,32 +438,32 @@ static int ALSA_CaptureFromDevice(SDL_AudioDevice *_this, void *buffer, int bufl
frames_left -= status; frames_left -= status;
} }
_this->hidden->swizzle_func(_this, buffer, total_frames - frames_left); device->hidden->swizzle_func(device, buffer, total_frames - frames_left);
return (total_frames - frames_left) * frame_size; return (total_frames - frames_left) * frame_size;
} }
static void ALSA_FlushCapture(SDL_AudioDevice *_this) static void ALSA_FlushCapture(SDL_AudioDevice *device)
{ {
ALSA_snd_pcm_reset(_this->hidden->pcm_handle); ALSA_snd_pcm_reset(device->hidden->pcm_handle);
} }
static void ALSA_CloseDevice(SDL_AudioDevice *_this) static void ALSA_CloseDevice(SDL_AudioDevice *device)
{ {
if (_this->hidden->pcm_handle) { if (device->hidden->pcm_handle) {
/* Wait for the submitted audio to drain /* Wait for the submitted audio to drain
ALSA_snd_pcm_drop() can hang, so don't use that. ALSA_snd_pcm_drop() can hang, so don't use that.
*/ */
Uint32 delay = ((_this->spec.samples * 1000) / _this->spec.freq) * 2; Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq) * 2;
SDL_Delay(delay); SDL_Delay(delay);
ALSA_snd_pcm_close(_this->hidden->pcm_handle); ALSA_snd_pcm_close(device->hidden->pcm_handle);
} }
SDL_free(_this->hidden->mixbuf); SDL_free(device->hidden->mixbuf);
SDL_free(_this->hidden); SDL_free(device->hidden);
} }
static int ALSA_set_buffer_size(SDL_AudioDevice *_this, snd_pcm_hw_params_t *params) static int ALSA_set_buffer_size(SDL_AudioDevice *device, snd_pcm_hw_params_t *params)
{ {
int status; int status;
snd_pcm_hw_params_t *hwparams; snd_pcm_hw_params_t *hwparams;
@@ -475,9 +475,9 @@ static int ALSA_set_buffer_size(SDL_AudioDevice *_this, snd_pcm_hw_params_t *par
ALSA_snd_pcm_hw_params_copy(hwparams, params); ALSA_snd_pcm_hw_params_copy(hwparams, params);
/* Attempt to match the period size to the requested buffer size */ /* Attempt to match the period size to the requested buffer size */
persize = _this->spec.samples; persize = device->spec.samples;
status = ALSA_snd_pcm_hw_params_set_period_size_near( status = ALSA_snd_pcm_hw_params_set_period_size_near(
_this->hidden->pcm_handle, hwparams, &persize, NULL); device->hidden->pcm_handle, hwparams, &persize, NULL);
if (status < 0) { if (status < 0) {
return -1; return -1;
} }
@@ -485,24 +485,24 @@ static int ALSA_set_buffer_size(SDL_AudioDevice *_this, snd_pcm_hw_params_t *par
/* Need to at least double buffer */ /* Need to at least double buffer */
periods = 2; periods = 2;
status = ALSA_snd_pcm_hw_params_set_periods_min( status = ALSA_snd_pcm_hw_params_set_periods_min(
_this->hidden->pcm_handle, hwparams, &periods, NULL); device->hidden->pcm_handle, hwparams, &periods, NULL);
if (status < 0) { if (status < 0) {
return -1; return -1;
} }
status = ALSA_snd_pcm_hw_params_set_periods_first( status = ALSA_snd_pcm_hw_params_set_periods_first(
_this->hidden->pcm_handle, hwparams, &periods, NULL); device->hidden->pcm_handle, hwparams, &periods, NULL);
if (status < 0) { if (status < 0) {
return -1; return -1;
} }
/* "set" the hardware with the desired parameters */ /* "set" the hardware with the desired parameters */
status = ALSA_snd_pcm_hw_params(_this->hidden->pcm_handle, hwparams); status = ALSA_snd_pcm_hw_params(device->hidden->pcm_handle, hwparams);
if (status < 0) { if (status < 0) {
return -1; return -1;
} }
_this->spec.samples = persize; device->spec.samples = persize;
/* This is useful for debugging */ /* This is useful for debugging */
if (SDL_getenv("SDL_AUDIO_ALSA_DEBUG")) { if (SDL_getenv("SDL_AUDIO_ALSA_DEBUG")) {
@@ -518,10 +518,10 @@ static int ALSA_set_buffer_size(SDL_AudioDevice *_this, snd_pcm_hw_params_t *par
return 0; return 0;
} }
static int ALSA_OpenDevice(SDL_AudioDevice *_this, const char *devname) static int ALSA_OpenDevice(SDL_AudioDevice *device, const char *devname)
{ {
int status = 0; int status = 0;
SDL_bool iscapture = _this->iscapture; SDL_bool iscapture = device->iscapture;
snd_pcm_t *pcm_handle = NULL; snd_pcm_t *pcm_handle = NULL;
snd_pcm_hw_params_t *hwparams = NULL; snd_pcm_hw_params_t *hwparams = NULL;
snd_pcm_sw_params_t *swparams = NULL; snd_pcm_sw_params_t *swparams = NULL;
@@ -536,16 +536,16 @@ static int ALSA_OpenDevice(SDL_AudioDevice *_this, const char *devname)
#endif #endif
/* Initialize all variables that we clean on shutdown */ /* Initialize all variables that we clean on shutdown */
_this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*_this->hidden)); device->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*device->hidden));
if (_this->hidden == NULL) { if (device->hidden == NULL) {
return SDL_OutOfMemory(); return SDL_OutOfMemory();
} }
SDL_zerop(_this->hidden); SDL_zerop(device->hidden);
/* Open the audio device */ /* Open the audio device */
/* Name of device should depend on # channels in spec */ /* Name of device should depend on # channels in spec */
status = ALSA_snd_pcm_open(&pcm_handle, status = ALSA_snd_pcm_open(&pcm_handle,
get_audio_device(_this->handle, _this->spec.channels), get_audio_device(device->handle, device->spec.channels),
iscapture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, iscapture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,
SND_PCM_NONBLOCK); SND_PCM_NONBLOCK);
@@ -553,7 +553,7 @@ static int ALSA_OpenDevice(SDL_AudioDevice *_this, const char *devname)
return SDL_SetError("ALSA: Couldn't open audio device: %s", ALSA_snd_strerror(status)); return SDL_SetError("ALSA: Couldn't open audio device: %s", ALSA_snd_strerror(status));
} }
_this->hidden->pcm_handle = pcm_handle; device->hidden->pcm_handle = pcm_handle;
/* Figure out what the hardware is capable of */ /* Figure out what the hardware is capable of */
snd_pcm_hw_params_alloca(&hwparams); snd_pcm_hw_params_alloca(&hwparams);
@@ -570,7 +570,7 @@ static int ALSA_OpenDevice(SDL_AudioDevice *_this, const char *devname)
} }
/* Try for a closest match on audio format */ /* Try for a closest match on audio format */
closefmts = SDL_ClosestAudioFormats(_this->spec.format); closefmts = SDL_ClosestAudioFormats(device->spec.format);
while ((test_format = *(closefmts++)) != 0) { while ((test_format = *(closefmts++)) != 0) {
switch (test_format) { switch (test_format) {
case SDL_AUDIO_U8: case SDL_AUDIO_U8:
@@ -607,19 +607,19 @@ static int ALSA_OpenDevice(SDL_AudioDevice *_this, const char *devname)
if (!test_format) { if (!test_format) {
return SDL_SetError("%s: Unsupported audio format", "alsa"); return SDL_SetError("%s: Unsupported audio format", "alsa");
} }
_this->spec.format = test_format; device->spec.format = test_format;
/* Validate number of channels and determine if swizzling is necessary /* Validate number of channels and determine if swizzling is necessary
* Assume original swizzling, until proven otherwise. * Assume original swizzling, until proven otherwise.
*/ */
_this->hidden->swizzle_func = swizzle_alsa_channels; device->hidden->swizzle_func = swizzle_alsa_channels;
#ifdef SND_CHMAP_API_VERSION #ifdef SND_CHMAP_API_VERSION
chmap = ALSA_snd_pcm_get_chmap(pcm_handle); chmap = ALSA_snd_pcm_get_chmap(pcm_handle);
if (chmap) { if (chmap) {
if (ALSA_snd_pcm_chmap_print(chmap, sizeof(chmap_str), chmap_str) > 0) { if (ALSA_snd_pcm_chmap_print(chmap, sizeof(chmap_str), chmap_str) > 0) {
if (SDL_strcmp("FL FR FC LFE RL RR", chmap_str) == 0 || if (SDL_strcmp("FL FR FC LFE RL RR", chmap_str) == 0 ||
SDL_strcmp("FL FR FC LFE SL SR", chmap_str) == 0) { SDL_strcmp("FL FR FC LFE SL SR", chmap_str) == 0) {
_this->hidden->swizzle_func = no_swizzle; device->hidden->swizzle_func = no_swizzle;
} }
} }
free(chmap); /* This should NOT be SDL_free() */ free(chmap); /* This should NOT be SDL_free() */
@@ -628,27 +628,27 @@ static int ALSA_OpenDevice(SDL_AudioDevice *_this, const char *devname)
/* Set the number of channels */ /* Set the number of channels */
status = ALSA_snd_pcm_hw_params_set_channels(pcm_handle, hwparams, status = ALSA_snd_pcm_hw_params_set_channels(pcm_handle, hwparams,
_this->spec.channels); device->spec.channels);
channels = _this->spec.channels; channels = device->spec.channels;
if (status < 0) { if (status < 0) {
status = ALSA_snd_pcm_hw_params_get_channels(hwparams, &channels); status = ALSA_snd_pcm_hw_params_get_channels(hwparams, &channels);
if (status < 0) { if (status < 0) {
return SDL_SetError("ALSA: Couldn't set audio channels"); return SDL_SetError("ALSA: Couldn't set audio channels");
} }
_this->spec.channels = channels; device->spec.channels = channels;
} }
/* Set the audio rate */ /* Set the audio rate */
rate = _this->spec.freq; rate = device->spec.freq;
status = ALSA_snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, status = ALSA_snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams,
&rate, NULL); &rate, NULL);
if (status < 0) { if (status < 0) {
return SDL_SetError("ALSA: Couldn't set audio frequency: %s", ALSA_snd_strerror(status)); return SDL_SetError("ALSA: Couldn't set audio frequency: %s", ALSA_snd_strerror(status));
} }
_this->spec.freq = rate; device->spec.freq = rate;
/* Set the buffer size, in samples */ /* Set the buffer size, in samples */
status = ALSA_set_buffer_size(_this, hwparams); status = ALSA_set_buffer_size(device, hwparams);
if (status < 0) { if (status < 0) {
return SDL_SetError("Couldn't set hardware audio parameters: %s", ALSA_snd_strerror(status)); return SDL_SetError("Couldn't set hardware audio parameters: %s", ALSA_snd_strerror(status));
} }
@@ -659,7 +659,7 @@ static int ALSA_OpenDevice(SDL_AudioDevice *_this, const char *devname)
if (status < 0) { if (status < 0) {
return SDL_SetError("ALSA: Couldn't get software config: %s", ALSA_snd_strerror(status)); return SDL_SetError("ALSA: Couldn't get software config: %s", ALSA_snd_strerror(status));
} }
status = ALSA_snd_pcm_sw_params_set_avail_min(pcm_handle, swparams, _this->spec.samples); status = ALSA_snd_pcm_sw_params_set_avail_min(pcm_handle, swparams, device->spec.samples);
if (status < 0) { if (status < 0) {
return SDL_SetError("Couldn't set minimum available samples: %s", ALSA_snd_strerror(status)); return SDL_SetError("Couldn't set minimum available samples: %s", ALSA_snd_strerror(status));
} }
@@ -674,16 +674,16 @@ static int ALSA_OpenDevice(SDL_AudioDevice *_this, const char *devname)
} }
/* Calculate the final parameters for this audio specification */ /* Calculate the final parameters for this audio specification */
SDL_CalculateAudioSpec(&_this->spec); SDL_CalculateAudioSpec(&device->spec);
/* Allocate mixing buffer */ /* Allocate mixing buffer */
if (!iscapture) { if (!iscapture) {
_this->hidden->mixlen = _this->spec.size; device->hidden->mixlen = device->spec.size;
_this->hidden->mixbuf = (Uint8 *)SDL_malloc(_this->hidden->mixlen); device->hidden->mixbuf = (Uint8 *)SDL_malloc(device->hidden->mixlen);
if (_this->hidden->mixbuf == NULL) { if (device->hidden->mixbuf == NULL) {
return SDL_OutOfMemory(); return SDL_OutOfMemory();
} }
SDL_memset(_this->hidden->mixbuf, _this->spec.silence, _this->hidden->mixlen); SDL_memset(device->hidden->mixbuf, device->spec.silence, device->hidden->mixlen);
} }
#if !SDL_ALSA_NON_BLOCKING #if !SDL_ALSA_NON_BLOCKING