import pango
import gobject
-class widget(gtk.EventBox):
+class AbspeakWidget(gtk.EventBox):
def __init__(self):
gtk.EventBox.__init__(self)
self.label = gtk.Label()
self.label.set_text(text)
-gobject.signal_new("reset", widget, gobject.SIGNAL_RUN_FIRST | gobject.SIGNAL_ACTION, gobject.TYPE_NONE, [])
-gobject.signal_new("volume-adjust", widget, gobject.SIGNAL_RUN_FIRST | gobject.SIGNAL_ACTION, gobject.TYPE_NONE, [gobject.TYPE_FLOAT])
+gobject.signal_new("reset", AbspeakWidget,
+ gobject.SIGNAL_RUN_FIRST | gobject.SIGNAL_ACTION, gobject.TYPE_NONE, [])
+gobject.signal_new("volume-adjust", AbspeakWidget,
+ gobject.SIGNAL_RUN_FIRST | gobject.SIGNAL_ACTION, gobject.TYPE_NONE, [gobject.TYPE_FLOAT])
import slider
import meter
import abspeak
-from serialization import serialized_object
+from serialization import SerializedObject
try:
import phat
phat = None
-class channel(gtk.VBox, serialized_object):
- '''Widget with slider and meter used as base class for more specific channel widgets'''
+class Channel(gtk.VBox, SerializedObject):
+ '''Widget with slider and meter used as base class for more specific
+ channel widgets'''
monitor_button = None
def __init__(self, app, name, stereo):
self.stereo = stereo
self.meter_scale = self.gui_factory.get_default_meter_scale()
self.slider_scale = self.gui_factory.get_default_slider_scale()
- self.slider_adjustment = slider.adjustment_dBFS(self.slider_scale, 0.0)
+ self.slider_adjustment = slider.AdjustmentdBFS(self.slider_scale, 0.0)
self.balance_adjustment = gtk.Adjustment(0.0, -1.0, 1.0, 0.02)
self.future_volume_midi_cc = None
self.future_balance_midi_cc = None
self.create_slider_widget()
if self.stereo:
- self.meter = meter.stereo(self.meter_scale)
+ self.meter = meter.StereoMeterWidget(self.meter_scale)
else:
- self.meter = meter.mono(self.meter_scale)
+ self.meter = meter.MonoMeterWidget(self.meter_scale)
self.on_vumeter_color_changed(self.gui_factory)
self.meter.set_events(gtk.gdk.SCROLL_MASK)
self.gui_factory.connect('vumeter-color-scheme-changed', self.on_vumeter_color_changed)
self.gui_factory.connect('use-custom-widgets-changed', self.on_custom_widgets_changed)
- self.abspeak = abspeak.widget()
+ self.abspeak = abspeak.AbspeakWidget()
self.abspeak.connect("reset", self.on_abspeak_reset)
self.abspeak.connect("volume-adjust", self.on_abspeak_adjust)
#print "Default slider scale change detected."
self.slider_scale = scale
self.slider_adjustment.set_scale(scale)
- self.channel.set_midi_scale(self.slider_scale.scale)
+ self.channel.midi_scale = self.slider_scale.scale
def on_vumeter_color_changed(self, gui_factory, *args):
color = gui_factory.get_vumeter_color()
self.app.set_monitored_channel(self)
self.monitor_button.set_active(True)
-gobject.signal_new('midi-event-received', channel,
+gobject.signal_new('midi-event-received', Channel,
gobject.SIGNAL_RUN_FIRST | gobject.SIGNAL_ACTION,
gobject.TYPE_NONE, ())
-class input_channel(channel):
+class InputChannel(Channel):
def __init__(self, app, name, stereo):
- channel.__init__(self, app, name, stereo)
+ Channel.__init__(self, app, name, stereo)
def realize(self):
self.channel = self.mixer.add_channel(self.channel_name, self.stereo)
if self.channel == None:
raise Exception,"Cannot create a channel"
- channel.realize(self)
+ Channel.realize(self)
if self.future_volume_midi_cc:
self.channel.volume_midi_cc = self.future_volume_midi_cc
if self.future_balance_midi_cc:
return None
def unrealize(self):
- channel.unrealize(self)
+ Channel.unrealize(self)
self.channel.remove()
self.channel = False
object_backend.add_property("type", "stereo")
else:
object_backend.add_property("type", "mono")
- channel.serialize(self, object_backend)
+ Channel.serialize(self, object_backend)
def unserialize_property(self, name, value):
if name == "name":
if value == "mono":
self.stereo = False
return True
- return channel.unserialize_property(self, name, value)
+ return Channel.unserialize_property(self, name, value)
def input_channel_serialization_name():
return "input_channel"
('#e9b96e', '#c17d11', '#6f4902'),
]
-class output_channel(channel):
+class OutputChannel(Channel):
colours = available_colours[:]
_display_solo_buttons = False
_init_solo_channels = None
def __init__(self, app, name, stereo):
- channel.__init__(self, app, name, stereo)
+ Channel.__init__(self, app, name, stereo)
def get_display_solo_buttons(self):
return self._display_solo_buttons
display_solo_buttons = property(get_display_solo_buttons, set_display_solo_buttons)
def realize(self):
- channel.realize(self)
+ Channel.realize(self)
self.channel = self.mixer.add_output_channel(self.channel_name, self.stereo)
if self.channel == None:
raise Exception,"Cannot create a channel"
- channel.realize(self)
+ Channel.realize(self)
self.channel.midi_scale = self.slider_scale.scale
self.channel.midi_change_callback = self.midi_change_callback
self.on_channel_properties()
def unrealize(self):
- channel.unrealize(self)
+ Channel.unrealize(self)
self.channel = False
def serialization_name(self):
object_backend.add_property('muted_channels', '|'.join([x.channel.name for x in muted_channels]))
if solo_channels:
object_backend.add_property('solo_channels', '|'.join([x.channel.name for x in solo_channels]))
- channel.serialize(self, object_backend)
+ Channel.serialize(self, object_backend)
def unserialize_property(self, name, value):
if name == "name":
if name == 'solo_channels':
self._init_solo_channels = value.split('|')
return True
- return channel.unserialize_property(self, name, value)
+ return Channel.unserialize_property(self, name, value)
def output_channel_serialization_name():
return "output_channel"
-class main_mix(channel):
+class MainMixChannel(Channel):
_init_muted_channels = None
_init_solo_channels = None
def __init__(self, app):
- channel.__init__(self, app, "MAIN", True)
+ Channel.__init__(self, app, "MAIN", True)
def realize(self):
- channel.realize(self)
+ Channel.realize(self)
self.channel = self.mixer.main_mix_channel
self.channel.midi_scale = self.slider_scale.scale
self.channel.midi_change_callback = self.midi_change_callback
self._init_solo_channels = None
def unrealize(self):
- channel.unrealize(self)
+ Channel.unrealize(self)
self.channel = False
def serialization_name(self):
object_backend.add_property('muted_channels', '|'.join([x.channel.name for x in muted_channels]))
if solo_channels:
object_backend.add_property('solo_channels', '|'.join([x.channel.name for x in solo_channels]))
- channel.serialize(self, object_backend)
+ Channel.serialize(self, object_backend)
def unserialize_property(self, name, value):
if name == 'muted_channels':
if name == 'solo_channels':
self._init_solo_channels = value.split('|')
return True
- return channel.unserialize_property(self, name, value)
+ return Channel.unserialize_property(self, name, value)
def main_mix_serialization_name():
return "main_mix_channel"
def on_solo_toggled(self, button):
self.output_channel.channel.set_solo(self.input_channel.channel, button.get_active())
self.app.update_monitor(self)
+
return scale
return None
-class factory(gobject.GObject):
+class Factory(gobject.GObject):
def __init__(self, topwindow, meter_scales, slider_scales):
gobject.GObject.__init__(self)
self.topwindow = topwindow
def get_use_custom_widgets(self):
return self.use_custom_widgets
-gobject.signal_new("default-meter-scale-changed", factory, gobject.SIGNAL_RUN_FIRST | gobject.SIGNAL_ACTION, gobject.TYPE_NONE, [gobject.TYPE_PYOBJECT])
-gobject.signal_new("default-slider-scale-changed", factory, gobject.SIGNAL_RUN_FIRST | gobject.SIGNAL_ACTION, gobject.TYPE_NONE, [gobject.TYPE_PYOBJECT])
-gobject.signal_new('vumeter-color-changed', factory,
+gobject.signal_new("default-meter-scale-changed", Factory,
+ gobject.SIGNAL_RUN_FIRST | gobject.SIGNAL_ACTION,
+ gobject.TYPE_NONE, [gobject.TYPE_PYOBJECT])
+gobject.signal_new("default-slider-scale-changed", Factory,
+ gobject.SIGNAL_RUN_FIRST | gobject.SIGNAL_ACTION,
+ gobject.TYPE_NONE, [gobject.TYPE_PYOBJECT])
+gobject.signal_new('vumeter-color-changed', Factory,
gobject.SIGNAL_RUN_FIRST | gobject.SIGNAL_ACTION,
gobject.TYPE_NONE, [str])
-gobject.signal_new('vumeter-color-scheme-changed', factory,
+gobject.signal_new('vumeter-color-scheme-changed', Factory,
gobject.SIGNAL_RUN_FIRST | gobject.SIGNAL_ACTION,
gobject.TYPE_NONE, [str])
-gobject.signal_new('use-custom-widgets-changed', factory,
+gobject.signal_new('use-custom-widgets-changed', Factory,
gobject.SIGNAL_RUN_FIRST | gobject.SIGNAL_ACTION,
gobject.TYPE_NONE, [bool])
import gui
from preferences import PreferencesDialog
-from serialization_xml import xml_serialization
-from serialization import serialized_object, serializator
+from serialization_xml import XmlSerialization
+from serialization import SerializedObject, Serializator
# restore Python modules lookup path
sys.path = old_path
-class jack_mixer(serialized_object):
+class JackMixer(SerializedObject):
# scales suitable as meter scales
- meter_scales = [scale.iec_268(), scale.linear_70dB(), scale.iec_268_minimalistic()]
+ meter_scales = [scale.IEC268(), scale.Linear70dB(), scale.IEC268Minimalistic()]
# scales suitable as volume slider scales
- slider_scales = [scale.linear_30dB(), scale.linear_70dB()]
+ slider_scales = [scale.Linear30dB(), scale.Linear70dB()]
# name of settngs file that is currently open
current_filename = None
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.set_title(name)
- self.gui_factory = gui.factory(self.window, self.meter_scales, self.slider_scales)
+ self.gui_factory = gui.Factory(self.window, self.meter_scales, self.slider_scales)
self.vbox_top = gtk.VBox()
self.window.add(self.vbox_top)
help_menu_item = gtk.MenuItem('_Help')
self.menubar.append(help_menu_item)
- self.window.set_default_size(120,300)
+ self.window.set_default_size(120, 300)
mixer_menu = gtk.Menu()
mixer_menu_item.set_submenu(mixer_menu)
mixer_menu.append(add_output_channel)
add_output_channel.connect("activate", self.on_add_output_channel)
- if lash_client is None and xml_serialization is not None:
+ if lash_client is None:
mixer_menu.append(gtk.SeparatorMenuItem())
open = gtk.ImageMenuItem(gtk.STOCK_OPEN)
mixer_menu.append(open)
self.scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self.scrolled_window.add_with_viewport(self.hbox_inputs)
- self.main_mix = main_mix(self)
+ self.main_mix = MainMixChannel(self)
self.hbox_outputs = gtk.HBox()
self.hbox_outputs.set_spacing(0)
self.hbox_outputs.set_border_width(0)
def add_channel(self, name, stereo, volume_cc, balance_cc):
try:
- channel = input_channel(self, name, stereo)
+ channel = InputChannel(self, name, stereo)
self.add_channel_precreated(channel)
except Exception:
err = gtk.MessageDialog(self.window,
def add_output_channel(self, name, stereo, volume_cc, balance_cc, display_solo_buttons):
try:
- channel = output_channel(self, name, stereo)
+ channel = OutputChannel(self, name, stereo)
channel.display_solo_buttons = display_solo_buttons
self.add_output_channel_precreated(channel)
except Exception:
- raise
err = gtk.MessageDialog(self.window,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
gtk.MESSAGE_ERROR,
if channel.channel.name == self._monitored_channel.channel.name:
return
self._monitored_channel = channel
- if type(channel) is input_channel:
+ if type(channel) is InputChannel:
# reset all solo/mute settings
for in_channel in self.channels:
self.monitor_channel.set_solo(in_channel.channel, False)
return
self.monitor_channel.volume = channel.channel.volume
self.monitor_channel.balance = channel.channel.balance
- if type(self.monitored_channel) is output_channel:
+ if type(self.monitored_channel) is OutputChannel:
# sync solo/muted channels
for input_channel in self.channels:
self.monitor_channel.set_solo(input_channel.channel,
channel.channel.is_solo(input_channel.channel))
self.monitor_channel.set_muted(input_channel.channel,
channel.channel.is_muted(input_channel.channel))
- elif type(self.monitored_channel) is main_mix:
+ elif type(self.monitored_channel) is MainMixChannel:
# sync solo/muted channels
for input_channel in self.channels:
self.monitor_channel.set_solo(input_channel.channel,
def save_to_xml(self, file):
#print "Saving to XML..."
- b = xml_serialization()
- s = serializator()
+ b = XmlSerialization()
+ s = Serializator()
s.serialize(self, b)
b.save(file)
#print "Loading from XML..."
self.on_channels_clear(None)
self.unserialized_channels = []
- b = xml_serialization()
+ b = XmlSerialization()
try:
b.load(file)
except:
if silence_errors:
return
raise
- s = serializator()
+ s = Serializator()
s.unserialize(self, b)
for channel in self.unserialized_channels:
- if isinstance(channel, input_channel):
+ if isinstance(channel, InputChannel):
self.add_channel_precreated(channel)
for channel in self.unserialized_channels:
- if isinstance(channel, output_channel):
+ if isinstance(channel, OutputChannel):
self.add_output_channel_precreated(channel)
del self.unserialized_channels
self.window.show_all()
return self.main_mix
if name == input_channel_serialization_name():
- channel = input_channel(self, "", True)
+ channel = InputChannel(self, "", True)
self.unserialized_channels.append(channel)
return channel
if name == output_channel_serialization_name():
- channel = output_channel(self, "", True)
+ channel = OutputChannel(self, "", True)
self.unserialized_channels.append(channel)
return channel
gtk.gdk.threads_init()
try:
- mixer = jack_mixer(name, lash_client)
+ mixer = JackMixer(name, lash_client)
except Exception, e:
err = gtk.MessageDialog(None,
gtk.DIALOG_MODAL,
"Failed loading settings.")
err.run()
err.destroy()
- mixer.window.set_default_size(60*(1+len(mixer.channels)+len(mixer.output_channels)),300)
+ mixer.window.set_default_size(60*(1+len(mixer.channels)+len(mixer.output_channels)), 300)
f.close()
mixer.main()
-#!/usr/bin/env python
-#
# This file is part of jack_mixer
#
# Copyright (C) 2006 Nedko Arnaudov <nedko@arnaudov.name>
import gtk
import cairo
-class meter(gtk.DrawingArea):
+class MeterWidget(gtk.DrawingArea):
def __init__(self, scale):
gtk.DrawingArea.__init__(self)
self.cache_surface = None
self.invalidate_all()
-class mono(meter):
+class MonoMeterWidget(MeterWidget):
def __init__(self, scale):
- meter.__init__(self, scale)
+ MeterWidget.__init__(self, scale)
self.value = 0.0
self.raw_value = 0.0
if (abs(old_value-self.value) * self.height) > 1:
self.invalidate_all()
-class stereo(meter):
+class StereoMeterWidget(MeterWidget):
def __init__(self, scale):
- meter.__init__(self, scale)
+ MeterWidget.__init__(self, scale)
self.left = 0.0
self.right = 0.0
-#!/usr/bin/env python
-#
# This file is part of jack_mixer
#
# Copyright (C) 2006 Nedko Arnaudov <nedko@arnaudov.name>
import math
import jack_mixer_c
-class mark:
+class Mark:
'''Encapsulates scale linear function edge and coefficients for scale = a * dB + b formula'''
def __init__(self, db, scale):
self.db = db
self.scale = scale
self.text = "%.0f" % math.fabs(db)
-class base:
+class Base:
'''Scale abstraction, various scale implementation derive from this class'''
def __init__(self, scale_id, description):
self.marks = []
def add_threshold(self, db, scale, is_mark):
self.scale.add_threshold(db, scale)
if is_mark:
- self.marks.append(mark(db, scale))
+ self.marks.append(Mark(db, scale))
def calculate_coefficients(self):
self.scale.calculate_coefficients()
return self.scale.scale_to_db(scale)
def add_mark(self, db):
- self.marks.append(mark(db, -1.0))
+ self.marks.append(Mark(db, -1.0))
def get_marks(self):
return self.marks
# IEC 60268-18 Peak programme level meters - Digital audio peak level meter
# Adapted from meterpridge, may be wrong, I'm not buying standards, event if they cost $45
# If someone has the standart, please eighter share it with me or fix the code.
-class iec_268(base):
+class IEC268(Base):
'''IEC 60268-18 Peak programme level meters - Digital audio peak level meter'''
def __init__(self):
- base.__init__(self, "iec_268", "IEC 60268-18 Peak programme level meters - Digital audio peak level meter")
+ Base.__init__(self, "iec_268",
+ "IEC 60268-18 Peak programme level meters - Digital audio peak level meter")
self.add_threshold(-70.0, 0.0, False)
self.add_threshold(-60.0, 0.05, True)
self.add_threshold(-50.0, 0.075, True)
self.calculate_coefficients()
self.scale_marks()
-class iec_268_minimalistic(base):
- '''IEC 60268-18 Peak programme level meters - Digital audio peak level meter, fewer marks'''
+class IEC268Minimalistic(Base):
+ '''IEC 60268-18 Peak programme level meters - Digital audio peak level meter,
+ fewer marks'''
def __init__(self):
- base.__init__(self, "iec_268_minimalistic", "IEC 60268-18 Peak programme level meters - Digital audio peak level meter, fewer marks")
+ Base.__init__(self, 'iec_268_minimalistic',
+ 'IEC 60268-18 Peak programme level meters - Digital audio peak level meter, fewer marks')
self.add_threshold(-70.0, 0.0, False)
self.add_threshold(-60.0, 0.05, True)
self.add_threshold(-50.0, 0.075, False)
self.calculate_coefficients()
self.scale_marks()
-class linear_70dB(base):
+class Linear70dB(Base):
'''Linear scale with range from -70 to 0 dBFS'''
def __init__(self):
- base.__init__(self, "linear_70dB", "Linear scale with range from -70 to 0 dBFS")
+ Base.__init__(self, "linear_70dB", "Linear scale with range from -70 to 0 dBFS")
self.add_threshold(-70.0, 0.0, False)
self.add_mark(-60.0)
self.add_mark(-50.0)
self.calculate_coefficients()
self.scale_marks()
-class linear_30dB(base):
+class Linear30dB(Base):
'''Linear scale with range from -30 to +30 dBFS'''
def __init__(self):
- base.__init__(self, "linear_30dB", "Linear scale with range from -30 to +30 dBFS")
+ Base.__init__(self, "linear_30dB", "Linear scale with range from -30 to +30 dBFS")
self.add_threshold(-30.0, 0.0, False)
self.add_threshold(+30.0, 1.0, True)
self.calculate_coefficients()
-#!/usr/bin/env python
-#
# This file is part of jack_mixer
#
# Copyright (C) 2006 Nedko Arnaudov <nedko@arnaudov.name>
-#
+#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-class serialization_backend:
+class SerializationBackend:
'''Base class for serialization backends'''
def get_root_serialization_object(self, name):
- '''Returns serialization object where properties of root object will be serialized to'''
- return None # this method should never be called for the base class
+ '''Returns serialization object where properties of root object
+ will be serialized to'''
+ # this method should never be called for the base class
+ raise NotImplementedError
def get_child_serialization_object(self, name, backend_object):
- return None # this method should never be called for the base class
+ # this method should never be called for the base class
+ raise NotImplementedError
-class serialization_object_backend:
- '''Base class for serialization backend objects where real object properties will be serialized to or unserialized from.'''
+class SerializationObjectBackend:
+ '''Base class for serialization backend objects where real object
+ properties will be serialized to or unserialized from.'''
def add_property(self, name, value):
'''Serialize particular property'''
pass
def serialization_name(self):
return None
-class serialized_object:
+class SerializedObject:
'''Base class for object supporting serialization'''
def serialization_name(self):
return None
def unserialize_child(self, name):
return None
-class serializator:
+class Serializator:
def __init__(self):
pass
childs = object.serialization_get_childs()
for child in childs:
#print "serializing child " + repr(child)
- self.serialize_one(backend, child, backend.get_child_serialization_object(child.serialization_name(), backend_object))
+ self.serialize_one(backend, child,
+ backend.get_child_serialization_object(
+ child.serialization_name(), backend_object))
-#!/usr/bin/env python
-#
# This file is part of jack_mixer
#
# Copyright (C) 2006 Nedko Arnaudov <nedko@arnaudov.name>
-#
+#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License
import xml.dom
import xml.dom.minidom
-class xml_serialization(serialization_backend):
+class XmlSerialization(SerializationBackend):
def get_root_serialization_object(self, name):
self.doc = xml.dom.getDOMImplementation().createDocument(xml.dom.EMPTY_NAMESPACE, name, None)
- return xml_serialization_object(self.doc, self.doc.documentElement)
+ return XmlSerializationObject(self.doc, self.doc.documentElement)
def get_root_unserialization_object(self, name):
if name != self.doc.documentElement.nodeName:
return None
- return xml_serialization_object(self.doc, self.doc.documentElement)
+ return XmlSerializationObject(self.doc, self.doc.documentElement)
def get_child_serialization_object(self, name, backend_object):
child = self.doc.createElement(name)
backend_object.element.appendChild(child)
- return xml_serialization_object(self.doc, child)
+ return XmlSerializationObject(self.doc, child)
def save(self, file):
file.write(self.doc.toprettyxml())
def load(self, file):
self.doc = xml.dom.minidom.parse(file)
-class xml_serialization_object:
+class XmlSerializationObject:
def __init__(self, doc, element):
self.doc = doc
self.element = element
childs = []
for child in child_elements:
if child.nodeType == child.ELEMENT_NODE:
- childs.append(xml_serialization_object(self.doc, child))
+ childs.append(XmlSerializationObject(self.doc, child))
return childs
def get_properties(self):
-#!/usr/bin/env python
-#
# This file is part of jack_mixer
#
# Copyright (C) 2006 Nedko Arnaudov <nedko@arnaudov.name>
import gtk
import gobject
-class adjustment_dBFS(gtk.Adjustment):
+class AdjustmentdBFS(gtk.Adjustment):
def __init__(self, scale, default_db):
self.default_value = scale.db_to_scale(default_db)
self.db = default_db
self.set_value(self.scale.db_to_scale(self.db))
self.disable_value_notify = False
-gobject.signal_new("volume-changed", adjustment_dBFS, gobject.SIGNAL_RUN_FIRST | gobject.SIGNAL_ACTION, gobject.TYPE_NONE, [])
+gobject.signal_new("volume-changed", AdjustmentdBFS,
+ gobject.SIGNAL_RUN_FIRST | gobject.SIGNAL_ACTION, gobject.TYPE_NONE, [])
class GtkSlider(gtk.VScale):