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 on_scroll(self
, widget
, event
):
130 if event
.direction
== gtk
.gdk
.SCROLL_DOWN
:
131 self
.slider_adjustment
.step_down()
132 elif event
.direction
== gtk
.gdk
.SCROLL_UP
:
133 self
.slider_adjustment
.step_up()
136 def update_volume(self
, update_engine
):
137 db
= self
.slider_adjustment
.get_value_db()
139 db_text
= "%.2f" % db
140 self
.volume_digits
.set_text(db_text
)
143 #print "Setting engine volume to " + db_text
144 jack_mixer_c
.channel_volume_write(self
.channel
, db
)
146 def on_volume_changed(self
, adjustment
):
147 self
.update_volume(True)
149 def on_balance_changed(self
, adjustment
):
150 balance
= self
.balance_adjustment
.get_value()
151 #print "%s balance: %f" % (self.channel_name, balance)
152 jack_mixer_c
.channel_balance_write(self
.channel
, balance
)
154 def on_key_pressed(self
, widget
, event
):
155 if (event
.keyval
== gtk
.keysyms
.Up
):
156 #print self.channel_name + " Up"
157 self
.slider_adjustment
.step_up()
159 elif (event
.keyval
== gtk
.keysyms
.Down
):
160 #print self.channel_name + " Down"
161 self
.slider_adjustment
.step_down()
166 def serialize(self
, object_backend
):
167 object_backend
.add_property("volume", "%f" % self
.slider_adjustment
.get_value_db())
168 object_backend
.add_property("balance", "%f" % self
.balance_adjustment
.get_value())
170 def unserialize_property(self
, name
, value
):
172 self
.slider_adjustment
.set_value_db(float(value
))
174 if name
== "balance":
175 self
.balance_adjustment
.set_value(float(value
))
179 class input_channel(channel
):
180 def __init__(self
, mixer
, gui_factory
, name
, stereo
):
181 channel
.__init
__(self
, mixer
, gui_factory
, name
, stereo
)
184 channel
.realize(self
)
185 self
.channel
= jack_mixer_c
.add_channel(self
.mixer
, self
.channel_name
, self
.stereo
)
187 self
.on_volume_changed(self
.slider_adjustment
)
188 self
.on_balance_changed(self
.balance_adjustment
)
190 # vbox child at upper part
191 self
.vbox
= gtk
.VBox()
192 self
.pack_start(self
.vbox
, False)
193 self
.label_name
= gtk
.Label()
194 self
.label_name
.set_text(self
.channel_name
)
195 self
.label_name
.set_size_request(0, -1)
196 self
.label_name_event_box
= gtk
.EventBox()
197 self
.label_name_event_box
.connect("button-press-event", self
.on_label_mouse
)
198 self
.label_name_event_box
.add(self
.label_name
)
199 self
.vbox
.pack_start(self
.label_name_event_box
, True)
200 # self.label_stereo = gtk.Label()
202 # self.label_stereo.set_text("stereo")
204 # self.label_stereo.set_text("mono")
205 # self.label_stereo.set_size_request(0, -1)
206 # self.vbox.pack_start(self.label_stereo, True)
208 # hbox for mute and solo buttons
209 self
.hbox_mutesolo
= gtk
.HBox()
211 self
.mute
= gtk
.ToggleButton()
212 self
.mute
.set_label("M")
213 self
.mute
.set_active(jack_mixer_c
.channel_is_muted(self
.channel
))
214 self
.mute
.connect("toggled", self
.on_mute_toggled
)
215 self
.hbox_mutesolo
.pack_start(self
.mute
, True)
217 self
.solo
= gtk
.ToggleButton()
218 self
.solo
.set_label("S")
219 self
.solo
.set_active(jack_mixer_c
.channel_is_soloed(self
.channel
))
220 self
.solo
.connect("toggled", self
.on_solo_toggled
)
221 self
.hbox_mutesolo
.pack_start(self
.solo
, True)
223 self
.vbox
.pack_start(self
.hbox_mutesolo
, False)
226 frame
.set_shadow_type(gtk
.SHADOW_IN
)
227 frame
.add(self
.abspeak
);
228 self
.vbox
.pack_start(frame
, False)
230 # hbox child at lower part
231 self
.hbox
= gtk
.HBox()
232 self
.hbox
.pack_start(self
.slider
, True)
234 frame
.set_shadow_type(gtk
.SHADOW_IN
)
235 frame
.add(self
.meter
);
236 self
.hbox
.pack_start(frame
, True)
238 frame
.set_shadow_type(gtk
.SHADOW_IN
)
239 frame
.add(self
.hbox
);
240 self
.pack_start(frame
, True)
242 self
.volume_digits
.set_size_request(0, -1)
243 self
.pack_start(self
.volume_digits
, False)
246 self
.balance
= phat
.HFanSlider()
247 self
.balance
.set_default_value(0)
248 self
.balance
.set_adjustment(self
.balance_adjustment
)
249 self
.pack_start(self
.balance
, False)
252 channel
.unrealize(self
)
253 jack_mixer_c
.remove_channel(self
.channel
)
256 def on_rename_channel(self
):
257 result
= self
.gui_factory
.run_dialog_rename_channel(self
.channel_name
)
259 #print "renaming to \"%s\"" % result
260 self
.channel_name
= result
261 self
.label_name
.set_text(self
.channel_name
)
262 jack_mixer_c
.channel_rename(self
.channel
, self
.channel_name
)
264 def on_label_mouse(self
, widget
, event
):
265 if event
.type == gtk
.gdk
._2BUTTON
_PRESS
:
266 if event
.button
== 1:
267 self
.on_rename_channel()
269 def on_mute_toggled(self
, button
):
270 if self
.mute
.get_active():
272 jack_mixer_c
.channel_mute(self
.channel
)
275 jack_mixer_c
.channel_unmute(self
.channel
)
277 def on_solo_toggled(self
, button
):
278 if self
.solo
.get_active():
280 jack_mixer_c
.channel_solo(self
.channel
)
283 jack_mixer_c
.channel_unsolo(self
.channel
)
285 def serialization_name(self
):
286 return input_channel_serialization_name()
288 def serialize(self
, object_backend
):
289 object_backend
.add_property("name", self
.channel_name
)
291 object_backend
.add_property("type", "stereo")
293 object_backend
.add_property("type", "mono")
294 channel
.serialize(self
, object_backend
)
296 def unserialize_property(self
, name
, value
):
298 self
.channel_name
= str(value
)
301 if value
== "stereo":
307 return channel
.unserialize_property(self
, name
, value
)
309 def input_channel_serialization_name():
310 return "input_channel"
312 class main_mix(channel
):
313 def __init__(self
, mixer
, gui_factory
):
314 channel
.__init
__(self
, mixer
, gui_factory
, "MAIN", True)
317 channel
.realize(self
)
318 self
.channel
= jack_mixer_c
.get_main_mix_channel(self
.mixer
)
320 self
.on_volume_changed(self
.slider_adjustment
)
321 self
.on_balance_changed(self
.balance_adjustment
)
323 # vbox child at upper part
324 self
.vbox
= gtk
.VBox()
325 self
.pack_start(self
.vbox
, False)
326 self
.label_name
= gtk
.Label()
327 self
.label_name
.set_text(self
.channel_name
)
328 self
.label_name
.set_size_request(0, -1)
329 self
.vbox
.pack_start(self
.label_name
, False)
331 frame
.set_shadow_type(gtk
.SHADOW_IN
)
332 frame
.add(self
.abspeak
);
333 self
.vbox
.pack_start(frame
, False)
335 # hbox child at lower part
336 self
.hbox
= gtk
.HBox()
337 self
.hbox
.pack_start(self
.slider
, True)
339 frame
.set_shadow_type(gtk
.SHADOW_IN
)
340 frame
.add(self
.meter
);
341 self
.hbox
.pack_start(frame
, True)
343 frame
.set_shadow_type(gtk
.SHADOW_IN
)
344 frame
.add(self
.hbox
);
345 self
.pack_start(frame
, True)
347 self
.volume_digits
.set_size_request(0, -1)
348 self
.pack_start(self
.volume_digits
, False)
351 self
.balance
= phat
.HFanSlider()
352 self
.balance
.set_default_value(0)
353 self
.balance
.set_adjustment(self
.balance_adjustment
)
354 self
.pack_start(self
.balance
, False)
357 channel
.unrealize(self
)
360 def serialization_name(self
):
361 return main_mix_serialization_name()
363 def main_mix_serialization_name():
364 return "main_mix_channel"