From d0e5e138e279f40f92b7d41d885695a206ec36c0 Mon Sep 17 00:00:00 2001
From: Chris Robinson <chris.kcat@gmail.com>
Date: Sat, 23 Oct 2021 07:51:06 -0700
Subject: Use a flag to indicate headphone-like output

---
 alc/alc.cpp                 | 14 ++++++++++++++
 alc/backends/dsound.cpp     |  3 +--
 alc/backends/pipewire.cpp   |  4 ++--
 alc/backends/pulseaudio.cpp |  4 ++--
 alc/backends/wasapi.cpp     |  3 +--
 alc/panning.cpp             | 16 +---------------
 core/device.h               |  5 ++++-
 7 files changed, 25 insertions(+), 24 deletions(-)

diff --git a/alc/alc.cpp b/alc/alc.cpp
index 4ba1ee48..44cc0f93 100644
--- a/alc/alc.cpp
+++ b/alc/alc.cpp
@@ -1835,6 +1835,20 @@ ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
     case DevFmtAmbi3D: break;
     }
 
+    if(device->Type != DeviceType::Loopback)
+    {
+        if(auto modeopt = device->configValue<std::string>(nullptr, "stereo-mode"))
+        {
+            const char *mode{modeopt->c_str()};
+            if(al::strcasecmp(mode, "headphones") == 0)
+                device->Flags.set(DirectEar);
+            else if(al::strcasecmp(mode, "speakers") == 0)
+                device->Flags.reset(DirectEar);
+            else if(al::strcasecmp(mode, "auto") != 0)
+                ERR("Unexpected stereo-mode: %s\n", mode);
+        }
+    }
+
     aluInitRenderer(device, hrtf_id, hrtfreq);
 
     device->NumAuxSends = new_sends;
diff --git a/alc/backends/dsound.cpp b/alc/backends/dsound.cpp
index 6513e8f3..acac4786 100644
--- a/alc/backends/dsound.cpp
+++ b/alc/backends/dsound.cpp
@@ -409,8 +409,7 @@ bool DSoundPlayback::reset()
             else
                 ERR("Unknown system speaker config: 0x%lx\n", speakers);
         }
-        mDevice->IsHeadphones = mDevice->FmtChans == DevFmtStereo
-            && speakers == DSSPEAKER_HEADPHONE;
+        mDevice->Flags.set(DirectEar, (speakers == DSSPEAKER_HEADPHONE));
 
         switch(mDevice->FmtChans)
         {
diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp
index 82b7a22f..5b172551 100644
--- a/alc/backends/pipewire.cpp
+++ b/alc/backends/pipewire.cpp
@@ -1185,7 +1185,7 @@ bool PipeWirePlayback::reset()
     /* If connecting to a specific device, update various device parameters to
      * match its format.
      */
-    mDevice->IsHeadphones = false;
+    mDevice->Flags.reset(DirectEar);
     if(mTargetId != PwIdAny)
     {
         EventWatcherLockGuard _{gEventHandler};
@@ -1207,7 +1207,7 @@ bool PipeWirePlayback::reset()
             if(!mDevice->Flags.test(ChannelsRequest) && match->mChannels != InvalidChannelConfig)
                 mDevice->FmtChans = match->mChannels;
             if(match->mChannels == DevFmtStereo && match->mIsHeadphones)
-                mDevice->IsHeadphones = true;
+                mDevice->Flags.set(DirectEar);
         }
     }
     /* Force planar 32-bit float output for playback. This is what PipeWire
diff --git a/alc/backends/pulseaudio.cpp b/alc/backends/pulseaudio.cpp
index cece08a0..84d9351a 100644
--- a/alc/backends/pulseaudio.cpp
+++ b/alc/backends/pulseaudio.cpp
@@ -815,8 +815,8 @@ void PulsePlayback::sinkInfoCallback(pa_context*, const pa_sink_info *info, int
 
     if(info->active_port)
         TRACE("Active port: %s (%s)\n", info->active_port->name, info->active_port->description);
-    mDevice->IsHeadphones = (mDevice->FmtChans == DevFmtStereo
-        && info->active_port && strcmp(info->active_port->name, "analog-output-headphones") == 0);
+    mDevice->Flags.set(DirectEar, (info->active_port
+        && strcmp(info->active_port->name, "analog-output-headphones") == 0));
 }
 
 void PulsePlayback::sinkNameCallback(pa_context*, const pa_sink_info *info, int eol) noexcept
diff --git a/alc/backends/wasapi.cpp b/alc/backends/wasapi.cpp
index c5c14d22..4abed9d3 100644
--- a/alc/backends/wasapi.cpp
+++ b/alc/backends/wasapi.cpp
@@ -1051,8 +1051,7 @@ HRESULT WasapiPlayback::resetProxy()
     mFrameStep = OutputType.Format.nChannels;
 
     const EndpointFormFactor formfactor{get_device_formfactor(mMMDev.get())};
-    mDevice->IsHeadphones = (mDevice->FmtChans == DevFmtStereo
-        && (formfactor == Headphones || formfactor == Headset));
+    mDevice->Flags.set(DirectEar, (formfactor == Headphones || formfactor == Headset));
 
     setChannelOrderFromWFXMask(OutputType.dwChannelMask);
 
diff --git a/alc/panning.cpp b/alc/panning.cpp
index bb600241..7b2215a4 100644
--- a/alc/panning.cpp
+++ b/alc/panning.cpp
@@ -921,25 +921,11 @@ void aluInitRenderer(ALCdevice *device, int hrtf_id, al::optional<bool> hrtfreq)
         return;
     }
 
-    bool headphones{device->IsHeadphones};
-    if(device->Type != DeviceType::Loopback)
-    {
-        if(auto modeopt = device->configValue<std::string>(nullptr, "stereo-mode"))
-        {
-            const char *mode{modeopt->c_str()};
-            if(al::strcasecmp(mode, "headphones") == 0)
-                headphones = true;
-            else if(al::strcasecmp(mode, "speakers") == 0)
-                headphones = false;
-            else if(al::strcasecmp(mode, "auto") != 0)
-                ERR("Unexpected stereo-mode: %s\n", mode);
-        }
-    }
 
     /* If there's no request for HRTF and the device is headphones, or if HRTF
      * is explicitly requested, try to enable it.
      */
-    if((!hrtfreq && headphones) || (hrtfreq && hrtfreq.value()))
+    if((!hrtfreq && device->Flags.test(DirectEar)) || hrtfreq.value_or(false))
     {
         if(device->mHrtfList.empty())
             device->enumerateHrtfs();
diff --git a/core/device.h b/core/device.h
index 0ffc05c4..5e2a3bfd 100644
--- a/core/device.h
+++ b/core/device.h
@@ -121,6 +121,10 @@ enum {
     // Specifies if the device is currently running
     DeviceRunning,
 
+    // Specifies if the output plays directly on/in ears (headphones, headset,
+    // ear buds, etc).
+    DirectEar,
+
     DeviceFlagsCount
 };
 
@@ -139,7 +143,6 @@ struct DeviceBase {
 
     DevFmtChannels FmtChans{};
     DevFmtType FmtType{};
-    bool IsHeadphones{false};
     uint mAmbiOrder{0};
     float mXOverFreq{400.0f};
     /* For DevFmtAmbi* output only, specifies the channel order and
-- 
cgit v1.2.3