Closed RESP3CT88 closed 3 years ago
There's no PulseSimple class in this repository. Pretty sure it's the wrapper from https://github.com/SoundWall/python-pulse-control repo, and you're probably using that fork, so should file an issue there, as that code is obviously was written and maintained by different folks, and I don't know much about it.
Going just by what I know about python, error seem to be that you didn't pass period_size
value to that class, which is apparently required, but defaults to None, causing it to be passed as None into that c.PA_BUFFER_ATTR()
struct, where - as error says - an integer is required.
(you can see that all other values in that stuct are static and hardcoded)
But you should file an issue there, if that repo is maintained, as again, I have no control or any kind of relation to it.
With regards to playing wav through this module in general ("this" as in mk-fg/python-pulse-control one, where you filed this issue, not the fork):
As README here says, it's not supported, and is not very useful thing to implement in blocking python code, as you'd have to do relatively intensive stuff fast, or have bad sound artifacts (buffer underruns, causing stuttering, crackle, etc), and with sync code you basically can't do anything else at the time, as that can easily block such performance-critical stuff.
Haven't really tested it though, and maybe modern hw is fast enough to do such stuff anyway, but imo it should at least be wrapped into something like asyncio to be useful, so that you can do other stuff concurrently without uncontrollable GIL switches and such.
Also, wrt playing wav from python through pulseaudio:
If it's an arbitrary wav file that you want to play once and forget about it, I'd probably use something like subprocess.run(['paplay', file_path])
to play it.
paplay is a small cli playback tool that comes with pulse, it has a bunch of relevant pulseaudio playback options exposed (e.g. can specify sink by name/index or set other stream parameters), and it'd run the background (just use "Popen" instead of "run" to start subprocess), allowing your other code to work without breaking the playback (as mentioned above).
If you are using this wav as some kind of notification chime over-and-over, e.g. play it when button is clicked or something, there is a liteweight wrapper lib for that - libcanberra, which is usually installed alongside pulse on all linux desktop systems.
It allows you to load specific file (or lookup sound file from a current user's XDG linux desktop theme) as a kind of "system sound" and then start playing it anytime by command.
You can probably google some better wrapper for it, but I've used it from python via ctypes here - https://github.com/mk-fg/notification-thing/blob/master/notification_thing/sounds.py - can save/import and use that in your code too (just a ~100-line wrapper).
While you did explicitly mention that you don't want to use ALSA, note that pulseaudio usually gets installed along with alsa compatibility module, which sends all playback done through ALSA userspace libs (libasound) to pulseaudio server (which is why e.g. "aplay" can work concurrently with pulse playback), so you can generally use its API and wrappers for playback just fine too, as it'll almost certainly end up in pulse anyway, if it's used on a particular system where you run that code at all.
Just thought to mention, in case you might want to explore alternatives to running sound playback stream from a python code, due to caveats mentioned in prev comment or whatever issues with the module there.
Thanks for the thorough answer! I will likely just use paplay or aplay. Sounds complicated to get sound playback from the API.
I am simply trying to playback a .wav file through my speakers using this API. I want to use PulseAudio to play a wav and not ALSA.
Any ideas what is wrong? Or is there a better way to play audio in python using a sink's name?