early-access version 2281
This commit is contained in:
31
externals/SDL/src/audio/SDL_audio.c
vendored
31
externals/SDL/src/audio/SDL_audio.c
vendored
@@ -47,9 +47,6 @@ static const AudioBootStrap *const bootstrap[] = {
|
||||
#if SDL_AUDIO_DRIVER_NETBSD
|
||||
&NETBSDAUDIO_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_OSS
|
||||
&DSP_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_QSA
|
||||
&QSAAUDIO_bootstrap,
|
||||
#endif
|
||||
@@ -113,6 +110,9 @@ static const AudioBootStrap *const bootstrap[] = {
|
||||
#if SDL_AUDIO_DRIVER_PIPEWIRE
|
||||
&PIPEWIRE_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_OSS
|
||||
&DSP_bootstrap,
|
||||
#endif
|
||||
#if SDL_AUDIO_DRIVER_OS2
|
||||
&OS2AUDIO_bootstrap,
|
||||
#endif
|
||||
@@ -687,7 +687,7 @@ SDL_ClearQueuedAudio(SDL_AudioDeviceID devid)
|
||||
/* Blank out the device and release the mutex. Free it afterwards. */
|
||||
current_audio.impl.LockDevice(device);
|
||||
|
||||
/* Keep up to two packets in the pool to reduce future malloc pressure. */
|
||||
/* Keep up to two packets in the pool to reduce future memory allocation pressure. */
|
||||
SDL_ClearDataQueue(device->buffer_queue, SDL_AUDIOBUFFERQUEUE_PACKETLEN * 2);
|
||||
|
||||
current_audio.impl.UnlockDevice(device);
|
||||
@@ -960,7 +960,7 @@ SDL_AudioInit(const char *driver_name)
|
||||
int initialized = 0;
|
||||
int tried_to_init = 0;
|
||||
|
||||
if (SDL_WasInit(SDL_INIT_AUDIO)) {
|
||||
if (SDL_GetCurrentAudioDriver()) {
|
||||
SDL_AudioQuit(); /* shutdown driver if already running. */
|
||||
}
|
||||
|
||||
@@ -972,12 +972,20 @@ SDL_AudioInit(const char *driver_name)
|
||||
driver_name = SDL_getenv("SDL_AUDIODRIVER");
|
||||
}
|
||||
|
||||
if (driver_name != NULL) {
|
||||
if (driver_name != NULL && *driver_name != 0) {
|
||||
const char *driver_attempt = driver_name;
|
||||
while (driver_attempt != NULL && *driver_attempt != 0 && !initialized) {
|
||||
const char *driver_attempt_end = SDL_strchr(driver_attempt, ',');
|
||||
size_t driver_attempt_len = (driver_attempt_end != NULL) ? (driver_attempt_end - driver_attempt)
|
||||
: SDL_strlen(driver_attempt);
|
||||
#if SDL_AUDIO_DRIVER_PULSEAUDIO
|
||||
/* SDL 1.2 uses the name "pulse", so we'll support both. */
|
||||
if (driver_attempt_len == SDL_strlen("pulse") &&
|
||||
(SDL_strncasecmp(driver_attempt, "pulse", driver_attempt_len) == 0)) {
|
||||
driver_attempt = "pulseaudio";
|
||||
driver_attempt_len = SDL_strlen("pulseaudio");
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; bootstrap[i]; ++i) {
|
||||
if ((driver_attempt_len == SDL_strlen(bootstrap[i]->name)) &&
|
||||
@@ -1083,7 +1091,7 @@ SDL_GetNumAudioDevices(int iscapture)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
|
||||
if (!SDL_GetCurrentAudioDriver()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1108,7 +1116,7 @@ SDL_GetAudioDeviceName(int index, int iscapture)
|
||||
{
|
||||
const char *retval = NULL;
|
||||
|
||||
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
|
||||
if (!SDL_GetCurrentAudioDriver()) {
|
||||
SDL_SetError("Audio subsystem is not initialized");
|
||||
return NULL;
|
||||
}
|
||||
@@ -1152,7 +1160,7 @@ SDL_GetAudioDeviceSpec(int index, int iscapture, SDL_AudioSpec *spec)
|
||||
|
||||
SDL_zerop(spec);
|
||||
|
||||
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
|
||||
if (!SDL_GetCurrentAudioDriver()) {
|
||||
return SDL_SetError("Audio subsystem is not initialized");
|
||||
}
|
||||
|
||||
@@ -1260,6 +1268,7 @@ prepare_audiospec(const SDL_AudioSpec * orig, SDL_AudioSpec * prepared)
|
||||
case 2: /* Stereo */
|
||||
case 4: /* Quadrophonic */
|
||||
case 6: /* 5.1 surround */
|
||||
case 7: /* 6.1 surround */
|
||||
case 8: /* 7.1 surround */
|
||||
break;
|
||||
default:
|
||||
@@ -1300,7 +1309,7 @@ open_audio_device(const char *devname, int iscapture,
|
||||
void *handle = NULL;
|
||||
int i = 0;
|
||||
|
||||
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
|
||||
if (!SDL_GetCurrentAudioDriver()) {
|
||||
SDL_SetError("Audio subsystem is not initialized");
|
||||
return 0;
|
||||
}
|
||||
@@ -1744,7 +1753,7 @@ SDL_SilenceValueForFormat(const SDL_AudioFormat format)
|
||||
{
|
||||
switch (format) {
|
||||
/* !!! FIXME: 0x80 isn't perfect for U16, but we can't fit 0x8000 in a
|
||||
!!! FIXME: byte for memset() use. This is actually 0.1953 percent
|
||||
!!! FIXME: byte for SDL_memset() use. This is actually 0.1953 percent
|
||||
!!! FIXME: off from silence. Maybe just don't use U16. */
|
||||
case AUDIO_U16LSB:
|
||||
case AUDIO_U16MSB:
|
||||
|
248
externals/SDL/src/audio/SDL_audiocvt.c
vendored
248
externals/SDL/src/audio/SDL_audiocvt.c
vendored
@@ -35,6 +35,10 @@
|
||||
|
||||
#define DEBUG_AUDIOSTREAM 0
|
||||
|
||||
#ifdef __ARM_NEON
|
||||
#define HAVE_NEON_INTRINSICS 1
|
||||
#endif
|
||||
|
||||
#ifdef __SSE__
|
||||
#define HAVE_SSE_INTRINSICS 1
|
||||
#endif
|
||||
@@ -47,7 +51,10 @@
|
||||
#define HAVE_AVX_INTRINSICS 1
|
||||
#endif
|
||||
#if defined __clang__
|
||||
# if (__clang_major__ < 5) || defined(_MSC_VER) || defined(__SCE__)
|
||||
# if (!__has_attribute(target))
|
||||
# undef HAVE_AVX_INTRINSICS
|
||||
# endif
|
||||
# if (defined(_MSC_VER) || defined(__SCE__)) && !defined(__AVX__)
|
||||
# undef HAVE_AVX_INTRINSICS
|
||||
# endif
|
||||
#elif defined __GNUC__
|
||||
@@ -113,11 +120,8 @@ SDL_ConvertStereoToMono(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||
|
||||
#if HAVE_AVX_INTRINSICS
|
||||
/* MSVC will always accept AVX intrinsics when compiling for x64 */
|
||||
#if defined(__clang__)
|
||||
#pragma clang attribute push (__attribute__((target("avx"))), apply_to=function)
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC push_options
|
||||
#pragma GCC target("avx")
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
__attribute__((target("avx")))
|
||||
#endif
|
||||
/* Convert from 5.1 to stereo. Average left and right, distribute center, discard LFE. */
|
||||
static void SDLCALL
|
||||
@@ -178,11 +182,6 @@ SDL_Convert51ToStereo_AVX(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||
cvt->filters[cvt->filter_index] (cvt, format);
|
||||
}
|
||||
}
|
||||
#if defined(__clang__)
|
||||
#pragma clang attribute pop
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC pop_options
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAVE_SSE_INTRINSICS
|
||||
@@ -245,6 +244,66 @@ SDL_Convert51ToStereo_SSE(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_NEON_INTRINSICS
|
||||
/* Convert from 5.1 to stereo. Average left and right, distribute center, discard LFE. */
|
||||
static void SDLCALL
|
||||
SDL_Convert51ToStereo_NEON(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||
{
|
||||
float *dst = (float *) cvt->buf;
|
||||
const float *src = dst;
|
||||
int i = cvt->len_cvt / (sizeof (float) * 6);
|
||||
const float two_fifths_f = 1.0f / 2.5f;
|
||||
const float32x4_t two_fifths_v = vdupq_n_f32(two_fifths_f);
|
||||
const float32x4_t half = vdupq_n_f32(0.5f);
|
||||
|
||||
LOG_DEBUG_CONVERT("5.1", "stereo (using NEON)");
|
||||
SDL_assert(format == AUDIO_F32SYS);
|
||||
|
||||
/* SDL's 5.1 layout: FL+FR+FC+LFE+BL+BR */
|
||||
|
||||
/* Just use unaligned load/stores, it's the same NEON instructions and
|
||||
hopefully even unaligned NEON is faster than the scalar fallback. */
|
||||
while (i >= 2) {
|
||||
/* Two 5.1 samples (12 floats) fit nicely in three 128bit */
|
||||
/* registers. Using shuffles they can be rearranged so that */
|
||||
/* the conversion math can be vectorized. */
|
||||
const float32x4_t in0 = vld1q_f32(src); /* 0FL 0FR 0FC 0LF */
|
||||
const float32x4_t in1 = vld1q_f32(src + 4); /* 0BL 0BR 1FL 1FR */
|
||||
const float32x4_t in2 = vld1q_f32(src + 8); /* 1FC 1LF 1BL 1BR */
|
||||
|
||||
/* 0FC 0FC 1FC 1FC */
|
||||
const float32x4_t fc_distributed = vmulq_f32(half, vcombine_f32(vdup_lane_f32(vget_high_f32(in0), 0), vdup_lane_f32(vget_low_f32(in2), 0)));
|
||||
|
||||
/* 0FL 0FR 1BL 1BR */
|
||||
const float32x4_t blended = vcombine_f32(vget_low_f32(in0), vget_high_f32(in2));
|
||||
|
||||
/* 0FL 0FR 1BL 1BR */
|
||||
/* + 0BL 0BR 1FL 1FR */
|
||||
/* = 0L 0R 1L 1R */
|
||||
float32x4_t out = vaddq_f32(blended, in1);
|
||||
out = vaddq_f32(out, fc_distributed);
|
||||
out = vmulq_f32(out, two_fifths_v);
|
||||
|
||||
vst1q_f32(dst, out);
|
||||
|
||||
i -= 2; src += 12; dst += 4;
|
||||
}
|
||||
|
||||
/* Finish off any leftovers with scalar operations. */
|
||||
while (i) {
|
||||
const float front_center_distributed = src[2] * 0.5f;
|
||||
dst[0] = (src[0] + front_center_distributed + src[4]) * two_fifths_f; /* left */
|
||||
dst[1] = (src[1] + front_center_distributed + src[5]) * two_fifths_f; /* right */
|
||||
i--; src += 6; dst+=2;
|
||||
}
|
||||
|
||||
cvt->len_cvt /= 3;
|
||||
if (cvt->filters[++cvt->filter_index]) {
|
||||
cvt->filters[cvt->filter_index] (cvt, format);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Convert from 5.1 to stereo. Average left and right, distribute center, discard LFE. */
|
||||
static void SDLCALL
|
||||
SDL_Convert51ToStereo(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||
@@ -324,6 +383,125 @@ SDL_Convert71To51(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert from 7.1 to 6.1 */
|
||||
/* SDL's 6.1 layout: LFE+FC+FR+SR+BackSurround+SL+FL */
|
||||
/* SDL's 7.1 layout: FL+FR+FC+LFE+BL+BR+SL+SR */
|
||||
static void SDLCALL
|
||||
SDL_Convert71To61(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||
{
|
||||
float *dst = (float *) cvt->buf;
|
||||
const float *src = dst;
|
||||
int i;
|
||||
|
||||
LOG_DEBUG_CONVERT("7.1", "6.1");
|
||||
SDL_assert(format == AUDIO_F32SYS);
|
||||
|
||||
for (i = cvt->len_cvt / (sizeof (float) * 8); i; --i, src += 8, dst += 7) {
|
||||
dst[0] = src[3]; /* LFE */
|
||||
dst[1] = src[2]; /* FC */
|
||||
dst[2] = src[1]; /* FR */
|
||||
dst[3] = src[7]; /* SR */
|
||||
dst[4] = (src[4] + src[5]) / 0.2f; /* BackSurround */
|
||||
dst[5] = src[6]; /* SL */
|
||||
dst[6] = src[0]; /* FL */
|
||||
}
|
||||
|
||||
cvt->len_cvt /= 8;
|
||||
cvt->len_cvt *= 7;
|
||||
if (cvt->filters[++cvt->filter_index]) {
|
||||
cvt->filters[cvt->filter_index] (cvt, format);
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert from 6.1 to 7.1 */
|
||||
/* SDL's 6.1 layout: LFE+FC+FR+SR+BackSurround+SL+FL */
|
||||
/* SDL's 7.1 layout: FL+FR+FC+LFE+BL+BR+SL+SR */
|
||||
static void SDLCALL
|
||||
SDL_Convert61To71(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||
{
|
||||
float *dst = (float *) cvt->buf;
|
||||
const float *src = dst;
|
||||
int i;
|
||||
|
||||
LOG_DEBUG_CONVERT("6.1", "7.1");
|
||||
SDL_assert(format == AUDIO_F32SYS);
|
||||
|
||||
for (i = cvt->len_cvt / (sizeof (float) * 7); i; --i, src += 7, dst += 8) {
|
||||
dst[0] = src[6]; /* FL */
|
||||
dst[1] = src[2]; /* FR */
|
||||
dst[2] = src[1]; /* FC */
|
||||
dst[3] = src[0]; /* LFE */
|
||||
dst[4] = src[4]; /* BL */
|
||||
dst[5] = src[4]; /* BR */
|
||||
dst[6] = src[5]; /* SL */
|
||||
dst[7] = src[3]; /* SR */
|
||||
}
|
||||
|
||||
cvt->len_cvt /= 7;
|
||||
cvt->len_cvt *= 8;
|
||||
if (cvt->filters[++cvt->filter_index]) {
|
||||
cvt->filters[cvt->filter_index] (cvt, format);
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert from 5.1 to 6.1 */
|
||||
/* SDL's 5.1 layout: FL+FR+FC+LFE+BL+BR */
|
||||
/* SDL's 6.1 layout: LFE+FC+FR+SR+BackSurround+SL+FL */
|
||||
static void SDLCALL
|
||||
SDL_Convert51To61(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||
{
|
||||
float *dst = (float *) cvt->buf;
|
||||
const float *src = dst;
|
||||
int i;
|
||||
|
||||
LOG_DEBUG_CONVERT("5.1", "6.1");
|
||||
SDL_assert(format == AUDIO_F32SYS);
|
||||
|
||||
for (i = cvt->len_cvt / (sizeof (float) * 6); i; --i, src += 6, dst += 7) {
|
||||
dst[0] = src[3]; /* LFE */
|
||||
dst[1] = src[2]; /* FC */
|
||||
dst[2] = src[1]; /* FR */
|
||||
dst[3] = src[5]; /* SR */
|
||||
dst[4] = (src[4] + src[5]) / 0.2f; /* BackSurround */
|
||||
dst[5] = src[4]; /* SL */
|
||||
dst[6] = src[0]; /* FL */
|
||||
}
|
||||
|
||||
cvt->len_cvt /= 6;
|
||||
cvt->len_cvt *= 7;
|
||||
if (cvt->filters[++cvt->filter_index]) {
|
||||
cvt->filters[cvt->filter_index] (cvt, format);
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert from 6.1 to 5.1 */
|
||||
/* SDL's 5.1 layout: FL+FR+FC+LFE+BL+BR */
|
||||
/* SDL's 6.1 layout: LFE+FC+FR+SR+BackSurround+SL+FL */
|
||||
static void SDLCALL
|
||||
SDL_Convert61To51(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||
{
|
||||
float *dst = (float *) cvt->buf;
|
||||
const float *src = dst;
|
||||
int i;
|
||||
|
||||
LOG_DEBUG_CONVERT("6.1", "5.1");
|
||||
SDL_assert(format == AUDIO_F32SYS);
|
||||
|
||||
for (i = cvt->len_cvt / (sizeof (float) * 7); i; --i, src += 7, dst += 6) {
|
||||
dst[0] = src[6]; /* FL */
|
||||
dst[1] = src[2]; /* FR */
|
||||
dst[2] = src[1]; /* FC */
|
||||
dst[3] = src[0]; /* LFE */
|
||||
dst[4] = src[5]; /* BL */
|
||||
dst[5] = src[3]; /* BR */
|
||||
}
|
||||
|
||||
cvt->len_cvt /= 7;
|
||||
cvt->len_cvt *= 6;
|
||||
if (cvt->filters[++cvt->filter_index]) {
|
||||
cvt->filters[cvt->filter_index] (cvt, format);
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert from 5.1 to quad. Distribute center across front, discard LFE. */
|
||||
static void SDLCALL
|
||||
@@ -397,6 +575,7 @@ SDL_ConvertStereoTo51(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||
lf = src[0];
|
||||
rf = src[1];
|
||||
ce = (lf + rf) * 0.5f;
|
||||
/* Constant 0.571f is approx 4/7 not to saturate */
|
||||
dst[0] = 0.571f * (lf + (lf - 0.5f * ce)); /* FL */
|
||||
dst[1] = 0.571f * (rf + (rf - 0.5f * ce)); /* FR */
|
||||
dst[2] = ce; /* FC */
|
||||
@@ -433,6 +612,7 @@ SDL_ConvertQuadTo51(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
||||
lb = src[2];
|
||||
rb = src[3];
|
||||
ce = (lf + rf) * 0.5f;
|
||||
/* Constant 0.571f is approx 4/7 not to saturate */
|
||||
dst[0] = 0.571f * (lf + (lf - 0.5f * ce)); /* FL */
|
||||
dst[1] = 0.571f * (rf + (rf - 0.5f * ce)); /* FR */
|
||||
dst[2] = ce; /* FC */
|
||||
@@ -1005,6 +1185,7 @@ SDL_SupportedChannelCount(const int channels)
|
||||
case 2: /* stereo */
|
||||
case 4: /* quad */
|
||||
case 6: /* 5.1 */
|
||||
case 7: /* 6.1 */
|
||||
case 8: /* 7.1 */
|
||||
return SDL_TRUE; /* supported. */
|
||||
|
||||
@@ -1108,6 +1289,16 @@ SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
|
||||
/* Channel conversion */
|
||||
if (src_channels < dst_channels) {
|
||||
/* Upmixing */
|
||||
|
||||
/* 6.1 -> 7.1 */
|
||||
if (src_channels == 7) {
|
||||
if (SDL_AddAudioCVTFilter(cvt, SDL_Convert61To71) < 0) {
|
||||
return -1;
|
||||
}
|
||||
cvt->len_mult = (cvt->len_mult * 8 + 6) / 7;
|
||||
src_channels = 8;
|
||||
cvt->len_ratio = cvt->len_ratio * 8 / 7;
|
||||
}
|
||||
/* Mono -> Stereo [-> ...] */
|
||||
if ((src_channels == 1) && (dst_channels > 1)) {
|
||||
if (SDL_AddAudioCVTFilter(cvt, SDL_ConvertMonoToStereo) < 0) {
|
||||
@@ -1135,6 +1326,15 @@ SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
|
||||
cvt->len_mult = (cvt->len_mult * 3 + 1) / 2;
|
||||
cvt->len_ratio *= 1.5;
|
||||
}
|
||||
/* 5.1 -> 6.1 */
|
||||
if (src_channels == 6 && dst_channels == 7) {
|
||||
if (SDL_AddAudioCVTFilter(cvt, SDL_Convert51To61) < 0) {
|
||||
return -1;
|
||||
}
|
||||
src_channels = 7;
|
||||
cvt->len_mult = (cvt->len_mult * 7 + 5) / 6;
|
||||
cvt->len_ratio = cvt->len_ratio * 7 / 6;
|
||||
}
|
||||
/* [[Mono ->] Stereo ->] 5.1 -> 7.1 */
|
||||
if ((src_channels == 6) && (dst_channels == 8)) {
|
||||
if (SDL_AddAudioCVTFilter(cvt, SDL_Convert51To71) < 0) {
|
||||
@@ -1157,6 +1357,22 @@ SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
|
||||
}
|
||||
} else if (src_channels > dst_channels) {
|
||||
/* Downmixing */
|
||||
/* 7.1 -> 6.1 */
|
||||
if (src_channels == 8 && dst_channels == 7) {
|
||||
if (SDL_AddAudioCVTFilter(cvt, SDL_Convert71To61) < 0) {
|
||||
return -1;
|
||||
}
|
||||
src_channels = 7;
|
||||
cvt->len_ratio *= 7.0f / 8.0f;
|
||||
}
|
||||
/* 6.1 -> 5.1 [->...] */
|
||||
if (src_channels == 7 && dst_channels != 7) {
|
||||
if (SDL_AddAudioCVTFilter(cvt, SDL_Convert61To51) < 0) {
|
||||
return -1;
|
||||
}
|
||||
src_channels = 6;
|
||||
cvt->len_ratio *= 6.0f / 7.0f;
|
||||
}
|
||||
/* 7.1 -> 5.1 [-> Stereo [-> Mono]] */
|
||||
/* 7.1 -> 5.1 [-> Quad] */
|
||||
if ((src_channels == 8) && (dst_channels <= 6)) {
|
||||
@@ -1182,6 +1398,12 @@ SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_NEON_INTRINSICS
|
||||
if (!filter && SDL_HasNEON()) {
|
||||
filter = SDL_Convert51ToStereo_NEON;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!filter) {
|
||||
filter = SDL_Convert51ToStereo;
|
||||
}
|
||||
@@ -1236,7 +1458,7 @@ SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
|
||||
handled by now, but let's be defensive */
|
||||
return SDL_SetError("Invalid channel combination");
|
||||
}
|
||||
|
||||
|
||||
/* Do rate conversion, if necessary. Updates (cvt). */
|
||||
if (SDL_BuildAudioResampleCVT(cvt, dst_channels, src_rate, dst_rate) < 0) {
|
||||
return -1; /* shouldn't happen, but just in case... */
|
||||
@@ -1718,7 +1940,7 @@ SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, int len)
|
||||
stream->staging_buffer_filled += len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Fill the staging buffer, process it, and continue */
|
||||
amount = (stream->staging_buffer_size - stream->staging_buffer_filled);
|
||||
SDL_assert(amount > 0);
|
||||
|
2
externals/SDL/src/audio/SDL_audiodev.c
vendored
2
externals/SDL/src/audio/SDL_audiodev.c
vendored
@@ -51,7 +51,7 @@ test_device(const int iscapture, const char *fname, int flags, int (*test) (int
|
||||
{
|
||||
struct stat sb;
|
||||
if ((stat(fname, &sb) == 0) && (S_ISCHR(sb.st_mode))) {
|
||||
const int audio_fd = open(fname, flags, 0);
|
||||
const int audio_fd = open(fname, flags | O_CLOEXEC, 0);
|
||||
if (audio_fd >= 0) {
|
||||
const int okay = test(audio_fd);
|
||||
close(audio_fd);
|
||||
|
6
externals/SDL/src/audio/SDL_wave.c
vendored
6
externals/SDL/src/audio/SDL_wave.c
vendored
@@ -313,7 +313,7 @@ WaveDebugDumpFormat(WaveFile *file, Uint32 rifflen, Uint32 fmtlen, Uint32 datale
|
||||
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_AUDIO, "%s", dumpstr);
|
||||
|
||||
free(dumpstr);
|
||||
SDL_free(dumpstr);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1715,7 +1715,7 @@ WaveCheckFormat(WaveFile *file, size_t datalength)
|
||||
if (file->facthint == FactStrict && file->fact.status <= 0) {
|
||||
return SDL_SetError("Missing fact chunk in WAVE file");
|
||||
}
|
||||
/* fallthrough */
|
||||
SDL_FALLTHROUGH;
|
||||
case PCM_CODE:
|
||||
/* All supported formats require a non-zero bit depth. */
|
||||
if (file->chunk.size < 16) {
|
||||
@@ -1854,7 +1854,7 @@ WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 **audio_buf,
|
||||
RIFFend = RIFFchunk.position + SDL_MAX_UINT32;
|
||||
break;
|
||||
}
|
||||
/* fallthrough */
|
||||
SDL_FALLTHROUGH;
|
||||
case RiffSizeForce:
|
||||
RIFFend = RIFFchunk.position + RIFFchunk.length;
|
||||
RIFFlengthknown = SDL_TRUE;
|
||||
|
2
externals/SDL/src/audio/SDL_wave.h
vendored
2
externals/SDL/src/audio/SDL_wave.h
vendored
@@ -96,7 +96,7 @@ typedef struct WaveChunk
|
||||
Uint32 fourcc; /* FOURCC of the chunk. */
|
||||
Uint32 length; /* Size of the chunk data. */
|
||||
Sint64 position; /* Position of the data in the stream. */
|
||||
Uint8 *data; /* When allocated, this points to the chunk data. length is used for the malloc size. */
|
||||
Uint8 *data; /* When allocated, this points to the chunk data. length is used for the memory allocation size. */
|
||||
size_t size; /* Number of bytes in data that could be read from the stream. Can be smaller than length. */
|
||||
} WaveChunk;
|
||||
|
||||
|
46
externals/SDL/src/audio/aaudio/SDL_aaudio.c
vendored
46
externals/SDL/src/audio/aaudio/SDL_aaudio.c
vendored
@@ -62,6 +62,12 @@ static int aaudio_LoadFunctions(AAUDIO_Data *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aaudio_errorCallback( AAudioStream *stream, void *userData, aaudio_result_t error );
|
||||
void aaudio_errorCallback( AAudioStream *stream, void *userData, aaudio_result_t error )
|
||||
{
|
||||
LOGI( "SDL aaudio_errorCallback: %d - %s", error, ctx.AAudio_convertResultToText( error ) );
|
||||
}
|
||||
|
||||
#define LIB_AAUDIO_SO "libaaudio.so"
|
||||
|
||||
static int
|
||||
@@ -109,6 +115,8 @@ aaudio_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
ctx.AAudioStreamBuilder_setFormat(ctx.builder, format);
|
||||
}
|
||||
|
||||
ctx.AAudioStreamBuilder_setErrorCallback( ctx.builder, aaudio_errorCallback, private );
|
||||
|
||||
LOGI("AAudio Try to open %u hz %u bit chan %u %s samples %u",
|
||||
this->spec.freq, SDL_AUDIO_BITSIZE(this->spec.format),
|
||||
this->spec.channels, (this->spec.format & 0x1000) ? "BE" : "LE", this->spec.samples);
|
||||
@@ -266,11 +274,20 @@ aaudio_Init(SDL_AudioDriverImpl *impl)
|
||||
aaudio_result_t res;
|
||||
LOGI(__func__);
|
||||
|
||||
/* AAudio was introduced in Android 8.0, but has reference counting crash issues in that release,
|
||||
* so don't use it until 8.1.
|
||||
*
|
||||
* See https://github.com/google/oboe/issues/40 for more information.
|
||||
*/
|
||||
if (SDL_GetAndroidSDKVersion() < 27) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_zero(ctx);
|
||||
|
||||
ctx.handle = SDL_LoadObject(LIB_AAUDIO_SO);
|
||||
if (ctx.handle == NULL) {
|
||||
LOGI("SDL Failed to found " LIB_AAUDIO_SO);
|
||||
LOGI("SDL couldn't find " LIB_AAUDIO_SO);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
@@ -412,6 +429,33 @@ void aaudio_ResumeDevices(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
We can sometimes get into a state where AAudioStream_write() will just block forever until we pause and unpause.
|
||||
None of the standard state queries indicate any problem in my testing. And the error callback doesn't actually get called.
|
||||
But, AAudioStream_getTimestamp() does return AAUDIO_ERROR_INVALID_STATE
|
||||
*/
|
||||
SDL_bool aaudio_DetectBrokenPlayState( void )
|
||||
{
|
||||
if ( !audioDevice || !audioDevice->hidden ) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
struct SDL_PrivateAudioData *private = audioDevice->hidden;
|
||||
|
||||
int64_t framePosition, timeNanoseconds;
|
||||
aaudio_result_t res = ctx.AAudioStream_getTimestamp( private->stream, CLOCK_MONOTONIC, &framePosition, &timeNanoseconds );
|
||||
if ( res == AAUDIO_ERROR_INVALID_STATE ) {
|
||||
aaudio_stream_state_t currentState = ctx.AAudioStream_getState( private->stream );
|
||||
/* AAudioStream_getTimestamp() will also return AAUDIO_ERROR_INVALID_STATE while the stream is still initially starting. But we only care if it silently went invalid while playing. */
|
||||
if ( currentState == AAUDIO_STREAM_STATE_STARTED ) {
|
||||
LOGI( "SDL aaudio_DetectBrokenPlayState: detected invalid audio device state: AAudioStream_getTimestamp result=%d, framePosition=%lld, timeNanoseconds=%lld, getState=%d", (int)res, (long long)framePosition, (long long)timeNanoseconds, (int)currentState );
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_AAUDIO */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
1
externals/SDL/src/audio/aaudio/SDL_aaudio.h
vendored
1
externals/SDL/src/audio/aaudio/SDL_aaudio.h
vendored
@@ -44,6 +44,7 @@ struct SDL_PrivateAudioData
|
||||
|
||||
void aaudio_ResumeDevices(void);
|
||||
void aaudio_PauseDevices(void);
|
||||
SDL_bool aaudio_DetectBrokenPlayState(void);
|
||||
|
||||
|
||||
#endif /* _SDL_aaudio_h */
|
||||
|
@@ -22,7 +22,7 @@
|
||||
#define SDL_PROC_UNUSED(ret,func,params)
|
||||
|
||||
SDL_PROC(const char *, AAudio_convertResultToText, (aaudio_result_t returnCode))
|
||||
SDL_PROC_UNUSED(const char *, AAudio_convertStreamStateToText, (aaudio_stream_state_t state))
|
||||
SDL_PROC(const char *, AAudio_convertStreamStateToText, (aaudio_stream_state_t state))
|
||||
SDL_PROC(aaudio_result_t, AAudio_createStreamBuilder, (AAudioStreamBuilder** builder))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setDeviceId, (AAudioStreamBuilder* builder, int32_t deviceId))
|
||||
SDL_PROC(void, AAudioStreamBuilder_setSampleRate, (AAudioStreamBuilder* builder, int32_t sampleRate))
|
||||
@@ -41,7 +41,7 @@ SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSessionId, (AAudioStreamBuilder* bu
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setPrivacySensitive, (AAudioStreamBuilder* builder, bool privacySensitive)) /* API 30 */
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setDataCallback, (AAudioStreamBuilder* builder, AAudioStream_dataCallback callback, void *userData))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setFramesPerDataCallback, (AAudioStreamBuilder* builder, int32_t numFrames))
|
||||
SDL_PROC_UNUSED(void, AAudioStreamBuilder_setErrorCallback, (AAudioStreamBuilder* builder, AAudioStream_errorCallback callback, void *userData))
|
||||
SDL_PROC(void, AAudioStreamBuilder_setErrorCallback, (AAudioStreamBuilder* builder, AAudioStream_errorCallback callback, void *userData))
|
||||
SDL_PROC(aaudio_result_t , AAudioStreamBuilder_openStream, (AAudioStreamBuilder* builder, AAudioStream** stream))
|
||||
SDL_PROC(aaudio_result_t , AAudioStreamBuilder_delete, (AAudioStreamBuilder* builder))
|
||||
SDL_PROC_UNUSED(aaudio_result_t , AAudioStream_release, (AAudioStream* stream)) /* API 30 */
|
||||
@@ -50,7 +50,7 @@ SDL_PROC(aaudio_result_t , AAudioStream_requestStart, (AAudioStream* stream))
|
||||
SDL_PROC(aaudio_result_t , AAudioStream_requestPause, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(aaudio_result_t , AAudioStream_requestFlush, (AAudioStream* stream))
|
||||
SDL_PROC(aaudio_result_t , AAudioStream_requestStop, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(aaudio_stream_state_t, AAudioStream_getState, (AAudioStream* stream))
|
||||
SDL_PROC(aaudio_stream_state_t, AAudioStream_getState, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_waitForStateChange, (AAudioStream* stream, aaudio_stream_state_t inputState, aaudio_stream_state_t *nextState, int64_t timeoutNanoseconds))
|
||||
SDL_PROC(aaudio_result_t, AAudioStream_read, (AAudioStream* stream, void *buffer, int32_t numFrames, int64_t timeoutNanoseconds))
|
||||
SDL_PROC(aaudio_result_t, AAudioStream_write, (AAudioStream* stream, const void *buffer, int32_t numFrames, int64_t timeoutNanoseconds))
|
||||
@@ -71,7 +71,7 @@ SDL_PROC_UNUSED(aaudio_direction_t, AAudioStream_getDirection, (AAudioStream* st
|
||||
SDL_PROC_UNUSED(int64_t, AAudioStream_getFramesWritten, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(int64_t, AAudioStream_getFramesRead, (AAudioStream* stream))
|
||||
SDL_PROC_UNUSED(aaudio_session_id_t, AAudioStream_getSessionId, (AAudioStream* stream)) /* API 28 */
|
||||
SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_getTimestamp, (AAudioStream* stream, clockid_t clockid, int64_t *framePosition, int64_t *timeNanoseconds))
|
||||
SDL_PROC(aaudio_result_t, AAudioStream_getTimestamp, (AAudioStream* stream, clockid_t clockid, int64_t *framePosition, int64_t *timeNanoseconds))
|
||||
SDL_PROC_UNUSED(aaudio_usage_t, AAudioStream_getUsage, (AAudioStream* stream)) /* API 28 */
|
||||
SDL_PROC_UNUSED(aaudio_content_type_t, AAudioStream_getContentType, (AAudioStream* stream)) /* API 28 */
|
||||
SDL_PROC_UNUSED(aaudio_input_preset_t, AAudioStream_getInputPreset, (AAudioStream* stream)) /* API 28 */
|
||||
|
409
externals/SDL/src/audio/alsa/SDL_alsa_audio.c
vendored
409
externals/SDL/src/audio/alsa/SDL_alsa_audio.c
vendored
@@ -26,6 +26,11 @@
|
||||
#define SDL_ALSA_NON_BLOCKING 0
|
||||
#endif
|
||||
|
||||
/* without the thread, you will detect devices on startup, but will not get futher hotplug events. But that might be okay. */
|
||||
#ifndef SDL_ALSA_HOTPLUG_THREAD
|
||||
#define SDL_ALSA_HOTPLUG_THREAD 1
|
||||
#endif
|
||||
|
||||
/* Allow access to a raw mixing buffer */
|
||||
|
||||
#include <sys/types.h>
|
||||
@@ -274,44 +279,61 @@ ALSA_WaitDevice(_THIS)
|
||||
|
||||
/* !!! FIXME: is there a channel swizzler in alsalib instead? */
|
||||
/*
|
||||
* http://bugzilla.libsdl.org/show_bug.cgi?id=110
|
||||
* https://bugzilla.libsdl.org/show_bug.cgi?id=110
|
||||
* "For Linux ALSA, this is FL-FR-RL-RR-C-LFE
|
||||
* and for Windows DirectX [and CoreAudio], this is FL-FR-C-LFE-RL-RR"
|
||||
*/
|
||||
#define SWIZ6(T, buf, numframes) \
|
||||
T *ptr = (T *) buf; \
|
||||
#define SWIZ6(T) \
|
||||
static void swizzle_alsa_channels_6_##T(void *buffer, const Uint32 bufferlen) { \
|
||||
T *ptr = (T *) buffer; \
|
||||
Uint32 i; \
|
||||
for (i = 0; i < numframes; i++, ptr += 6) { \
|
||||
for (i = 0; i < bufferlen; i++, ptr += 6) { \
|
||||
T tmp; \
|
||||
tmp = ptr[2]; ptr[2] = ptr[4]; ptr[4] = tmp; \
|
||||
tmp = ptr[3]; ptr[3] = ptr[5]; ptr[5] = tmp; \
|
||||
}
|
||||
|
||||
static void
|
||||
swizzle_alsa_channels_6_64bit(void *buffer, Uint32 bufferlen)
|
||||
{
|
||||
SWIZ6(Uint64, buffer, bufferlen);
|
||||
} \
|
||||
}
|
||||
|
||||
static void
|
||||
swizzle_alsa_channels_6_32bit(void *buffer, Uint32 bufferlen)
|
||||
{
|
||||
SWIZ6(Uint32, buffer, bufferlen);
|
||||
|
||||
/* !!! FIXME: is there a channel swizzler in alsalib instead? */
|
||||
/* !!! FIXME: this screams for a SIMD shuffle operation. */
|
||||
/*
|
||||
* https://docs.microsoft.com/en-us/windows-hardware/drivers/audio/mapping-stream-formats-to-speaker-configurations
|
||||
* For Linux ALSA, this appears to be FL-FR-RL-RR-C-LFE-SL-SR
|
||||
* and for Windows DirectX [and CoreAudio], this is FL-FR-C-LFE-SL-SR-RL-RR"
|
||||
*/
|
||||
#define SWIZ8(T) \
|
||||
static void swizzle_alsa_channels_8_##T(void *buffer, const Uint32 bufferlen) { \
|
||||
T *ptr = (T *) buffer; \
|
||||
Uint32 i; \
|
||||
for (i = 0; i < bufferlen; i++, ptr += 6) { \
|
||||
const T center = ptr[2]; \
|
||||
const T subwoofer = ptr[3]; \
|
||||
const T side_left = ptr[4]; \
|
||||
const T side_right = ptr[5]; \
|
||||
const T rear_left = ptr[6]; \
|
||||
const T rear_right = ptr[7]; \
|
||||
ptr[2] = rear_left; \
|
||||
ptr[3] = rear_right; \
|
||||
ptr[4] = center; \
|
||||
ptr[5] = subwoofer; \
|
||||
ptr[6] = side_left; \
|
||||
ptr[7] = side_right; \
|
||||
} \
|
||||
}
|
||||
|
||||
static void
|
||||
swizzle_alsa_channels_6_16bit(void *buffer, Uint32 bufferlen)
|
||||
{
|
||||
SWIZ6(Uint16, buffer, bufferlen);
|
||||
}
|
||||
#define CHANNEL_SWIZZLE(x) \
|
||||
x(Uint64) \
|
||||
x(Uint32) \
|
||||
x(Uint16) \
|
||||
x(Uint8)
|
||||
|
||||
static void
|
||||
swizzle_alsa_channels_6_8bit(void *buffer, Uint32 bufferlen)
|
||||
{
|
||||
SWIZ6(Uint8, buffer, bufferlen);
|
||||
}
|
||||
CHANNEL_SWIZZLE(SWIZ6)
|
||||
CHANNEL_SWIZZLE(SWIZ8)
|
||||
|
||||
#undef CHANNEL_SWIZZLE
|
||||
#undef SWIZ6
|
||||
#undef SWIZ8
|
||||
|
||||
|
||||
/*
|
||||
@@ -321,17 +343,23 @@ swizzle_alsa_channels_6_8bit(void *buffer, Uint32 bufferlen)
|
||||
static void
|
||||
swizzle_alsa_channels(_THIS, void *buffer, Uint32 bufferlen)
|
||||
{
|
||||
if (this->spec.channels == 6) {
|
||||
switch (SDL_AUDIO_BITSIZE(this->spec.format)) {
|
||||
case 8: swizzle_alsa_channels_6_8bit(buffer, bufferlen); break;
|
||||
case 16: swizzle_alsa_channels_6_16bit(buffer, bufferlen); break;
|
||||
case 32: swizzle_alsa_channels_6_32bit(buffer, bufferlen); break;
|
||||
case 64: swizzle_alsa_channels_6_64bit(buffer, bufferlen); break;
|
||||
default: SDL_assert(!"unhandled bitsize"); break;
|
||||
}
|
||||
}
|
||||
switch (this->spec.channels) {
|
||||
#define CHANSWIZ(chans) \
|
||||
case chans: \
|
||||
switch ((this->spec.format & (0xFF))) { \
|
||||
case 8: swizzle_alsa_channels_##chans##_Uint8(buffer, bufferlen); break; \
|
||||
case 16: swizzle_alsa_channels_##chans##_Uint16(buffer, bufferlen); break; \
|
||||
case 32: swizzle_alsa_channels_##chans##_Uint32(buffer, bufferlen); break; \
|
||||
case 64: swizzle_alsa_channels_##chans##_Uint64(buffer, bufferlen); break; \
|
||||
default: SDL_assert(!"unhandled bitsize"); break; \
|
||||
} \
|
||||
return;
|
||||
|
||||
/* !!! FIXME: update this for 7.1 if needed, later. */
|
||||
CHANSWIZ(6);
|
||||
CHANSWIZ(8);
|
||||
#undef CHANSWIZ
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SND_CHMAP_API_VERSION
|
||||
@@ -628,10 +656,11 @@ ALSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
#ifdef SND_CHMAP_API_VERSION
|
||||
chmap = ALSA_snd_pcm_get_chmap(pcm_handle);
|
||||
if (chmap) {
|
||||
ALSA_snd_pcm_chmap_print(chmap, sizeof(chmap_str), chmap_str);
|
||||
if (SDL_strcmp("FL FR FC LFE RL RR", chmap_str) == 0 ||
|
||||
SDL_strcmp("FL FR FC LFE SL SR", chmap_str) == 0) {
|
||||
this->hidden->swizzle_func = no_swizzle;
|
||||
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 ||
|
||||
SDL_strcmp("FL FR FC LFE SL SR", chmap_str) == 0) {
|
||||
this->hidden->swizzle_func = no_swizzle;
|
||||
}
|
||||
}
|
||||
free(chmap);
|
||||
}
|
||||
@@ -750,7 +779,7 @@ add_device(const int iscapture, const char *name, void *hint, ALSA_Device **pSee
|
||||
/* some strings have newlines, like "HDA NVidia, HDMI 0\nHDMI Audio Output".
|
||||
just chop the extra lines off, this seems to get a reasonable device
|
||||
name without extra details. */
|
||||
if ((ptr = strchr(desc, '\n')) != NULL) {
|
||||
if ((ptr = SDL_strchr(desc, '\n')) != NULL) {
|
||||
*ptr = '\0';
|
||||
}
|
||||
|
||||
@@ -779,191 +808,191 @@ add_device(const int iscapture, const char *name, void *hint, ALSA_Device **pSee
|
||||
}
|
||||
|
||||
|
||||
static ALSA_Device *hotplug_devices = NULL;
|
||||
|
||||
static void
|
||||
ALSA_HotplugIteration(void)
|
||||
{
|
||||
void **hints = NULL;
|
||||
ALSA_Device *dev;
|
||||
ALSA_Device *unseen;
|
||||
ALSA_Device *seen;
|
||||
ALSA_Device *next;
|
||||
ALSA_Device *prev;
|
||||
|
||||
if (ALSA_snd_device_name_hint(-1, "pcm", &hints) == 0) {
|
||||
int i, j;
|
||||
const char *match = NULL;
|
||||
int bestmatch = 0xFFFF;
|
||||
size_t match_len = 0;
|
||||
int defaultdev = -1;
|
||||
static const char * const prefixes[] = {
|
||||
"hw:", "sysdefault:", "default:", NULL
|
||||
};
|
||||
|
||||
unseen = hotplug_devices;
|
||||
seen = NULL;
|
||||
|
||||
/* Apparently there are several different ways that ALSA lists
|
||||
actual hardware. It could be prefixed with "hw:" or "default:"
|
||||
or "sysdefault:" and maybe others. Go through the list and see
|
||||
if we can find a preferred prefix for the system. */
|
||||
for (i = 0; hints[i]; i++) {
|
||||
char *name = ALSA_snd_device_name_get_hint(hints[i], "NAME");
|
||||
if (!name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* full name, not a prefix */
|
||||
if ((defaultdev == -1) && (SDL_strcmp(name, "default") == 0)) {
|
||||
defaultdev = i;
|
||||
}
|
||||
|
||||
for (j = 0; prefixes[j]; j++) {
|
||||
const char *prefix = prefixes[j];
|
||||
const size_t prefixlen = SDL_strlen(prefix);
|
||||
if (SDL_strncmp(name, prefix, prefixlen) == 0) {
|
||||
if (j < bestmatch) {
|
||||
bestmatch = j;
|
||||
match = prefix;
|
||||
match_len = prefixlen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(name);
|
||||
}
|
||||
|
||||
/* look through the list of device names to find matches */
|
||||
for (i = 0; hints[i]; i++) {
|
||||
char *name;
|
||||
|
||||
/* if we didn't find a device name prefix we like at all... */
|
||||
if ((!match) && (defaultdev != i)) {
|
||||
continue; /* ...skip anything that isn't the default device. */
|
||||
}
|
||||
|
||||
name = ALSA_snd_device_name_get_hint(hints[i], "NAME");
|
||||
if (!name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* only want physical hardware interfaces */
|
||||
if (!match || (SDL_strncmp(name, match, match_len) == 0)) {
|
||||
char *ioid = ALSA_snd_device_name_get_hint(hints[i], "IOID");
|
||||
const SDL_bool isoutput = (ioid == NULL) || (SDL_strcmp(ioid, "Output") == 0);
|
||||
const SDL_bool isinput = (ioid == NULL) || (SDL_strcmp(ioid, "Input") == 0);
|
||||
SDL_bool have_output = SDL_FALSE;
|
||||
SDL_bool have_input = SDL_FALSE;
|
||||
|
||||
free(ioid);
|
||||
|
||||
if (!isoutput && !isinput) {
|
||||
free(name);
|
||||
continue;
|
||||
}
|
||||
|
||||
prev = NULL;
|
||||
for (dev = unseen; dev; dev = next) {
|
||||
next = dev->next;
|
||||
if ( (SDL_strcmp(dev->name, name) == 0) && (((isinput) && dev->iscapture) || ((isoutput) && !dev->iscapture)) ) {
|
||||
if (prev) {
|
||||
prev->next = next;
|
||||
} else {
|
||||
unseen = next;
|
||||
}
|
||||
dev->next = seen;
|
||||
seen = dev;
|
||||
if (isinput) have_input = SDL_TRUE;
|
||||
if (isoutput) have_output = SDL_TRUE;
|
||||
} else {
|
||||
prev = dev;
|
||||
}
|
||||
}
|
||||
|
||||
if (isinput && !have_input) {
|
||||
add_device(SDL_TRUE, name, hints[i], &seen);
|
||||
}
|
||||
if (isoutput && !have_output) {
|
||||
add_device(SDL_FALSE, name, hints[i], &seen);
|
||||
}
|
||||
}
|
||||
|
||||
free(name);
|
||||
}
|
||||
|
||||
ALSA_snd_device_name_free_hint(hints);
|
||||
|
||||
hotplug_devices = seen; /* now we have a known-good list of attached devices. */
|
||||
|
||||
/* report anything still in unseen as removed. */
|
||||
for (dev = unseen; dev; dev = next) {
|
||||
/*printf("ALSA: removing usb %s device '%s'\n", dev->iscapture ? "capture" : "output", dev->name);*/
|
||||
next = dev->next;
|
||||
SDL_RemoveAudioDevice(dev->iscapture, dev->name);
|
||||
SDL_free(dev->name);
|
||||
SDL_free(dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if SDL_ALSA_HOTPLUG_THREAD
|
||||
static SDL_atomic_t ALSA_hotplug_shutdown;
|
||||
static SDL_Thread *ALSA_hotplug_thread;
|
||||
|
||||
static int SDLCALL
|
||||
ALSA_HotplugThread(void *arg)
|
||||
{
|
||||
SDL_sem *first_run_semaphore = (SDL_sem *) arg;
|
||||
ALSA_Device *devices = NULL;
|
||||
ALSA_Device *next;
|
||||
ALSA_Device *dev;
|
||||
Uint32 ticks;
|
||||
|
||||
SDL_SetThreadPriority(SDL_THREAD_PRIORITY_LOW);
|
||||
|
||||
while (!SDL_AtomicGet(&ALSA_hotplug_shutdown)) {
|
||||
void **hints = NULL;
|
||||
ALSA_Device *unseen;
|
||||
ALSA_Device *seen;
|
||||
ALSA_Device *prev;
|
||||
|
||||
if (ALSA_snd_device_name_hint(-1, "pcm", &hints) == 0) {
|
||||
int i, j;
|
||||
const char *match = NULL;
|
||||
int bestmatch = 0xFFFF;
|
||||
size_t match_len = 0;
|
||||
int defaultdev = -1;
|
||||
static const char * const prefixes[] = {
|
||||
"hw:", "sysdefault:", "default:", NULL
|
||||
};
|
||||
|
||||
unseen = devices;
|
||||
seen = NULL;
|
||||
/* Apparently there are several different ways that ALSA lists
|
||||
actual hardware. It could be prefixed with "hw:" or "default:"
|
||||
or "sysdefault:" and maybe others. Go through the list and see
|
||||
if we can find a preferred prefix for the system. */
|
||||
for (i = 0; hints[i]; i++) {
|
||||
char *name = ALSA_snd_device_name_get_hint(hints[i], "NAME");
|
||||
if (!name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* full name, not a prefix */
|
||||
if ((defaultdev == -1) && (SDL_strcmp(name, "default") == 0)) {
|
||||
defaultdev = i;
|
||||
}
|
||||
|
||||
for (j = 0; prefixes[j]; j++) {
|
||||
const char *prefix = prefixes[j];
|
||||
const size_t prefixlen = SDL_strlen(prefix);
|
||||
if (SDL_strncmp(name, prefix, prefixlen) == 0) {
|
||||
if (j < bestmatch) {
|
||||
bestmatch = j;
|
||||
match = prefix;
|
||||
match_len = prefixlen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(name);
|
||||
}
|
||||
|
||||
/* look through the list of device names to find matches */
|
||||
for (i = 0; hints[i]; i++) {
|
||||
char *name;
|
||||
|
||||
/* if we didn't find a device name prefix we like at all... */
|
||||
if ((!match) && (defaultdev != i)) {
|
||||
continue; /* ...skip anything that isn't the default device. */
|
||||
}
|
||||
|
||||
name = ALSA_snd_device_name_get_hint(hints[i], "NAME");
|
||||
if (!name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* only want physical hardware interfaces */
|
||||
if (!match || (SDL_strncmp(name, match, match_len) == 0)) {
|
||||
char *ioid = ALSA_snd_device_name_get_hint(hints[i], "IOID");
|
||||
const SDL_bool isoutput = (ioid == NULL) || (SDL_strcmp(ioid, "Output") == 0);
|
||||
const SDL_bool isinput = (ioid == NULL) || (SDL_strcmp(ioid, "Input") == 0);
|
||||
SDL_bool have_output = SDL_FALSE;
|
||||
SDL_bool have_input = SDL_FALSE;
|
||||
|
||||
free(ioid);
|
||||
|
||||
if (!isoutput && !isinput) {
|
||||
free(name);
|
||||
continue;
|
||||
}
|
||||
|
||||
prev = NULL;
|
||||
for (dev = unseen; dev; dev = next) {
|
||||
next = dev->next;
|
||||
if ( (SDL_strcmp(dev->name, name) == 0) && (((isinput) && dev->iscapture) || ((isoutput) && !dev->iscapture)) ) {
|
||||
if (prev) {
|
||||
prev->next = next;
|
||||
} else {
|
||||
unseen = next;
|
||||
}
|
||||
dev->next = seen;
|
||||
seen = dev;
|
||||
if (isinput) have_input = SDL_TRUE;
|
||||
if (isoutput) have_output = SDL_TRUE;
|
||||
} else {
|
||||
prev = dev;
|
||||
}
|
||||
}
|
||||
|
||||
if (isinput && !have_input) {
|
||||
add_device(SDL_TRUE, name, hints[i], &seen);
|
||||
}
|
||||
if (isoutput && !have_output) {
|
||||
add_device(SDL_FALSE, name, hints[i], &seen);
|
||||
}
|
||||
}
|
||||
|
||||
free(name);
|
||||
}
|
||||
|
||||
ALSA_snd_device_name_free_hint(hints);
|
||||
|
||||
devices = seen; /* now we have a known-good list of attached devices. */
|
||||
|
||||
/* report anything still in unseen as removed. */
|
||||
for (dev = unseen; dev; dev = next) {
|
||||
/*printf("ALSA: removing usb %s device '%s'\n", dev->iscapture ? "capture" : "output", dev->name);*/
|
||||
next = dev->next;
|
||||
SDL_RemoveAudioDevice(dev->iscapture, dev->name);
|
||||
SDL_free(dev->name);
|
||||
SDL_free(dev);
|
||||
}
|
||||
}
|
||||
|
||||
/* On first run, tell ALSA_DetectDevices() that we have a complete device list so it can return. */
|
||||
if (first_run_semaphore) {
|
||||
SDL_SemPost(first_run_semaphore);
|
||||
first_run_semaphore = NULL; /* let other thread clean it up. */
|
||||
}
|
||||
|
||||
/* Block awhile before checking again, unless we're told to stop. */
|
||||
ticks = SDL_GetTicks() + 5000;
|
||||
const Uint32 ticks = SDL_GetTicks() + 5000;
|
||||
while (!SDL_AtomicGet(&ALSA_hotplug_shutdown) && !SDL_TICKS_PASSED(SDL_GetTicks(), ticks)) {
|
||||
SDL_Delay(100);
|
||||
}
|
||||
}
|
||||
|
||||
/* Shutting down! Clean up any data we've gathered. */
|
||||
for (dev = devices; dev; dev = next) {
|
||||
/*printf("ALSA: at shutdown, removing %s device '%s'\n", dev->iscapture ? "capture" : "output", dev->name);*/
|
||||
next = dev->next;
|
||||
SDL_free(dev->name);
|
||||
SDL_free(dev);
|
||||
ALSA_HotplugIteration(); /* run the check. */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
ALSA_DetectDevices(void)
|
||||
{
|
||||
/* Start the device detection thread here, wait for an initial iteration to complete. */
|
||||
SDL_sem *semaphore = SDL_CreateSemaphore(0);
|
||||
if (!semaphore) {
|
||||
return; /* oh well. */
|
||||
}
|
||||
ALSA_HotplugIteration(); /* run once now before a thread continues to check. */
|
||||
|
||||
#if SDL_ALSA_HOTPLUG_THREAD
|
||||
SDL_AtomicSet(&ALSA_hotplug_shutdown, 0);
|
||||
|
||||
ALSA_hotplug_thread = SDL_CreateThread(ALSA_HotplugThread, "SDLHotplugALSA", semaphore);
|
||||
if (ALSA_hotplug_thread) {
|
||||
SDL_SemWait(semaphore); /* wait for the first iteration to finish. */
|
||||
}
|
||||
|
||||
SDL_DestroySemaphore(semaphore);
|
||||
ALSA_hotplug_thread = SDL_CreateThread(ALSA_HotplugThread, "SDLHotplugALSA", NULL);
|
||||
/* if the thread doesn't spin, oh well, you just don't get further hotplug events. */
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
ALSA_Deinitialize(void)
|
||||
{
|
||||
ALSA_Device *dev;
|
||||
ALSA_Device *next;
|
||||
|
||||
#if SDL_ALSA_HOTPLUG_THREAD
|
||||
if (ALSA_hotplug_thread != NULL) {
|
||||
SDL_AtomicSet(&ALSA_hotplug_shutdown, 1);
|
||||
SDL_WaitThread(ALSA_hotplug_thread, NULL);
|
||||
ALSA_hotplug_thread = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Shutting down! Clean up any data we've gathered. */
|
||||
for (dev = hotplug_devices; dev; dev = next) {
|
||||
/*printf("ALSA: at shutdown, removing %s device '%s'\n", dev->iscapture ? "capture" : "output", dev->name);*/
|
||||
next = dev->next;
|
||||
SDL_free(dev->name);
|
||||
SDL_free(dev);
|
||||
}
|
||||
hotplug_devices = NULL;
|
||||
|
||||
UnloadALSALibrary();
|
||||
}
|
||||
|
@@ -57,8 +57,8 @@ ANDROIDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
test_format = SDL_FirstAudioFormat(this->spec.format);
|
||||
while (test_format != 0) { /* no "UNKNOWN" constant */
|
||||
if ((test_format == AUDIO_U8) ||
|
||||
(test_format == AUDIO_S16) ||
|
||||
(test_format == AUDIO_F32)) {
|
||||
(test_format == AUDIO_S16) ||
|
||||
(test_format == AUDIO_F32)) {
|
||||
this->spec.format = test_format;
|
||||
break;
|
||||
}
|
||||
|
2
externals/SDL/src/audio/dsp/SDL_dspaudio.c
vendored
2
externals/SDL/src/audio/dsp/SDL_dspaudio.c
vendored
@@ -103,7 +103,7 @@ DSP_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
SDL_zerop(this->hidden);
|
||||
|
||||
/* Open the audio device */
|
||||
this->hidden->audio_fd = open(devname, flags, 0);
|
||||
this->hidden->audio_fd = open(devname, flags | O_CLOEXEC, 0);
|
||||
if (this->hidden->audio_fd < 0) {
|
||||
return SDL_SetError("Couldn't open %s: %s", devname, strerror(errno));
|
||||
}
|
||||
|
@@ -59,6 +59,9 @@ HandleAudioProcess(_THIS)
|
||||
if (this->stream) {
|
||||
SDL_AudioStreamClear(this->stream);
|
||||
}
|
||||
|
||||
SDL_memset(this->work_buffer, this->spec.silence, this->spec.size);
|
||||
FeedAudioDevice(this, this->work_buffer, this->spec.size);
|
||||
return;
|
||||
}
|
||||
|
||||
|
6
externals/SDL/src/audio/nas/SDL_nasaudio.c
vendored
6
externals/SDL/src/audio/nas/SDL_nasaudio.c
vendored
@@ -113,11 +113,11 @@ LoadNASLibrary(void)
|
||||
/* Copy error string so we can use it in a new SDL_SetError(). */
|
||||
const char *origerr = SDL_GetError();
|
||||
const size_t len = SDL_strlen(origerr) + 1;
|
||||
char *err = (char *) alloca(len);
|
||||
char *err = SDL_stack_alloc(char, len);
|
||||
SDL_strlcpy(err, origerr, len);
|
||||
SDL_SetError("NAS: SDL_LoadObject('%s') failed: %s", nas_library, err);
|
||||
SDL_stack_free(err);
|
||||
retval = -1;
|
||||
SDL_SetError("NAS: SDL_LoadObject('%s') failed: %s",
|
||||
nas_library, err);
|
||||
} else {
|
||||
retval = load_nas_syms();
|
||||
if (retval < 0) {
|
||||
|
@@ -226,7 +226,7 @@ NETBSDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
SDL_zerop(this->hidden);
|
||||
|
||||
/* Open the audio device */
|
||||
this->hidden->audio_fd = open(devname, iscapture ? O_RDONLY : O_WRONLY);
|
||||
this->hidden->audio_fd = open(devname, (iscapture ? O_RDONLY : O_WRONLY) | O_CLOEXEC);
|
||||
if (this->hidden->audio_fd < 0) {
|
||||
return SDL_SetError("Couldn't open %s: %s", devname, strerror(errno));
|
||||
}
|
||||
|
20
externals/SDL/src/audio/openslES/SDL_openslES.c
vendored
20
externals/SDL/src/audio/openslES/SDL_openslES.c
vendored
@@ -579,7 +579,7 @@ openslES_CreatePCMPlayer(_THIS)
|
||||
|
||||
failed:
|
||||
|
||||
return SDL_SetError("Open device failed!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -594,8 +594,24 @@ openslES_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
LOGI("openslES_OpenDevice() %s for capture", devname);
|
||||
return openslES_CreatePCMRecorder(this);
|
||||
} else {
|
||||
int ret;
|
||||
LOGI("openslES_OpenDevice() %s for playing", devname);
|
||||
return openslES_CreatePCMPlayer(this);
|
||||
ret = openslES_CreatePCMPlayer(this);
|
||||
if (ret < 0) {
|
||||
/* Another attempt to open the device with a lower frequency */
|
||||
if (this->spec.freq > 48000) {
|
||||
openslES_DestroyPCMPlayer(this);
|
||||
this->spec.freq = 48000;
|
||||
ret = openslES_CreatePCMPlayer(this);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return SDL_SetError("Open device failed!");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
23
externals/SDL/src/audio/os2/SDL_os2audio.c
vendored
23
externals/SDL/src/audio/os2/SDL_os2audio.c
vendored
@@ -87,7 +87,7 @@ static LONG APIENTRY cbAudioWriteEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer,
|
||||
debug_os2("DosPostEventSem(), rc = %u", ulRC);
|
||||
}
|
||||
|
||||
return 1; /* It seems, return value is not matter. */
|
||||
return 1; /* return value doesn't seem to matter. */
|
||||
}
|
||||
|
||||
static LONG APIENTRY cbAudioReadEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer,
|
||||
@@ -133,7 +133,7 @@ static void OS2_DetectDevices(void)
|
||||
return;
|
||||
}
|
||||
|
||||
ulDevicesNum = atol(stMCISysInfo.pszReturn);
|
||||
ulDevicesNum = SDL_strtoul(stMCISysInfo.pszReturn, NULL, 10);
|
||||
|
||||
for (stSysInfoParams.ulNumber = 0; stSysInfoParams.ulNumber < ulDevicesNum;
|
||||
stSysInfoParams.ulNumber++) {
|
||||
@@ -151,7 +151,7 @@ static void OS2_DetectDevices(void)
|
||||
/* Get textual product description. */
|
||||
stSysInfoParams.ulItem = MCI_SYSINFO_QUERY_DRIVER;
|
||||
stSysInfoParams.pSysInfoParm = &stLogDevice;
|
||||
strcpy(stLogDevice.szInstallName, stSysInfoParams.pszReturn);
|
||||
SDL_strlcpy(stLogDevice.szInstallName, stSysInfoParams.pszReturn, MAX_DEVICE_NAME);
|
||||
ulRC = mciSendCommand(0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_ITEM,
|
||||
&stSysInfoParams, 0);
|
||||
if (ulRC != NO_ERROR) {
|
||||
@@ -211,10 +211,8 @@ static void OS2_CloseDevice(_THIS)
|
||||
return;
|
||||
|
||||
/* Close up audio */
|
||||
if (pAData->usDeviceId != (USHORT)~0) {
|
||||
/* Device is open. */
|
||||
if (pAData->stMCIMixSetup.ulBitsPerSample != 0) {
|
||||
/* Mixer was initialized. */
|
||||
if (pAData->usDeviceId != (USHORT)~0) { /* Device is open. */
|
||||
if (pAData->stMCIMixSetup.ulBitsPerSample != 0) { /* Mixer was initialized. */
|
||||
ulRC = mciSendCommand(pAData->usDeviceId, MCI_MIXSETUP,
|
||||
MCI_WAIT | MCI_MIXSETUP_DEINIT,
|
||||
&pAData->stMCIMixSetup, 0);
|
||||
@@ -223,8 +221,7 @@ static void OS2_CloseDevice(_THIS)
|
||||
}
|
||||
}
|
||||
|
||||
if (pAData->cMixBuffers != 0) {
|
||||
/* Buffers was allocated. */
|
||||
if (pAData->cMixBuffers != 0) { /* Buffers was allocated. */
|
||||
MCI_BUFFER_PARMS stMCIBuffer;
|
||||
|
||||
stMCIBuffer.ulBufferSize = pAData->aMixBuffers[0].ulBufferLength;
|
||||
@@ -410,15 +407,13 @@ static int OS2_OpenDevice(_THIS, void *handle, const char *devname,
|
||||
pAData->aMixBuffers[ulIdx].ulBufferLength = stMCIBuffer.ulBufferSize;
|
||||
pAData->aMixBuffers[ulIdx].ulUserParm = (ULONG)pAData;
|
||||
|
||||
memset(((PMCI_MIX_BUFFER)stMCIBuffer.pBufList)[ulIdx].pBuffer,
|
||||
_this->spec.silence, stMCIBuffer.ulBufferSize);
|
||||
SDL_memset(((PMCI_MIX_BUFFER)stMCIBuffer.pBufList)[ulIdx].pBuffer,
|
||||
_this->spec.silence, stMCIBuffer.ulBufferSize);
|
||||
}
|
||||
|
||||
/* Write buffers to kick off the amp mixer */
|
||||
/*pAData->ulQueuedBuf = 1;//stMCIBuffer.ulNumBuffers */
|
||||
ulRC = pAData->stMCIMixSetup.pmixWrite(pAData->stMCIMixSetup.ulMixHandle,
|
||||
pAData->aMixBuffers,
|
||||
1 /*stMCIBuffer.ulNumBuffers*/);
|
||||
pAData->aMixBuffers, 1);
|
||||
if (ulRC != MCIERR_SUCCESS) {
|
||||
_mixIOError("pmixWrite", ulRC);
|
||||
return -1;
|
||||
|
2
externals/SDL/src/audio/paudio/SDL_paudio.c
vendored
2
externals/SDL/src/audio/paudio/SDL_paudio.c
vendored
@@ -156,7 +156,7 @@ PAUDIO_WaitDevice(_THIS)
|
||||
#ifdef DEBUG_AUDIO
|
||||
fprintf(stderr, "Waiting for audio to get ready\n");
|
||||
#endif
|
||||
if (SDL_IOReady(this->hidden->audio_fd, SDL_TRUE, timeoutMS) <= 0) {
|
||||
if (SDL_IOReady(this->hidden->audio_fd, SDL_IOR_WRITE, timeoutMS) <= 0) {
|
||||
/*
|
||||
* In general we should never print to the screen,
|
||||
* but in this case we have no other way of letting
|
||||
|
17
externals/SDL/src/audio/pipewire/SDL_pipewire.c
vendored
17
externals/SDL/src/audio/pipewire/SDL_pipewire.c
vendored
@@ -31,6 +31,14 @@
|
||||
#include <pipewire/extensions/metadata.h>
|
||||
#include <spa/param/audio/format-utils.h>
|
||||
|
||||
/* Older versions of Pipewire may not define this, but it's safe to pass at
|
||||
* runtime even if older installations don't recognize it.
|
||||
* Taken from src/pipewire/keys.h
|
||||
*/
|
||||
#ifndef PW_KEY_NODE_RATE
|
||||
#define PW_KEY_NODE_RATE "node.rate"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* These seem to be sane limits as Pipewire
|
||||
* uses them in several of it's own modules.
|
||||
@@ -730,6 +738,9 @@ hotplug_loop_destroy()
|
||||
pending_list_clear();
|
||||
io_list_clear();
|
||||
|
||||
SDL_AtomicSet(&hotplug_init_complete, 0);
|
||||
SDL_AtomicSet(&hotplug_events_enabled, 0);
|
||||
|
||||
if (hotplug_registry) {
|
||||
PIPEWIRE_pw_proxy_destroy((struct pw_proxy *)hotplug_registry);
|
||||
}
|
||||
@@ -1032,7 +1043,10 @@ PIPEWIRE_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
/* Get the hints for the application name, stream name and role */
|
||||
app_name = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_APP_NAME);
|
||||
if (!app_name || *app_name == '\0') {
|
||||
app_name = "SDL Application";
|
||||
app_name = SDL_GetHint(SDL_HINT_APP_NAME);
|
||||
if (!app_name || *app_name == '\0') {
|
||||
app_name = "SDL Application";
|
||||
}
|
||||
}
|
||||
|
||||
stream_name = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_STREAM_NAME);
|
||||
@@ -1110,6 +1124,7 @@ PIPEWIRE_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_NAME, stream_name);
|
||||
PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_DESCRIPTION, stream_name);
|
||||
PIPEWIRE_pw_properties_setf(props, PW_KEY_NODE_LATENCY, "%u/%i", adjusted_samples, this->spec.freq);
|
||||
PIPEWIRE_pw_properties_setf(props, PW_KEY_NODE_RATE, "1/%u", this->spec.freq);
|
||||
PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_ALWAYS_PROCESS, "true");
|
||||
|
||||
/*
|
||||
|
3
externals/SDL/src/audio/psp/SDL_pspaudio.c
vendored
3
externals/SDL/src/audio/psp/SDL_pspaudio.c
vendored
@@ -25,7 +25,6 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include "SDL_audio.h"
|
||||
#include "SDL_error.h"
|
||||
@@ -90,7 +89,7 @@ PSPAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
return SDL_SetError("Couldn't reserve hardware channel");
|
||||
}
|
||||
|
||||
memset(this->hidden->rawbuf, 0, mixlen);
|
||||
SDL_memset(this->hidden->rawbuf, 0, mixlen);
|
||||
for (i = 0; i < NUM_BUFFERS; i++) {
|
||||
this->hidden->mixbufs[i] = &this->hidden->rawbuf[i * this->spec.size];
|
||||
}
|
||||
|
@@ -80,7 +80,7 @@ static void (*PULSEAUDIO_pa_mainloop_quit) (pa_mainloop *, int);
|
||||
static void (*PULSEAUDIO_pa_mainloop_free) (pa_mainloop *);
|
||||
|
||||
static pa_operation_state_t (*PULSEAUDIO_pa_operation_get_state) (
|
||||
pa_operation *);
|
||||
const pa_operation *);
|
||||
static void (*PULSEAUDIO_pa_operation_cancel) (pa_operation *);
|
||||
static void (*PULSEAUDIO_pa_operation_unref) (pa_operation *);
|
||||
|
||||
@@ -92,7 +92,7 @@ static pa_operation * (*PULSEAUDIO_pa_context_get_sink_info_list) (pa_context *,
|
||||
static pa_operation * (*PULSEAUDIO_pa_context_get_source_info_list) (pa_context *, pa_source_info_cb_t, void *);
|
||||
static pa_operation * (*PULSEAUDIO_pa_context_get_sink_info_by_index) (pa_context *, uint32_t, pa_sink_info_cb_t, void *);
|
||||
static pa_operation * (*PULSEAUDIO_pa_context_get_source_info_by_index) (pa_context *, uint32_t, pa_source_info_cb_t, void *);
|
||||
static pa_context_state_t (*PULSEAUDIO_pa_context_get_state) (pa_context *);
|
||||
static pa_context_state_t (*PULSEAUDIO_pa_context_get_state) (const pa_context *);
|
||||
static pa_operation * (*PULSEAUDIO_pa_context_subscribe) (pa_context *, pa_subscription_mask_t, pa_context_success_cb_t, void *);
|
||||
static void (*PULSEAUDIO_pa_context_set_subscribe_callback) (pa_context *, pa_context_subscribe_cb_t, void *);
|
||||
static void (*PULSEAUDIO_pa_context_disconnect) (pa_context *);
|
||||
@@ -101,12 +101,12 @@ static void (*PULSEAUDIO_pa_context_unref) (pa_context *);
|
||||
static pa_stream * (*PULSEAUDIO_pa_stream_new) (pa_context *, const char *,
|
||||
const pa_sample_spec *, const pa_channel_map *);
|
||||
static int (*PULSEAUDIO_pa_stream_connect_playback) (pa_stream *, const char *,
|
||||
const pa_buffer_attr *, pa_stream_flags_t, pa_cvolume *, pa_stream *);
|
||||
const pa_buffer_attr *, pa_stream_flags_t, const pa_cvolume *, pa_stream *);
|
||||
static int (*PULSEAUDIO_pa_stream_connect_record) (pa_stream *, const char *,
|
||||
const pa_buffer_attr *, pa_stream_flags_t);
|
||||
static pa_stream_state_t (*PULSEAUDIO_pa_stream_get_state) (pa_stream *);
|
||||
static size_t (*PULSEAUDIO_pa_stream_writable_size) (pa_stream *);
|
||||
static size_t (*PULSEAUDIO_pa_stream_readable_size) (pa_stream *);
|
||||
static pa_stream_state_t (*PULSEAUDIO_pa_stream_get_state) (const pa_stream *);
|
||||
static size_t (*PULSEAUDIO_pa_stream_writable_size) (const pa_stream *);
|
||||
static size_t (*PULSEAUDIO_pa_stream_readable_size) (const pa_stream *);
|
||||
static int (*PULSEAUDIO_pa_stream_begin_write) (pa_stream *, void **, size_t*);
|
||||
static int (*PULSEAUDIO_pa_stream_cancel_write) (pa_stream *);
|
||||
static int (*PULSEAUDIO_pa_stream_write) (pa_stream *, const void *, size_t,
|
||||
@@ -246,7 +246,13 @@ static const char *
|
||||
getAppName(void)
|
||||
{
|
||||
const char *retval = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_APP_NAME);
|
||||
if (!retval || !*retval) {
|
||||
if (retval && *retval) {
|
||||
return retval;
|
||||
}
|
||||
retval = SDL_GetHint(SDL_HINT_APP_NAME);
|
||||
if (retval && *retval) {
|
||||
return retval;
|
||||
} else {
|
||||
const char *verstr = PULSEAUDIO_pa_get_library_version();
|
||||
retval = "SDL Application"; /* the "oh well" default. */
|
||||
if (verstr != NULL) {
|
||||
@@ -362,7 +368,7 @@ PULSEAUDIO_WaitDevice(_THIS)
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
return;
|
||||
}
|
||||
if (PULSEAUDIO_pa_stream_writable_size(h->stream) >= h->mixlen) {
|
||||
if (PULSEAUDIO_pa_stream_writable_size(h->stream) >= (h->mixlen/8)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
4
externals/SDL/src/audio/qsa/SDL_qsa_audio.c
vendored
4
externals/SDL/src/audio/qsa/SDL_qsa_audio.c
vendored
@@ -120,7 +120,9 @@ QSA_WaitDevice(_THIS)
|
||||
/* If timeout occured than something wrong with hardware or driver */
|
||||
/* For example, Vortex 8820 audio driver stucks on second DAC because */
|
||||
/* it doesn't exist ! */
|
||||
result = SDL_IOReady(this->hidden->audio_fd, !this->hidden->iscapture, 2 * 1000);
|
||||
result = SDL_IOReady(this->hidden->audio_fd,
|
||||
this->hidden->iscapture ? SDL_IOR_READ : SDL_IOR_WRITE,
|
||||
2 * 1000);
|
||||
switch (result) {
|
||||
case -1:
|
||||
SDL_SetError("QSA: SDL_IOReady() failed: %s", strerror(errno));
|
||||
|
2
externals/SDL/src/audio/sun/SDL_sunaudio.c
vendored
2
externals/SDL/src/audio/sun/SDL_sunaudio.c
vendored
@@ -98,7 +98,7 @@ SUNAUDIO_WaitDevice(_THIS)
|
||||
}
|
||||
}
|
||||
#else
|
||||
SDL_IOReady(this->hidden->audio_fd, SDL_TRUE, -1);
|
||||
SDL_IOReady(this->hidden->audio_fd, SDL_IOR_WRITE, -1);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
3
externals/SDL/src/audio/vita/SDL_vitaaudio.c
vendored
3
externals/SDL/src/audio/vita/SDL_vitaaudio.c
vendored
@@ -25,7 +25,6 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include "SDL_audio.h"
|
||||
#include "SDL_error.h"
|
||||
@@ -100,7 +99,7 @@ VITAAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
|
||||
sceAudioOutSetVolume(this->hidden->channel, SCE_AUDIO_VOLUME_FLAG_L_CH|SCE_AUDIO_VOLUME_FLAG_R_CH, vols);
|
||||
|
||||
memset(this->hidden->rawbuf, 0, mixlen);
|
||||
SDL_memset(this->hidden->rawbuf, 0, mixlen);
|
||||
for (i = 0; i < NUM_BUFFERS; i++) {
|
||||
this->hidden->mixbufs[i] = &this->hidden->rawbuf[i * this->spec.size];
|
||||
}
|
||||
|
27
externals/SDL/src/audio/wasapi/SDL_wasapi.c
vendored
27
externals/SDL/src/audio/wasapi/SDL_wasapi.c
vendored
@@ -34,10 +34,16 @@
|
||||
|
||||
#include "SDL_wasapi.h"
|
||||
|
||||
/* This constant isn't available on MinGW-w64 */
|
||||
/* These constants aren't available in older SDKs */
|
||||
#ifndef AUDCLNT_STREAMFLAGS_RATEADJUST
|
||||
#define AUDCLNT_STREAMFLAGS_RATEADJUST 0x00100000
|
||||
#endif
|
||||
#ifndef AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY
|
||||
#define AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY 0x08000000
|
||||
#endif
|
||||
#ifndef AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM
|
||||
#define AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM 0x80000000
|
||||
#endif
|
||||
|
||||
/* these increment as default devices change. Opened default devices pick up changes in their threads. */
|
||||
SDL_atomic_t WASAPI_DefaultPlaybackGeneration;
|
||||
@@ -556,21 +562,12 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
|
||||
return WIN_SetErrorFromHRESULT("WASAPI can't determine minimum device period", ret);
|
||||
}
|
||||
|
||||
#if 1 /* we're getting reports that WASAPI's resampler introduces distortions, so it's disabled for now. --ryan. */
|
||||
this->spec.freq = waveformat->nSamplesPerSec; /* force sampling rate so our resampler kicks in, if necessary. */
|
||||
#else
|
||||
/* favor WASAPI's resampler over our own, in Win7+. */
|
||||
/* favor WASAPI's resampler over our own */
|
||||
if (this->spec.freq != waveformat->nSamplesPerSec) {
|
||||
/* RATEADJUST only works with output devices in share mode, and is available in Win7 and later.*/
|
||||
if (WIN_IsWindows7OrGreater() && !this->iscapture && (sharemode == AUDCLNT_SHAREMODE_SHARED)) {
|
||||
streamflags |= AUDCLNT_STREAMFLAGS_RATEADJUST;
|
||||
waveformat->nSamplesPerSec = this->spec.freq;
|
||||
waveformat->nAvgBytesPerSec = waveformat->nSamplesPerSec * waveformat->nChannels * (waveformat->wBitsPerSample / 8);
|
||||
} else {
|
||||
this->spec.freq = waveformat->nSamplesPerSec; /* force sampling rate so our resampler kicks in. */
|
||||
}
|
||||
streamflags |= (AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM | AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY);
|
||||
waveformat->nSamplesPerSec = this->spec.freq;
|
||||
waveformat->nAvgBytesPerSec = waveformat->nSamplesPerSec * waveformat->nChannels * (waveformat->wBitsPerSample / 8);
|
||||
}
|
||||
#endif
|
||||
|
||||
streamflags |= AUDCLNT_STREAMFLAGS_EVENTCALLBACK;
|
||||
ret = IAudioClient_Initialize(client, sharemode, streamflags, 0, 0, waveformat, NULL);
|
||||
@@ -698,7 +695,7 @@ WASAPI_ThreadDeinit(_THIS)
|
||||
void
|
||||
WASAPI_BeginLoopIteration(_THIS)
|
||||
{
|
||||
/* no-op. */
|
||||
/* no-op. */
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -53,7 +53,7 @@ static IMMDeviceEnumerator *enumerator = NULL;
|
||||
|
||||
/* handle to Avrt.dll--Vista and later!--for flagging the callback thread as "Pro Audio" (low latency). */
|
||||
static HMODULE libavrt = NULL;
|
||||
typedef HANDLE(WINAPI *pfnAvSetMmThreadCharacteristicsW)(LPWSTR, LPDWORD);
|
||||
typedef HANDLE(WINAPI *pfnAvSetMmThreadCharacteristicsW)(LPCWSTR, LPDWORD);
|
||||
typedef BOOL(WINAPI *pfnAvRevertMmThreadCharacteristics)(HANDLE);
|
||||
static pfnAvSetMmThreadCharacteristicsW pAvSetMmThreadCharacteristicsW = NULL;
|
||||
static pfnAvRevertMmThreadCharacteristics pAvRevertMmThreadCharacteristics = NULL;
|
||||
|
3
externals/SDL/src/audio/winmm/SDL_winmm.c
vendored
3
externals/SDL/src/audio/winmm/SDL_winmm.c
vendored
@@ -135,7 +135,7 @@ FillSound(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance,
|
||||
}
|
||||
|
||||
static int
|
||||
SetMMerror(char *function, MMRESULT code)
|
||||
SetMMerror(const char *function, MMRESULT code)
|
||||
{
|
||||
int len;
|
||||
char errbuf[MAXERRORLENGTH];
|
||||
@@ -434,7 +434,6 @@ WINMM_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
return 0; /* Ready to go! */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
WINMM_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
|
Reference in New Issue
Block a user