Skip to content

Conversation

@ivyl
Copy link
Contributor

@ivyl ivyl commented Oct 30, 2025

https://wiki.libsdl.org/SDL3/CategoryAudio#channel-layouts:
8 channels (7.1) layout: FL, FR, FC, LFE, BL, BR, SL, SR

https://learn.microsoft.com/en-us/windows-hardware/drivers/audio/header-file-changes:

KSAUDIO_SPEAKER_7POINT1_SURROUND FL, FR, FC, LFE, BL, BR, SL, SR

In Windows Vista and later versions of Windows, the
KSAUDIO_SPEAKER_7POINT1 speaker configuration is no longer supported

https://wiki.libsdl.org/SDL3/CategoryAudio#channel-layouts:
  8 channels (7.1) layout: FL, FR, FC, LFE, BL, BR, SL, SR

https://learn.microsoft.com/en-us/windows-hardware/drivers/audio/header-file-changes:

  KSAUDIO_SPEAKER_7POINT1_SURROUND FL, FR, FC, LFE, BL, BR, SL, SR

  In Windows Vista and later versions of Windows, the
  KSAUDIO_SPEAKER_7POINT1 speaker configuration is no longer supported
@ivyl
Copy link
Contributor Author

ivyl commented Oct 30, 2025

In my testing I've been getting SPEAKER_7POINT1_SURROUND on Windows 11 as the mix format across different devices (PCIe soundcard, USB soundcard, HDMI connected to AV receiver).

SDL backends seem to be also hardcoding this map for 8 channels. DirectAudio & PipeWire do. WASAPI works just because of the mixformat matching things. PulseAudio seems to be a bit broken due to reliance on pa_channel_map_init_auto() which does the wrong thing. I'll either submit a PR or issue for this soon.

@ivyl
Copy link
Contributor Author

ivyl commented Oct 30, 2025

This came up when working on Wine and Ghost of Tsushima. The game was using wrong map compared to Windows resulting in silent or muffled channels. I've checked what native XAudio2 uses as default channel maps and those are as follows:

diff --git a/dlls/xaudio2_7/tests/xaudio2.c b/dlls/xaudio2_7/tests/xaudio2.c
index 52850343da21..d5e8fba84905 100644
--- a/dlls/xaudio2_7/tests/xaudio2.c
+++ b/dlls/xaudio2_7/tests/xaudio2.c
@@ -1279,6 +1279,42 @@ static void test_setchannelvolumes(IXAudio2 *xa)
     IXAudio2MasteringVoice_DestroyVoice(master);
 }
 
+#if XAUDIO2_VER >= 8
+struct channel_count_mask { UINT count; DWORD chmask; };
+
+static void test_default_channel_masks(IXAudio2 *xa)
+{
+    IXAudio2MasteringVoice *master;
+    DWORD chmask;
+    HRESULT hr;
+    UINT i;
+    struct channel_count_mask ccm[] = {
+        { 1, KSAUDIO_SPEAKER_MONO },
+        { 2, KSAUDIO_SPEAKER_STEREO },
+        { 3, KSAUDIO_SPEAKER_STEREO | SPEAKER_LOW_FREQUENCY },
+        { 4, KSAUDIO_SPEAKER_QUAD },
+        { 5, KSAUDIO_SPEAKER_QUAD | SPEAKER_LOW_FREQUENCY },
+        { 6, KSAUDIO_SPEAKER_5POINT1_SURROUND },
+        { 7, KSAUDIO_SPEAKER_5POINT1_SURROUND | SPEAKER_BACK_CENTER },
+        { 8, KSAUDIO_SPEAKER_7POINT1_SURROUND },
+    };
+
+
+    for (i = 0; i < ARRAY_SIZE(ccm); i++)
+    {
+        hr = create_mastering_voice(xa, ccm[i].count, &master);
+        ok(hr == S_OK, "CreateMasteringVoice failed: %08lx\n", hr);
+
+        IXAudio2MasteringVoice_GetChannelMask(master, &chmask);
+        ok(chmask == ccm[i].chmask, "Got unexpected channel mask 0x%lx for %u channels, expected 0x%lx\n", chmask, ccm[i].count, ccm[i].chmask);
+
+        IXAudio2MasteringVoice_DestroyVoice(master);
+    }
+}
+#else
+static void test_default_channel_masks(IXAudio2 *xa) {}
+#endif
+
 static UINT32 check_has_devices(IXAudio2 *xa)
 {
     HRESULT hr;
@@ -1316,6 +1352,7 @@ START_TEST(xaudio2)
         test_submix(audio);
         test_flush(audio);
         test_setchannelvolumes(audio);
+        test_default_channel_masks(audio);
     }
 
     ref = IXAudio2_Release(audio);

But trying to fully follow this would create a mismatch with SDL's assumptions, so I've only fixed 7.1 here.

@flibitijibibo
Copy link
Member

All makes sense to me, CC me for the SDL side issue whenever that's ready!

@flibitijibibo flibitijibibo merged commit 13e1a47 into FNA-XNA:master Oct 30, 2025
12 checks passed
@ford-prefect
Copy link

PulseAudio seems to be a bit broken due to reliance on pa_channel_map_init_auto() which does the wrong thing.

I was wondering what to do about this (presumably you're talking about the PA_CHANNEL_MAP_WAVEEX case). I think changing it to the "new" defaults makes sense. Please do file an issue when you can, and I'll handle that upstream.

@ivyl
Copy link
Contributor Author

ivyl commented Oct 30, 2025

I'm working on Pull Request that will fix this. Should be ready in a bit :-)

Plagman pushed a commit to ValveSoftware/wine that referenced this pull request Oct 30, 2025
Already upstreamed. This patch can be dropped once upstream Wine updates
vendored faudio and we pull that in.

Link: FNA-XNA/FAudio#392

CW-Bug-Id: #26135
Plagman pushed a commit to ValveSoftware/wine that referenced this pull request Nov 19, 2025
Already upstreamed. This patch can be dropped once upstream Wine updates
vendored faudio and we pull that in.

Link: FNA-XNA/FAudio#392

CW-Bug-Id: #26135
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants