From 6f774908feee5263ae1fe5b0ae5a81b2157207e0 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Mon, 8 Dec 2025 11:24:21 -0500
Subject: [PATCH] audio: SDL_GetAudioDeviceName() now works with the default
device IDs.
Fixes #14615.
---
include/SDL3/SDL_audio.h | 9 +++++++++
src/audio/SDL_audio.c | 8 ++++++++
test/loopwave.c | 1 +
3 files changed, 18 insertions(+)
diff --git a/include/SDL3/SDL_audio.h b/include/SDL3/SDL_audio.h
index 104992bcfd358..0eb2d4af042c8 100644
--- a/include/SDL3/SDL_audio.h
+++ b/include/SDL3/SDL_audio.h
@@ -577,6 +577,15 @@ extern SDL_DECLSPEC SDL_AudioDeviceID * SDLCALL SDL_GetAudioRecordingDevices(int
/**
* Get the human-readable name of a specific audio device.
*
+ * **WARNING**: this function will work with SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK
+ * and SDL_AUDIO_DEVICE_DEFAULT_RECORDING, returning the current default
+ * physical devices' names. However, as the default device may change at any
+ * time, it is likely better to show a generic name to the user, like "System
+ * default audio device" or perhaps "default [currently %s]". Do not store
+ * this name to disk to reidentify the device in a later run of the program,
+ * as the default might change in general, and the string will be the name
+ * of a specific device and not the abstract system default.
+ *
* \param devid the instance ID of the device to query.
* \returns the name of the audio device, or NULL on failure; call
* SDL_GetError() for more information.
diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c
index e084f24cfc758..22babfbc6a89f 100644
--- a/src/audio/SDL_audio.c
+++ b/src/audio/SDL_audio.c
@@ -1579,6 +1579,14 @@ const char *SDL_GetAudioDeviceName(SDL_AudioDeviceID devid)
// remains valid (in case the device is unplugged at the wrong moment), we hold the
// subsystem_rwlock while we copy the string.
SDL_LockRWLockForReading(current_audio.subsystem_rwlock);
+
+ // Allow default device IDs to be used, just return the current default physical device's name.
+ if (devid == SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK) {
+ devid = current_audio.default_playback_device_id;
+ } else if (devid == SDL_AUDIO_DEVICE_DEFAULT_RECORDING) {
+ devid = current_audio.default_recording_device_id;
+ }
+
SDL_FindInHashTable(islogical ? current_audio.device_hash_logical : current_audio.device_hash_physical, (const void *) (uintptr_t) devid, &vdev);
if (!vdev) {
SDL_SetError("Invalid audio device instance ID");
diff --git a/test/loopwave.c b/test/loopwave.c
index e5b55e7df9512..2e83c39c3296f 100644
--- a/test/loopwave.c
+++ b/test/loopwave.c
@@ -109,6 +109,7 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
}
SDL_Log("Using audio driver: %s", SDL_GetCurrentAudioDriver());
+ SDL_Log("Current audio device name: %s", SDL_GetAudioDeviceName(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK));
stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &wave.spec, NULL, NULL);
if (!stream) {