SDL: audio: Fix SDL_GetAudioDeviceName() not working with logical devices. (01ef4)

From 01ef4c46a1731400bb9760434c4e09329540b9b7 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Mon, 12 May 2025 13:53:30 -0400
Subject: [PATCH] audio: Fix SDL_GetAudioDeviceName() not working with logical
 devices.

Fixes #12977.

(cherry picked from commit 0a34279578a2cce104efc0d605cd5a51ece25e95)
---
 src/audio/SDL_audio.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c
index a3a115c48d6b2..d8a6d662158d7 100644
--- a/src/audio/SDL_audio.c
+++ b/src/audio/SDL_audio.c
@@ -1502,8 +1502,10 @@ SDL_AudioDevice *SDL_FindPhysicalAudioDeviceByHandle(void *handle)
 
 const char *SDL_GetAudioDeviceName(SDL_AudioDeviceID devid)
 {
+    // bit #1 of devid is set for physical devices and unset for logical.
+    const bool islogical = !(devid & (1<<1));
     const char *result = NULL;
-    SDL_AudioDevice *device = NULL;
+    const void *vdev = NULL;
 
     if (!SDL_GetCurrentAudioDriver()) {
         SDL_SetError("Audio subsystem is not initialized");
@@ -1513,10 +1515,14 @@ const char *SDL_GetAudioDeviceName(SDL_AudioDeviceID devid)
         // remains valid (in case the device is unplugged at the wrong moment), we hold the
         // device_hash_lock while we copy the string.
         SDL_LockRWLockForReading(current_audio.device_hash_lock);
-        SDL_FindInHashTable(current_audio.device_hash, (const void *) (uintptr_t) devid, (const void **) &device);
-        if (!device) {
+        SDL_FindInHashTable(current_audio.device_hash, (const void *) (uintptr_t) devid, &vdev);
+        if (!vdev) {
             SDL_SetError("Invalid audio device instance ID");
+        } else if (islogical) {
+            const SDL_LogicalAudioDevice *logdev = (const SDL_LogicalAudioDevice *) vdev;
+            result = SDL_GetPersistentString(logdev->physical_device->name);
         } else {
+            const SDL_AudioDevice *device = (const SDL_AudioDevice *) vdev;
             result = SDL_GetPersistentString(device->name);
         }
         SDL_UnlockRWLock(current_audio.device_hash_lock);