Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Audio #4

Open
Morganamilo opened this issue Dec 21, 2019 · 64 comments
Open

Audio #4

Morganamilo opened this issue Dec 21, 2019 · 64 comments
Labels
fixed in xone This issue has been fixed/resolved in xone

Comments

@Morganamilo
Copy link

Does this driver support audio? Or are there plans to?

@medusalix medusalix added the enhancement New feature or request label Dec 21, 2019
@medusalix
Copy link
Owner

I've looked into audio while developing the macOS version of this driver. It doesn't seem too complicated, but I'm not sure how to implement Linux audio devices in user mode.

@medusalix medusalix added the help wanted Help is wanted label Dec 23, 2019
@LiamFredericks000
Copy link

I can connect my arctis 9x pro to my linux machine via bluetooth, but I'm stuck using the ad2p bluetooth interface, so I can't use the headset's mic. I used XOW to allow the xbox usb adapter to connect to my headset, but my I couldn't find the headset in linux. Is there anything specific you need help with in order to connect a headset using the xbox wireless adapter?

@medusalix
Copy link
Owner

medusalix commented Jan 5, 2020

The first step would be to create input and output audio devices for the headset but I'm not even sure if that's possible from user mode on Linux. If this can only be done from kernel mode then it's impossible for me to implement this in xow.

@LiamFredericks000
Copy link

hhhmmm... When I connect my headset I didn't see the device anywhere. So even if I were able to create the output and input devices, I couldn't link them to anything.

@medusalix
Copy link
Owner

Yeah, this is way too much work for me right now, considering I don't even have a device/headset to test this with. I may implement this for a 1.0 release of xow.

@YangtseSu
Copy link

I think you need a headset with 3.5mm to connect to the gamepad.
Not a headset connect to the Linux OS directly.

@YangtseSu
Copy link

Use xbox device as Pulseaudio audio sink and source .
https://www.freedesktop.org/wiki/Software/PulseAudio/

@LiamFredericks000
Copy link

That makes sense. I don't actually own a xbox controller so this doesn't work. I used to have a arctis 9x, but i've returned it since I wasn't able to use it wirelessly in linux (except for bluetooth).

@medusalix
Copy link
Owner

I did some packet capturing and reverse engineered the important parts of the protocol:

  • The controller sends a special packet when you plug in a headphone/headset.
  • The driver responds, creates a local audio device and enables the controller's audio stream.
  • The controller periodically sends audio data from the headset's microphone.
  • The driver sends a new audio output packet every 8 milliseconds.
  • Audio samples are encoded as uncompressed 2-channel 16-bit PCM.
  • Every audio out packet contains exactly 1536 (0x600) bytes of data which equals a sample rate of 48 KHz.

Those things would have to be implemented in xow (using PulseAudio). The timing of the individual packets (8 ms) is VERY important (that might be the biggest problem).

@medusalix medusalix added this to the v0.4 milestone Jan 21, 2020
@medusalix medusalix modified the milestones: v0.4, v0.5 Mar 10, 2020
@LorenzoMinutolo
Copy link

Hi All,
Thanks for this beautiful library, keep it up!
I'm testing now on Ubuntu 18, wireless dongle slim and Turtle Beach 600. The pairing goes well, the device does not show anywhere (expected). Running ./xow I get this:
screen_xow

@medusalix
Copy link
Owner

@LorenzoMinutolo I'm currently focusing on implementing the audio for the controllers first, I might consider supporting third-party headsets for a future release.

@medusalix
Copy link
Owner

medusalix commented Apr 15, 2020

I've implemented experimental headphone support, available in the audio branch (only audio output right now). I'm still working on it, so please don't be surprised if you hear any crackling noises. I only tested it on my 1708 controller.

Important notes: You will have to install the PulseAudio libraries to compile xow. The PulseAudio daemon is usually running as a user-service and refuses any connections from root accounts. That's why I've decided to convert xow's system-service to a user-service. You will have to uninstall the system-service (sudo systemctl) before installing the user-service (systemctl --user) as described in the updated README. Running xow manually is not recommended and will increase the discernable audio noise.

@medusalix medusalix removed the help wanted Help is wanted label Apr 15, 2020
@andreashuetter
Copy link

andreashuetter commented Apr 15, 2020

I just tried the audio branch.

First I could not compile it, but after performing sudo apt-get install libpulse-dev I could.

I also did
sudo systemctl stop xow.service
sudo systemctl disable xow.service
sudo make uninstall
of the other version before.

But I can not enable or start the audio version:

desktop@sn970:~/xow$ sudo systemctl --user enable xow.service
Failed to get D-Bus connection: Verbindungsaufbau abgelehnt
desktop@sn970:~/xow$ sudo systemctl --user start xow.service
Failed to get D-Bus connection: Verbindungsaufbau abgelehnt

Running the audio branch of xow manually (which is not recommended for the audio branch) still works:

desktop@sn970:~/xow$ ./xow
 INFO  - xow v0.4-17-g6c8aa7c ©Severin v. W.
 INFO  - Dongle plugged in
 INFO  - Wireless address: 62:45:b4:fa:b0:d2
 INFO  - Dongle initialized
 INFO  - Controller '1' connected
 INFO  - Product ID: 02ea
 INFO  - Serial number: 02600021263813

The PulseAudio daemon is running (I don't know if this information is helpful):

desktop@sn970:~/xow$ ps -ef|grep -i pulse
pulse      646     1  0 15:52 ?        00:00:01 /usr/bin/pulseaudio --system --disallow-exit --daemonize=no --high-priority

@medusalix
Copy link
Owner

@andreashuetter Make sure to run systemctl --user without sudo.

@andreashuetter
Copy link

andreashuetter commented Apr 15, 2020

Well, the reason why I tried it with sudo was that without sudo I always got:

desktop@sn970:~/xow$ systemctl --user enable xow.service
Failed to execute operation: No such file or directory

But now I tried
systemctl --user enable /lib/systemd/user/xow.service
and this at least did not return any error message.

But it doesn't seem to work at all. After
systemctl --user enable /lib/systemd/user/xow.service
and
systemctl --user start xow.service

I rebooted the machine, and it says it's not active:

desktop@sn970:~/xow$ systemctl status xow
● xow.service
   Loaded: not-found (Reason: No such file or directory)
   Active: inactive (dead)

@andreashuetter
Copy link

andreashuetter commented Apr 15, 2020

Silly me, of course systemctl status xow is the wrong command in this case.

Of course, systemctl --user status xow is the way to go here:

desktop@sn970:~/xow$ systemctl --user status xow 
● xow.service - Xbox One Wireless Dongle Driver
   Loaded: loaded (/lib/systemd/user/xow.service; enabled)
   Active: active (running) since Mi 2020-04-15 18:24:30 CEST; 2min 44s ago
 Main PID: 1409 (xow)
   CGroup: /user.slice/user-1000.slice/user@1000.service/xow.service
           └─1409 /usr/local/bin/xow

But after some trying I fear that this version of xow is not suited for SteamOS.

The thing is, when SteamOS gets started it always starts in Big Picture Mode and everything is run by the user steam.
In Big Picture Mode there is no desktop, no terminal window and so on. Only the steam gui. But there is the possibility to exit from steam and launch a Gnome Desktop instead where you can have a terminal window, a browser and so on (but no steam). When you do this you get logged on as user desktop.

So whenever I had to do something like checking out xow from github, compiling it and installing it, I did this as user desktop. Calling sudo make install and sudo systemctl enable xow made sure that xow gets started by the system on startup. But when I do systemctl --user enable /lib/systemd/user/xow.service as user desktop this won't work on startup, because this user is not even logged on on startup (as I described, this user only can get logged on by closing the steam session and launching the Gnome desktop instead). So I thought that maybe I have to try this as user steam (by performing sudo su - steam and then systemctl --user enable /lib/systemd/user/xow.service), but this is not possible because the user steam has very few priviliges and is not allowed to perform such things.

I switched back to the (system-service) master branch of xow now, because I think currently it's not possible to get the (user-service) audio branch to work properly on SteamOS.

@medusalix
Copy link
Owner

Hmm, I think you could try using the old xow.service file with the new audio branch. I've noticed that you're running PulseAudio as a system-wide daemon (--system), whereas most modern Linux distribution start individual instances of PulseAudio for each user, so a system-service might even work in your specific case.

@TauAkiou
Copy link

I tried on Fedora 31, built and worked up until I plugged in a pair of headphones, then crashed:

Kernel: 5.5.15-200.fc31.x86_64

2020-04-15 20:30:28 DEBUG - Opening device...
2020-04-15 20:30:28 INFO  - Dongle plugged in
2020-04-15 20:30:28 DEBUG - Firmware already loaded, resetting...
2020-04-15 20:30:28 DEBUG - Firmware loaded
2020-04-15 20:30:28 DEBUG - ASIC version: 7632
2020-04-15 20:30:28 DEBUG - MAC version: 7662
2020-04-15 20:30:28 DEBUG - Chip id: 7612
2020-04-15 20:30:28 INFO  - Wireless address: 62:45:b4:ee:94:05
2020-04-15 20:30:28 INFO  - Dongle initialized
2020-04-15 20:30:30 DEBUG - Client associating: 7e:ed:8c:80:45:6f
2020-04-15 20:30:30 INFO  - Controller '1' connected
2020-04-15 20:30:30 INFO  - Product ID: 02ea
2020-04-15 20:30:30 DEBUG - Firmware version: 3.1.1221.0
2020-04-15 20:30:30 DEBUG - Hardware version: 1284.1.1.1
2020-04-15 20:30:30 INFO  - Serial number: 03600187504835
2020-04-15 20:30:32 DEBUG - Battery type: 1, level: 3
2020-04-15 20:30:41 INFO  - Product ID: 02f6
2020-04-15 20:30:41 DEBUG - Firmware version: 3.1.1221.0
2020-04-15 20:30:41 DEBUG - Hardware version: 1284.1.1.1
terminate called after throwing an instance of 'InputException'
  what():  Error adding key code: Invalid argument
Aborted (core dumped)

@andreashuetter
Copy link

andreashuetter commented Apr 16, 2020

Hmm, I think you could try using the old xow.service file with the new audio branch. I've noticed that you're running PulseAudio as a system-wide daemon (--system), whereas most modern Linux distribution start individual instances of PulseAudio for each user, so a system-service might even work in your specific case.

I tried what you suggested: Using the old xow.service file with the new audio branch (on SteamOS).
The result is that the controllers work as expected, but when I plug in the headset, nothing happens (the controller is still working). I tried to select the headset for audio output, but it didn't appear anywhere.
I guess connecting the headset to the controller is supposed to lead to an additional audio sink beeing listed?

desktop@sn970:~$ pactl list sinks
Sink #0
	State: SUSPENDED
	Name: alsa_output.pci-0000_00_1f.3.analog-stereo
	Description: Internes Audio Analog Stereo
	Driver: module-alsa-card.c
	Sample Specification: s16le 2ch 44100Hz
	Channel Map: front-left,front-right
	Owner Module: 1
	Mute: yes
	Volume: front-left: 5621 /   9% / -64,00 dB,   front-right: 5621 /   9% / -64,00 dB
	        balance 0,00
	Base Volume: 65536 / 100% / 0,00 dB
	Monitor Source: alsa_output.pci-0000_00_1f.3.analog-stereo.monitor
	Latency: 0 usec, configured 0 usec
	Flags: HARDWARE HW_MUTE_CTRL HW_VOLUME_CTRL DECIBEL_VOLUME LATENCY 
	Properties:
		alsa.resolution_bits = "16"
		device.api = "alsa"
		device.class = "sound"
		alsa.class = "generic"
		alsa.subclass = "generic-mix"
		alsa.name = "ALC892 Analog"
		alsa.id = "ALC892 Analog"
		alsa.subdevice = "0"
		alsa.subdevice_name = "subdevice #0"
		alsa.device = "0"
		alsa.card = "0"
		alsa.card_name = "HDA Intel PCH"
		alsa.long_card_name = "HDA Intel PCH at 0xdf220000 irq 130"
		alsa.driver_name = "snd_hda_intel"
		device.bus_path = "pci-0000:00:1f.3"
		sysfs.path = "/devices/pci0000:00/0000:00:1f.3/sound/card0"
		device.bus = "pci"
		device.vendor.id = "8086"
		device.vendor.name = "Intel Corporation"
		device.product.id = "a170"
		device.form_factor = "internal"
		device.string = "front:0"
		device.buffering.buffer_size = "352800"
		device.buffering.fragment_size = "176400"
		device.access_mode = "mmap+timer"
		device.profile.name = "analog-stereo"
		device.profile.description = "Analog Stereo"
		device.description = "Internes Audio Analog Stereo"
		alsa.mixer_name = "Realtek ALC892"
		alsa.components = "HDA:10ec0892,19dab246,00100302"
		module-udev-detect.discovered = "1"
		device.icon_name = "audio-card-pci"
	Profile:
		analog-output: Analoge Ausgabe (priority: 9900)
		analog-output-lineout: Line Out (priority: 9900, not available)
	Aktive Profile: analog-output
	Formats:
		pcm

Sink #2
	State: SUSPENDED
	Name: alsa_output.pci-0000_01_00.1.hdmi-stereo-extra2
	Description: HDA NVidia Digital Stereo (HDMI)
	Driver: module-alsa-card.c
	Sample Specification: s16le 2ch 44100Hz
	Channel Map: front-left,front-right
	Owner Module: 15
	Mute: no
	Volume: front-left: 65536 / 100% / 0,00 dB,   front-right: 65536 / 100% / 0,00 dB
	        balance 0,00
	Base Volume: 65536 / 100% / 0,00 dB
	Monitor Source: alsa_output.pci-0000_01_00.1.hdmi-stereo-extra2.monitor
	Latency: 0 usec, configured 0 usec
	Flags: HARDWARE DECIBEL_VOLUME LATENCY SET_FORMATS 
	Properties:
		alsa.resolution_bits = "16"
		device.api = "alsa"
		device.class = "sound"
		alsa.class = "generic"
		alsa.subclass = "generic-mix"
		alsa.name = "HDMI 2"
		alsa.id = "HDMI 2"
		alsa.subdevice = "0"
		alsa.subdevice_name = "subdevice #0"
		alsa.device = "8"
		alsa.card = "1"
		alsa.card_name = "HDA NVidia"
		alsa.long_card_name = "HDA NVidia at 0xdf080000 irq 17"
		alsa.driver_name = "snd_hda_intel"
		device.bus_path = "pci-0000:01:00.1"
		sysfs.path = "/devices/pci0000:00/0000:00:01.0/0000:01:00.1/sound/card1"
		device.bus = "pci"
		device.vendor.id = "10de"
		device.vendor.name = "NVIDIA Corporation"
		device.product.id = "0fbb"
		device.string = "hdmi:1,2"
		device.buffering.buffer_size = "352768"
		device.buffering.fragment_size = "176384"
		device.access_mode = "mmap+timer"
		device.profile.name = "hdmi-stereo-extra2"
		device.profile.description = "Digital Stereo (HDMI)"
		device.description = "HDA NVidia Digital Stereo (HDMI)"
		alsa.mixer_name = "Nvidia GPU 71 HDMI/DP"
		alsa.components = "HDA:10de0071,19dab282,00100100"
		module-udev-detect.discovered = "1"
		device.icon_name = "audio-card-pci"
	Profile:
		hdmi-output-2: HDMI / DisplayPort 3 (priority: 5700, available)
	Aktive Profile: hdmi-output-2
	Formats:
		pcm

When I stop the xow service and start xow manually to get more info then it keeps printing that it has detected the audio device, but never stops printing this (even if I disconnect the headphone it keeps printing these lines) until I press Ctrl+C:

desktop@sn970:~$ sudo systemctl stop xow
desktop@sn970:~$ /usr/local/bin/xow
 INFO  - xow v0.4-17-g6c8aa7c ©Severin v. W.
 ERROR - Error creating lock file: Bad file descriptor
desktop@sn970:~$ sudo /usr/local/bin/xow
 INFO  - xow v0.4-17-g6c8aa7c ©Severin v. W.
 INFO  - Dongle plugged in
 INFO  - Wireless address: 62:45:b4:fa:b0:d2
 INFO  - Dongle initialized
 INFO  - Controller '1' connected
 INFO  - Product ID: 02ea
 INFO  - Serial number: 02600238452701
 INFO  - Accessory announced
 INFO  - Assuming it's an audio device
 INFO  - Accessory announced
 INFO  - Assuming it's an audio device
 INFO  - Accessory announced
 INFO  - Assuming it's an audio device
 INFO  - Accessory announced
 INFO  - Assuming it's an audio device
 INFO  - Accessory announced
 INFO  - Assuming it's an audio device
 INFO  - Accessory announced
 INFO  - Assuming it's an audio device
 INFO  - Accessory announced
 INFO  - Assuming it's an audio device
 INFO  - Accessory announced
 INFO  - Assuming it's an audio device
 INFO  - Accessory announced
 INFO  - Assuming it's an audio device
 INFO  - Accessory announced
 INFO  - Assuming it's an audio device
 INFO  - Accessory announced
 INFO  - Assuming it's an audio device
 INFO  - Accessory announced
 INFO  - Assuming it's an audio device
^C INFO  - Dongle power-off
 ERROR - Error in bulk read: LIBUSB_ERROR_NO_DEVICE
 ERROR - Error in bulk read: LIBUSB_ERROR_NO_DEVICE

@medusalix
Copy link
Owner

medusalix commented Apr 17, 2020

@TauAkiou It looks like it identified your headphones as an input device. I fixed this problem in the latest commit, but you might run into the same issue as @andreashuetter.

I guess connecting the headset to the controller is supposed to lead to an additional audio sink being listed?

Yes, it creates an audio sink for the controller's input (currently non-functional) and an audio source for the output. In your case, it seems to get stuck during the audio initialization (it should normally log Audio enabled). Further analysis will definitely require a USB packet capture (on Windows), where you're plugging in the headphones, so I can find out why xow refuses to work.

@Aerol
Copy link

Aerol commented Apr 18, 2020

Building audio branch and running xow from source directory I get the following output

❯ ./xow
2020-04-18 11:11:02 INFO - xow v0.4-19-gdfed4ea ©Severin v. W.
2020-04-18 11:11:02 DEBUG - Opening device...
2020-04-18 11:11:02 INFO - Dongle plugged in
2020-04-18 11:11:02 DEBUG - Firmware already loaded, resetting...
2020-04-18 11:11:02 DEBUG - Firmware loaded
2020-04-18 11:11:02 DEBUG - ASIC version: 7632
2020-04-18 11:11:02 DEBUG - MAC version: 7662
2020-04-18 11:11:02 DEBUG - Chip id: 7613
2020-04-18 11:11:02 INFO - Wireless address: 62:45:b5:10:74:a9
2020-04-18 11:11:02 INFO - Dongle initialized
2020-04-18 11:11:06 DEBUG - Client associating: 7e:ed:8c:45:0c:f7
2020-04-18 11:11:06 INFO - Controller '1' connected
2020-04-18 11:11:07 INFO - Device announced, id: 02dd
2020-04-18 11:11:07 DEBUG - Firmware version: 2.3.2385.0
2020-04-18 11:11:07 DEBUG - Hardware version: 2.1.1.1
2020-04-18 11:11:07 INFO - Device type: controller
2020-04-18 11:11:08 INFO - Device announced, id: 02e4
2020-04-18 11:11:08 DEBUG - Firmware version: 2.3.2385.0
2020-04-18 11:11:08 DEBUG - Hardware version: 2.1.1.1
2020-04-18 11:11:08 INFO - Device type: controller
terminate called after throwing an instance of 'InputException'
what(): Error adding key code: Invalid argument
[1] 23864 abort ./xow

That's with headset plugged in; without it runs normally

@medusalix
Copy link
Owner

medusalix commented Apr 18, 2020

@Aerol I've just pushed out a commit that should fix this issue.

@Aerol
Copy link

Aerol commented Apr 18, 2020

@Aerol I've just pushed out a commit that should fix this issue.

It has indeed!
Now getting more proper output

2020-04-18 13:35:39 DEBUG - Firmware version: 2.3.2385.0
2020-04-18 13:35:39 DEBUG - Hardware version: 2.1.1.1
2020-04-18 13:35:39 INFO - Device type: headset
2020-04-18 13:35:41 INFO - Device announced, id: 02e4

@medusalix
Copy link
Owner

medusalix commented Apr 20, 2020

@andreashuetter Your issue should most likely be fixed now (didn't need the USB capture).

@petrkutalek
Copy link

petrkutalek commented Jul 9, 2020

I don't think so. bluez-alsa is definitely userspace app and it creates sink device.

EDIT: There is a comment in the issue 48 that outlines other possible solutions via Alsa.

@medusalix
Copy link
Owner

medusalix commented Jul 9, 2020

I know about bluez-alsa, I even tried writing an Alsa PCM plugin for xow.
The point is that it simply doesn't behave like an audio card would. You can create sinks and sources that aplay and arecord can access. It's not exposed by PulseAudio and most applications can't even output to it. I need to create dedicated sound devices for xow, not a virtual device that you pipe your audio to.
Literally the only viable alternative would be PulseAudio modules, but they don't have a stable API.

@petrkutalek
Copy link

petrkutalek commented Jul 9, 2020

OK, thank you Severin. I do not agree with you, nevertheless I accept your decision on your (actually nice) project. 👍 I do not use Pulse Audio at all, just Alsa and I do not have any problems with it. I do not know any app that does not with Alsa but Pulse Audio. In fact Pulse Audio could utilize underlying Alsa. Nevermind.

@medusalix
Copy link
Owner

medusalix commented Jul 9, 2020

The problem is that applications like Discord show you a list of PulseAudio sinks and sources (at least if you've got PulseAudio installed). They simply don't give you an option to select which Alsa sink/source you want your output/input to go to. In fact, PulseAudio provides an Alsa device which allows legacy Alsa-only applications to interface with PulseAudio over their plugin.
Alsa PCM plugins unfortunately don't appear in PulseAudio's device list (at least to my knowledge) which means you have to use workarounds like aplay to route your default audio output to the Alsa plugin on systems where PulseAudio is installed.
It's not a decision I've taken, it's more like a shortcoming of Alsa's (and PulseAudio's) design. I'm definitely open for suggestions, I don't want to limit myself to a specific audio system, I just want to make sure it's (1) as simple as possible to use and (2) it works on every system out there.

@VanGrx
Copy link

VanGrx commented Jul 12, 2020

I examined audio branch from some repo that forked this one before when audio branch existed (sweet times 😢 ).

Basically, I think you made a good approach with simple API from PulseAudio (note that maybe async API will give better results. I managed to make some async API integration but as there were a lot of callbacks and controller needed to receive exact 0x600 bytes of data, that means threads and internal buffers implementation so I gave up for just POW case 😄 )

The only thing that should have been added that could be the key to the remaining problems is to create ALSA virtual device and connect with PulseAudio simple API to it. PulseAudio should automatically detect created ALSA virtual device so Discord user-case or any that needs PulseAudio should work. From there, PulseAudio simple(or async) API can be handled from xow and sent to controller(or to the virtual driver for mic).

@VanGrx
Copy link

VanGrx commented Jul 14, 2020

Hi guys,

After a wild adventure with ALSA drivers, I gave up and found more simple solution:

After calling
pactl load-module module-null-sink sink_name=XboxOutput sink_properties=device.description="Xbox_controller_sink"
Another device will be added to the pulse audio.
In the xow code, the changes were:

sink = pa_simple_new(
    nullptr,
    name.c_str(),
    PA_STREAM_PLAYBACK,
    "XboxOutput1",
    STREAM_NAME_SINK,
    &config,
    nullptr,
    nullptr,
    &error
);

and

source = pa_simple_new(
    nullptr,
    name.c_str(),
    PA_STREAM_RECORD,
    "XboxOutput1.monitor",
    STREAM_NAME_SOURCE,
    &config,
    nullptr,
    nullptr,
    &error
);

Note: difference is that 4th parameter is changed from nullptr to the name of the module we created.

After this, the audio was able to play only on headphones after selecting them from PulseAudio menu.

For the microphone to work, there must be another module created only for microphone capture. If I understood correctly in xow there must be 2 use-cases detected:
1 is when controller is sending special packet with audio samples and is waiting for the dongle to return them (to establish connection from what I tested)
2 is when controller is sending audio from the mic (in this case we should send samples to other module so we don't hear ourselves and so we can select that specific module for input in the apps)
So probably some special case should be if controller is connected or it is connecting.

Hope this is good progress for you and if you agree to integrate audio branch back with this changes included, I can continue on checking microphone pipeline that is needed. 😄

@medusalix
Copy link
Owner

Like I said in one of my earlier comments, I think if we're going to going to use PulseAudio's API for this then we'd be better of using module-pipe-sink and module-pipe-source directly instead of redirecting the audio through a null sink/source.
What bothers me the most is the fact that PulseAudio is by default running in local-user mode and only allows connections from your user account (not from root). That's the reason why I had to switch to a systemd user service for the audio branch. This will cause issues for multi-user systems because we can't have multiple instances of xow running at the same time. I don't think it makes much sense for a device driver to have per-user instances, as opposed to a single system-wide instance.

Now here's a solution that I'd imagine would work pretty well:

  • Running a second user-local script (or daemon) that connects to xow (via UNIX sockets or something else)
  • Whenever an audio device gets connected, xow sends the configuration (sample rate, etc.) to all connected user daemons
  • The user daemon sets up the pipe-sinks/sources and streams the audio data from xow

Either the suggestion outlined above or a dedicated PulseAudio module would work, I think.

@kakra
Copy link
Contributor

kakra commented Jul 14, 2020

I think that split-design is the best suggestion: Input devices should be created by system services because udev and logind already setup the permissions etc, connecting to pulse audio is a user service, so it needs to be the proxy between the xow system server and pulseaudio user service and it would probably be pretty light-weight. You could use dbus to signal the user service connection to the system daemon. For multiuser setups, there's "just" one thing to solve: You should track which user session currently claims the input device and only signal that particular user daemon. It should not be possible for other user sessions to "listen" to the audio.

@VanGrx
Copy link

VanGrx commented Jul 14, 2020

Like I said in one of my earlier comments, I think if we're going to going to use PulseAudio's API for this then we'd be better of using module-pipe-sink and module-pipe-source directly instead of redirecting the audio through a null sink/source.

The problem with piping is that you must always have a reader on the other side or the reproduction of the sound will block. That can block write() function in xow if I am not mistaken.

This will cause issues for multi-user systems because we can't have multiple instances of xow running at the same time.

This is overthinking. If multi-user case is a big issue, a install script option that runs PulseAudio in system-wide mode can resolve this (if anybody actually cares if xow is system wide or not). No need to add another layer just for case that will probably never happen.

@medusalix
Copy link
Owner

medusalix commented Jul 14, 2020

The problem with piping is that you must always have a reader on the other side or the reproduction of the sound will block. That can block write() function in xow if I am not mistaken.

According to pipe(7), a write with O_NONBLOCK set on the file descriptor should return EAGAIN in case the FIFO buffer is already full (please correct me if I'm wrong). If we load the module with pa_context_load_module the reader should be available right after the module is loaded.

This is overthinking. If multi-user case is a big issue, a install script option that runs PulseAudio in system-wide mode can resolve this.

You'd have to add an option that runs xow in system-wide mode though, not PA.

[...] if anybody actually cares if xow is system wide or not [...]

Would you expect your mouse or keyboard to turn off as soon as you logged out though? I certainly wouldn't. I believe nobody expects their input devices (or any device for that matter) to be bound to the lifetime of a specific user session. Oh, and there people who run multi-user systems (take a look at this comment).
I'm also curious about the (possible) issues that would arise by installing such a version of xow via a package manager like apt. Would the command sudo apt install xow be able to start the service for the current user? I don't know.

@kakra
Copy link
Contributor

kakra commented Jul 14, 2020

Would the command sudo apt install xow be able to start the service for the current user? I don't know.

Short answer: No... Long answer: apt runs in root context, it could run systemctl enable --now xow-system.service but that's it. The user would have to start it on its own. There's dbus activation for user services - not sure if it would work to activate a user service from a system service that way, I don't think so. But even then, the user session systemd must be reloaded to pick up the new service files. So: no. You'd need to re-login.

Also, I don't see why blocking in xow would be an issue as the writer could be implemented in a separate thread without blocking the main thread. It actually should be done that way. Also, the xow system service that receives the sound endpoint, doesn't even write directly to pa (except you manage to pass FDs around), it will probably be a proxy and should do reads and writes in separate threads anyways. The xow audio handler and input handler must be separate threads.

@VanGrx
Copy link

VanGrx commented Jul 14, 2020

According to pipe(7), a write with O_NONBLOCK

Also, I don't see why blocking in xow would be an issue as the writer could be implemented in a separate thread without blocking the main thread.

You are right, but, the problem that other audio apps also cannot play any audio until you start read thread from xow. So all audio on the system is blocked by the speed of xow read. I am not sure if this is OK as there are a lot of use-cases in my head that can block something. 😄 I also couldn't connect headphones with pipe module when testing my changes. With null sink, there is no block so connection was successful every time.

I am not sure right now what is the idea for read/write. I was suggesting to use null sink for audio playback on the headphones by monitoring the sink and for microphone to use pipe module but instead of PulseAudio API just write to the FIFO file. But now I think that was also your idea, right?

Oh, and there people who run multi-user systems (take a look at this comment).

I see the Steam OS issue, but I also can see from this comment that Steam OS is running pulse audio system wide and not --user, so running system-wide xow with audio patches would be a solution to this actually as I said in the comment that PA system-wide would solve this. Right?

For multiuser setups, there's "just" one thing to solve: You should track which user session currently claims the input device and only signal that particular user daemon. It should not be possible for other user sessions to "listen" to the audio.

Not sure about this. Wouldn't it be easier for user-space daemon to send to xow that he is active when he start, so xow can start communication with him when audio is connected?

@kakra
Copy link
Contributor

kakra commented Jul 15, 2020

Not sure about this. Wouldn't it be easier for user-space daemon to send to xow that he is active when he start, so xow can start communication with him when audio is connected?

I think it needs a two-way handshake:

  1. announce "I am here", the user session daemon registers with the system wide daemon.
  2. The system wide daemon announces "Here's an input device with audio, please listen and send" to the correct peer process.

At any time, the user session daemon should probably read and write audio but only relay it from/to the system wide daemon if it was actually announced. Until then, it just relays (generated) silence... That is unless there's a way to dynamically attach to the pipe API of PA and create sinks on the fly. That way it should not block if something isn't online.

Everything that goes deeper is currently out of my scope as I didn't look into the implementation details of the PA API. And also I'm currently still very busy with xpadneo and thus didn't dug much into the code of xow. It would be an interesting project of converting the dongle driver to a native kernel driver and see if we can expose the controller on the input bus there. This would make it possible to also expose a real audio device.

@ghost
Copy link

ghost commented Nov 16, 2020

Any news about audio integration ?

@sorryusernameisalreadytaken
Copy link

sorryusernameisalreadytaken commented Feb 27, 2021

@medusalix first of all, thank you for xow and your work. I respect that very much!

I've been looking for a better wireless headset that can send and receive good audio at the same time since the covid crap.

With the SteelSeries Arctis 9X Wireless Gaming Headset I found what I was looking for. On Windows it works great with Teams, Discord, Webex and Zoom. However, I would very much like to move on to Linux and not always have to switch to windows for meetings, for example.
Xow is here a piece of puzzle for me only unfortunately I have little idea of your coding-magic :D

I hope you don't mind my novel, but it would be a real highlight for me if this would work with the Pulseaudio connection.

If I can support you in any way, just say a word. :)

@Merrit
Copy link

Merrit commented Mar 2, 2021

@sorryusernameisalreadytaken

It can be very hard to devote dev time to an open source project when life is applying pressure, if you aren't able to contribute code our friendly xow dev accepts donations! 😀

There is a donate link on the xow README, here it is for convenience.

I always encourage those who are financially sound & enjoying an open source project to consider buying the devs a coffee to show their appreciation 🌈

Not everyone is in a financial position to do so, and that's okay too. Keep in mind things like answering community questions if you are able, providing troubleshooting, checking grammar and spelling, fleshing out READMEs & docs, managing a packaging aspect, many other things like this besides code can be a great help to a project. ❤️

@sorryusernameisalreadytaken

@sorryusernameisalreadytaken

It can be very hard to devote dev time to an open source project when life is applying pressure, if you aren't able to contribute code our friendly xow dev accepts donations! 😀

There is a donate link on the xow README, here it is for convenience.

I always encourage those who are financially sound & enjoying an open source project to consider buying the devs a coffee to show their appreciation 🌈

Not everyone is in a financial position to do so, and that's okay too. Keep in mind things like answering community questions if you are able, providing troubleshooting, checking grammar and spelling, fleshing out READMEs & docs, managing a packaging aspect, many other things like this besides code can be a great help to a project. ❤️

True. In the first place, I meant it more technically. Like for example create a suitable USB sniff under Windows or similar. Otherwise, I'm more in the Web / Java area on the road.

On my annual list is xow already, but to avoid fees, they take place only 1 time a year. Sounds a bit strange but it is partly unbelievable how much in fees for donations to the service providers falls off.

The idea with the documentation and issue responses is good.

@medusalix
Copy link
Owner

medusalix commented Jun 5, 2021

Hi, sorry for the delayed response.
I've been working on a new driver that includes support for audio devices through ALSA. You can find out more about it here. I'm always looking for testers and while it's currently wired-only it already paves the way for wireless audio functionality.

@sorryusernameisalreadytaken, @Merrit Thank you so much for your support!

@nkoester
Copy link

nkoester commented Jun 6, 2021

One general question regarding audio: How are multiple controllers handled? would it be possible to attach headphones to both controllers and have the same audio? This use-case exists for local multiplayer games

@medusalix
Copy link
Owner

How are multiple controllers handled?

Each gamepad is handled separately. You get individual input and output devices for every controller.

Would it be possible to attach headphones to both controllers and have the same audio?

That depends on the audio server you're using. For PulseAudio there's an option to simultaneously output audio to all devices.

@francisco-gamonal
Copy link

@sorryusernameisalreadytaken I also have an arctis 9x headset with the Microsoft Xbox Wireless adapter.

Everything works fine in windows 10, but I tried Ubuntu 20.04 with Xow and it doesn't appear as an audio device or microphone, did you manage to connect your headset in linux? Can I use the headset with audio and microphone for google meet? Steam games?

I would appreciate your help.

@sorryusernameisalreadytaken

@sorryusernameisalreadytaken I also have an arctis 9x headset with the Microsoft Xbox Wireless adapter.

Everything works fine in windows 10, but I tried Ubuntu 20.04 with Xow and it doesn't appear as an audio device or microphone, did you manage to connect your headset in linux? Can I use the headset with audio and microphone for google meet? Steam games?

I would appreciate your help.

Hello francisco-gamonal.
The arctis 9x headset has no usb-cable mode. You can just use Audio Input or output with Bluetooth or Xbox-Wireless. xow just work with devices that can handle this over a usb-cable.

Yes, you can use your arctis 9x headset with Linux but just with bluetooth at the moment. And sadly I need to say that the Headset-Audio protocol on Linux is not nice. Android's headset protocol is quite better and the propriatary Windows Headset protocol is one of the Best I know. By the way: Bluetooth is not cool for sending and receiving audio in the same moment. This is the reason I have a lot of hope for xow. xow could be the first solution to have a loseless Headset working on linux.

@TauAkiou
Copy link

The audio branch, as far as I've noticed, was dropped a long time ago and according to the readme.md, xow hasn't been regularly worked on for quite awhile now. The author is planning on replacing it with a proper kernel driver, which is poised to fix lots of the core issues Xow as far as I could always tell was never written with audio headsets in mind, either - just controllers.

I would recommend tracking progress on xone (https://github.com/medusalix/xone), which currently doesn't have support for the wireless dongle but is likely to at some point.

@francisco-gamonal
Copy link

@sorryusernameisalreadytaken thanks for your answer, right now I am using the headset with windows with dongle and in android by bluetooh, since with ubuntu through bluetooh the audio quality seems bad and the microphone does not work.

@TauAkiou I'm going to follow up on the xone project, maybe in the near future it will have dongle support in linux.

@medusalix medusalix added fixed in xone This issue has been fixed/resolved in xone and removed enhancement New feature or request labels Mar 20, 2022
@medusalix
Copy link
Owner

I've released a new driver for the Xbox wireless dongle that features audio input and output. You can check it out here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fixed in xone This issue has been fixed/resolved in xone
Projects
None yet
Development

No branches or pull requests