From 530aee883c0d5a83ff2d60322936e5e9e5bdf8d6 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 28 Dec 2024 10:22:46 -0800 Subject: [PATCH] Update the device format earlier with CoreAudio --- alc/backends/coreaudio.cpp | 85 +++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 43 deletions(-) diff --git a/alc/backends/coreaudio.cpp b/alc/backends/coreaudio.cpp index 27107dc985..ef98ed8928 100644 --- a/alc/backends/coreaudio.cpp +++ b/alc/backends/coreaudio.cpp @@ -40,6 +40,7 @@ #include "core/converter.h" #include "core/device.h" #include "core/logging.h" +#include "fmt/core.h" #include "ringbuffer.h" #include @@ -285,14 +286,12 @@ void EnumerateDevices(std::vector &list, bool isCapture) { return entry.mName == curitem->mName; }; if(std::find_if(newdevs.begin(), curitem, check_match) != curitem) { - std::string name{curitem->mName}; - size_t count{1}; + auto name = std::string{curitem->mName}; + auto count = 1_uz; auto check_name = [&name](const DeviceEntry &entry) -> bool { return entry.mName == name; }; do { - name = curitem->mName; - name += " #"; - name += std::to_string(++count); + name = fmt::format("{} #{}", curitem->mName, ++count); } while(std::find_if(newdevs.begin(), curitem, check_name) != curitem); curitem->mName = std::move(name); } @@ -541,8 +540,44 @@ bool CoreAudioPlayback::reset() { DevFmtMono, MonoChanMap, false } }}; - /* FIXME: How to tell what channels are what in the output device, and how - * to specify what we're giving? e.g. 6.0 vs 5.1 + if(!mDevice->Flags.test(ChannelsRequest)) + { + auto propSize = UInt32{}; + auto writable = Boolean{}; + + err = AudioUnitGetPropertyInfo(mAudioUnit, kAudioUnitProperty_AudioChannelLayout, + kAudioUnitScope_Output, OutputElement, &propSize, &writable); + if(err == noErr) + { + auto layout_data = std::make_unique(propSize); + auto *layout = reinterpret_cast(layout_data.get()); + + err = AudioUnitGetProperty(mAudioUnit, kAudioUnitProperty_AudioChannelLayout, + kAudioUnitScope_Output, OutputElement, layout, &propSize); + if(err == noErr) + { + auto descs = al::span{std::data(layout->mChannelDescriptions), + layout->mNumberChannelDescriptions}; + auto labels = std::vector(descs.size()); + + std::transform(descs.begin(), descs.end(), labels.begin(), + std::mem_fn(&AudioChannelDescription::mChannelLabel)); + sort(labels.begin(), labels.end()); + + auto check_labels = [&labels](const ChannelMap &chanmap) -> bool + { + return std::includes(labels.begin(), labels.end(), chanmap.map.begin(), + chanmap.map.end()); + }; + auto chaniter = std::find_if(chanmaps.cbegin(), chanmaps.cend(), check_labels); + if(chaniter != chanmaps.cend()) + mDevice->FmtChans = chaniter->fmt; + } + } + } + + /* TODO: Also set kAudioUnitProperty_AudioChannelLayout according to the AL + * device's channel configuration. */ streamFormat.mChannelsPerFrame = mDevice->channelsFromFmt(); @@ -589,42 +624,6 @@ bool CoreAudioPlayback::reset() return false; } - if(!mDevice->Flags.test(ChannelsRequest)) - { - auto propSize = UInt32{}; - auto writable = Boolean{}; - - err = AudioUnitGetPropertyInfo(mAudioUnit, kAudioUnitProperty_AudioChannelLayout, - kAudioUnitScope_Output, OutputElement, &propSize, &writable); - if(err == noErr) - { - auto layout_data = std::make_unique(propSize); - auto *layout = reinterpret_cast(layout_data.get()); - - err = AudioUnitGetProperty(mAudioUnit, kAudioUnitProperty_AudioChannelLayout, - kAudioUnitScope_Output, OutputElement, layout, &propSize); - if(err == noErr) - { - auto descs = al::span{std::data(layout->mChannelDescriptions), - layout->mNumberChannelDescriptions}; - auto labels = std::vector(descs.size()); - - std::transform(descs.begin(), descs.end(), labels.begin(), - std::mem_fn(&AudioChannelDescription::mChannelLabel)); - sort(labels.begin(), labels.end()); - - auto chaniter = std::find_if(chanmaps.cbegin(), chanmaps.cend(), - [&labels](const ChannelMap &chanmap) -> bool - { - return std::includes(labels.begin(), labels.end(), chanmap.map.begin(), - chanmap.map.end()); - }); - if(chaniter != chanmaps.cend()) - mDevice->FmtChans = chaniter->fmt; - } - } - } - setDefaultWFXChannelOrder(); /* setup callback */