2 Copyright (C) 2001-2011 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 "gtk2ardour-config.h"
24 #include <boost/algorithm/string.hpp>
26 #include <gtkmm/liststore.h>
27 #include <gtkmm/stock.h>
28 #include <gtkmm/scale.h>
30 #include <gtkmm2ext/utils.h>
31 #include <gtkmm2ext/slider_controller.h>
32 #include <gtkmm2ext/gtk_ui.h>
33 #include <gtkmm2ext/paths_dialog.h>
38 #include "ardour/audioengine.h"
39 #include "ardour/dB.h"
40 #include "ardour/rc_configuration.h"
41 #include "ardour/control_protocol_manager.h"
42 #include "ardour/plugin_manager.h"
43 #include "control_protocol/control_protocol.h"
45 #include "canvas/wave_view.h"
47 #include "ardour_ui.h"
48 #include "ardour_window.h"
49 #include "ardour_dialog.h"
50 #include "gui_thread.h"
51 #include "midi_tracer.h"
52 #include "rc_option_editor.h"
54 #include "midi_port_dialog.h"
61 using namespace Gtkmm2ext;
63 using namespace ARDOUR;
64 using namespace ARDOUR_UI_UTILS;
66 class ClickOptions : public OptionEditorBox
69 ClickOptions (RCConfiguration* c, Gtk::Window* p)
73 Table* t = manage (new Table (2, 3));
76 Label* l = manage (left_aligned_label (_("Click audio file:")));
77 t->attach (*l, 0, 1, 0, 1, FILL);
78 t->attach (_click_path_entry, 1, 2, 0, 1, FILL);
79 Button* b = manage (new Button (_("Browse...")));
80 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
81 t->attach (*b, 2, 3, 0, 1, FILL);
83 l = manage (left_aligned_label (_("Click emphasis audio file:")));
84 t->attach (*l, 0, 1, 1, 2, FILL);
85 t->attach (_click_emphasis_path_entry, 1, 2, 1, 2, FILL);
86 b = manage (new Button (_("Browse...")));
87 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
88 t->attach (*b, 2, 3, 1, 2, FILL);
90 _box->pack_start (*t, false, false);
92 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
93 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
96 void parameter_changed (string const & p)
98 if (p == "click-sound") {
99 _click_path_entry.set_text (_rc_config->get_click_sound());
100 } else if (p == "click-emphasis-sound") {
101 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
105 void set_state_from_config ()
107 parameter_changed ("click-sound");
108 parameter_changed ("click-emphasis-sound");
113 void click_browse_clicked ()
115 SoundFileChooser sfdb (_("Choose Click"));
117 if (sfdb.run () == RESPONSE_OK) {
118 click_chosen (sfdb.get_filename());
122 void click_chosen (string const & path)
124 _click_path_entry.set_text (path);
125 _rc_config->set_click_sound (path);
128 void click_changed ()
130 click_chosen (_click_path_entry.get_text ());
133 void click_emphasis_browse_clicked ()
135 SoundFileChooser sfdb (_("Choose Click Emphasis"));
140 if (sfdb.run () == RESPONSE_OK) {
141 click_emphasis_chosen (sfdb.get_filename());
145 void click_emphasis_chosen (string const & path)
147 _click_emphasis_path_entry.set_text (path);
148 _rc_config->set_click_emphasis_sound (path);
151 void click_emphasis_changed ()
153 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
156 RCConfiguration* _rc_config;
157 Gtk::Window* _parent;
158 Entry _click_path_entry;
159 Entry _click_emphasis_path_entry;
162 class UndoOptions : public OptionEditorBox
165 UndoOptions (RCConfiguration* c) :
167 _limit_undo_button (_("Limit undo history to")),
168 _save_undo_button (_("Save undo history of"))
170 Table* t = new Table (2, 3);
173 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
174 _limit_undo_spin.set_range (0, 512);
175 _limit_undo_spin.set_increments (1, 10);
176 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
177 Label* l = manage (left_aligned_label (_("commands")));
178 t->attach (*l, 2, 3, 0, 1);
180 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
181 _save_undo_spin.set_range (0, 512);
182 _save_undo_spin.set_increments (1, 10);
183 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
184 l = manage (left_aligned_label (_("commands")));
185 t->attach (*l, 2, 3, 1, 2);
187 _box->pack_start (*t);
189 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
190 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
191 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
192 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
195 void parameter_changed (string const & p)
197 if (p == "history-depth") {
198 int32_t const d = _rc_config->get_history_depth();
199 _limit_undo_button.set_active (d != 0);
200 _limit_undo_spin.set_sensitive (d != 0);
201 _limit_undo_spin.set_value (d);
202 } else if (p == "save-history") {
203 bool const x = _rc_config->get_save_history ();
204 _save_undo_button.set_active (x);
205 _save_undo_spin.set_sensitive (x);
206 } else if (p == "save-history-depth") {
207 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
211 void set_state_from_config ()
213 parameter_changed ("save-history");
214 parameter_changed ("history-depth");
215 parameter_changed ("save-history-depth");
218 void limit_undo_toggled ()
220 bool const x = _limit_undo_button.get_active ();
221 _limit_undo_spin.set_sensitive (x);
222 int32_t const n = x ? 16 : 0;
223 _limit_undo_spin.set_value (n);
224 _rc_config->set_history_depth (n);
227 void limit_undo_changed ()
229 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
232 void save_undo_toggled ()
234 bool const x = _save_undo_button.get_active ();
235 _rc_config->set_save_history (x);
238 void save_undo_changed ()
240 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
244 RCConfiguration* _rc_config;
245 CheckButton _limit_undo_button;
246 SpinButton _limit_undo_spin;
247 CheckButton _save_undo_button;
248 SpinButton _save_undo_spin;
253 static const struct {
265 { "Key|Shift", GDK_SHIFT_MASK },
266 { "Command", GDK_META_MASK },
267 { "Control", GDK_CONTROL_MASK },
268 { "Option", GDK_MOD1_MASK },
269 { "Command-Shift", GDK_META_MASK|GDK_SHIFT_MASK },
270 { "Command-Option", GDK_MOD1_MASK|GDK_META_MASK },
271 { "Shift-Option", GDK_SHIFT_MASK|GDK_MOD1_MASK },
272 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_META_MASK },
275 { "Key|Shift", GDK_SHIFT_MASK },
276 { "Control", GDK_CONTROL_MASK },
277 { "Alt (Mod1)", GDK_MOD1_MASK },
278 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
279 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
280 { "Shift-Alt", GDK_SHIFT_MASK|GDK_MOD1_MASK },
281 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
282 { "Mod2", GDK_MOD2_MASK },
283 { "Mod3", GDK_MOD3_MASK },
284 { "Mod4", GDK_MOD4_MASK },
285 { "Mod5", GDK_MOD5_MASK },
291 class KeyboardOptions : public OptionEditorBox
295 _delete_button_adjustment (3, 1, 12),
296 _delete_button_spin (_delete_button_adjustment),
297 _edit_button_adjustment (3, 1, 5),
298 _edit_button_spin (_edit_button_adjustment),
299 _insert_note_button_adjustment (3, 1, 5),
300 _insert_note_button_spin (_insert_note_button_adjustment)
302 /* internationalize and prepare for use with combos */
305 for (int i = 0; modifiers[i].name; ++i) {
306 dumb.push_back (S_(modifiers[i].name));
309 set_popdown_strings (_edit_modifier_combo, dumb);
310 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
312 for (int x = 0; modifiers[x].name; ++x) {
313 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
314 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
319 Table* t = manage (new Table (4, 4));
322 Label* l = manage (left_aligned_label (_("Edit using:")));
323 l->set_name ("OptionsLabel");
325 t->attach (*l, 0, 1, 0, 1, FILL | EXPAND, FILL);
326 t->attach (_edit_modifier_combo, 1, 2, 0, 1, FILL | EXPAND, FILL);
328 l = manage (new Label (_("+ button")));
329 l->set_name ("OptionsLabel");
331 t->attach (*l, 3, 4, 0, 1, FILL | EXPAND, FILL);
332 t->attach (_edit_button_spin, 4, 5, 0, 1, FILL | EXPAND, FILL);
334 _edit_button_spin.set_name ("OptionsEntry");
335 _edit_button_adjustment.set_value (Keyboard::edit_button());
336 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
338 set_popdown_strings (_delete_modifier_combo, dumb);
339 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
341 for (int x = 0; modifiers[x].name; ++x) {
342 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
343 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
348 l = manage (left_aligned_label (_("Delete using:")));
349 l->set_name ("OptionsLabel");
351 t->attach (*l, 0, 1, 1, 2, FILL | EXPAND, FILL);
352 t->attach (_delete_modifier_combo, 1, 2, 1, 2, FILL | EXPAND, FILL);
354 l = manage (new Label (_("+ button")));
355 l->set_name ("OptionsLabel");
357 t->attach (*l, 3, 4, 1, 2, FILL | EXPAND, FILL);
358 t->attach (_delete_button_spin, 4, 5, 1, 2, FILL | EXPAND, FILL);
360 _delete_button_spin.set_name ("OptionsEntry");
361 _delete_button_adjustment.set_value (Keyboard::delete_button());
362 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
365 set_popdown_strings (_insert_note_modifier_combo, dumb);
366 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
368 for (int x = 0; modifiers[x].name; ++x) {
369 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
370 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
375 l = manage (left_aligned_label (_("Insert note using:")));
376 l->set_name ("OptionsLabel");
378 t->attach (*l, 0, 1, 2, 3, FILL | EXPAND, FILL);
379 t->attach (_insert_note_modifier_combo, 1, 2, 2, 3, FILL | EXPAND, FILL);
381 l = manage (new Label (_("+ button")));
382 l->set_name ("OptionsLabel");
384 t->attach (*l, 3, 4, 2, 3, FILL | EXPAND, FILL);
385 t->attach (_insert_note_button_spin, 4, 5, 2, 3, FILL | EXPAND, FILL);
387 _insert_note_button_spin.set_name ("OptionsEntry");
388 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
389 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
392 set_popdown_strings (_snap_modifier_combo, dumb);
393 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
395 for (int x = 0; modifiers[x].name; ++x) {
396 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
397 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
402 l = manage (left_aligned_label (_("Ignore snap using:")));
403 l->set_name ("OptionsLabel");
405 t->attach (*l, 0, 1, 3, 4, FILL | EXPAND, FILL);
406 t->attach (_snap_modifier_combo, 1, 2, 3, 4, FILL | EXPAND, FILL);
410 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
411 strs.push_back (bf->first);
414 set_popdown_strings (_keyboard_layout_selector, strs);
415 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
416 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
418 l = manage (left_aligned_label (_("Keyboard layout:")));
419 l->set_name ("OptionsLabel");
421 t->attach (*l, 0, 1, 4, 5, FILL | EXPAND, FILL);
422 t->attach (_keyboard_layout_selector, 1, 2, 4, 5, FILL | EXPAND, FILL);
424 _box->pack_start (*t, false, false);
427 void parameter_changed (string const &)
429 /* XXX: these aren't really config options... */
432 void set_state_from_config ()
434 /* XXX: these aren't really config options... */
439 void bindings_changed ()
441 string const txt = _keyboard_layout_selector.get_active_text();
443 /* XXX: config...? for all this keyboard stuff */
445 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
446 if (txt == i->first) {
447 if (Keyboard::load_keybindings (i->second)) {
448 Keyboard::save_keybindings ();
454 void edit_modifier_chosen ()
456 string const txt = _edit_modifier_combo.get_active_text();
458 for (int i = 0; modifiers[i].name; ++i) {
459 if (txt == _(modifiers[i].name)) {
460 Keyboard::set_edit_modifier (modifiers[i].modifier);
466 void delete_modifier_chosen ()
468 string const txt = _delete_modifier_combo.get_active_text();
470 for (int i = 0; modifiers[i].name; ++i) {
471 if (txt == _(modifiers[i].name)) {
472 Keyboard::set_delete_modifier (modifiers[i].modifier);
478 void insert_note_modifier_chosen ()
480 string const txt = _insert_note_modifier_combo.get_active_text();
482 for (int i = 0; modifiers[i].name; ++i) {
483 if (txt == _(modifiers[i].name)) {
484 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
490 void snap_modifier_chosen ()
492 string const txt = _snap_modifier_combo.get_active_text();
494 for (int i = 0; modifiers[i].name; ++i) {
495 if (txt == _(modifiers[i].name)) {
496 Keyboard::set_snap_modifier (modifiers[i].modifier);
502 void delete_button_changed ()
504 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
507 void edit_button_changed ()
509 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
512 void insert_note_button_changed ()
514 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
517 ComboBoxText _keyboard_layout_selector;
518 ComboBoxText _edit_modifier_combo;
519 ComboBoxText _delete_modifier_combo;
520 ComboBoxText _insert_note_modifier_combo;
521 ComboBoxText _snap_modifier_combo;
522 Adjustment _delete_button_adjustment;
523 SpinButton _delete_button_spin;
524 Adjustment _edit_button_adjustment;
525 SpinButton _edit_button_spin;
526 Adjustment _insert_note_button_adjustment;
527 SpinButton _insert_note_button_spin;
531 class FontScalingOptions : public OptionEditorBox
534 FontScalingOptions (RCConfiguration* c) :
536 _dpi_adjustment (50, 50, 250, 1, 10),
537 _dpi_slider (_dpi_adjustment)
539 _dpi_adjustment.set_value (floor ((double)(_rc_config->get_font_scale () / 1024)));
541 Label* l = manage (new Label (_("Font scaling:")));
542 l->set_name ("OptionsLabel");
544 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
545 HBox* h = manage (new HBox);
547 h->pack_start (*l, false, false);
548 h->pack_start (_dpi_slider, true, true);
550 _box->pack_start (*h, false, false);
552 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
555 void parameter_changed (string const & p)
557 if (p == "font-scale") {
558 _dpi_adjustment.set_value (floor ((double)(_rc_config->get_font_scale() / 1024)));
562 void set_state_from_config ()
564 parameter_changed ("font-scale");
571 _rc_config->set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024));
572 /* XXX: should be triggered from the parameter changed signal */
576 RCConfiguration* _rc_config;
577 Adjustment _dpi_adjustment;
581 class ClipLevelOptions : public OptionEditorBox
584 ClipLevelOptions (RCConfiguration* c)
586 , _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
587 , _clip_level_slider (_clip_level_adjustment)
589 _clip_level_adjustment.set_value (_rc_config->get_waveform_clip_level ());
591 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
592 l->set_name ("OptionsLabel");
594 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
595 HBox* h = manage (new HBox);
597 h->pack_start (*l, false, false);
598 h->pack_start (_clip_level_slider, true, true);
600 _box->pack_start (*h, false, false);
602 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
605 void parameter_changed (string const & p)
607 if (p == "waveform-clip-level") {
608 _clip_level_adjustment.set_value (_rc_config->get_waveform_clip_level());
612 void set_state_from_config ()
614 parameter_changed ("waveform-clip-level");
619 void clip_level_changed ()
621 _rc_config->set_waveform_clip_level (_clip_level_adjustment.get_value());
622 /* XXX: should be triggered from the parameter changed signal */
623 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
626 RCConfiguration* _rc_config;
627 Adjustment _clip_level_adjustment;
628 HScale _clip_level_slider;
631 class BufferingOptions : public OptionEditorBox
634 BufferingOptions (RCConfiguration* c)
636 , _playback_adjustment (5, 1, 60, 1, 4)
637 , _capture_adjustment (5, 1, 60, 1, 4)
638 , _playback_slider (_playback_adjustment)
639 , _capture_slider (_capture_adjustment)
641 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
643 Label* l = manage (new Label (_("Playback (seconds of buffering):")));
644 l->set_name ("OptionsLabel");
646 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
647 HBox* h = manage (new HBox);
649 h->pack_start (*l, false, false);
650 h->pack_start (_playback_slider, true, true);
652 _box->pack_start (*h, false, false);
654 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
656 l = manage (new Label (_("Recording (seconds of buffering):")));
657 l->set_name ("OptionsLabel");
659 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
660 h = manage (new HBox);
662 h->pack_start (*l, false, false);
663 h->pack_start (_capture_slider, true, true);
665 _box->pack_start (*h, false, false);
667 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
668 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
671 void parameter_changed (string const & p)
673 if (p == "playback-buffer-seconds") {
674 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
675 } else if (p == "capture-buffer-seconds") {
676 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
680 void set_state_from_config ()
682 parameter_changed ("playback-buffer-seconds");
683 parameter_changed ("capture-buffer-seconds");
688 void playback_changed ()
690 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
693 void capture_changed ()
695 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
698 RCConfiguration* _rc_config;
699 Adjustment _playback_adjustment;
700 Adjustment _capture_adjustment;
701 HScale _playback_slider;
702 HScale _capture_slider;
705 class ControlSurfacesOptions : public OptionEditorBox
708 ControlSurfacesOptions (Gtk::Window& parent)
710 , _ignore_view_change (0)
712 _store = ListStore::create (_model);
713 _view.set_model (_store);
714 _view.append_column (_("Control Surface Protocol"), _model.name);
715 _view.get_column(0)->set_resizable (true);
716 _view.get_column(0)->set_expand (true);
717 _view.append_column_editable (_("Enabled"), _model.enabled);
718 _view.append_column_editable (_("Feedback"), _model.feedback);
720 _box->pack_start (_view, false, false);
722 Label* label = manage (new Label);
723 label->set_markup (string_compose (X_("<i>%1</i>"), _("Double-click on a name to edit settings for an enabled protocol")));
725 _box->pack_start (*label, false, false);
728 ControlProtocolManager& m = ControlProtocolManager::instance ();
729 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
730 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
732 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
733 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
736 void parameter_changed (std::string const &)
741 void set_state_from_config ()
745 ControlProtocolManager& m = ControlProtocolManager::instance ();
746 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
748 if (!(*i)->mandatory) {
749 TreeModel::Row r = *_store->append ();
750 r[_model.name] = (*i)->name;
751 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
752 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
753 r[_model.protocol_info] = *i;
760 void protocol_status_changed (ControlProtocolInfo* cpi) {
762 TreeModel::Children rows = _store->children();
764 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
765 string n = ((*x)[_model.name]);
767 if ((*x)[_model.protocol_info] == cpi) {
768 _ignore_view_change++;
769 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
770 _ignore_view_change--;
776 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
778 TreeModel::Row r = *i;
780 if (_ignore_view_change) {
784 ControlProtocolInfo* cpi = r[_model.protocol_info];
789 bool const was_enabled = (cpi->protocol != 0);
790 bool const is_enabled = r[_model.enabled];
793 if (was_enabled != is_enabled) {
796 ControlProtocolManager::instance().activate (*cpi);
798 ControlProtocolManager::instance().deactivate (*cpi);
802 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
803 bool const is_feedback = r[_model.feedback];
805 if (was_feedback != is_feedback && cpi->protocol) {
806 cpi->protocol->set_feedback (is_feedback);
810 void edit_clicked (GdkEventButton* ev)
812 if (ev->type != GDK_2BUTTON_PRESS) {
817 ControlProtocolInfo* cpi;
820 row = *(_view.get_selection()->get_selected());
821 if (!row[_model.enabled]) {
824 cpi = row[_model.protocol_info];
825 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
828 Box* box = (Box*) cpi->protocol->get_gui ();
832 if (box->get_parent()) {
833 static_cast<ArdourWindow*>(box->get_parent())->present();
836 string title = row[_model.name];
837 /* once created, the window is managed by the surface itself (as ->get_parent())
838 * Surface's tear_down_gui() is called on session close, when de-activating
839 * or re-initializing a surface.
840 * tear_down_gui() hides an deletes the Window if it exists.
842 ArdourWindow* win = new ArdourWindow (_parent, title);
843 win->set_title ("Control Protocol Options");
849 class ControlSurfacesModelColumns : public TreeModelColumnRecord
853 ControlSurfacesModelColumns ()
861 TreeModelColumn<string> name;
862 TreeModelColumn<bool> enabled;
863 TreeModelColumn<bool> feedback;
864 TreeModelColumn<ControlProtocolInfo*> protocol_info;
867 Glib::RefPtr<ListStore> _store;
868 ControlSurfacesModelColumns _model;
870 Gtk::Window& _parent;
871 PBD::ScopedConnection protocol_status_connection;
872 uint32_t _ignore_view_change;
875 class VideoTimelineOptions : public OptionEditorBox
878 VideoTimelineOptions (RCConfiguration* c)
880 , _show_video_export_info_button (_("Show Video Export Info before export"))
881 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
882 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
884 Table* t = manage (new Table (2, 6));
887 t->attach (_video_advanced_setup_button, 0, 2, 0, 1);
888 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
889 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
890 _("<b>When enabled</b> you can speficify a custom video-server URL and docroot. - Do not enable this option unless you know what you are doing."));
892 Label* l = manage (new Label (_("Video Server URL:")));
893 l->set_alignment (0, 0.5);
894 t->attach (*l, 0, 1, 1, 2, FILL);
895 t->attach (_video_server_url_entry, 1, 2, 1, 2, FILL);
896 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
897 _("Base URL of the video-server including http prefix. This is usually 'http://hostname.example.org:1554/' and defaults to 'http://localhost:1554/' when the video-server is running locally"));
899 l = manage (new Label (_("Video Folder:")));
900 l->set_alignment (0, 0.5);
901 t->attach (*l, 0, 1, 2, 3, FILL);
902 t->attach (_video_server_docroot_entry, 1, 2, 2, 3);
903 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
904 _("Local path to the video-server document-root. Only files below this directory will be accessible by the video-server. If the server run on a remote host, it should point to a network mounted folder of the server's docroot or be left empty if it is unvailable. It is used for the local video-monitor and file-browsing when opening/adding a video file."));
906 /* small vspace y=3..4 */
908 t->attach (_show_video_export_info_button, 0, 2, 4, 5);
909 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
910 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
911 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
913 t->attach (_show_video_server_dialog_button, 0, 2, 5, 6);
914 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
915 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
916 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
918 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
919 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
920 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
921 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
923 _box->pack_start (*t,true,true);
926 void server_url_changed ()
928 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
931 void server_docroot_changed ()
933 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
936 void show_video_export_info_toggled ()
938 bool const x = _show_video_export_info_button.get_active ();
939 _rc_config->set_show_video_export_info (x);
942 void show_video_server_dialog_toggled ()
944 bool const x = _show_video_server_dialog_button.get_active ();
945 _rc_config->set_show_video_server_dialog (x);
948 void video_advanced_setup_toggled ()
950 bool const x = _video_advanced_setup_button.get_active ();
951 _rc_config->set_video_advanced_setup(x);
954 void parameter_changed (string const & p)
956 if (p == "video-server-url") {
957 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
958 } else if (p == "video-server-docroot") {
959 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
960 } else if (p == "show-video-export-info") {
961 bool const x = _rc_config->get_show_video_export_info();
962 _show_video_export_info_button.set_active (x);
963 } else if (p == "show-video-server-dialog") {
964 bool const x = _rc_config->get_show_video_server_dialog();
965 _show_video_server_dialog_button.set_active (x);
966 } else if (p == "video-advanced-setup") {
967 bool const x = _rc_config->get_video_advanced_setup();
968 _video_advanced_setup_button.set_active(x);
969 _video_server_docroot_entry.set_sensitive(x);
970 _video_server_url_entry.set_sensitive(x);
974 void set_state_from_config ()
976 parameter_changed ("video-server-url");
977 parameter_changed ("video-server-docroot");
978 parameter_changed ("video-monitor-setup-dialog");
979 parameter_changed ("show-video-export-info");
980 parameter_changed ("show-video-server-dialog");
981 parameter_changed ("video-advanced-setup");
985 RCConfiguration* _rc_config;
986 Entry _video_server_url_entry;
987 Entry _video_server_docroot_entry;
988 CheckButton _show_video_export_info_button;
989 CheckButton _show_video_server_dialog_button;
990 CheckButton _video_advanced_setup_button;
993 class PluginOptions : public OptionEditorBox
996 PluginOptions (RCConfiguration* c)
998 , _display_plugin_scan_progress (_("Always Display Plugin Scan Progress"))
999 , _discover_vst_on_start (_("Scan for new VST Plugins on Application Start"))
1000 , _timeout_adjustment (0, 0, 3000, 50, 50)
1001 , _timeout_slider (_timeout_adjustment)
1004 std::stringstream ss;
1005 Table* t = manage (new Table (2, 6));
1006 t->set_spacings (4);
1010 ss << "<b>" << _("General") << "</b>";
1011 l = manage (left_aligned_label (ss.str()));
1012 l->set_use_markup (true);
1013 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1014 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1016 b = manage (new Button (_("Scan for Plugins")));
1017 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::refresh_clicked));
1018 t->attach (*b, 0, 2, n, n+1, FILL); ++n;
1020 t->attach (_display_plugin_scan_progress, 0, 2, n, n+1); ++n;
1021 _display_plugin_scan_progress.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::display_plugin_scan_progress_toggled));
1022 Gtkmm2ext::UI::instance()->set_tip (_display_plugin_scan_progress,
1023 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
1025 _timeout_slider.set_digits (0);
1026 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &PluginOptions::timeout_changed));
1028 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1029 _("Specify the default timeout for plugin instantiation in 1/10 seconds. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1031 l = manage (left_aligned_label (_("Scan Time Out [deciseconds]")));;
1032 HBox* h = manage (new HBox);
1034 h->pack_start (*l, false, false);
1035 h->pack_start (_timeout_slider, true, true);
1036 t->attach (*h, 0, 2, n, n+1); ++n;
1039 ss << "<b>" << _("VST") << "</b>";
1040 l = manage (left_aligned_label (ss.str()));
1041 l->set_use_markup (true);
1042 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1043 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1045 b = manage (new Button (_("Clear VST Cache")));
1046 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_cache_clicked));
1047 t->attach (*b, 0, 1, n, n+1, FILL);
1049 b = manage (new Button (_("Clear VST Blacklist")));
1050 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_blacklist_clicked));
1051 t->attach (*b, 1, 2, n, n+1, FILL);
1054 t->attach (_discover_vst_on_start, 0, 2, n, n+1); ++n;
1055 _discover_vst_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_vst_on_start_toggled));
1056 Gtkmm2ext::UI::instance()->set_tip (_discover_vst_on_start,
1057 _("<b>When enabled</b> new VST plugins are searched, tested and added to the cache index on application start. When disabled new plugins will only be available after triggering a 'Scan' manually"));
1059 #ifdef LXVST_SUPPORT
1060 t->attach (*manage (left_aligned_label (_("Linux VST Path:"))), 0, 1, n, n+1);
1061 b = manage (new Button (_("Edit")));
1062 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_lxvst_path_clicked));
1063 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1066 #ifdef WINDOWS_VST_SUPPORT
1067 t->attach (*manage (left_aligned_label (_("Windows VST Path:"))), 0, 1, n, n+1);
1068 b = manage (new Button (_("Edit")));
1069 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_vst_path_clicked));
1070 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1073 _box->pack_start (*t,true,true);
1076 void parameter_changed (string const & p) {
1077 if (p == "show-plugin-scan-window") {
1078 bool const x = _rc_config->get_show_plugin_scan_window();
1079 _display_plugin_scan_progress.set_active (x);
1081 else if (p == "discover-vst-on-start") {
1082 bool const x = _rc_config->get_discover_vst_on_start();
1083 _discover_vst_on_start.set_active (x);
1085 else if (p == "vst-scan-timeout") {
1086 int const x = _rc_config->get_vst_scan_timeout();
1087 _timeout_adjustment.set_value (x);
1091 void set_state_from_config () {
1092 parameter_changed ("show-plugin-scan-window");
1093 parameter_changed ("discover-vst-on-start");
1094 parameter_changed ("vst-scan-timeout");
1098 RCConfiguration* _rc_config;
1099 CheckButton _display_plugin_scan_progress;
1100 CheckButton _discover_vst_on_start;
1101 Adjustment _timeout_adjustment;
1102 HScale _timeout_slider;
1104 void display_plugin_scan_progress_toggled () {
1105 bool const x = _display_plugin_scan_progress.get_active();
1106 _rc_config->set_show_plugin_scan_window(x);
1109 void discover_vst_on_start_toggled () {
1110 bool const x = _discover_vst_on_start.get_active();
1111 _rc_config->set_discover_vst_on_start(x);
1114 void timeout_changed () {
1115 int x = floor(_timeout_adjustment.get_value());
1116 _rc_config->set_vst_scan_timeout(x);
1119 void clear_vst_cache_clicked () {
1120 PluginManager::instance().clear_vst_cache();
1123 void clear_vst_blacklist_clicked () {
1124 PluginManager::instance().clear_vst_blacklist();
1127 void edit_vst_path_clicked () {
1128 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1129 _("Set Windows VST Search Path"),
1130 _rc_config->get_plugin_path_vst(),
1131 PluginManager::instance().get_default_windows_vst_path()
1133 ResponseType r = (ResponseType) pd->run ();
1135 if (r == RESPONSE_ACCEPT) {
1136 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
1141 // todo consolidate with edit_vst_path_clicked..
1142 void edit_lxvst_path_clicked () {
1143 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1144 _("Set Linux VST Search Path"),
1145 _rc_config->get_plugin_path_lxvst(),
1146 PluginManager::instance().get_default_lxvst_path()
1148 ResponseType r = (ResponseType) pd->run ();
1150 if (r == RESPONSE_ACCEPT) {
1151 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
1156 void refresh_clicked () {
1157 PluginManager::instance().refresh();
1162 /** A class which allows control of visibility of some editor components usign
1163 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1164 * which has the correct members, but with null widget pointers. This
1165 * class allows the user to set visibility of the members, the details
1166 * of which are stored in a configuration variable which can be watched
1167 * by parts of the editor that actually contain the widgets whose visibility
1168 * is being controlled.
1171 class VisibilityOption : public Option
1174 /** @param name User-visible name for this group.
1175 * @param g `Dummy' VisibilityGroup (as described above).
1176 * @param get Method to get the value of the appropriate configuration variable.
1177 * @param set Method to set the value of the appropriate configuration variable.
1179 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1180 : Option (g->get_state_name(), name)
1182 , _visibility_group (g)
1186 /* Watch for changes made by the user to our members */
1187 _visibility_group->VisibilityChanged.connect_same_thread (
1188 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1192 void set_state_from_config ()
1194 /* Set our state from the current configuration */
1195 _visibility_group->set_state (_get ());
1198 void add_to_page (OptionEditorPage* p)
1200 _heading.add_to_page (p);
1201 add_widget_to_page (p, _visibility_group->list_view ());
1204 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1209 /* The user has changed something, so reflect this change
1210 in the RCConfiguration.
1212 _set (_visibility_group->get_state_value ());
1215 OptionEditorHeading _heading;
1216 VisibilityGroup* _visibility_group;
1217 sigc::slot<std::string> _get;
1218 sigc::slot<bool, std::string> _set;
1219 PBD::ScopedConnection _visibility_group_connection;
1224 RCOptionEditor::RCOptionEditor ()
1225 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1226 , _rc_config (Config)
1227 , _mixer_strip_visibility ("mixer-element-visibility")
1231 uint32_t hwcpus = hardware_concurrency ();
1233 BoolComboOption* bco;
1236 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1238 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1240 _("Signal processing uses"),
1241 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1242 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1245 procs->add (-1, _("all but one processor"));
1246 procs->add (0, _("all available processors"));
1248 for (uint32_t i = 1; i <= hwcpus; ++i) {
1249 procs->add (i, string_compose (_("%1 processors"), i));
1252 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1254 add_option (_("Misc"), procs);
1257 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1259 add_option (_("Misc"), new UndoOptions (_rc_config));
1261 add_option (_("Misc"),
1263 "verify-remove-last-capture",
1264 _("Verify removal of last capture"),
1265 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1266 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1269 add_option (_("Misc"),
1271 "periodic-safety-backups",
1272 _("Make periodic backups of the session file"),
1273 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1274 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1277 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1279 add_option (_("Misc"),
1281 "only-copy-imported-files",
1282 _("Always copy imported files"),
1283 sigc::mem_fun (*_rc_config, &RCConfiguration::get_only_copy_imported_files),
1284 sigc::mem_fun (*_rc_config, &RCConfiguration::set_only_copy_imported_files)
1287 add_option (_("Misc"), new DirectoryOption (
1288 X_("default-session-parent-dir"),
1289 _("Default folder for new sessions:"),
1290 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1291 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1294 add_option (_("Misc"),
1295 new SpinOption<uint32_t> (
1296 "max-recent-sessions",
1297 _("Maximum number of recent sessions"),
1298 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1299 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1303 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1305 add_option (_("Misc"), new ClickOptions (_rc_config, this));
1307 add_option (_("Misc"),
1310 _("Click gain level"),
1311 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1312 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1315 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1317 add_option (_("Misc"),
1318 new SpinOption<double> (
1319 "automation-thinning-factor",
1320 _("Thinning factor (larger value => less data)"),
1321 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1322 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1326 add_option (_("Misc"),
1327 new SpinOption<double> (
1328 "automation-interval-msecs",
1329 _("Automation sampling interval (milliseconds)"),
1330 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1331 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1339 tsf = new BoolOption (
1340 "latched-record-enable",
1341 _("Keep record-enable engaged on stop"),
1342 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1343 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1345 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1346 add_option (_("Transport"), tsf);
1348 tsf = new BoolOption (
1349 "stop-recording-on-xrun",
1350 _("Stop recording when an xrun occurs"),
1351 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
1352 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
1354 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1355 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
1357 add_option (_("Transport"), tsf);
1359 tsf = new BoolOption (
1361 _("Play loop is a transport mode"),
1362 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1363 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1365 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1366 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1367 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1368 add_option (_("Transport"), tsf);
1370 tsf = new BoolOption (
1371 "create-xrun-marker",
1372 _("Create markers where xruns occur"),
1373 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
1374 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
1376 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1377 add_option (_("Transport"), tsf);
1379 tsf = new BoolOption (
1380 "stop-at-session-end",
1381 _("Stop at the end of the session"),
1382 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
1383 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
1385 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1386 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
1387 "when it reaches the current session end marker\n\n"
1388 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
1390 add_option (_("Transport"), tsf);
1392 tsf = new BoolOption (
1394 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
1395 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
1396 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
1398 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1399 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
1400 "preventing any need to do a transport locate at the end of the loop\n\n"
1401 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
1402 "which will often cause a small click or delay"), PROGRAM_NAME));
1403 add_option (_("Transport"), tsf);
1405 tsf = new BoolOption (
1406 "disable-disarm-during-roll",
1407 _("Disable per-track record disarm while rolling"),
1408 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
1409 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
1411 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("<b>When enabled</b> this will prevent you from accidentally stopping specific tracks recording during a take"));
1412 add_option (_("Transport"), tsf);
1414 tsf = new BoolOption (
1416 _("12dB gain reduction during fast-forward and fast-rewind"),
1417 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
1418 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
1420 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
1421 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
1422 add_option (_("Transport"), tsf);
1424 add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
1426 _sync_source = new ComboOption<SyncSource> (
1428 _("External timecode source"),
1429 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
1430 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
1433 populate_sync_options ();
1434 add_option (_("Transport"), _sync_source);
1436 _sync_framerate = new BoolOption (
1437 "timecode-sync-frame-rate",
1438 _("Match session video frame rate to external timecode"),
1439 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
1440 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
1442 Gtkmm2ext::UI::instance()->set_tip
1443 (_sync_framerate->tip_widget(),
1444 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
1445 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
1446 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
1447 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
1448 "timecode standard and the session standard."), PROGRAM_NAME));
1450 add_option (_("Transport"), _sync_framerate);
1452 _sync_genlock = new BoolOption (
1453 "timecode-source-is-synced",
1454 _("External timecode is sync locked"),
1455 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
1456 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
1458 Gtkmm2ext::UI::instance()->set_tip
1459 (_sync_genlock->tip_widget(),
1460 _("<b>When enabled</b> indicates that the selected external timecode source shares sync (Black & Burst, Wordclock, etc) with the audio interface."));
1463 add_option (_("Transport"), _sync_genlock);
1465 _sync_source_2997 = new BoolOption (
1466 "timecode-source-2997",
1467 _("Lock to 29.9700 fps instead of 30000/1001"),
1468 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
1469 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
1471 Gtkmm2ext::UI::instance()->set_tip
1472 (_sync_source_2997->tip_widget(),
1473 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
1474 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
1475 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
1476 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
1477 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
1478 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
1481 add_option (_("Transport"), _sync_source_2997);
1483 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
1485 _ltc_port = new ComboStringOption (
1487 _("LTC incoming port"),
1488 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
1489 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
1492 vector<string> physical_inputs;
1493 physical_inputs.push_back (_("None"));
1494 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
1495 _ltc_port->set_popdown_strings (physical_inputs);
1497 add_option (_("Transport"), _ltc_port);
1499 // TODO; rather disable this button than not compile it..
1500 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
1502 add_option (_("Transport"),
1505 _("Enable LTC generator"),
1506 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
1507 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
1510 _ltc_send_continuously = new BoolOption (
1511 "ltc-send-continuously",
1512 _("Send LTC while stopped"),
1513 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
1514 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
1516 Gtkmm2ext::UI::instance()->set_tip
1517 (_ltc_send_continuously->tip_widget(),
1518 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
1519 add_option (_("Transport"), _ltc_send_continuously);
1521 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
1522 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
1523 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
1524 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
1526 Gtkmm2ext::UI::instance()->set_tip
1527 (_ltc_volume_slider->tip_widget(),
1528 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
1530 add_option (_("Transport"), _ltc_volume_slider);
1531 parameter_changed ("send-ltc");
1533 parameter_changed ("sync-source");
1537 add_option (S_("Editor"),
1539 "draggable-playhead",
1540 _("Allow dragging of playhead"),
1541 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_draggable_playhead),
1542 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_draggable_playhead)
1545 add_option (_("Editor"),
1547 "automation-follows-regions",
1548 _("Move relevant automation when audio regions are moved"),
1549 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
1550 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
1553 add_option (_("Editor"),
1555 "show-track-meters",
1556 _("Show meters on tracks in the editor"),
1557 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_track_meters),
1558 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_track_meters)
1561 add_option (_("Editor"),
1563 "show-editor-meter",
1564 _("Display master-meter in the toolbar"),
1565 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_editor_meter),
1566 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_editor_meter)
1569 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
1570 "default-fade-shape",
1571 _("Default fade shape"),
1572 sigc::mem_fun (*_rc_config,
1573 &RCConfiguration::get_default_fade_shape),
1574 sigc::mem_fun (*_rc_config,
1575 &RCConfiguration::set_default_fade_shape)
1578 fadeshape->add (FadeLinear,
1579 _("Linear (for highly correlated material)"));
1580 fadeshape->add (FadeConstantPower, _("Constant power"));
1581 fadeshape->add (FadeSymmetric, _("Symmetric"));
1582 fadeshape->add (FadeSlow, _("Slow"));
1583 fadeshape->add (FadeFast, _("Fast"));
1585 add_option (_("Editor"), fadeshape);
1588 bco = new BoolComboOption (
1589 "use-overlap-equivalency",
1590 _("Regions in active edit groups are edited together"),
1591 _("whenever they overlap in time"),
1592 _("only if they have identical length, position and origin"),
1593 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
1594 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
1597 add_option (_("Editor"), bco);
1599 add_option (_("Editor"),
1601 "rubberbanding-snaps-to-grid",
1602 _("Make rubberband selection rectangle snap to the grid"),
1603 sigc::mem_fun (*_rc_config, &RCConfiguration::get_rubberbanding_snaps_to_grid),
1604 sigc::mem_fun (*_rc_config, &RCConfiguration::set_rubberbanding_snaps_to_grid)
1607 add_option (_("Editor"),
1610 _("Show waveforms in regions"),
1611 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms),
1612 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms)
1615 add_option (_("Editor"),
1616 new BoolComboOption (
1617 "show-region-gain-envelopes",
1618 _("Show gain envelopes in audio regions"),
1620 _("only in region gain mode"),
1621 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_region_gain),
1622 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_region_gain)
1625 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
1627 _("Waveform scale"),
1628 sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_scale),
1629 sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_scale)
1632 wfs->add (Linear, _("linear"));
1633 wfs->add (Logarithmic, _("logarithmic"));
1635 add_option (_("Editor"), wfs);
1637 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
1639 _("Waveform shape"),
1640 sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_shape),
1641 sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_shape)
1644 wfsh->add (Traditional, _("traditional"));
1645 wfsh->add (Rectified, _("rectified"));
1647 add_option (_("Editor"), wfsh);
1649 add_option (_("Editor"), new ClipLevelOptions (_rc_config));
1651 add_option (_("Editor"),
1653 "show-waveforms-while-recording",
1654 _("Show waveforms for audio while it is being recorded"),
1655 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms_while_recording),
1656 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms_while_recording)
1659 add_option (_("Editor"),
1662 _("Show zoom toolbar"),
1663 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_zoom_tools),
1664 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_zoom_tools)
1667 add_option (_("Editor"),
1669 "update-editor-during-summary-drag",
1670 _("Update editor window during drags of the summary"),
1671 sigc::mem_fun (*_rc_config, &RCConfiguration::get_update_editor_during_summary_drag),
1672 sigc::mem_fun (*_rc_config, &RCConfiguration::set_update_editor_during_summary_drag)
1675 add_option (_("Editor"),
1677 "link-editor-and-mixer-selection",
1678 _("Synchronise editor and mixer selection"),
1679 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_editor_and_mixer_selection),
1680 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_editor_and_mixer_selection)
1683 bo = new BoolOption (
1685 _("Name new markers"),
1686 sigc::mem_fun (*_rc_config, &RCConfiguration::get_name_new_markers),
1687 sigc::mem_fun (*_rc_config, &RCConfiguration::set_name_new_markers)
1690 add_option (_("Editor"), bo);
1691 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(), _("If enabled, popup a dialog when a new marker is created to allow its name to be set as it is created."
1692 "\n\nYou can always rename markers by right-clicking on them"));
1694 add_option (_("Editor"),
1696 "autoscroll-editor",
1697 _("Auto-scroll editor window when dragging near its edges"),
1698 sigc::mem_fun (*_rc_config, &RCConfiguration::get_autoscroll_editor),
1699 sigc::mem_fun (*_rc_config, &RCConfiguration::set_autoscroll_editor)
1704 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
1706 add_option (_("Audio"), new BufferingOptions (_rc_config));
1708 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
1710 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
1712 _("Record monitoring handled by"),
1713 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
1714 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
1717 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
1718 mm->add (HardwareMonitoring, _("via Audio Driver"));
1721 string prog (PROGRAM_NAME);
1722 boost::algorithm::to_lower (prog);
1723 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
1724 mm->add (ExternalMonitoring, _("audio hardware"));
1726 add_option (_("Audio"), mm);
1728 add_option (_("Audio"),
1730 "tape-machine-mode",
1731 _("Tape machine mode"),
1732 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
1733 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
1736 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
1738 add_option (_("Audio"),
1740 "auto-connect-standard-busses",
1741 _("Auto-connect master/monitor busses"),
1742 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
1743 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
1746 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
1747 "input-auto-connect",
1748 _("Connect track inputs"),
1749 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
1750 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
1753 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
1754 iac->add (ManualConnect, _("manually"));
1756 add_option (_("Audio"), iac);
1758 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
1759 "output-auto-connect",
1760 _("Connect track and bus outputs"),
1761 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
1762 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
1765 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
1766 oac->add (AutoConnectMaster, _("automatically to master bus"));
1767 oac->add (ManualConnect, _("manually"));
1769 add_option (_("Audio"), oac);
1771 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
1773 add_option (_("Audio"),
1775 "denormal-protection",
1776 _("Use DC bias to protect against denormals"),
1777 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
1778 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
1781 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
1783 _("Processor handling"),
1784 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
1785 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
1788 dm->add (DenormalNone, _("no processor handling"));
1792 if (fpu.has_flush_to_zero()) {
1793 dm->add (DenormalFTZ, _("use FlushToZero"));
1796 if (fpu.has_denormals_are_zero()) {
1797 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
1800 if (fpu.has_flush_to_zero() && fpu.has_denormals_are_zero()) {
1801 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
1804 add_option (_("Audio"), dm);
1806 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
1808 add_option (_("Audio"),
1810 "plugins-stop-with-transport",
1811 _("Silence plugins when the transport is stopped"),
1812 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
1813 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
1816 add_option (_("Audio"),
1818 "new-plugins-active",
1819 _("Make new plugins active"),
1820 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
1821 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
1824 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
1826 add_option (_("Audio"),
1828 "auto-analyse-audio",
1829 _("Enable automatic analysis of audio"),
1830 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
1831 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
1834 add_option (_("Audio"),
1836 "replicate-missing-region-channels",
1837 _("Replicate missing region channels"),
1838 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
1839 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
1844 add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
1846 add_option (_("Solo / mute"),
1849 _("Solo-in-place mute cut (dB)"),
1850 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
1851 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
1854 _solo_control_is_listen_control = new BoolOption (
1855 "solo-control-is-listen-control",
1856 _("Solo controls are Listen controls"),
1857 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
1858 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
1861 add_option (_("Solo / mute"), _solo_control_is_listen_control);
1863 _listen_position = new ComboOption<ListenPosition> (
1865 _("Listen Position"),
1866 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
1867 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
1870 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
1871 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
1873 add_option (_("Solo / mute"), _listen_position);
1875 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
1877 _("PFL signals come from"),
1878 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
1879 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
1882 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
1883 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
1885 add_option (_("Solo / mute"), pp);
1887 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
1889 _("AFL signals come from"),
1890 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
1891 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
1894 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
1895 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
1897 add_option (_("Solo / mute"), pa);
1899 parameter_changed ("use-monitor-bus");
1901 add_option (_("Solo / mute"),
1904 _("Exclusive solo"),
1905 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
1906 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
1909 add_option (_("Solo / mute"),
1912 _("Show solo muting"),
1913 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
1914 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
1917 add_option (_("Solo / mute"),
1919 "solo-mute-override",
1920 _("Soloing overrides muting"),
1921 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
1922 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
1925 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
1927 add_option (_("Solo / mute"),
1929 "mute-affects-pre-fader",
1930 _("Mute affects pre-fader sends"),
1931 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
1932 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
1935 add_option (_("Solo / mute"),
1937 "mute-affects-post-fader",
1938 _("Mute affects post-fader sends"),
1939 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
1940 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
1943 add_option (_("Solo / mute"),
1945 "mute-affects-control-outs",
1946 _("Mute affects control outputs"),
1947 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
1948 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
1951 add_option (_("Solo / mute"),
1953 "mute-affects-main-outs",
1954 _("Mute affects main outputs"),
1955 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
1956 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
1959 add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
1961 add_option (_("Solo / mute"),
1963 "link-send-and-route-panner",
1964 _("Link panners of Aux and External Sends with main panner by default"),
1965 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
1966 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
1969 add_option (_("MIDI"),
1972 _("Send MIDI Clock"),
1973 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
1974 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
1977 add_option (_("MIDI"),
1980 _("Send MIDI Time Code"),
1981 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
1982 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
1985 add_option (_("MIDI"),
1986 new SpinOption<int> (
1987 "mtc-qf-speed-tolerance",
1988 _("Percentage either side of normal transport speed to transmit MTC"),
1989 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
1990 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
1994 add_option (_("MIDI"),
1997 _("Obey MIDI Machine Control commands"),
1998 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
1999 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2002 add_option (_("MIDI"),
2005 _("Send MIDI Machine Control commands"),
2006 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2007 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2010 add_option (_("MIDI"),
2013 _("Send MIDI control feedback"),
2014 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2015 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2018 add_option (_("MIDI"),
2019 new SpinOption<uint8_t> (
2020 "mmc-receive-device-id",
2021 _("Inbound MMC device ID"),
2022 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2023 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2027 add_option (_("MIDI"),
2028 new SpinOption<uint8_t> (
2029 "mmc-send-device-id",
2030 _("Outbound MMC device ID"),
2031 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2032 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2036 add_option (_("MIDI"),
2037 new SpinOption<int32_t> (
2038 "initial-program-change",
2039 _("Initial program change"),
2040 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2041 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2045 add_option (_("MIDI"),
2047 "display-first-midi-bank-as-zero",
2048 _("Display first MIDI bank/program as 0"),
2049 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2050 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2053 add_option (_("MIDI"),
2055 "never-display-periodic-midi",
2056 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2057 sigc::mem_fun (*_rc_config, &RCConfiguration::get_never_display_periodic_midi),
2058 sigc::mem_fun (*_rc_config, &RCConfiguration::set_never_display_periodic_midi)
2061 add_option (_("MIDI"),
2064 _("Sound MIDI notes as they are selected"),
2065 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sound_midi_notes),
2066 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sound_midi_notes)
2069 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2071 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2072 "midi-audition-synth-uri",
2073 _("Midi Audition Synth (LV2)"),
2074 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2075 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2078 audition_synth->add(X_(""), _("None"));
2079 PluginInfoList all_plugs;
2080 PluginManager& manager (PluginManager::instance());
2082 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2084 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2085 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2086 if (!(*i)->is_instrument()) continue;
2087 if ((*i)->type != ARDOUR::LV2) continue;
2088 audition_synth->add((*i)->unique_id, (*i)->name);
2092 add_option (_("MIDI"), audition_synth);
2094 /* USER INTERACTION */
2096 if (getenv ("ARDOUR_BUNDLED")) {
2097 add_option (_("User interaction"),
2099 "enable-translation",
2100 string_compose (_("Use translations of %1 messages\n"
2101 " <i>(requires a restart of %1 to take effect)</i>\n"
2102 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2103 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2104 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2107 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2109 add_option (_("User interaction"), new KeyboardOptions);
2111 /* Control Surfaces */
2113 add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this));
2115 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2117 _("Control surface remote ID"),
2118 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2119 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2122 rm->add (UserOrdered, _("assigned by user"));
2123 rm->add (MixerOrdered, _("follows order of mixer"));
2125 add_option (_("Control Surfaces"), rm);
2127 /* VIDEO Timeline */
2128 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2130 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
2131 /* Plugin options (currrently VST only) */
2132 add_option (_("Plugins"), new PluginOptions (_rc_config));
2137 add_option (S_("Preferences|GUI"),
2140 _("Graphically indicate mouse pointer hovering over various widgets"),
2141 sigc::mem_fun (*_rc_config, &RCConfiguration::get_widget_prelight),
2142 sigc::mem_fun (*_rc_config, &RCConfiguration::set_widget_prelight)
2145 add_option (S_("Preferences|GUI"),
2148 _("Show tooltips if mouse hovers over a control"),
2149 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_tooltips),
2150 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_tooltips)
2153 add_option (S_("Preferences|GUI"),
2155 "show-name-highlight",
2156 _("Use name highlight bars in region displays"),
2157 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_name_highlight),
2158 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_name_highlight)
2162 /* font scaling does nothing with GDK/Quartz */
2163 add_option (S_("Preferences|GUI"), new FontScalingOptions (_rc_config));
2166 add_option (S_("GUI"),
2168 "super-rapid-clock-update",
2169 _("update transport clock display at FPS instead of every 100ms"),
2170 sigc::mem_fun (*_rc_config, &RCConfiguration::get_super_rapid_clock_update),
2171 sigc::mem_fun (*_rc_config, &RCConfiguration::set_super_rapid_clock_update)
2174 /* Lock GUI timeout */
2176 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
2177 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2178 _("Lock timeout (seconds)"),
2180 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_lock_gui_after_seconds),
2181 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_lock_gui_after_seconds)
2183 slts->scale().set_digits (0);
2184 Gtkmm2ext::UI::instance()->set_tip
2185 (slts->tip_widget(),
2186 _("Lock GUI after this many idle seconds (zero to never lock)"));
2187 add_option (S_("Preferences|GUI"), slts);
2189 /* The names of these controls must be the same as those given in MixerStrip
2190 for the actual widgets being controlled.
2192 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
2193 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
2194 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
2195 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
2196 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
2197 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
2200 S_("Preferences|GUI"),
2201 new VisibilityOption (
2203 &_mixer_strip_visibility,
2204 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mixer_strip_visibility),
2205 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mixer_strip_visibility)
2209 add_option (S_("Preferences|GUI"),
2211 "default-narrow_ms",
2212 _("Use narrow strips in the mixer by default"),
2213 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_narrow_ms),
2214 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_narrow_ms)
2217 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2219 ComboOption<float>* mht = new ComboOption<float> (
2221 _("Peak hold time"),
2222 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_hold),
2223 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_hold)
2226 mht->add (MeterHoldOff, _("off"));
2227 mht->add (MeterHoldShort, _("short"));
2228 mht->add (MeterHoldMedium, _("medium"));
2229 mht->add (MeterHoldLong, _("long"));
2231 add_option (S_("Preferences|Metering"), mht);
2233 ComboOption<float>* mfo = new ComboOption<float> (
2236 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2237 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2240 mfo->add (METER_FALLOFF_OFF, _("off"));
2241 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2242 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2243 mfo->add (METER_FALLOFF_SLOWISH, _("slowish [12.0dB/sec] (DIN)"));
2244 mfo->add (METER_FALLOFF_MODERATE, _("moderate [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2245 mfo->add (METER_FALLOFF_MEDIUM, _("medium [20dB/sec]"));
2246 mfo->add (METER_FALLOFF_FAST, _("fast [32dB/sec]"));
2247 mfo->add (METER_FALLOFF_FASTER, _("faster [46dB/sec]"));
2248 mfo->add (METER_FALLOFF_FASTEST, _("fastest [70dB/sec]"));
2250 add_option (S_("Preferences|Metering"), mfo);
2252 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2253 "meter-line-up-level",
2254 _("Meter line-up level; 0dBu"),
2255 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_line_up_level),
2256 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_line_up_level)
2259 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2260 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2261 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2262 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2264 Gtkmm2ext::UI::instance()->set_tip (mlu->tip_widget(), _("Configure meter-marks and color-knee point for dBFS scale DPM, set reference level for IEC1/Nordic, IEC2 PPM and VU meter."));
2266 add_option (S_("Preferences|Metering"), mlu);
2268 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2269 "meter-line-up-din",
2270 _("IEC1/DIN Meter line-up level; 0dBu"),
2271 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_line_up_din),
2272 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_line_up_din)
2275 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2276 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2277 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2278 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2280 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2282 add_option (S_("Preferences|Metering"), mld);
2284 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2285 "meter-vu-standard",
2286 _("VU Meter standard"),
2287 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_vu_standard),
2288 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_vu_standard)
2291 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2292 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2293 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2294 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2296 add_option (S_("Preferences|Metering"), mvu);
2298 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
2299 HSliderOption *mpks = new HSliderOption("meter-peak",
2300 _("Peak threshold [dBFS]"),
2302 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_peak),
2303 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_peak)
2306 Gtkmm2ext::UI::instance()->set_tip
2307 (mpks->tip_widget(),
2308 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
2310 add_option (S_("Preferences|Metering"), mpks);
2312 add_option (S_("Preferences|Metering"),
2315 _("LED meter style"),
2316 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_style_led),
2317 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_style_led)
2323 RCOptionEditor::parameter_changed (string const & p)
2325 OptionEditor::parameter_changed (p);
2327 if (p == "use-monitor-bus") {
2328 bool const s = Config->get_use_monitor_bus ();
2330 /* we can't use this if we don't have a monitor bus */
2331 Config->set_solo_control_is_listen_control (false);
2333 _solo_control_is_listen_control->set_sensitive (s);
2334 _listen_position->set_sensitive (s);
2335 } else if (p == "sync-source") {
2336 _sync_source->set_sensitive (true);
2338 _sync_source->set_sensitive (!_session->config.get_external_sync());
2340 switch(Config->get_sync_source()) {
2343 _sync_genlock->set_sensitive (true);
2344 _sync_framerate->set_sensitive (true);
2345 _sync_source_2997->set_sensitive (true);
2348 _sync_genlock->set_sensitive (false);
2349 _sync_framerate->set_sensitive (false);
2350 _sync_source_2997->set_sensitive (false);
2353 } else if (p == "send-ltc") {
2354 bool const s = Config->get_send_ltc ();
2355 _ltc_send_continuously->set_sensitive (s);
2356 _ltc_volume_slider->set_sensitive (s);
2360 void RCOptionEditor::ltc_generator_volume_changed () {
2361 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
2365 RCOptionEditor::populate_sync_options ()
2367 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
2369 _sync_source->clear ();
2371 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
2372 _sync_source->add (*i, sync_source_to_string (*i));