diff --git a/DS4Windows/DS4Control/ControlServiceDeviceOptions.cs b/DS4Windows/DS4Control/ControlServiceDeviceOptions.cs index 081c86b..b113347 100644 --- a/DS4Windows/DS4Control/ControlServiceDeviceOptions.cs +++ b/DS4Windows/DS4Control/ControlServiceDeviceOptions.cs @@ -229,6 +229,28 @@ public enum MuteLEDMode : ushort Pulse } + public enum HapticsMode : ushort + { + Off, + SystemAudio, + RumbleToHaptics, + Mix, + } + + public enum AudioOutputRoute : ushort + { + Auto, // headphone jack when plugged in, speaker otherwise + Headphone, + Speaker, + } + + public enum AudioLatencyMode : ushort + { + Smooth, // maximum buffering; survives congested links + Balanced, + LowLatency, // minimum buffering; needs a clean link + } + private LEDBarMode ledMode = LEDBarMode.MultipleControllers; public LEDBarMode LedMode { @@ -255,6 +277,112 @@ public MuteLEDMode MuteLedMode } public event EventHandler MuteLedModeChanged; + // Bluetooth audio-haptics streaming settings. Fires a single combined + // change event; the device applies live-safe fields or restarts the + // capture pipeline as needed. + private HapticsMode btHapticsMode = HapticsMode.Off; + public HapticsMode BTHapticsMode + { + get => btHapticsMode; + set + { + if (btHapticsMode == value) return; + btHapticsMode = value; + BTHapticsOptionChanged?.Invoke(this, EventArgs.Empty); + } + } + + private double btHapticsGain = 3.0; + public double BTHapticsGain + { + get => btHapticsGain; + set + { + value = Math.Clamp(value, 0.1, 10.0); + if (btHapticsGain == value) return; + btHapticsGain = value; + BTHapticsOptionChanged?.Invoke(this, EventArgs.Empty); + } + } + + private int btHapticsLowPassHz = 350; + public int BTHapticsLowPassHz + { + get => btHapticsLowPassHz; + set + { + value = Math.Clamp(value, 40, 1000); + if (btHapticsLowPassHz == value) return; + btHapticsLowPassHz = value; + BTHapticsOptionChanged?.Invoke(this, EventArgs.Empty); + } + } + + private string btHapticsAudioDeviceId = string.Empty; + public string BTHapticsAudioDeviceId + { + get => btHapticsAudioDeviceId; + set + { + value ??= string.Empty; + if (btHapticsAudioDeviceId == value) return; + btHapticsAudioDeviceId = value; + BTHapticsOptionChanged?.Invoke(this, EventArgs.Empty); + } + } + + // Bluetooth listening-audio (headphone jack / speaker) settings. + private bool btAudioEnabled = false; + public bool BTAudioEnabled + { + get => btAudioEnabled; + set + { + if (btAudioEnabled == value) return; + btAudioEnabled = value; + BTHapticsOptionChanged?.Invoke(this, EventArgs.Empty); + } + } + + private AudioOutputRoute btAudioRoute = AudioOutputRoute.Auto; + public AudioOutputRoute BTAudioRoute + { + get => btAudioRoute; + set + { + if (btAudioRoute == value) return; + btAudioRoute = value; + BTHapticsOptionChanged?.Invoke(this, EventArgs.Empty); + } + } + + private int btAudioVolume = 50; + public int BTAudioVolume + { + get => btAudioVolume; + set + { + value = Math.Clamp(value, 0, 100); + if (btAudioVolume == value) return; + btAudioVolume = value; + BTHapticsOptionChanged?.Invoke(this, EventArgs.Empty); + } + } + + private AudioLatencyMode btAudioLatency = AudioLatencyMode.Smooth; + public AudioLatencyMode BTAudioLatency + { + get => btAudioLatency; + set + { + if (btAudioLatency == value) return; + btAudioLatency = value; + BTHapticsOptionChanged?.Invoke(this, EventArgs.Empty); + } + } + + public event EventHandler BTHapticsOptionChanged; + public DualSenseControllerOptions(InputDeviceType deviceType) : base(deviceType) { diff --git a/DS4Windows/DS4Control/DTOXml/DualSenseControllerOptsDTO.cs b/DS4Windows/DS4Control/DTOXml/DualSenseControllerOptsDTO.cs index ab85355..48b4a06 100644 --- a/DS4Windows/DS4Control/DTOXml/DualSenseControllerOptsDTO.cs +++ b/DS4Windows/DS4Control/DTOXml/DualSenseControllerOptsDTO.cs @@ -40,16 +40,80 @@ public MuteLEDMode MuteLedMode get; set; } + [XmlElement("BTHapticsMode")] + public HapticsMode BTHapticsMode + { + get; set; + } = HapticsMode.Off; + + [XmlElement("BTHapticsGain")] + public double BTHapticsGain + { + get; set; + } = 3.0; + + [XmlElement("BTHapticsLowPassHz")] + public int BTHapticsLowPassHz + { + get; set; + } = 350; + + [XmlElement("BTHapticsAudioDeviceId")] + public string BTHapticsAudioDeviceId + { + get; set; + } = string.Empty; + + [XmlElement("BTAudioEnabled")] + public bool BTAudioEnabled + { + get; set; + } = false; + + [XmlElement("BTAudioRoute")] + public AudioOutputRoute BTAudioRoute + { + get; set; + } = AudioOutputRoute.Auto; + + [XmlElement("BTAudioVolume")] + public int BTAudioVolume + { + get; set; + } = 50; + + [XmlElement("BTAudioLatency")] + public AudioLatencyMode BTAudioLatency + { + get; set; + } = AudioLatencyMode.Smooth; + public void MapFrom(DualSenseControllerOptions source) { LEDMode = source.LedMode; MuteLedMode = source.MuteLedMode; + BTHapticsMode = source.BTHapticsMode; + BTHapticsGain = source.BTHapticsGain; + BTHapticsLowPassHz = source.BTHapticsLowPassHz; + BTHapticsAudioDeviceId = source.BTHapticsAudioDeviceId; + BTAudioEnabled = source.BTAudioEnabled; + BTAudioRoute = source.BTAudioRoute; + BTAudioVolume = source.BTAudioVolume; + BTAudioLatency = source.BTAudioLatency; } public void MapTo(DualSenseControllerOptions destination) { destination.LedMode = LEDMode; destination.MuteLedMode = MuteLedMode; + destination.BTHapticsMode = BTHapticsMode; + destination.BTHapticsGain = BTHapticsGain; + destination.BTHapticsLowPassHz = BTHapticsLowPassHz; + destination.BTHapticsAudioDeviceId = BTHapticsAudioDeviceId; + destination.BTAudioEnabled = BTAudioEnabled; + destination.BTAudioRoute = BTAudioRoute; + destination.BTAudioVolume = BTAudioVolume; + destination.BTAudioLatency = BTAudioLatency; } } } diff --git a/DS4Windows/DS4Forms/ControllerRegisterOptionsWindow.xaml b/DS4Windows/DS4Forms/ControllerRegisterOptionsWindow.xaml index 062d5c3..116fc0b 100644 --- a/DS4Windows/DS4Forms/ControllerRegisterOptionsWindow.xaml +++ b/DS4Windows/DS4Forms/ControllerRegisterOptionsWindow.xaml @@ -72,6 +72,61 @@