[alsa-devel] [PATCH - hwmixvolume 3/9] hwmixvolume: use four spaces instead of one tab for indent
Emmanuel Gil Peyrot
linkmauve at jabberfr.org
Wed Aug 8 17:56:31 CEST 2018
Signed-off-by: Emmanuel Gil Peyrot <linkmauve at linkmauve.fr>
diff --git a/hwmixvolume/hwmixvolume b/hwmixvolume/hwmixvolume
index 039ca17..267228c 100755
--- a/hwmixvolume/hwmixvolume
+++ b/hwmixvolume/hwmixvolume
@@ -29,289 +29,289 @@ EVENT_INFO = alsahcontrol.event_mask['INFO']
EVENT_REMOVE = alsahcontrol.event_mask_remove
class Stream:
- def __init__(self, element, parent):
- self.element = element
- self.element.set_callback(self)
- self.parent = parent
- self.label = None
- self.scales = []
- self.adjustments = []
- self.callback(self.element, EVENT_INFO)
-
- def destroy(self):
- self.deactivate()
-
- def callback(self, e, mask):
- if mask == EVENT_REMOVE:
- self.deactivate()
- elif (mask & EVENT_INFO) != 0:
- info = alsahcontrol.Info(self.element)
- if info.is_inactive:
- self.deactivate()
- else:
- self.activate()
- elif (mask & EVENT_VALUE) != 0:
- self.update_scales_from_ctl()
-
- def activate(self):
- if self.label:
- return
- info = alsahcontrol.Info(self.element)
- value = alsahcontrol.Value(self.element)
- value.read()
- values = value.get_tuple(TYPE_INTEGER, info.count)
- self.label = Gtk.Label(self.get_label(info))
- self.label.set_single_line_mode(True)
- self.parent.scales_vbox.add(self.label)
- for i in range(info.count):
- adj = Gtk.Adjustment(value=values[i],
- lower=info.min, upper=info.max,
- step_incr=1,
- page_incr=(info.max-info.min+1)/8)
- adj.connect('value-changed', self.update_ctl_from_scale, i)
- scale = Gtk.HScale(adj)
- scale.set_draw_value(False)
- self.parent.scales_vbox.add(scale)
- self.scales.append(scale)
- self.adjustments.append(adj)
- self.parent.scales_vbox.show_all()
- self.parent.update_msg_label()
-
- def deactivate(self):
- if not self.label:
- return
- self.label.destroy()
- for s in self.scales:
- s.destroy()
- self.label = None
- self.scales = []
- self.adjustments = []
- self.parent.update_msg_label()
-
- def update_scales_from_ctl(self):
- if not self.label:
- return
- count = len(self.adjustments)
- value = alsahcontrol.Value(self.element)
- value.read()
- values = value.get_tuple(TYPE_INTEGER, count)
- for i in range(count):
- self.adjustments[i].set_value(values[i])
-
- def update_ctl_from_scale(self, adj, index):
- scale_value = adj.get_value()
- value_to_set = int(round(adj.get_value()))
- count = len(self.adjustments)
- value = alsahcontrol.Value(self.element)
- if self.parent.lock_check.get_active():
- values = [value_to_set for i in range(count)]
- else:
- value.read()
- values = value.get_array(TYPE_INTEGER, count)
- values[index] = value_to_set
- value.set_array(TYPE_INTEGER, values)
- value.write()
- if value_to_set != scale_value:
- adj.set_value(value_to_set)
-
- def get_label(self, info):
- pid = self.get_pid(info)
- if pid:
- cmdline = self.get_pid_cmdline(pid)
- if cmdline:
- return cmdline
- else:
- return "PID %d" % pid
- else:
- name = info.name
- if name[-7:] == " Volume":
- name = name[:-7]
- if name[-9:] == " Playback":
- name = name[:-9]
- return name
-
- def get_pid(self, info):
- card = self.parent.current_card
- device = info.device
- subdevice = info.subdevice
- if subdevice == 0:
- subdevice = info.index
- filename = "/proc/asound/card%d/pcm%dp/sub%d/status" % (card, device, subdevice)
- try:
- f = open(filename, "r")
- except IOError:
- return None
- try:
- for line in f.readlines():
- if line[:9] == "owner_pid":
- return int(line.split(':')[1].strip())
- finally:
- f.close()
- return None
-
- def get_pid_cmdline(self, pid):
- try:
- f = open("/proc/%d/cmdline" % pid, "r")
- except IOError:
- return None
- try:
- cmdline = f.read()
- finally:
- f.close()
- return cmdline.replace('\x00', ' ').strip()
+ def __init__(self, element, parent):
+ self.element = element
+ self.element.set_callback(self)
+ self.parent = parent
+ self.label = None
+ self.scales = []
+ self.adjustments = []
+ self.callback(self.element, EVENT_INFO)
+
+ def destroy(self):
+ self.deactivate()
+
+ def callback(self, e, mask):
+ if mask == EVENT_REMOVE:
+ self.deactivate()
+ elif (mask & EVENT_INFO) != 0:
+ info = alsahcontrol.Info(self.element)
+ if info.is_inactive:
+ self.deactivate()
+ else:
+ self.activate()
+ elif (mask & EVENT_VALUE) != 0:
+ self.update_scales_from_ctl()
+
+ def activate(self):
+ if self.label:
+ return
+ info = alsahcontrol.Info(self.element)
+ value = alsahcontrol.Value(self.element)
+ value.read()
+ values = value.get_tuple(TYPE_INTEGER, info.count)
+ self.label = Gtk.Label(self.get_label(info))
+ self.label.set_single_line_mode(True)
+ self.parent.scales_vbox.add(self.label)
+ for i in range(info.count):
+ adj = Gtk.Adjustment(value=values[i],
+ lower=info.min, upper=info.max,
+ step_incr=1,
+ page_incr=(info.max-info.min+1)/8)
+ adj.connect('value-changed', self.update_ctl_from_scale, i)
+ scale = Gtk.HScale(adj)
+ scale.set_draw_value(False)
+ self.parent.scales_vbox.add(scale)
+ self.scales.append(scale)
+ self.adjustments.append(adj)
+ self.parent.scales_vbox.show_all()
+ self.parent.update_msg_label()
+
+ def deactivate(self):
+ if not self.label:
+ return
+ self.label.destroy()
+ for s in self.scales:
+ s.destroy()
+ self.label = None
+ self.scales = []
+ self.adjustments = []
+ self.parent.update_msg_label()
+
+ def update_scales_from_ctl(self):
+ if not self.label:
+ return
+ count = len(self.adjustments)
+ value = alsahcontrol.Value(self.element)
+ value.read()
+ values = value.get_tuple(TYPE_INTEGER, count)
+ for i in range(count):
+ self.adjustments[i].set_value(values[i])
+
+ def update_ctl_from_scale(self, adj, index):
+ scale_value = adj.get_value()
+ value_to_set = int(round(adj.get_value()))
+ count = len(self.adjustments)
+ value = alsahcontrol.Value(self.element)
+ if self.parent.lock_check.get_active():
+ values = [value_to_set for i in range(count)]
+ else:
+ value.read()
+ values = value.get_array(TYPE_INTEGER, count)
+ values[index] = value_to_set
+ value.set_array(TYPE_INTEGER, values)
+ value.write()
+ if value_to_set != scale_value:
+ adj.set_value(value_to_set)
+
+ def get_label(self, info):
+ pid = self.get_pid(info)
+ if pid:
+ cmdline = self.get_pid_cmdline(pid)
+ if cmdline:
+ return cmdline
+ else:
+ return "PID %d" % pid
+ else:
+ name = info.name
+ if name[-7:] == " Volume":
+ name = name[:-7]
+ if name[-9:] == " Playback":
+ name = name[:-9]
+ return name
+
+ def get_pid(self, info):
+ card = self.parent.current_card
+ device = info.device
+ subdevice = info.subdevice
+ if subdevice == 0:
+ subdevice = info.index
+ filename = "/proc/asound/card%d/pcm%dp/sub%d/status" % (card, device, subdevice)
+ try:
+ f = open(filename, "r")
+ except IOError:
+ return None
+ try:
+ for line in f.readlines():
+ if line[:9] == "owner_pid":
+ return int(line.split(':')[1].strip())
+ finally:
+ f.close()
+ return None
+
+ def get_pid_cmdline(self, pid):
+ try:
+ f = open("/proc/%d/cmdline" % pid, "r")
+ except IOError:
+ return None
+ try:
+ cmdline = f.read()
+ finally:
+ f.close()
+ return cmdline.replace('\x00', ' ').strip()
class MixerWindow(Gtk.Window):
- card_numbers = alsacard.card_list()
- current_card = -1
- hcontrol = None
- scales_vbox = None
- msg_label = None
- streams = []
- hctl_sources = []
-
- def __init__(self):
- Gtk.Window.__init__(self)
- self.connect('destroy', lambda w: Gtk.main_quit())
- self.set_title("Hardware Mixer Volumes")
-
- vbox = Gtk.Grid()
- vbox.set_orientation(Gtk.Orientation.VERTICAL)
- self.add(vbox)
-
- hbox = Gtk.Grid()
- vbox.add(hbox)
-
- label = Gtk.Label.new_with_mnemonic("_Sound Card: ")
- hbox.add(label)
-
- combo = Gtk.ComboBoxText()
- combo.set_hexpand(True)
- for i in self.card_numbers:
- str = "%d: %s" % (i, alsacard.card_get_name(i))
- combo.append_text(str)
- if len(self.card_numbers) > 0:
- combo.set_active(0)
- combo.connect('changed', lambda c: self.change_card(self.card_numbers[combo.get_active()]))
- hbox.add(combo)
- label.set_mnemonic_widget(combo)
-
- self.lock_check = Gtk.CheckButton.new_with_mnemonic(label="_Lock Channels")
- self.lock_check.set_active(True)
- vbox.add(self.lock_check)
-
- scrollwin = Gtk.ScrolledWindow()
- scrollwin.set_policy(hscrollbar_policy=Gtk.PolicyType.NEVER, vscrollbar_policy=Gtk.PolicyType.AUTOMATIC)
- scrollwin.set_shadow_type(Gtk.ShadowType.NONE)
- scrollwin.set_vexpand(True)
- vbox.add(scrollwin)
-
- self.scales_vbox = Gtk.Grid()
- self.scales_vbox.set_orientation(Gtk.Orientation.VERTICAL)
- scrollwin.add_with_viewport(self.scales_vbox)
-
- label = Gtk.Label()
- label.set_single_line_mode(True)
- line_height = label.size_request().height
- label.destroy()
- scale = Gtk.HScale()
- scale.set_draw_value(False)
- line_height += scale.size_request().height
- scale.destroy()
- # always have space for at least four sliders
- scrollwin.set_size_request(width=-1, height=line_height*4+4)
-
- # TODO: select the default card or the first card with stream controls
- if len(self.card_numbers) > 0:
- self.change_card(self.card_numbers[0])
- self.update_msg_label()
-
- self.show_all()
-
- def change_card(self, cardnum):
- for s in self.hctl_sources:
- GLib.source_remove(s)
- self.hctl_sources = []
-
- self.hcontrol = self.open_hcontrol_for_card(cardnum)
-
- for s in self.streams:
- s.destroy()
- self.streams = []
-
- self.current_card = cardnum
-
- if not self.hcontrol:
- self.update_msg_label()
- return
-
- for id in self.hcontrol.list():
- if not self.is_stream_elem(id):
- continue
- elem = alsahcontrol.Element(self.hcontrol, id[0])
- info = alsahcontrol.Info(elem)
- if not self.is_stream_info(info):
- continue
- stream = Stream(elem, self)
- self.streams.append(stream)
-
- for fd,condition in self.hcontrol.poll_fds:
- self.hctl_sources.append(GLib.io_add_watch(fd, 0, GLib.IOCondition(condition), self.hctl_io_callback))
-
- self.update_msg_label()
-
- self.scales_vbox.show_all()
-
- def update_msg_label(self):
- needs_msg = len(self.scales_vbox.get_children()) < 2
- has_msg = self.msg_label
- if has_msg and not needs_msg:
- self.msg_label.destroy()
- self.msg_label = None
- elif needs_msg:
- if len(self.streams) > 0:
- msg = "There are no open streams."
- else:
- msg = "This card does not have stream controls."
- if not has_msg:
- self.msg_label = Gtk.Label(msg)
- self.msg_label.set_vexpand(True)
- self.scales_vbox.add(self.msg_label)
- self.scales_vbox.show_all()
- elif self.msg_label.get_text() != msg:
- self.msg_label.set_text(msg)
-
- def open_hcontrol_for_card(self, cardnum):
- devname = "hw:CARD=" + str(cardnum)
- try:
- hc = alsahcontrol.HControl(name=devname,
- mode=alsahcontrol.open_mode['NONBLOCK'])
- except:
- # TODO: alsa error msg
- dlg = Gtk.MessageDialog(self,
- Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
- Gtk.MessageType.ERROR, Gtk.ButtonsType.OK,
- "Cannot open sound card control device.")
- dlg.run()
- dlg.destroy()
- return None
- return hc
-
- def is_stream_elem(self, id):
- return ((id[1] == INTF_PCM and
- id[4] in ("PCM Playback Volume", "EMU10K1 PCM Volume")) or
- (id[1] == INTF_MIXER and
- id[4] == "VIA DXS Playback Volume"))
-
- def is_stream_info(self, info):
- return info.is_readable and info.is_writable and info.type == TYPE_INTEGER
-
- def hctl_io_callback(self, source, condition):
- self.hcontrol.handle_events()
- return True
+ card_numbers = alsacard.card_list()
+ current_card = -1
+ hcontrol = None
+ scales_vbox = None
+ msg_label = None
+ streams = []
+ hctl_sources = []
+
+ def __init__(self):
+ Gtk.Window.__init__(self)
+ self.connect('destroy', lambda w: Gtk.main_quit())
+ self.set_title("Hardware Mixer Volumes")
+
+ vbox = Gtk.Grid()
+ vbox.set_orientation(Gtk.Orientation.VERTICAL)
+ self.add(vbox)
+
+ hbox = Gtk.Grid()
+ vbox.add(hbox)
+
+ label = Gtk.Label.new_with_mnemonic("_Sound Card: ")
+ hbox.add(label)
+
+ combo = Gtk.ComboBoxText()
+ combo.set_hexpand(True)
+ for i in self.card_numbers:
+ str = "%d: %s" % (i, alsacard.card_get_name(i))
+ combo.append_text(str)
+ if len(self.card_numbers) > 0:
+ combo.set_active(0)
+ combo.connect('changed', lambda c: self.change_card(self.card_numbers[combo.get_active()]))
+ hbox.add(combo)
+ label.set_mnemonic_widget(combo)
+
+ self.lock_check = Gtk.CheckButton.new_with_mnemonic(label="_Lock Channels")
+ self.lock_check.set_active(True)
+ vbox.add(self.lock_check)
+
+ scrollwin = Gtk.ScrolledWindow()
+ scrollwin.set_policy(hscrollbar_policy=Gtk.PolicyType.NEVER, vscrollbar_policy=Gtk.PolicyType.AUTOMATIC)
+ scrollwin.set_shadow_type(Gtk.ShadowType.NONE)
+ scrollwin.set_vexpand(True)
+ vbox.add(scrollwin)
+
+ self.scales_vbox = Gtk.Grid()
+ self.scales_vbox.set_orientation(Gtk.Orientation.VERTICAL)
+ scrollwin.add_with_viewport(self.scales_vbox)
+
+ label = Gtk.Label()
+ label.set_single_line_mode(True)
+ line_height = label.size_request().height
+ label.destroy()
+ scale = Gtk.HScale()
+ scale.set_draw_value(False)
+ line_height += scale.size_request().height
+ scale.destroy()
+ # always have space for at least four sliders
+ scrollwin.set_size_request(width=-1, height=line_height*4+4)
+
+ # TODO: select the default card or the first card with stream controls
+ if len(self.card_numbers) > 0:
+ self.change_card(self.card_numbers[0])
+ self.update_msg_label()
+
+ self.show_all()
+
+ def change_card(self, cardnum):
+ for s in self.hctl_sources:
+ GLib.source_remove(s)
+ self.hctl_sources = []
+
+ self.hcontrol = self.open_hcontrol_for_card(cardnum)
+
+ for s in self.streams:
+ s.destroy()
+ self.streams = []
+
+ self.current_card = cardnum
+
+ if not self.hcontrol:
+ self.update_msg_label()
+ return
+
+ for id in self.hcontrol.list():
+ if not self.is_stream_elem(id):
+ continue
+ elem = alsahcontrol.Element(self.hcontrol, id[0])
+ info = alsahcontrol.Info(elem)
+ if not self.is_stream_info(info):
+ continue
+ stream = Stream(elem, self)
+ self.streams.append(stream)
+
+ for fd,condition in self.hcontrol.poll_fds:
+ self.hctl_sources.append(GLib.io_add_watch(fd, 0, GLib.IOCondition(condition), self.hctl_io_callback))
+
+ self.update_msg_label()
+
+ self.scales_vbox.show_all()
+
+ def update_msg_label(self):
+ needs_msg = len(self.scales_vbox.get_children()) < 2
+ has_msg = self.msg_label
+ if has_msg and not needs_msg:
+ self.msg_label.destroy()
+ self.msg_label = None
+ elif needs_msg:
+ if len(self.streams) > 0:
+ msg = "There are no open streams."
+ else:
+ msg = "This card does not have stream controls."
+ if not has_msg:
+ self.msg_label = Gtk.Label(msg)
+ self.msg_label.set_vexpand(True)
+ self.scales_vbox.add(self.msg_label)
+ self.scales_vbox.show_all()
+ elif self.msg_label.get_text() != msg:
+ self.msg_label.set_text(msg)
+
+ def open_hcontrol_for_card(self, cardnum):
+ devname = "hw:CARD=" + str(cardnum)
+ try:
+ hc = alsahcontrol.HControl(name=devname,
+ mode=alsahcontrol.open_mode['NONBLOCK'])
+ except:
+ # TODO: alsa error msg
+ dlg = Gtk.MessageDialog(self,
+ Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
+ Gtk.MessageType.ERROR, Gtk.ButtonsType.OK,
+ "Cannot open sound card control device.")
+ dlg.run()
+ dlg.destroy()
+ return None
+ return hc
+
+ def is_stream_elem(self, id):
+ return ((id[1] == INTF_PCM and
+ id[4] in ("PCM Playback Volume", "EMU10K1 PCM Volume")) or
+ (id[1] == INTF_MIXER and
+ id[4] == "VIA DXS Playback Volume"))
+
+ def is_stream_info(self, info):
+ return info.is_readable and info.is_writable and info.type == TYPE_INTEGER
+
+ def hctl_io_callback(self, source, condition):
+ self.hcontrol.handle_events()
+ return True
def main():
- MixerWindow()
- Gtk.main()
+ MixerWindow()
+ Gtk.main()
main()
--
2.18.0
More information about the Alsa-devel
mailing list