SDL icon indicating copy to clipboard operation
SDL copied to clipboard

Associate HID controller with audio device

Open isXander opened this issue 1 year ago • 7 comments
trafficstars

The DualSense controller provides a USB Audio device. In Windows' device manager, the audio device shows a parent device of USB\VID_054C&PID_0CE6\8&ef6451e&0&8. The matching VID/PID of the controller. I need this since Dualsense HD haptics work through an extra stereo pair (making 4 channels total) in the audio device.

Is it possible with SDL to find an audio device via the HID identifier of the controller?

isXander avatar Mar 04 '24 16:03 isXander

Additional question. The haptics in a dualsense controller are on channels 3 and 4, 1 and 2 being for actual audio passthru to headphones. With SDL, is there a way to bind an audio stream with a spec of two channels to specific channels on the device?

Currently I've got the basic

SDL_LoadWav_RW(.. wavSpec, ..);
SDL_AudioStream stream = SDL_CreateAudioStream(wavSpec, devSpec);

SDL_OpenAudioDevice(dualSenseOutput, devSpec);
SDL_BindAudioStream(dualSenseOutput, stream);

SDL_PutAudioStreamData(stream, ..);

The easy way to do this would to just have all wav files quadrophonic, but this isn't really suitable, as I'd like to load OGG sounds later on, and skip out on the SDL_LoadWav method

isXander avatar Mar 04 '24 22:03 isXander

We don't really have a way to bind a stream to certain channels, and in the normal audio use case this doesn't make any sense. It would be fairly straightforward for you to implement an audio mixer on top of the quadrophonic stream that puts game audio into channels 1 and 2 and haptics into channels 3 and 4.

It would be handy to have a way of detecting when an audio device is associated with a controller. @icculus, is there a way to get the USB VID/PID of the audio device, or can this be done by name?

slouken avatar Mar 06 '24 16:03 slouken

is there a way to get the USB VID/PID of the audio device, or can this be done by name?

It...might be difficult to get this information, in most APIs.

This might be worth adding a property to audio devices, though, that says "this audio device is part of this game controller ID" and adding some special case Windows code to do this with PS5 controllers (and maybe others in the future, if it makes sense).

icculus avatar Mar 06 '24 17:03 icculus

I was considering making a PR myself to add HD haptics, but I believe this to be out of scope for SDL since it is literally just an audio stream, and can be achieved quite easily using the audio API, as long as you have the correct audio output device. Maybe the correct approach is to add a single method to gamepad API to get SDL_AudioDeviceID, or null if unavailable.

I'm not sure if this works on Linux, but I just searched for output devices with names containing 'DualSense', however I have seen online that people need to patch wine to make dualsense controllers appear as 'Wireless Controller' so they are picked up.

In The Last Of Us Part 1 PC, there exists an option to change the output device of the haptics and vibrations, suggesting there is definitely a way to do it. image

isXander avatar Mar 06 '24 19:03 isXander

We are scoping work for the SDL 3.2.0 release, so please let us know if this is a showstopper for you.

slouken avatar Oct 06 '24 18:10 slouken

I did manage to get this working by mixing audio, adding empty channel data and doing a primitive audio device name checks to find the correct device, looking for strings like "dualsense".

It means it's not a show stopper, but limits me to having one Dualsense controller at a time that is able to do HD haptics.

isXander avatar Oct 12 '24 11:10 isXander

We wouldn't be able to do any better, as far as I know.

slouken avatar Oct 12 '24 15:10 slouken

Audio channel maps seem to be new, and might make my code simpler to remap from stereo input to quadrophonic output. The documentation https://github.com/libsdl-org/SDL/blob/main/include/SDL3/SDL_audio.h#L1233 says you can pass null to reset the channel map, but can a channel itself be bound to null, or -1?

isXander avatar Oct 20 '24 18:10 isXander

It can't be bound to null, but you could have a map like this: { 0, 1, 0, 1 } That would duplicate the stereo channels to all four channels.

slouken avatar Oct 21 '24 15:10 slouken

It can't be bound to null, but you could have a map like this: { 0, 1, 0, 1 } That would duplicate the stereo channels to all four channels.

So it's impossible to make a channel play nothing?

isXander avatar Oct 25 '24 22:10 isXander

Currently that is correct, but feel free to open an issue to request that functionality.

slouken avatar Oct 25 '24 22:10 slouken

Hi, a while ago I've worked a bit on Wine/Proton patches to support DualSense features in games that have support, and found this issue when searching for more information today.

I did manage to get this working by mixing audio, adding empty channel data and doing a primitive audio device name checks to find the correct device, looking for strings like "dualsense".

It means it's not a show stopper, but limits me to having one Dualsense controller at a time that is able to do HD haptics.

I'm curious what algorithm you used to pick the audio output, as other commercial games may be using something similar.

So far, I have seen commercial games with official support either:

  • look for a device containing the name “Wireless Controller”
  • use various APIs to get the BaseContainerID of the HID device and matches it with the audio output, ensuring the audio device corresponds to the controller being used, even if there are multiple controllers

There are other games that likely do other things that I have not been able to identify. My patches basically used the USB device path as an approximation for the BaseContainerID because unique Base Container IDs roughly coincide with individual USB devices, and that is definitely enough for this specific purpose. That being said, it might be useful to use the BaseContainerID specifically in SDL, so that it can be used together with e.g. the proprietary Sony libraries which I suppose expose this information.

ClearlyClaire avatar Mar 03 '25 20:03 ClearlyClaire

I'm curious what algorithm you used to pick the audio output, as other commercial games may be using something similar.

I look for keywords in audio device name, namely "Wireless Controller" and "DualSense". It's not great, but it has presented no issues so far, though limits HD haptics to one controller per system.

isXander avatar Mar 12 '25 21:03 isXander