Some users have reported the center/LFE channels being swapped when playing games that support surround sound. After investigating, it appears that winecoreaudio never sets AudioChannelLayout on the audio unit, and assumes that it matches the Windows layout (which is the order of `dwChannelMask`). This is often true, but not always. Using some test code [1] in `ca_setup_audiounit()` to get the AudioChannelLayout (Dell U2711 over HDMI), for some reason the audio unit defaults to having the center (3) and LFE (4) positions swapped from where Windows lays them out: ``` 1389548.056:0020:0124:err:coreaudio:ca_setup_audiounit Got channel layout: {tag: 0x0, bitmap: 0x0, num_descs: 6} 1389548.056:0020:0124:err:coreaudio:ca_setup_audiounit desc 0: label 1 flags 0 1389548.056:0020:0124:err:coreaudio:ca_setup_audiounit desc 1: label 2 flags 0 1389548.056:0020:0124:err:coreaudio:ca_setup_audiounit desc 2: label 4 flags 0 1389548.056:0020:0124:err:coreaudio:ca_setup_audiounit desc 3: label 3 flags 0 1389548.056:0020:0124:err:coreaudio:ca_setup_audiounit desc 4: label 5 flags 0 1389548.056:0020:0124:err:coreaudio:ca_setup_audiounit desc 5: label 6 flags 0 ``` To fix this, set the AudioChannelLayout in `ca_setup_audiounit()`. Happily the Core Audio `AudioChannelBitmap` and Windows `dwChannelMask` perfectly match each other in speaker/bit positions, so this is easy. Marked as draft pending some extra testing. [1]: ``` { UInt32 size; Boolean writable; sc = AudioUnitGetPropertyInfo(unit, kAudioUnitProperty_AudioChannelLayout, kAudioUnitScope_Output, 0, &size, &writable); ERR("AudioChannelLayout sc %d\n", sc); if (sc == noErr) { AudioChannelLayout *layout = malloc(size); sc = AudioUnitGetProperty(unit, kAudioUnitProperty_AudioChannelLayout, kAudioUnitScope_Output, 0, layout, &size); ERR("AudioChannelLayout 2 sc %d\n", sc); ERR("Got channel layout: {tag: 0x%x, bitmap: 0x%x, num_descs: %u}\n", (unsigned int)layout->mChannelLayoutTag, (unsigned int)layout->mChannelBitmap, (unsigned int)layout->mNumberChannelDescriptions); for (unsigned int i = 0; i < layout->mNumberChannelDescriptions; i++) { ERR("desc %d: label %d flags %x\n", i, layout->mChannelDescriptions[i].mChannelLabel, layout->mChannelDescriptions[i].mChannelFlags); } free(layout); } } } ``` -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9663