From: Frédéric Péters Date: Fri, 11 Dec 2009 16:20:04 +0000 (+0100) Subject: Add a monitor output channel, and toggle buttons on individual tracks X-Git-Tag: release-7~21 X-Git-Url: https://git.0d.be/?p=jack_mixer.git;a=commitdiff_plain;h=4c36f43015bf63a382cf6463274bbaea78643efd Add a monitor output channel, and toggle buttons on individual tracks This allows no plumbing monitoring of output channels, as well as *prefader* content of input channels (implementing a feature comparable to "Pre-Fade Listen"). --- diff --git a/channel.py b/channel.py index 7895e9c..fb19345 100644 --- a/channel.py +++ b/channel.py @@ -38,6 +38,8 @@ import fpconst class channel(gtk.VBox, serialized_object): '''Widget with slider and meter used as base class for more specific channel widgets''' + monitor_button = None + def __init__(self, app, name, stereo): gtk.VBox.__init__(self) self.app = app @@ -113,6 +115,8 @@ class channel(gtk.VBox, serialized_object): self.balance = gtk.HScale(self.balance_adjustment) self.balance.set_draw_value(False) self.pack_start(self.balance, False) + if self.monitor_button: + self.reorder_child(self.monitor_button, -1) self.balance.show() def create_slider_widget(self): @@ -205,6 +209,7 @@ class channel(gtk.VBox, serialized_object): if update_engine: #print "Setting engine volume to " + db_text self.channel.volume = db + self.app.update_monitor(self) def on_volume_changed(self, adjustment): self.update_volume(True) @@ -213,6 +218,7 @@ class channel(gtk.VBox, serialized_object): balance = self.balance_adjustment.get_value() #print "%s balance: %f" % (self.channel_name, balance) self.channel.balance = balance + self.app.update_monitor(self) def on_key_pressed(self, widget, event): if (event.keyval == gtk.keysyms.Up): @@ -259,6 +265,24 @@ class channel(gtk.VBox, serialized_object): # absolutely have to be done from the gtk thread. self.emit('midi-event-received') + def on_monitor_button_toggled(self, button): + if not button.get_active(): + self.app.main_mix.monitor_button.set_active(True) + else: + for channel in self.app.channels + self.app.output_channels + [self.app.main_mix]: + if channel.monitor_button.get_active() and channel.monitor_button is not button: + channel.monitor_button.handler_block_by_func( + channel.on_monitor_button_toggled) + channel.monitor_button.set_active(False) + channel.monitor_button.handler_unblock_by_func( + channel.on_monitor_button_toggled) + self.app.set_monitored_channel(self) + + def set_monitored(self): + if self.channel: + self.app.set_monitored_channel(self) + self.monitor_button.set_active(True) + gobject.signal_new('midi-event-received', channel, gobject.SIGNAL_RUN_FIRST | gobject.SIGNAL_ACTION, gobject.TYPE_NONE, ()) @@ -339,6 +363,10 @@ class input_channel(channel): self.create_balance_widget() + self.monitor_button = gtk.ToggleButton('MON') + self.monitor_button.connect('toggled', self.on_monitor_button_toggled) + self.pack_start(self.monitor_button, False, False) + def add_control_group(self, channel): control_group = ControlGroup(channel, self) control_group.show_all() @@ -369,9 +397,11 @@ class input_channel(channel): def on_mute_toggled(self, button): self.channel.mute = self.mute.get_active() + self.app.update_monitor(self.app.main_mix) def on_solo_toggled(self, button): self.channel.solo = self.solo.get_active() + self.app.update_monitor(self.app.main_mix) def serialization_name(self): return input_channel_serialization_name() @@ -481,6 +511,10 @@ class output_channel(channel): self.create_balance_widget() + self.monitor_button = gtk.ToggleButton('MON') + self.monitor_button.connect('toggled', self.on_monitor_button_toggled) + self.pack_start(self.monitor_button, False, False) + channel_properties_dialog = None def on_channel_properties(self): if not self.channel_properties_dialog: @@ -571,6 +605,10 @@ class main_mix(channel): self.create_balance_widget() + self.monitor_button = gtk.ToggleButton('MON') + self.monitor_button.connect('toggled', self.on_monitor_button_toggled) + self.pack_start(self.monitor_button, False, False) + def unrealize(self): channel.unrealize(self) self.channel = False @@ -790,6 +828,7 @@ class ControlGroup(gtk.Alignment): gtk.Alignment.__init__(self, 0.5, 0.5, 0, 0) self.output_channel = output_channel self.input_channel = input_channel + self.app = input_channel.app hbox = gtk.HBox() self.hbox = hbox @@ -827,6 +866,8 @@ class ControlGroup(gtk.Alignment): def on_mute_toggled(self, button): self.output_channel.channel.set_muted(self.input_channel.channel, button.get_active()) + self.app.update_monitor(self) def on_solo_toggled(self, button): self.output_channel.channel.set_solo(self.input_channel.channel, button.get_active()) + self.app.update_monitor(self) diff --git a/jack_mixer.py b/jack_mixer.py index 9008300..a06d5d3 100755 --- a/jack_mixer.py +++ b/jack_mixer.py @@ -62,6 +62,7 @@ class jack_mixer(serialized_object): self.mixer = jack_mixer_c.Mixer(name) if not self.mixer: return + self.monitor_channel = self.mixer.add_output_channel("Monitor", True, True) if lash_client: # Send our client name to server @@ -157,6 +158,7 @@ class jack_mixer(serialized_object): self.main_mix = main_mix(self) self.main_mix.realize() + self.main_mix.set_monitored() self.hbox_outputs = gtk.HBox() self.hbox_outputs.set_spacing(0) self.hbox_outputs.set_border_width(0) @@ -354,6 +356,48 @@ class jack_mixer(serialized_object): for inputchannel in self.channels: inputchannel.add_control_group(channel) + _monitored_channel = None + def get_monitored_channel(self): + return self._monitored_channel + + def set_monitored_channel(self, channel): + if self._monitored_channel: + if channel.channel.name == self._monitored_channel.channel.name: + return + self._monitored_channel = channel + if type(channel) is input_channel: + # reset all solo/mute settings + for in_channel in self.channels: + self.monitor_channel.set_solo(in_channel.channel, False) + self.monitor_channel.set_muted(in_channel.channel, False) + self.monitor_channel.set_solo(channel.channel, True) + self.monitor_channel.prefader = True + else: + self.monitor_channel.prefader = False + self.update_monitor(channel) + monitored_channel = property(get_monitored_channel, set_monitored_channel) + + def update_monitor(self, channel): + if self.monitored_channel is not channel: + return + self.monitor_channel.volume = channel.channel.volume + self.monitor_channel.balance = channel.channel.balance + if type(self.monitored_channel) is output_channel: + # 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: + # sync solo/muted channels + for input_channel in self.channels: + self.monitor_channel.set_solo(input_channel.channel, + input_channel.channel.solo) + self.monitor_channel.set_muted(input_channel.channel, + input_channel.channel.mute) + + def lash_check_events(self): while lash.lash_get_pending_event_count(self.lash_client): event = lash.lash_get_event(self.lash_client)