From 068c7854919cdb67633e7e0ebaff4496226b9659 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Fri, 19 Jul 2024 20:25:23 -0400
Subject: [PATCH] audio: Assigning a device channel map to an audio stream was
quietly failing.
Fixes #10317.
---
src/audio/SDL_audio.c | 2 +-
src/audio/SDL_audiocvt.c | 4 ++--
src/audio/SDL_sysaudio.h | 4 ++++
3 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c
index 3253956c167d7..9f3b0160c3c8e 100644
--- a/src/audio/SDL_audio.c
+++ b/src/audio/SDL_audio.c
@@ -251,7 +251,7 @@ static void UpdateAudioStreamFormatsPhysical(SDL_AudioDevice *device)
// SDL_SetAudioStreamFormat does a ton of validation just to memcpy an audiospec.
SDL_LockMutex(stream->lock);
SDL_copyp(&stream->dst_spec, &spec);
- SDL_SetAudioStreamOutputChannelMap(stream, device->chmap, spec.channels); // this should be fast for normal cases, though!
+ SetAudioStreamChannelMap(stream, &stream->dst_spec, &stream->dst_chmap, device->chmap, spec.channels, -1); // this should be fast for normal cases, though!
SDL_UnlockMutex(stream->lock);
}
}
diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c
index a7226dabf99d8..d785b14dc37d2 100644
--- a/src/audio/SDL_audiocvt.c
+++ b/src/audio/SDL_audiocvt.c
@@ -584,7 +584,7 @@ int SDL_SetAudioStreamFormat(SDL_AudioStream *stream, const SDL_AudioSpec *src_s
return 0;
}
-static int SetAudioStreamChannelMap(SDL_AudioStream *stream, const SDL_AudioSpec *spec, int **stream_chmap, const int *chmap, int channels, SDL_bool isinput)
+int SetAudioStreamChannelMap(SDL_AudioStream *stream, const SDL_AudioSpec *spec, int **stream_chmap, const int *chmap, int channels, int isinput)
{
if (!stream) {
return SDL_InvalidParamError("stream");
@@ -602,7 +602,7 @@ static int SetAudioStreamChannelMap(SDL_AudioStream *stream, const SDL_AudioSpec
// already have this map, don't allocate/copy it again.
} else if (SDL_ChannelMapIsBogus(chmap, channels)) {
retval = SDL_SetError("Invalid channel mapping");
- } else if (stream->bound_device && (!!isinput == !!stream->bound_device->physical_device->recording)) {
+ } else if ((isinput != -1) && stream->bound_device && (!!isinput == !!stream->bound_device->physical_device->recording)) {
// quietly refuse to change the format of the end currently bound to a device.
} else {
if (SDL_ChannelMapIsDefault(chmap, channels)) {
diff --git a/src/audio/SDL_sysaudio.h b/src/audio/SDL_sysaudio.h
index 20ca908574a4f..d21a6e3c6a8f4 100644
--- a/src/audio/SDL_sysaudio.h
+++ b/src/audio/SDL_sysaudio.h
@@ -137,6 +137,10 @@ extern void OnAudioStreamDestroy(SDL_AudioStream *stream);
// This just lets audio playback apply logical device gain at the same time as audiostream gain, so it's one multiplication instead of thousands.
extern int SDL_GetAudioStreamDataAdjustGain(SDL_AudioStream *stream, void *voidbuf, int len, float extra_gain);
+// This is the bulk of `SDL_SetAudioStream*putChannelMap`'s work, but it lets you skip the check about changing the device end of a stream if isinput==-1.
+extern int SetAudioStreamChannelMap(SDL_AudioStream *stream, const SDL_AudioSpec *spec, int **stream_chmap, const int *chmap, int channels, int isinput);
+
+
typedef struct SDL_AudioDriverImpl
{
void (*DetectDevices)(SDL_AudioDevice **default_playback, SDL_AudioDevice **default_recording);