3 # This file is part of jack_mixer
5 # Copyright (C) 2006 Nedko Arnaudov <nedko@arnaudov.name>
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; version 2 of the License
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
28 from serialization
import serialized_object
33 print "PHAT audio widgets not found, some features will not be available"
38 class channel(gtk
.VBox
, serialized_object
):
39 '''Widget with slider and meter used as base class for more specific channel widgets'''
40 def __init__(self
, mixer
, gui_factory
, name
, stereo
):
41 gtk
.VBox
.__init
__(self
)
43 self
.gui_factory
= gui_factory
44 self
.channel_name
= name
46 self
.meter_scale
= gui_factory
.get_default_meter_scale()
47 self
.slider_scale
= gui_factory
.get_default_slider_scale()
48 self
.slider_adjustment
= slider
.adjustment_dBFS(self
.slider_scale
, 0.0)
49 self
.balance_adjustment
= gtk
.Adjustment(0.0, -1.0, 1.0, 0.02)
52 #print "Realizing channel \"%s\"" % self.channel_name
54 self
.slider_adjustment
.connect("volume-changed", self
.on_volume_changed
)
55 self
.balance_adjustment
.connect("value-changed", self
.on_balance_changed
)
57 self
.slider
= slider
.widget(self
.slider_adjustment
)
60 self
.meter
= meter
.stereo(self
.meter_scale
)
62 self
.meter
= meter
.mono(self
.meter_scale
)
64 self
.meter
.set_events(gtk
.gdk
.SCROLL_MASK
)
66 self
.gui_factory
.connect("default-meter-scale-changed", self
.on_default_meter_scale_changed
)
67 self
.gui_factory
.connect("default-slider-scale-changed", self
.on_default_slider_scale_changed
)
69 self
.abspeak
= abspeak
.widget()
70 self
.abspeak
.connect("reset", self
.on_abspeak_reset
)
71 self
.abspeak
.connect("volume-adjust", self
.on_abspeak_adjust
)
73 self
.volume_digits
= gtk
.Entry()
74 self
.volume_digits
.connect("key-press-event", self
.on_volume_digits_key_pressed
)
75 self
.volume_digits
.connect("focus-out-event", self
.on_volume_digits_focus_out
)
77 self
.connect("key-press-event", self
.on_key_pressed
)
78 self
.connect("scroll-event", self
.on_scroll
)
81 #print "Unrealizing channel \"%s\"" % self.channel_name
84 def on_default_meter_scale_changed(self
, gui_factory
, scale
):
85 #print "Default meter scale change detected."
86 self
.meter
.set_scale(scale
)
88 def on_default_slider_scale_changed(self
, gui_factory
, scale
):
89 #print "Default slider scale change detected."
90 self
.slider_adjustment
.set_scale(scale
)
92 def on_abspeak_adjust(self
, abspeak
, adjust
):
93 #print "abspeak adjust %f" % adjust
94 self
.slider_adjustment
.set_value_db(self
.slider_adjustment
.get_value_db() + adjust
)
95 jack_mixer_c
.channel_abspeak_reset(self
.channel
)
96 #self.update_volume(False) # We want to update gui even if actual decibels have not changed (scale wrap for example)
98 def on_abspeak_reset(self
, abspeak
):
99 #print "abspeak reset"
100 jack_mixer_c
.channel_abspeak_reset(self
.channel
)
102 def on_volume_digits_key_pressed(self
, widget
, event
):
103 if (event
.keyval
== gtk
.keysyms
.Return
or event
.keyval
== gtk
.keysyms
.KP_Enter
):
104 db_text
= self
.volume_digits
.get_text()
107 #print "Volume digits confirmation \"%f dBFS\"" % db
108 except (ValueError), e
:
109 #print "Volume digits confirmation ignore, reset to current"
110 self
.update_volume(False)
112 self
.slider_adjustment
.set_value_db(db
)
114 #self.update_volume(False) # We want to update gui even if actual decibels have not changed (scale wrap for example)
116 def on_volume_digits_focus_out(self
, widget
, event
):
117 #print "volume digits focus out detected"
118 self
.update_volume(False)
120 def read_meter(self
):
122 meter_left
, meter_right
= jack_mixer_c
.channel_stereo_meter_read(self
.channel
)
123 self
.meter
.set_values(meter_left
, meter_right
)
125 self
.meter
.set_value(jack_mixer_c
.channel_mono_meter_read(self
.channel
))
127 self
.abspeak
.set_peak(jack_mixer_c
.channel_abspeak_read(self
.channel
))
129 def midi_change_check(self
):
130 if jack_mixer_c
.channel_is_midi_modified(self
.channel
):
131 volume
= jack_mixer_c
.channel_volume_read(self
.channel
)
132 balance
= jack_mixer_c
.channel_balance_read(self
.channel
)
133 #print volume, balance
134 self
.slider_adjustment
.set_value_db(volume
)
135 self
.balance
.set_value(balance
)
137 def on_scroll(self
, widget
, event
):
138 if event
.direction
== gtk
.gdk
.SCROLL_DOWN
:
139 self
.slider_adjustment
.step_down()
140 elif event
.direction
== gtk
.gdk
.SCROLL_UP
:
141 self
.slider_adjustment
.step_up()
144 def update_volume(self
, update_engine
):
145 db
= self
.slider_adjustment
.get_value_db()
147 db_text
= "%.2f" % db
148 self
.volume_digits
.set_text(db_text
)
151 #print "Setting engine volume to " + db_text
152 jack_mixer_c
.channel_volume_write(self
.channel
, db
)
154 def on_volume_changed(self
, adjustment
):
155 self
.update_volume(True)
157 def on_balance_changed(self
, adjustment
):
158 balance
= self
.balance_adjustment
.get_value()
159 #print "%s balance: %f" % (self.channel_name, balance)
160 jack_mixer_c
.channel_balance_write(self
.channel
, balance
)
162 def on_key_pressed(self
, widget
, event
):
163 if (event
.keyval
== gtk
.keysyms
.Up
):
164 #print self.channel_name + " Up"
165 self
.slider_adjustment
.step_up()
167 elif (event
.keyval
== gtk
.keysyms
.Down
):
168 #print self.channel_name + " Down"
169 self
.slider_adjustment
.step_down()
174 def serialize(self
, object_backend
):
175 object_backend
.add_property("volume", "%f" % self
.slider_adjustment
.get_value_db())
176 object_backend
.add_property("balance", "%f" % self
.balance_adjustment
.get_value())
178 def unserialize_property(self
, name
, value
):
180 self
.slider_adjustment
.set_value_db(float(value
))
182 if name
== "balance":
183 self
.balance_adjustment
.set_value(float(value
))
187 class input_channel(channel
):
188 def __init__(self
, mixer
, gui_factory
, name
, stereo
):
189 channel
.__init
__(self
, mixer
, gui_factory
, name
, stereo
)
192 channel
.realize(self
)
193 self
.channel
= jack_mixer_c
.add_channel(self
.mixer
, self
.channel_name
, self
.stereo
)
195 self
.on_volume_changed(self
.slider_adjustment
)
196 self
.on_balance_changed(self
.balance_adjustment
)
198 # vbox child at upper part
199 self
.vbox
= gtk
.VBox()
200 self
.pack_start(self
.vbox
, False)
201 self
.label_name
= gtk
.Label()
202 self
.label_name
.set_text(self
.channel_name
)
203 self
.label_name
.set_size_request(0, -1)
204 self
.label_name_event_box
= gtk
.EventBox()
205 self
.label_name_event_box
.connect("button-press-event", self
.on_label_mouse
)
206 self
.label_name_event_box
.add(self
.label_name
)
207 self
.vbox
.pack_start(self
.label_name_event_box
, True)
208 # self.label_stereo = gtk.Label()
210 # self.label_stereo.set_text("stereo")
212 # self.label_stereo.set_text("mono")
213 # self.label_stereo.set_size_request(0, -1)
214 # self.vbox.pack_start(self.label_stereo, True)
216 # hbox for mute and solo buttons
217 self
.hbox_mutesolo
= gtk
.HBox()
219 self
.mute
= gtk
.ToggleButton()
220 self
.mute
.set_label("M")
221 self
.mute
.set_active(jack_mixer_c
.channel_is_muted(self
.channel
))
222 self
.mute
.connect("toggled", self
.on_mute_toggled
)
223 self
.hbox_mutesolo
.pack_start(self
.mute
, True)
225 self
.solo
= gtk
.ToggleButton()
226 self
.solo
.set_label("S")
227 self
.solo
.set_active(jack_mixer_c
.channel_is_soloed(self
.channel
))
228 self
.solo
.connect("toggled", self
.on_solo_toggled
)
229 self
.hbox_mutesolo
.pack_start(self
.solo
, True)
231 self
.vbox
.pack_start(self
.hbox_mutesolo
, False)
234 frame
.set_shadow_type(gtk
.SHADOW_IN
)
235 frame
.add(self
.abspeak
);
236 self
.vbox
.pack_start(frame
, False)
238 # hbox child at lower part
239 self
.hbox
= gtk
.HBox()
240 self
.hbox
.pack_start(self
.slider
, True)
242 frame
.set_shadow_type(gtk
.SHADOW_IN
)
243 frame
.add(self
.meter
);
244 self
.hbox
.pack_start(frame
, True)
246 frame
.set_shadow_type(gtk
.SHADOW_IN
)
247 frame
.add(self
.hbox
);
248 self
.pack_start(frame
, True)
250 self
.volume_digits
.set_size_request(0, -1)
251 self
.pack_start(self
.volume_digits
, False)
254 self
.balance
= phat
.HFanSlider()
255 self
.balance
.set_default_value(0)
256 self
.balance
.set_adjustment(self
.balance_adjustment
)
257 self
.pack_start(self
.balance
, False)
260 channel
.unrealize(self
)
261 jack_mixer_c
.remove_channel(self
.channel
)
264 def on_rename_channel(self
):
265 result
= self
.gui_factory
.run_dialog_rename_channel(self
.channel_name
)
267 #print "renaming to \"%s\"" % result
268 self
.channel_name
= result
269 self
.label_name
.set_text(self
.channel_name
)
270 jack_mixer_c
.channel_rename(self
.channel
, self
.channel_name
)
272 def on_label_mouse(self
, widget
, event
):
273 if event
.type == gtk
.gdk
._2BUTTON
_PRESS
:
274 if event
.button
== 1:
275 self
.on_rename_channel()
277 def on_mute_toggled(self
, button
):
278 if self
.mute
.get_active():
280 jack_mixer_c
.channel_mute(self
.channel
)
283 jack_mixer_c
.channel_unmute(self
.channel
)
285 def on_solo_toggled(self
, button
):
286 if self
.solo
.get_active():
288 jack_mixer_c
.channel_solo(self
.channel
)
291 jack_mixer_c
.channel_unsolo(self
.channel
)
293 def serialization_name(self
):
294 return input_channel_serialization_name()
296 def serialize(self
, object_backend
):
297 object_backend
.add_property("name", self
.channel_name
)
299 object_backend
.add_property("type", "stereo")
301 object_backend
.add_property("type", "mono")
302 channel
.serialize(self
, object_backend
)
304 def unserialize_property(self
, name
, value
):
306 self
.channel_name
= str(value
)
309 if value
== "stereo":
315 return channel
.unserialize_property(self
, name
, value
)
317 def input_channel_serialization_name():
318 return "input_channel"
320 class main_mix(channel
):
321 def __init__(self
, mixer
, gui_factory
):
322 channel
.__init
__(self
, mixer
, gui_factory
, "MAIN", True)
325 channel
.realize(self
)
326 self
.channel
= jack_mixer_c
.get_main_mix_channel(self
.mixer
)
328 self
.on_volume_changed(self
.slider_adjustment
)
329 self
.on_balance_changed(self
.balance_adjustment
)
331 # vbox child at upper part
332 self
.vbox
= gtk
.VBox()
333 self
.pack_start(self
.vbox
, False)
334 self
.label_name
= gtk
.Label()
335 self
.label_name
.set_text(self
.channel_name
)
336 self
.label_name
.set_size_request(0, -1)
337 self
.vbox
.pack_start(self
.label_name
, False)
339 frame
.set_shadow_type(gtk
.SHADOW_IN
)
340 frame
.add(self
.abspeak
);
341 self
.vbox
.pack_start(frame
, False)
343 # hbox child at lower part
344 self
.hbox
= gtk
.HBox()
345 self
.hbox
.pack_start(self
.slider
, True)
347 frame
.set_shadow_type(gtk
.SHADOW_IN
)
348 frame
.add(self
.meter
);
349 self
.hbox
.pack_start(frame
, True)
351 frame
.set_shadow_type(gtk
.SHADOW_IN
)
352 frame
.add(self
.hbox
);
353 self
.pack_start(frame
, True)
355 self
.volume_digits
.set_size_request(0, -1)
356 self
.pack_start(self
.volume_digits
, False)
359 self
.balance
= phat
.HFanSlider()
360 self
.balance
.set_default_value(0)
361 self
.balance
.set_adjustment(self
.balance_adjustment
)
362 self
.pack_start(self
.balance
, False)
365 channel
.unrealize(self
)
368 def serialization_name(self
):
369 return main_mix_serialization_name()
371 def main_mix_serialization_name():
372 return "main_mix_channel"