Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def _ctx_init(self):
if self._ctx:
with self._loop_lock:
self.disconnect()
c.pa.context_unref(self._ctx)
self._ctx = c.pa.context_new(self._api, self.name)
c.pa.context_set_state_callback(self._ctx, self._pa_state_cb, None)
c.pa.context_set_subscribe_callback(self._ctx, self._pa_subscribe_cb, None)
def init(self):
self._pa_state_cb = c.PA_STATE_CB_T(self._pulse_state_cb)
self._pa_subscribe_cb = c.PA_SUBSCRIBE_CB_T(self._pulse_subscribe_cb)
self._loop, self._loop_lock = c.pa.mainloop_new(), FakeLock()
self._loop_running = self._loop_closed = False
self._api = c.pa.mainloop_get_api(self._loop)
self._ret = c.pa.return_value()
self._ctx_init()
self.event_types = sorted(PulseEventTypeEnum._values.values())
self.event_facilities = sorted(PulseEventFacilityEnum._values.values())
self.event_masks = sorted(PulseEventMaskEnum._values.values())
self.event_callback = None
return print(f'{func_label} (type={vt}): {val:.2f} -> {func(val):.2f}')
if opts.conf: conf = conf_read(opts.conf)
for k,v in vars(opts).items(): setattr(conf, k, v)
del opts
logging.basicConfig(
level=logging.DEBUG if conf.debug else logging.WARNING,
format='%(asctime)s :: %(threadName)s %(levelname)s :: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S' )
log = get_logger('main')
print = ft.partial(print, file=sys.stderr, flush=True) # stdout is used by curses
log.debug('Initializing...')
while True:
with Pulse('pa-mixer-mk3', connect=False, threading_lock=True) as pulse:
pulse.connect(wait=conf.reconnect)
attic, streams = None, PAMixerStreams(pulse, conf, fatal=conf.fatal)
if conf.show_stored_values and pulse.stream_restore_test() is not None:
attic = PAMixerAttic(streams.update_wakeup, conf, fatal=conf.fatal)
with streams.update_wakeup_poller(streams.update_wakeup_handler) as poller_thread:
log.debug('Starting pulsectl event poller thread...')
poller_thread.start()
with PAMixerUI(streams, attic, conf) as curses_ui:
# Any output will mess-up curses ui, so try to close sys.stderr if possible
if not conf.verbose and not conf.debug and not conf.dump_stream_params:
sys.stderr.flush()
fd = os.open(os.devnull, os.O_WRONLY)
os.dup2(fd, sys.stderr.fileno())
def _ctx_init(self):
if self._ctx:
with self._loop_lock:
self.disconnect()
c.pa.context_unref(self._ctx)
self._ctx = c.pa.context_new(self._api, self.name)
c.pa.context_set_state_callback(self._ctx, self._pa_state_cb, None)
c.pa.context_set_subscribe_callback(self._ctx, self._pa_subscribe_cb, None)
def init(self):
self._pa_state_cb = c.PA_STATE_CB_T(self._pulse_state_cb)
self._pa_subscribe_cb = c.PA_SUBSCRIBE_CB_T(self._pulse_subscribe_cb)
self._loop, self._loop_lock = c.pa.mainloop_new(), FakeLock()
self._loop_running = self._loop_closed = False
self._api = c.pa.mainloop_get_api(self._loop)
self._ret = c.pa.return_value()
self._ctx_init()
self.event_types = sorted(PulseEventTypeEnum._values.values())
self.event_facilities = sorted(PulseEventFacilityEnum._values.values())
self.event_masks = sorted(PulseEventMaskEnum._values.values())
self.event_callback = None
def connect(self, autospawn=False, wait=False):
'''Connect to pulseaudio server.
"autospawn" option will start new pulse daemon, if necessary.
Specifying "wait" option will make function block until pulseaudio server appears.'''
if self._loop_closed:
raise PulseError('Eventloop object was already'
' destroyed and cannot be reused from this instance.')
if self.connected is not None: self._ctx_init()
flags, self.connected = 0, None
if not autospawn: flags |= c.PA_CONTEXT_NOAUTOSPAWN
if wait: flags |= c.PA_CONTEXT_NOFAIL
try: c.pa.context_connect(self._ctx, self.server, flags, None)
except c.pa.CallError: self.connected = False
while self.connected is None: self._pulse_iterate()
if self.connected is False: raise PulseError('Failed to connect to pulseaudio server')
kws = list(it.starmap('{}={}'.format, kws.items()))
if fields:
if is_str_native(fields): fields = fields.split()
kws.extend('{}={!r}'.format(k, getattr(self, k)) for k in fields)
kws = sorted(kws)
if ext: kws.append(str(ext))
return ', '.join(kws)
def __str__(self):
return self._as_str(fields=self.c_struct_fields)
def __repr__(self):
return '<{} at {:x} - {}>'.format(self.__class__.__name__, id(self), str(self))
class PulsePortInfo(PulseObject):
c_struct_fields = 'name description available priority'
def _init_from_struct(self, struct):
self.available = PulsePortAvailableEnum._c_val(struct.available)
self.available_state = self.available # for compatibility with <=17.6.0
def __eq__(self, o):
if not isinstance(o, PulsePortInfo): raise TypeError(o)
return self.name == o.name
def __hash__(self): return hash(self.name)
class PulseClientInfo(PulseObject):
c_struct_fields = 'name index driver owner_module'
class PulseServerInfo(PulseObject):
"channel_list" can be a pulse channel map string (comma-separated) or list
of channel names. Defaults to stereo map, should probably match volume channels.
"device" - name of sink/source or None (default).'''
if is_str(struct_or_name):
struct_or_name = self.struct_from_value(
struct_or_name, volume, channel_list, mute, device )
super(PulseExtStreamRestoreInfo, self).__init__(struct_or_name)
def to_struct(self):
return self.struct_from_value(**dict(
(k, getattr(self, k)) for k in 'name volume channel_list mute device'.split() ))
def __str__(self):
return self._as_str(self.volume, fields='name mute device')
class PulseEventInfo(PulseObject):
def __init__(self, ev_t, facility, index):
self.t, self.facility, self.index = ev_t, facility, index
def __str__(self):
return self._as_str(fields='t facility index'.split())
class Pulse(object):
_ctx = None
def __init__(self, client_name=None, server=None, connect=True, threading_lock=False):
'''Connects to specified pulse server by default.
Specifying "connect=False" here prevents that, but be sure to call connect() later.
"connect=False" can also be used here to
def connect(self, autospawn=False, wait=False):
'''Connect to pulseaudio server.
"autospawn" option will start new pulse daemon, if necessary.
Specifying "wait" option will make function block until pulseaudio server appears.'''
if self._loop_closed:
raise PulseError('Eventloop object was already'
' destroyed and cannot be reused from this instance.')
if self.connected is not None: self._ctx_init()
flags, self.connected = 0, None
if not autospawn: flags |= c.PA_CONTEXT_NOAUTOSPAWN
if wait: flags |= c.PA_CONTEXT_NOFAIL
try: c.pa.context_connect(self._ctx, self.server, flags, None)
except c.pa.CallError: self.connected = False
while self.connected is None: self._pulse_iterate()
if self.connected is False: raise PulseError('Failed to connect to pulseaudio server')
def connect(self, autospawn=False, wait=False):
'''Connect to pulseaudio server.
"autospawn" option will start new pulse daemon, if necessary.
Specifying "wait" option will make function block until pulseaudio server appears.'''
if self._loop_closed:
raise PulseError('Eventloop object was already'
' destroyed and cannot be reused from this instance.')
if self.connected is not None: self._ctx_init()
flags, self.connected = 0, None
if not autospawn: flags |= c.PA_CONTEXT_NOAUTOSPAWN
if wait: flags |= c.PA_CONTEXT_NOFAIL
try: c.pa.context_connect(self._ctx, self.server, flags, None)
except c.pa.CallError: self.connected = False
while self.connected is None: self._pulse_iterate()
if self.connected is False: raise PulseError('Failed to connect to pulseaudio server')