-
Notifications
You must be signed in to change notification settings - Fork 213
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
Basic audio working. Many kinks. #80
base: master
Are you sure you want to change the base?
Conversation
@@ -145,6 +160,11 @@ def control(self, big_rumble=0, small_rumble=0, | |||
# Time to flash dark (255 = 2.5 seconds) | |||
pkt[offset+9] = min(flash_led2, 255) | |||
|
|||
if report_id == 0x11: | |||
pkt[offset+18] = min(volume_l, 255) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It appears that the volume is set in percentage.
0-100
And I do not understand why there needs gtk. Maybe better use GObject.MainLoop. And gst.Bus for catch EOS and other signal from gstreamer |
Me neither. It was in the tutorials I was following and it worked. I'll check those bits out. |
GObject.MainLoop is working MUCH better. |
I've finally got a pure pulseaudio / sbc implementation working in C. Getting the buffering right was a real pain. I'm looking into wrapping the necessary bits and pieces for python. |
@poconbhui Have a link to the C example? |
@parkerlreed I've just pushed a working pulseaudio/sbc implementation. It's pretty rough and still has some debug print statements littered throughout. Getting some of this stuff working nicely is a bit painful. Python threading and multiprocessing has a number of painful limitations so it works in Windows and Linux, which I don't really care about here. I started out trying to use the data management bits from those modules, but os.pipe does a muuuch better job than anything I could put together with them. Another is that writing to the hidraw output on my system sometimes hangs, so I need some way of interrupting a system call. Python only allows signal/setitimer to be set on the main thread. I've managed to add a gross workaround here using the multiprocessing Pool. I've opted not to use a pure Process, since these sometimes die unexpectedly and a Pool reboots its worker thread automatically. I think the audio timeout needs some tweaking as well. I'm not sure of the best way of getting frame time length, since the result from sbc_get_frame_duration seems to lie on my system. I think SWIG might be overkill here too. I can probably make the pulseaudio class an opaque type and make new/start/stop/add_fd/remove_fd functions with C linkage and just wrap those with ctypes. I just used it because I've used it a number of times before. I should probably also wrap sbc.h instead of the sbc header parser I wrote from following the docs. |
… controller's eventloop.
This should now be fully integrated with the controller's eventloop, so each controller is processing their own audio on their own thread. I'm finding that sending other data to the controller, ie LED colour update on profile switch, causes some skipping in the audio. I think a different model of writing data to the controller might be better. I'm thinking of a constant write loop which will sync the ds4drv controller state to the controller, including LED, audio etc, instead of different events competing for bandwidth. |
…works as expected.
…tation on what to check is poor, so I can't be sure what I've missed.
Ok, I think this is about it on my end as far as basic implementation goes. Could someone give this a go on their machine and tell me if it works well enough? I think the timeout might still not be tight enough. I'm sure @Ape will have plenty to say about my style and a number of bits and pieces that may need some cleaning up. |
Thanks for your effort, we are actually getting audio support! I tried using this. It runs and creates a pulse audio sink just fine, but the audio I am hearing sounds like this (no matter what I try to play): https://x.ape3000.com/projects/ds4drv/audio.mp3 |
…r sink is set up.
Sounds like an encoding issue. I've tried fixing it there. Let me know if that worked. It all works on my machine, so I might have some difficulty guessing what's wrong from my end... |
I'll test on my end in just a second. |
Ok so I have ds4drv installed from your add-audio branch. Do I just launch ds4drv in --hidraw mode and it should work or is there an argument to pass? |
I just ran Checked the hidraw permissions and saw they were rw for everybody. Tried without sudo and I get the same two sinks that don't output to controller. Also closing out of ds4drv via ^C doesn't clean up the sinks. EDIT: Ok exiting cleans up one sink but not the other. |
Rebooted to start fresh. Running ds4drv as user created the single sink correctly but still no audio output. I am using the Bluez method of Share + PS to connect and get the hidraw device. |
... It works. I didn't realize it was only outputting to the headphone jack. :| I kept wondering why it wasn't going to the speaker, haha. Few pops here and there but overall sounds really good on a set of speakers. (Pops are probably just due to Bluetooth connection) |
Sweet. Some options and tweaks still need to be added to handle audio like managing the headphone jack and volume. Are the sinks cleaning up properly now? Are you sure you only have one instance of ds4drv with audio running? I still need to add some stuff for reconnecting to pulseaudio if it's killed at some point. |
Yeah the double sinks just seemed to be an issue with pulse running as user and ds4drv as root. All running as user works and cleans up correctly. |
The current version works really well. There are just some rare pops like parkerlreed said. Clean up seems to be working for me. Is it possible to add another sink for the controller speaker? Or is just one stream at a time? Does this work with multiple controllers at once? |
@poconbhui i realized that this is in development atm ;) Also i must say this is an incredebile amazing work from you and i hope i can investigate and help to bring this to SteamOS and other OS edit.: also sbc.h should be maybe packed with this version because SteamOS failed to find it easily edit2: if we manage to make this fully working i will try to take the code to the windows version wich is more like my skills |
… out any c++11 only bits.
Check out if Jessie has sbc and sbc-dev as separate packages. The -dev might be needed for building. It comes as the one sbc package on my distro. If they are split into package and package-dev, something like pulse-dev and boost-dev might be needed for building as well. The compiler doesn't have -std=c++11 set because I didn't put it in setup.py. My version of gcc (6.1.1) has -std=gnu++14 by default, so I missed it. Whatever is on Jessie probably has an older standard as default. I've set -std=c++98, the oldest, reasonable one that seemed to work and stripped out the c++11 only headers. Should compile fine on Jessie now... hopefully. See the discussion with @a1ien (#76) for more information on playing audio and a simpler example if you're looking to get it working on Windows. |
are you still working with Python 2.7 ? or do i need to run it in Python3.5.x Environment. |
I've been working with python 3 so this branch might have some python 3 only syntax in it. It should be python 2.7 compatible when it's done and cleaned up. |
I saw this :) on debian i#m searching for a way to setup python3.5 since 3.4 also have errors in multithreading and TimeoutError is a Python3.5.2 definition. |
Ah... oh dear... That one piece of multithreading is vital... but TimeoutError can be changed to anything. I'll have a look at running it with python 2.7 next chance I get. |
Seems like really really good work here. What needs to happen for this to get merged in? |
The audio isn't perfectly smooth. The fundamental problem is the threading model in python. I think the threading model in python isn't performant enough to keep up with audio because of the global interpreter lock. One approach to fix it would be to run the audio stream and sending messages to the controller in a separate process using the multiprocessing module and have the main process pass messages about volume, led, rumble to that process via queues. Adding it in nicely could need a pretty hefty change to how sending and receiving messages is handled. It's a bit gross and I haven't played with the controller in a while, so I've not touched it yet. |
Hi,
With file playback you can throttle the data you send, with live stream you perhaps can deliberate delay a little to ensure that the buffer never empties. |
Hi all,. Cheers, |
Hey guys im sorry im from Windows 7, i saw that you have been get progress in audio from ds4 on pc, do you have anything for windows ? thank you |
yes, please |
@mungewell Is that latest script only for raw file playing? Would be cool to test input going into Pulse. |
Hey @poconbhui sorry for the dumb question, I've been reading all these threads and looking at your code out of curiosity, did you initially write the pulseaudio_sbc_stream in C++ to get it working and then port it to python so that it could be used within the ds4drv project? I'm just trying to figure out the general structure of your code and how it's used from the main project. Thanks for any help. Edit: Second question, I have your ds4drv running but I get the error "AttributeError: 'DS4Controller' object has no attribute 'sbc_stream'" after I connect to my controller. Might be wonky since i'm running Ubuntu as a dual boot on my MacBook Pro, but everything seems to be working fine so far. |
@mungewell Would you mind explaining to me how I should go about using your python file? I'm noticing weird behavior. I have the correct device entered but all the script does is change my LED color to a kind of turqoise every time. I got the original script to play choppy audio so I know nothing's wrong with the controller. I followed the preparation instructions but I assume i'm passing parameters wrong. I tried giving a wav, au, and sbc, file all of which didn't work and i prepared the au file with either method. What am i missing? |
@JunPritsker From what I tested that script isn't for Pulseaduio or even playing a regular file. You have to pipe it a very specific format. Check the first handful of comments in that file if you haven't already (I honestly couldn't get it going myself either) |
@parkerlreed Oh ok gotcha, are you saying I should just pipe the output of that sox command to the execution of the python file? I used test.au which I generated with my wav file as the first parameter to the playfile and playfile produces output as if it's working except the only effect on the DS4 is the change in LED color like I said. |
@JunPritsker It's written in C++ and wrapped with SWIG so it can be called from Python. I started trying to wrap the pulseaudio stuff for python using ctypes, but there was too much wrapping and faffing involved, so I wrote the C stuff in C (later in C++) and has SWIG automatically generate the necessary interfaces. It's a bit of a nuclear option with so few exported interfaces now, but there were many more in earlier development. I can't say why you're getting the error you are because I haven't looked at the code in a good while. It still needs a bit of cleaning up and hardening. My controller is in a different country so I can't do much for now :( |
Ok gotcha, thanks for clarifying. I should've looked more into the uses of SWIG, I didn't know that it was used to wrap code for higher level use! Could you spare me one more explanation about all of the preparation of the audio before it can be streamed to the controller? I don't know much when it comes to audio but I do understand everything that's going on with the HID communication and whatnot. Any reading you could point me to would be fine too. Also, Happy New Year! |
Pulseaudio is a little gross because it's all based on callbacks. I eventually get the pulse stuff wrangled so it runs a the The pulseaudio manager is run in a separate C++ thread (as opposed to a python thread) for performance reasons. The file descriptor mentioned is made on the python end and passed to the pulseaudio manager with the Information on the format for the bluetooth frames sent to the controller can be found at http://eleccelerator.com/wiki/index.php?title=DualShock_4 , more information on playing about with sending audio to the controllers at #76 . Depending how into SBC encoding you want to go, the SBC specs are available in the A2DP docs. Mostly useful for knowing exactly how long SBC frames and headers are going to be. The pulseaudio docs are absolute crap. If you want more info on that, I can go into my development approach there. |
@poconbhui Did something stop working with https://github.com/poconbhui/ds4drv/tree/add-audio ? Tried both with and without sudo, pulse sink shows up either way, but no audio can be heard on speaker or headset. EDIT: Oh I forgot to connect with Bluez first and use --hidraw, woops Not sure if interference but latency is really really bad at the moment. |
@poconbhui I know this a very old thread, but I'm hoping you will be able to help me with the audio branch for ds4drv. I cloned your 'add-audio' branch and installed it using command: I had to download a few dependence, but I was able to get the project to compile and run. I first connect my DS4 (version 1, original controller) with the bluetooth that comes with Ubuntu 16.04 Here is my terminal output: `[info][PulseaudioSBCStream] Connecting to Pulseaudio [info][PulseaudioSBCStream] Stream format s16le [info][PulseaudioSBCStream] Stream sample rate 32000 [info][PulseaudioSBCStream] Stream codesize: 512 [info][PulseaudioSBCStream] Stream frame_length: 112 [info][controller 1] Created devices /dev/input/js1 (joystick) /dev/input/event23 (evdev) [info][controller 1] Connected to Bluetooth Controller (2A:26:1D:3C:91:5B hidraw5) [info][hidraw] Scanning for devices [info][controller 1] Battery: 50% [info][controller 1] Audio: Speaker [info][controller 1] Audio: Headphones [info][controller 1] Audio: Headset Do you see a problem that I could be missing or running in to? |
@mungewell Your script is no longer hosted on dropbox. Would you mind reuploading in a more permanent location, such as a gist or fork? |
@jonas222 I have the same problem. Have you find a solution to make? I am in ubuntu 18.04.
|
apologies if necroposting but i get the same exact result as jonas222 on Fedora 38 using the same steps |
This is a little nebulous. I pulled the audio processing out to another thread for performance. So there's effectively two event machines going on here over a number of threads. I could probably do with cleaning up some terminology. Suggestions?
I'm having some weird problems with Gtk where xcb is complaining about multiple threads. I'm also having an annoying issue where the write_report function isn't being called from a "main thread" for the audio, even though I'm pretty sure it's being called from a process in a way I've done before, so I can't put a timeout on the write. The write timeout is pretty important on my end for smooth audio.
I might actually start looking at pulling Gtk/gstreamer out now since they aren't playing nicely with threads.