2 Copyright (C) 2002-2006 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include <gtkmm2ext/gtk_ui.h>
22 #include <gtkmm2ext/stop_signal.h>
23 #include <gtkmm2ext/choice.h>
24 #include <gtkmm2ext/doi.h>
25 #include <gtkmm2ext/bindable_button.h>
27 #include <ardour/route_group.h>
28 #include <pbd/memento_command.h>
29 #include <pbd/stacktrace.h>
30 #include <pbd/shiva.h>
36 #include "gui_thread.h"
38 #include <ardour/route.h>
39 #include <ardour/session.h>
40 #include <ardour/audioengine.h>
41 #include <ardour/audio_track.h>
42 #include <ardour/audio_diskstream.h>
47 using namespace Gtkmm2ext;
48 using namespace ARDOUR;
51 RouteUI::RouteUI (boost::shared_ptr<ARDOUR::Route> rt, ARDOUR::Session& sess, const char* m_name,
52 const char* s_name, const char* r_name)
62 remote_control_menu = 0;
63 ignore_toggle = false;
64 wait_for_release = false;
65 route_active_menu_item = 0;
67 if (set_color_from_route()) {
68 set_color (unique_random_color());
71 new PairedShiva<Route,RouteUI> (*_route, *this);
73 _route->active_changed.connect (mem_fun (*this, &RouteUI::route_active_changed));
75 mute_button = manage (new BindableToggleButton (_route->mute_control(), m_name ));
76 solo_button = manage (new BindableToggleButton (_route->solo_control(), s_name ));
78 // mute_button->unset_flags (Gtk::CAN_FOCUS);
79 // solo_button->unset_flags (Gtk::CAN_FOCUS);
81 _route->mute_changed.connect (mem_fun(*this, &RouteUI::mute_changed));
82 _route->solo_changed.connect (mem_fun(*this, &RouteUI::solo_changed));
83 _route->solo_safe_changed.connect (mem_fun(*this, &RouteUI::solo_changed));
85 update_solo_display ();
86 update_mute_display ();
89 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_route);
91 t->diskstream()->RecordEnableChanged.connect (mem_fun (*this, &RouteUI::route_rec_enable_changed));
93 _session.RecordStateChanged.connect (mem_fun (*this, &RouteUI::session_rec_enable_changed));
95 rec_enable_button = manage (new BindableToggleButton (t->rec_enable_control(), r_name ));
96 rec_enable_button->unset_flags (Gtk::CAN_FOCUS);
98 update_rec_display ();
101 /* map the current state */
108 GoingAway (); /* EMIT SIGNAL */
113 RouteUI::mute_press(GdkEventButton* ev)
115 if (!ignore_toggle) {
117 if (Keyboard::is_context_menu_event (ev)) {
123 mute_menu->popup(0,ev->time);
127 if (ev->button == 2) {
128 // ctrl-button2 click is the midi binding click
129 // button2-click is "momentary"
131 if (!Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::Control))) {
132 wait_for_release = true;
138 if (ev->button == 1 || ev->button == 2) {
140 if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Shift))) {
142 /* ctrl-shift-click applies change to all routes */
144 _session.begin_reversible_command (_("mute change"));
145 Session::GlobalMuteStateCommand *cmd = new Session::GlobalMuteStateCommand(_session, this);
146 _session.set_all_mute (!_route->muted());
148 _session.add_command(cmd);
149 _session.commit_reversible_command ();
151 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
153 /* ctrl-click applies change to the mix group.
154 ctrl-button2 is MIDI learn.
157 if (ev->button == 1) {
158 set_mix_group_mute (_route, !_route->muted());
163 /* plain click applies change to this route */
165 reversibly_apply_route_boolean ("mute change", &Route::set_mute, !_route->muted(), this);
176 RouteUI::mute_release(GdkEventButton* ev)
178 if (!ignore_toggle) {
179 if (wait_for_release){
180 wait_for_release = false;
182 // because the press was the last undoable thing we did
190 RouteUI::solo_press(GdkEventButton* ev)
192 if (!ignore_toggle) {
194 if (Keyboard::is_context_menu_event (ev)) {
196 if (solo_menu == 0) {
200 solo_menu->popup (1, ev->time);
204 if (ev->button == 2) {
206 // ctrl-button2 click is the midi binding click
207 // button2-click is "momentary"
209 if (!Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::Control))) {
210 wait_for_release = true;
216 if (ev->button == 1 || ev->button == 2) {
218 if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Shift))) {
220 /* ctrl-shift-click applies change to all routes */
222 _session.begin_reversible_command (_("solo change"));
223 Session::GlobalSoloStateCommand *cmd = new Session::GlobalSoloStateCommand(_session, this);
224 _session.set_all_solo (!_route->soloed());
226 _session.add_command (cmd);
227 _session.commit_reversible_command ();
229 } else if (Keyboard::modifier_state_contains (ev->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Alt))) {
231 // ctrl-alt-click: exclusively solo this track, not a toggle */
233 _session.begin_reversible_command (_("solo change"));
234 Session::GlobalSoloStateCommand *cmd = new Session::GlobalSoloStateCommand (_session, this);
235 _session.set_all_solo (false);
236 _route->set_solo (true, this);
238 _session.add_command(cmd);
239 _session.commit_reversible_command ();
241 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
243 // shift-click: set this route to solo safe
245 _route->set_solo_safe (!_route->solo_safe(), this);
246 wait_for_release = false;
248 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
250 /* ctrl-click: solo mix group.
251 ctrl-button2 is MIDI learn.
254 if (ev->button == 1) {
255 set_mix_group_solo (_route, !_route->soloed());
260 /* click: solo this route */
262 reversibly_apply_route_boolean ("solo change", &Route::set_solo, !_route->soloed(), this);
272 RouteUI::solo_release(GdkEventButton* ev)
274 if (!ignore_toggle) {
275 if (wait_for_release) {
276 wait_for_release = false;
278 // because the press was the last undoable thing we did
288 RouteUI::rec_enable_press(GdkEventButton* ev)
290 if (!_session.engine().connected()) {
291 MessageDialog msg (_("Not connected to JACK - cannot engage record"));
296 if (!ignore_toggle && is_track() && rec_enable_button) {
298 if (ev->button == 2 && Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
299 // do nothing on midi bind event
301 else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Shift))) {
303 _session.begin_reversible_command (_("rec-enable change"));
304 Session::GlobalRecordEnableStateCommand *cmd = new Session::GlobalRecordEnableStateCommand(_session, this);
306 if (rec_enable_button->get_active()) {
307 _session.record_disenable_all ();
309 _session.record_enable_all ();
313 _session.add_command(cmd);
314 _session.commit_reversible_command ();
316 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
318 set_mix_group_rec_enable (_route, !_route->record_enabled());
322 reversibly_apply_audio_track_boolean ("rec-enable change", &AudioTrack::set_record_enable, !audio_track()->record_enabled(), this);
324 ignore_toggle = true;
325 rec_enable_button->set_active(audio_track()->record_enabled());
326 ignore_toggle = false;
329 stop_signal (*rec_enable_button, "button-press-event");
336 RouteUI::solo_changed(void* src)
338 Gtkmm2ext::UI::instance()->call_slot (mem_fun (*this, &RouteUI::update_solo_display));
342 RouteUI::update_solo_display ()
346 if (solo_button->get_active() != (x = _route->soloed())){
347 ignore_toggle = true;
348 solo_button->set_active(x);
349 ignore_toggle = false;
354 if (_route->solo_safe()){
355 solo_button->set_name(safe_solo_button_name());
357 solo_button->set_name(solo_button_name());
362 RouteUI::mute_changed(void* src)
364 Gtkmm2ext::UI::instance()->call_slot (mem_fun (*this, &RouteUI::update_mute_display));
368 RouteUI::update_mute_display ()
372 if (mute_button->get_active() != (x = _route->muted())){
373 ignore_toggle = true;
374 mute_button->set_active(x);
375 ignore_toggle = false;
380 RouteUI::route_rec_enable_changed ()
382 Gtkmm2ext::UI::instance()->call_slot (mem_fun (*this, &RouteUI::update_rec_display));
386 RouteUI::session_rec_enable_changed ()
388 Gtkmm2ext::UI::instance()->call_slot (mem_fun (*this, &RouteUI::update_rec_display));
392 RouteUI::update_rec_display ()
394 bool model = _route->record_enabled();
395 bool view = rec_enable_button->get_active();
397 /* first make sure the button's "depressed" visual
402 ignore_toggle = true;
403 rec_enable_button->set_active (model);
404 ignore_toggle = false;
407 /* now make sure its color state is correct */
411 switch (_session.record_status ()) {
412 case Session::Disabled:
413 case Session::Enabled:
414 if (rec_enable_button->get_state() != Gtk::STATE_ACTIVE) {
415 rec_enable_button->set_state (Gtk::STATE_ACTIVE);
419 case Session::Recording:
420 if (rec_enable_button->get_state() != Gtk::STATE_SELECTED) {
421 rec_enable_button->set_state (Gtk::STATE_SELECTED);
427 if (rec_enable_button->get_state() != Gtk::STATE_NORMAL) {
428 rec_enable_button->set_state (Gtk::STATE_NORMAL);
434 RouteUI::build_remote_control_menu ()
436 remote_control_menu = manage (new Menu);
437 refresh_remote_control_menu ();
441 RouteUI::refresh_remote_control_menu ()
443 using namespace Menu_Helpers;
445 RadioMenuItem::Group rc_group;
446 CheckMenuItem* rc_active;
447 uint32_t limit = _session.ntracks();
450 MenuList& rc_items = remote_control_menu->items();
453 /* note that this menu list starts at zero, not 1, because zero
454 is a valid, if useless, ID.
457 limit += 4; /* leave some breathing room */
459 rc_items.push_back (RadioMenuElem (rc_group, _("None")));
460 if (_route->remote_control_id() == 0) {
461 rc_active = dynamic_cast<CheckMenuItem*> (&rc_items.back());
462 rc_active->set_active ();
465 for (uint32_t i = 1; i < limit; ++i) {
466 snprintf (buf, sizeof (buf), "%u", i);
467 rc_items.push_back (RadioMenuElem (rc_group, buf));
468 rc_active = dynamic_cast<RadioMenuItem*>(&rc_items.back());
469 if (_route->remote_control_id() == i) {
470 rc_active = dynamic_cast<CheckMenuItem*> (&rc_items.back());
471 rc_active->set_active ();
473 rc_active->signal_activate().connect (bind (mem_fun (*this, &RouteUI::set_remote_control_id), i, rc_active));
478 RouteUI::set_remote_control_id (uint32_t id, CheckMenuItem* item)
480 /* this is called when the radio menu item is toggled, and so
481 is actually invoked twice per menu selection. we only
482 care about the invocation for the item that was being
486 if (item->get_active()) {
487 _route->set_remote_control_id (id);
492 RouteUI::build_solo_menu (void)
494 using namespace Menu_Helpers;
496 solo_menu = new Menu;
497 solo_menu->set_name ("ArdourContextMenu");
498 MenuList& items = solo_menu->items();
499 CheckMenuItem* check;
501 check = new CheckMenuItem(_("Solo-safe"));
502 check->set_active (_route->solo_safe());
503 check->signal_toggled().connect (bind (mem_fun (*this, &RouteUI::toggle_solo_safe), check));
504 _route->solo_safe_changed.connect(bind (mem_fun (*this, &RouteUI::solo_safe_toggle), check));
505 items.push_back (CheckMenuElem(*check));
508 //items.push_back (SeparatorElem());
509 // items.push_back (MenuElem (_("MIDI Bind"), mem_fun (*mute_button, &BindableToggleButton::midi_learn)));
514 RouteUI::build_mute_menu(void)
516 using namespace Menu_Helpers;
518 mute_menu = new Menu;
519 mute_menu->set_name ("ArdourContextMenu");
520 MenuList& items = mute_menu->items();
521 CheckMenuItem* check;
523 check = new CheckMenuItem(_("Pre Fader"));
524 init_mute_menu(PRE_FADER, check);
525 check->signal_toggled().connect(bind (mem_fun (*this, &RouteUI::toggle_mute_menu), PRE_FADER, check));
526 _route->pre_fader_changed.connect(bind (mem_fun (*this, &RouteUI::pre_fader_toggle), check));
527 items.push_back (CheckMenuElem(*check));
530 check = new CheckMenuItem(_("Post Fader"));
531 init_mute_menu(POST_FADER, check);
532 check->signal_toggled().connect(bind (mem_fun (*this, &RouteUI::toggle_mute_menu), POST_FADER, check));
533 _route->post_fader_changed.connect(bind (mem_fun (*this, &RouteUI::post_fader_toggle), check));
534 items.push_back (CheckMenuElem(*check));
537 check = new CheckMenuItem(_("Control Outs"));
538 init_mute_menu(CONTROL_OUTS, check);
539 check->signal_toggled().connect(bind (mem_fun (*this, &RouteUI::toggle_mute_menu), CONTROL_OUTS, check));
540 _route->control_outs_changed.connect(bind (mem_fun (*this, &RouteUI::control_outs_toggle), check));
541 items.push_back (CheckMenuElem(*check));
544 check = new CheckMenuItem(_("Main Outs"));
545 init_mute_menu(MAIN_OUTS, check);
546 check->signal_toggled().connect(bind (mem_fun (*this, &RouteUI::toggle_mute_menu), MAIN_OUTS, check));
547 _route->main_outs_changed.connect(bind (mem_fun (*this, &RouteUI::main_outs_toggle), check));
548 items.push_back (CheckMenuElem(*check));
551 //items.push_back (SeparatorElem());
552 // items.push_back (MenuElem (_("MIDI Bind"), mem_fun (*mute_button, &BindableToggleButton::midi_learn)));
556 RouteUI::init_mute_menu(mute_type type, CheckMenuItem* check)
558 if (_route->get_mute_config (type)) {
559 check->set_active (true);
564 RouteUI::toggle_mute_menu(mute_type type, Gtk::CheckMenuItem* check)
566 _route->set_mute_config(type, check->get_active(), this);
570 RouteUI::toggle_solo_safe (Gtk::CheckMenuItem* check)
572 _route->set_solo_safe (check->get_active(), this);
576 RouteUI::set_mix_group_solo(boost::shared_ptr<Route> route, bool yn)
578 RouteGroup* mix_group;
580 if((mix_group = route->mix_group()) != 0){
581 _session.begin_reversible_command (_("mix group solo change"));
582 Session::GlobalSoloStateCommand *cmd = new Session::GlobalSoloStateCommand(_session, this);
583 mix_group->apply(&Route::set_solo, yn, this);
585 _session.add_command (cmd);
586 _session.commit_reversible_command ();
588 reversibly_apply_route_boolean ("solo change", &Route::set_solo, !route->soloed(), this);
593 RouteUI::reversibly_apply_route_boolean (string name, void (Route::*func)(bool, void *), bool yn, void *arg)
595 _session.begin_reversible_command (name);
596 XMLNode &before = _route->get_state();
597 bind(mem_fun(*_route, func), yn, arg)();
598 XMLNode &after = _route->get_state();
599 _session.add_command (new MementoCommand<Route>(*_route, &before, &after));
600 _session.commit_reversible_command ();
604 RouteUI::reversibly_apply_audio_track_boolean (string name, void (AudioTrack::*func)(bool, void *), bool yn, void *arg)
606 _session.begin_reversible_command (name);
607 XMLNode &before = audio_track()->get_state();
608 bind (mem_fun (*audio_track(), func), yn, arg)();
609 XMLNode &after = audio_track()->get_state();
610 _session.add_command (new MementoCommand<AudioTrack>(*audio_track(), &before, &after));
611 _session.commit_reversible_command ();
615 RouteUI::set_mix_group_mute(boost::shared_ptr<Route> route, bool yn)
617 RouteGroup* mix_group;
619 if((mix_group = route->mix_group()) != 0){
620 _session.begin_reversible_command (_("mix group mute change"));
621 Session::GlobalMuteStateCommand *cmd = new Session::GlobalMuteStateCommand (_session, this);
622 mix_group->apply(&Route::set_mute, yn, this);
624 _session.add_command(cmd);
625 _session.commit_reversible_command ();
627 reversibly_apply_route_boolean ("mute change", &Route::set_mute, !route->muted(), this);
632 RouteUI::set_mix_group_rec_enable(boost::shared_ptr<Route> route, bool yn)
634 RouteGroup* mix_group;
636 if((mix_group = route->mix_group()) != 0){
637 _session.begin_reversible_command (_("mix group rec-enable change"));
638 Session::GlobalRecordEnableStateCommand *cmd = new Session::GlobalRecordEnableStateCommand(_session, this);
639 mix_group->apply (&Route::set_record_enable, yn, this);
641 _session.add_command(cmd);
642 _session.commit_reversible_command ();
644 reversibly_apply_route_boolean ("rec-enable change", &Route::set_record_enable, !_route->record_enabled(), this);
650 RouteUI::choose_color()
655 color = Gtkmm2ext::UI::instance()->get_color (_("ardour: color selection"), picked, &_color);
665 RouteUI::set_color (const Gdk::Color & c)
672 snprintf (buf, sizeof (buf), "%d:%d:%d", c.get_red(), c.get_green(), c.get_blue());
673 xml_node->add_property ("color", buf);
675 _route->gui_changed ("color", (void *) 0); /* EMIT_SIGNAL */
680 RouteUI::ensure_xml_node ()
683 if ((xml_node = _route->extra_xml ("GUI")) == 0) {
684 xml_node = new XMLNode ("GUI");
685 _route->add_extra_xml (*xml_node);
691 RouteUI::get_child_xml_node (const string & childname)
698 if ((child = find_named_node (*xml_node, childname)) == 0) {
699 child = new XMLNode (childname);
700 xml_node->add_child_nocopy (*child);
707 RouteUI::set_color_from_route ()
711 RouteUI::ensure_xml_node ();
713 if ((prop = xml_node->property ("color")) != 0) {
715 sscanf (prop->value().c_str(), "%d:%d:%d", &r, &g, &b);
725 RouteUI::remove_this_route ()
727 vector<string> choices;
731 prompt = string_compose (_("Do you really want to remove track \"%1\" ?\n\nYou may also lose the playlist used by this track.\n(cannot be undone)"), _route->name());
733 prompt = string_compose (_("Do you really want to remove bus \"%1\" ?\n(cannot be undone)"), _route->name());
736 choices.push_back (_("No, do nothing."));
737 choices.push_back (_("Yes, remove it."));
739 Choice prompter (prompt, choices);
741 if (prompter.run () == 1) {
742 Glib::signal_idle().connect (bind (sigc::ptr_fun (&RouteUI::idle_remove_this_route), this));
747 RouteUI::idle_remove_this_route (RouteUI *rui)
749 rui->_session.remove_route (rui->_route);
754 RouteUI::route_rename ()
756 ArdourPrompter name_prompter (true);
758 name_prompter.set_prompt (_("New Name: "));
759 name_prompter.set_initial_text (_route->name());
760 name_prompter.add_button (_("Rename"), Gtk::RESPONSE_ACCEPT);
761 name_prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
762 name_prompter.show_all ();
764 switch (name_prompter.run ()) {
766 case Gtk::RESPONSE_ACCEPT:
767 name_prompter.get_result (result);
768 if (result.length()) {
769 _route->set_name (result, this);
779 RouteUI::name_changed (void *src)
781 ENSURE_GUI_THREAD(bind (mem_fun (*this, &RouteUI::name_changed), src));
783 name_label.set_text (_route->name());
787 RouteUI::toggle_route_active ()
791 if (route_active_menu_item) {
792 if (route_active_menu_item->get_active() != (yn = _route->active())) {
793 _route->set_active (!yn);
799 RouteUI::route_active_changed ()
801 if (route_active_menu_item) {
802 Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun (*route_active_menu_item, &CheckMenuItem::set_active), _route->active()));
807 RouteUI::toggle_polarity ()
809 if (polarity_menu_item) {
813 ENSURE_GUI_THREAD(mem_fun (*this, &RouteUI::toggle_polarity));
815 if ((x = polarity_menu_item->get_active()) != _route->phase_invert()) {
816 _route->set_phase_invert (x, this);
818 name_label.set_text (X_("Ø ") + name_label.get_text());
820 name_label.set_text (_route->name());
827 RouteUI::polarity_changed ()
829 /* no signal for this yet */
833 RouteUI::solo_safe_toggle(void* src, Gtk::CheckMenuItem* check)
835 bool yn = _route->solo_safe ();
837 if (check->get_active() != yn) {
838 check->set_active (yn);
842 RouteUI::pre_fader_toggle(void* src, Gtk::CheckMenuItem* check)
844 ENSURE_GUI_THREAD(bind (mem_fun (*this, &RouteUI::pre_fader_toggle), src, check));
846 bool yn = _route->get_mute_config(PRE_FADER);
847 if (check->get_active() != yn) {
848 check->set_active (yn);
853 RouteUI::post_fader_toggle(void* src, Gtk::CheckMenuItem* check)
855 ENSURE_GUI_THREAD(bind (mem_fun (*this, &RouteUI::post_fader_toggle), src, check));
857 bool yn = _route->get_mute_config(POST_FADER);
858 if (check->get_active() != yn) {
859 check->set_active (yn);
864 RouteUI::control_outs_toggle(void* src, Gtk::CheckMenuItem* check)
866 ENSURE_GUI_THREAD(bind (mem_fun (*this, &RouteUI::control_outs_toggle), src, check));
868 bool yn = _route->get_mute_config(CONTROL_OUTS);
869 if (check->get_active() != yn) {
870 check->set_active (yn);
875 RouteUI::main_outs_toggle(void* src, Gtk::CheckMenuItem* check)
877 ENSURE_GUI_THREAD(bind (mem_fun (*this, &RouteUI::main_outs_toggle), src, check));
879 bool yn = _route->get_mute_config(MAIN_OUTS);
880 if (check->get_active() != yn) {
881 check->set_active (yn);
886 RouteUI::disconnect_input ()
888 _route->disconnect_inputs (this);
892 RouteUI::disconnect_output ()
894 _route->disconnect_outputs (this);
898 RouteUI::is_track () const
900 return dynamic_cast<Track*>(_route.get()) != 0;
904 RouteUI::track() const
906 return dynamic_cast<Track*>(_route.get());
910 RouteUI::is_audio_track () const
912 return dynamic_cast<AudioTrack*>(_route.get()) != 0;
916 RouteUI::audio_track() const
918 return dynamic_cast<AudioTrack*>(_route.get());
921 boost::shared_ptr<Diskstream>
922 RouteUI::get_diskstream () const
924 boost::shared_ptr<Track> t;
926 if ((t = boost::dynamic_pointer_cast<Track>(_route)) != 0) {
927 return t->diskstream();
929 return boost::shared_ptr<Diskstream> ((Diskstream*) 0);
934 RouteUI::name() const
936 return _route->name();
940 RouteUI::map_frozen ()
942 ENSURE_GUI_THREAD (mem_fun (*this, &RouteUI::map_frozen));
944 AudioTrack* at = dynamic_cast<AudioTrack*>(_route.get());
947 switch (at->freeze_state()) {
948 case AudioTrack::Frozen:
949 rec_enable_button->set_sensitive (false);
952 rec_enable_button->set_sensitive (true);