From 9c136bb3b4e7651cd67c1661c31ac7ed730c4646 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 12 Sep 2021 03:04:46 -0700 Subject: Track whether nodes are marked as headphones Newer versions of PipeWire copy the PW_KEY_DEVICE_FORM_FACTOR property to the sink node, so this should work to detect whether the device should be treated as headphones or not. --- alc/backends/pipewire.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'alc/backends/pipewire.cpp') diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp index e0b66092..6501a194 100644 --- a/alc/backends/pipewire.cpp +++ b/alc/backends/pipewire.cpp @@ -397,6 +397,7 @@ struct DeviceNode { uint32_t mId{}; bool mCapture{}; + bool mIsHeadphones{}; uint mSampleRate{}; DevFmtChannels mChannels{InvalidChannelConfig}; @@ -517,13 +518,21 @@ void NodeProxy::infoCallback(const pw_node_info *info) return; } + bool isHeadphones{}; + if(const char *form_factor{spa_dict_lookup(info->props, PW_KEY_DEVICE_FORM_FACTOR)}) + { + if(al::strcasecmp(form_factor, "headphones") == 0 + || al::strcasecmp(form_factor, "headset") == 0) + isHeadphones = true; + } + const char *devName{spa_dict_lookup(info->props, PW_KEY_NODE_NAME)}; const char *nodeName{spa_dict_lookup(info->props, PW_KEY_NODE_DESCRIPTION)}; if(!nodeName || !*nodeName) nodeName = spa_dict_lookup(info->props, PW_KEY_NODE_NICK); if(!nodeName || !*nodeName) nodeName = devName; - TRACE("Got %s device \"%s\"\n", isCapture ? "capture" : "playback", - devName ? devName : "(nil)"); + TRACE("Got %s device \"%s\"%s\n", isCapture ? "capture" : "playback", + devName ? devName : "(nil)", isHeadphones ? " (headphones)" : ""); TRACE(" \"%s\" = ID %u\n", nodeName ? nodeName : "(nil)", info->id); DeviceNode &node = AddDeviceNode(info->id); @@ -531,6 +540,7 @@ void NodeProxy::infoCallback(const pw_node_info *info) else node.mName = "PipeWire node #"+std::to_string(info->id); node.mDevName = devName ? devName : ""; node.mCapture = isCapture; + node.mIsHeadphones = isHeadphones; } } @@ -1195,6 +1205,8 @@ bool PipeWirePlayback::reset() } if(!mDevice->Flags.test(ChannelsRequest) && match->mChannels != InvalidChannelConfig) mDevice->FmtChans = match->mChannels; + if(match->mChannels == DevFmtStereo && match->mIsHeadphones) + mDevice->IsHeadphones = true; } } /* Force planar 32-bit float output for playback. This is what PipeWire -- cgit v1.2.3