Closed mfeif closed 8 years ago
Ok, digging a little deeper (sorry):
In _pulsectl.py, there is wrapping for state:
class PA_SINK_INFO(Structure):
_fields_ = [
('name', c_char_p),
('index', c_uint32),
('description', c_char_p),
('sample_spec', PA_SAMPLE_SPEC),
('channel_map', PA_CHANNEL_MAP),
('owner_module', c_uint32),
('volume', PA_CVOLUME),
('mute', c_int),
('monitor_source', c_uint32),
('monitor_source_name', c_char_p),
('latency', PA_USEC_T),
('driver', c_char_p),
('flags', c_int),
('proplist', POINTER(PA_PROPLIST)),
('configured_latency', PA_USEC_T),
('base_volume', c_int),
('state', c_int),
('n_volume_steps', c_int),
('card', c_uint32),
('n_ports', c_uint32),
('ports', POINTER(POINTER(PA_PORT_INFO))),
('active_port', POINTER(PA_PORT_INFO)),
]
But in pulsectl.py:
class PulseSinkInfo(PulseObject):
c_struct_fields = ( 'index name mute'
' description sample_spec owner_module latency driver'
' monitor_source monitor_source_name flags configured_latency' )
def __str__(self):
return self._as_str(self.volume, fields='index name description mute')
So maybe I can just add that?
What about suspend cause? Doesn't seem like it's in the api.
Ok, I've answered my own question and added it. The pull request is #4
Hey,
Yeah, there's more stuff in pulseaudio than exposed in python, which I just didn't need for the use-cases I had, so didn't spend time wrapping. Probably a good idea to mention exactly that in the README, and link this issue so that anyone interested in these would know where to look and how to add these, as you've described the whole process.
In general, C headers and docs for libpulse are most useful to discover which structs have needed (and maybe not yet exposed in python) info, and how to parse/use it, with most things residing in src/pulse/introspect.h and src/pulse/def.h.
Unfortunately, suspend cause seem to only live as a value in server structs, described in core.h and handled in sink.c:
/* This is a bitmask that encodes the cause why a sink/source is
* suspended. */
typedef enum pa_suspend_cause {
PA_SUSPEND_USER = 1, /* Exposed to the user via some protocol */
PA_SUSPEND_APPLICATION = 2, /* Used by the device reservation logic */
PA_SUSPEND_IDLE = 4, /* Used by module-suspend-on-idle */
PA_SUSPEND_SESSION = 8, /* Used by module-hal for mark inactive sessions */
PA_SUSPEND_PASSTHROUGH = 16, /* Used to suspend monitor sources when the sink is in passthrough mode */
PA_SUSPEND_INTERNAL = 32, /* This is used for short period server-internal suspends, such as for sample rate updates */
PA_SUSPEND_ALL = 0xFFFF /* Magic cause that can be used to resume forcibly */
} pa_suspend_cause_t;
Don't think there's access to these from the client, only through "dump" command in "module-cli", head request on http, in logs on SIGHUP, afaict.
I think connecting to that socket (pa_runtime_path("cli")
) and opening it (pulse has signal for loading module-cli) can be handled in the module, and then I guess you can write "dump" there from the app and parse cause from the response.
Doesn't seem much better than e.g. running pacmd dump
from subprocess in this case though.
Maybe present your case to pulse developers and ask to expose that info client API, same as state value itself? Would definitely be a lot simplier to get it there.
Merged #4, but changed how "state" is exposed a bit (to allow for more values without multiple boolean attrs, 03bea80), as mentioned there.
Also added a note with link to this issue to the README, as of 3d0cca8.
Will probably also add some "connect_to_cli_socket" method (mimicking what pacmd does), as mentioned.
Added pulse.connect_to_cli()
in fde0096, but as noted in the README, parsing state reason from "dump" output is probably still not a great idea, yet I don't think there's a way to get it from server in any other fashion (in a generic pulseaudio setup).
Easiest ways to make it available cleanly I think are patching pulseaudio introspection api (preferrably upstream, as mentioned), or installing/loading custom pulseaudio module (.so file, compiled against installed pulseaudio) that'd expose that stuff in some way.
Note that I say this based on brief skimming through the code, so if you really need that info and both ways above are not good enough, I'd suggest double-checking yourself and maybe asking in e.g. #pulseaudio (on freenode irc) to confirm that I haven't missed something.
Thanks!
I can live without suspend cause, but I do need state.
I didn't know about the other values for state; yeah, having 4 booleans would have been too much.
Hi there. Thanks for this library! I've been looking for something like this, and am extremely grateful that someone has put in the hard work to make it possible.
I am interested (it seems) in a feature that isn't present in your wrapper, or perhaps it isn't present in libpulse...
When I use pacmd, and
list-sinks
, I get output like this:And doing
pulse.sink_list()
gives me a python list representation of this (awesome!). But if I inspect one of the sink objects, I get fewer attributes:In particular, I'm looking for "state: RUNNING", "suspend cause:"... I'd like to write some code that detects when sound is flowing, or at least when PA thinks it hasn't and has therefore suspended a sink.
Am I missing something?
Thanks again!