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;
65 class ClickOptions : public OptionEditorBox
68 ClickOptions (RCConfiguration* c, Gtk::Window* p)
72 Table* t = manage (new Table (2, 3));
75 Label* l = manage (left_aligned_label (_("Click audio file:")));
76 t->attach (*l, 0, 1, 0, 1, FILL);
77 t->attach (_click_path_entry, 1, 2, 0, 1, FILL);
78 Button* b = manage (new Button (_("Browse...")));
79 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
80 t->attach (*b, 2, 3, 0, 1, FILL);
82 l = manage (left_aligned_label (_("Click emphasis audio file:")));
83 t->attach (*l, 0, 1, 1, 2, FILL);
84 t->attach (_click_emphasis_path_entry, 1, 2, 1, 2, FILL);
85 b = manage (new Button (_("Browse...")));
86 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
87 t->attach (*b, 2, 3, 1, 2, FILL);
89 _box->pack_start (*t, false, false);
91 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
92 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
95 void parameter_changed (string const & p)
97 if (p == "click-sound") {
98 _click_path_entry.set_text (_rc_config->get_click_sound());
99 } else if (p == "click-emphasis-sound") {
100 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
104 void set_state_from_config ()
106 parameter_changed ("click-sound");
107 parameter_changed ("click-emphasis-sound");
112 void click_browse_clicked ()
114 SoundFileChooser sfdb (_("Choose Click"));
116 if (sfdb.run () == RESPONSE_OK) {
117 click_chosen (sfdb.get_filename());
121 void click_chosen (string const & path)
123 _click_path_entry.set_text (path);
124 _rc_config->set_click_sound (path);
127 void click_changed ()
129 click_chosen (_click_path_entry.get_text ());
132 void click_emphasis_browse_clicked ()
134 SoundFileChooser sfdb (_("Choose Click Emphasis"));
139 if (sfdb.run () == RESPONSE_OK) {
140 click_emphasis_chosen (sfdb.get_filename());
144 void click_emphasis_chosen (string const & path)
146 _click_emphasis_path_entry.set_text (path);
147 _rc_config->set_click_emphasis_sound (path);
150 void click_emphasis_changed ()
152 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
155 RCConfiguration* _rc_config;
156 Gtk::Window* _parent;
157 Entry _click_path_entry;
158 Entry _click_emphasis_path_entry;
161 class UndoOptions : public OptionEditorBox
164 UndoOptions (RCConfiguration* c) :
166 _limit_undo_button (_("Limit undo history to")),
167 _save_undo_button (_("Save undo history of"))
169 Table* t = new Table (2, 3);
172 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
173 _limit_undo_spin.set_range (0, 512);
174 _limit_undo_spin.set_increments (1, 10);
175 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
176 Label* l = manage (left_aligned_label (_("commands")));
177 t->attach (*l, 2, 3, 0, 1);
179 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
180 _save_undo_spin.set_range (0, 512);
181 _save_undo_spin.set_increments (1, 10);
182 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
183 l = manage (left_aligned_label (_("commands")));
184 t->attach (*l, 2, 3, 1, 2);
186 _box->pack_start (*t);
188 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
189 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
190 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
191 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
194 void parameter_changed (string const & p)
196 if (p == "history-depth") {
197 int32_t const d = _rc_config->get_history_depth();
198 _limit_undo_button.set_active (d != 0);
199 _limit_undo_spin.set_sensitive (d != 0);
200 _limit_undo_spin.set_value (d);
201 } else if (p == "save-history") {
202 bool const x = _rc_config->get_save_history ();
203 _save_undo_button.set_active (x);
204 _save_undo_spin.set_sensitive (x);
205 } else if (p == "save-history-depth") {
206 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
210 void set_state_from_config ()
212 parameter_changed ("save-history");
213 parameter_changed ("history-depth");
214 parameter_changed ("save-history-depth");
217 void limit_undo_toggled ()
219 bool const x = _limit_undo_button.get_active ();
220 _limit_undo_spin.set_sensitive (x);
221 int32_t const n = x ? 16 : 0;
222 _limit_undo_spin.set_value (n);
223 _rc_config->set_history_depth (n);
226 void limit_undo_changed ()
228 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
231 void save_undo_toggled ()
233 bool const x = _save_undo_button.get_active ();
234 _rc_config->set_save_history (x);
237 void save_undo_changed ()
239 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
243 RCConfiguration* _rc_config;
244 CheckButton _limit_undo_button;
245 SpinButton _limit_undo_spin;
246 CheckButton _save_undo_button;
247 SpinButton _save_undo_spin;
252 static const struct {
264 { "Key|Shift", GDK_SHIFT_MASK },
265 { "Command", GDK_META_MASK },
266 { "Control", GDK_CONTROL_MASK },
267 { "Option", GDK_MOD1_MASK },
268 { "Command-Shift", GDK_META_MASK|GDK_SHIFT_MASK },
269 { "Command-Option", GDK_MOD1_MASK|GDK_META_MASK },
270 { "Shift-Option", GDK_SHIFT_MASK|GDK_MOD1_MASK },
271 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_META_MASK },
274 { "Key|Shift", GDK_SHIFT_MASK },
275 { "Control", GDK_CONTROL_MASK },
276 { "Alt (Mod1)", GDK_MOD1_MASK },
277 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
278 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
279 { "Shift-Alt", GDK_SHIFT_MASK|GDK_MOD1_MASK },
280 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
281 { "Mod2", GDK_MOD2_MASK },
282 { "Mod3", GDK_MOD3_MASK },
283 { "Mod4", GDK_MOD4_MASK },
284 { "Mod5", GDK_MOD5_MASK },
290 class KeyboardOptions : public OptionEditorBox
294 _delete_button_adjustment (3, 1, 12),
295 _delete_button_spin (_delete_button_adjustment),
296 _edit_button_adjustment (3, 1, 5),
297 _edit_button_spin (_edit_button_adjustment),
298 _insert_note_button_adjustment (3, 1, 5),
299 _insert_note_button_spin (_insert_note_button_adjustment)
301 /* internationalize and prepare for use with combos */
304 for (int i = 0; modifiers[i].name; ++i) {
305 dumb.push_back (S_(modifiers[i].name));
308 set_popdown_strings (_edit_modifier_combo, dumb);
309 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
311 for (int x = 0; modifiers[x].name; ++x) {
312 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
313 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
318 Table* t = manage (new Table (4, 4));
321 Label* l = manage (left_aligned_label (_("Edit using:")));
322 l->set_name ("OptionsLabel");
324 t->attach (*l, 0, 1, 0, 1, FILL | EXPAND, FILL);
325 t->attach (_edit_modifier_combo, 1, 2, 0, 1, FILL | EXPAND, FILL);
327 l = manage (new Label (_("+ button")));
328 l->set_name ("OptionsLabel");
330 t->attach (*l, 3, 4, 0, 1, FILL | EXPAND, FILL);
331 t->attach (_edit_button_spin, 4, 5, 0, 1, FILL | EXPAND, FILL);
333 _edit_button_spin.set_name ("OptionsEntry");
334 _edit_button_adjustment.set_value (Keyboard::edit_button());
335 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
337 set_popdown_strings (_delete_modifier_combo, dumb);
338 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
340 for (int x = 0; modifiers[x].name; ++x) {
341 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
342 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
347 l = manage (left_aligned_label (_("Delete using:")));
348 l->set_name ("OptionsLabel");
350 t->attach (*l, 0, 1, 1, 2, FILL | EXPAND, FILL);
351 t->attach (_delete_modifier_combo, 1, 2, 1, 2, FILL | EXPAND, FILL);
353 l = manage (new Label (_("+ button")));
354 l->set_name ("OptionsLabel");
356 t->attach (*l, 3, 4, 1, 2, FILL | EXPAND, FILL);
357 t->attach (_delete_button_spin, 4, 5, 1, 2, FILL | EXPAND, FILL);
359 _delete_button_spin.set_name ("OptionsEntry");
360 _delete_button_adjustment.set_value (Keyboard::delete_button());
361 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
364 set_popdown_strings (_insert_note_modifier_combo, dumb);
365 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
367 for (int x = 0; modifiers[x].name; ++x) {
368 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
369 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
374 l = manage (left_aligned_label (_("Insert note using:")));
375 l->set_name ("OptionsLabel");
377 t->attach (*l, 0, 1, 2, 3, FILL | EXPAND, FILL);
378 t->attach (_insert_note_modifier_combo, 1, 2, 2, 3, FILL | EXPAND, FILL);
380 l = manage (new Label (_("+ button")));
381 l->set_name ("OptionsLabel");
383 t->attach (*l, 3, 4, 2, 3, FILL | EXPAND, FILL);
384 t->attach (_insert_note_button_spin, 4, 5, 2, 3, FILL | EXPAND, FILL);
386 _insert_note_button_spin.set_name ("OptionsEntry");
387 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
388 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
391 set_popdown_strings (_snap_modifier_combo, dumb);
392 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
394 for (int x = 0; modifiers[x].name; ++x) {
395 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
396 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
401 l = manage (left_aligned_label (_("Ignore snap using:")));
402 l->set_name ("OptionsLabel");
404 t->attach (*l, 0, 1, 3, 4, FILL | EXPAND, FILL);
405 t->attach (_snap_modifier_combo, 1, 2, 3, 4, FILL | EXPAND, FILL);
409 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
410 strs.push_back (bf->first);
413 set_popdown_strings (_keyboard_layout_selector, strs);
414 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
415 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
417 l = manage (left_aligned_label (_("Keyboard layout:")));
418 l->set_name ("OptionsLabel");
420 t->attach (*l, 0, 1, 4, 5, FILL | EXPAND, FILL);
421 t->attach (_keyboard_layout_selector, 1, 2, 4, 5, FILL | EXPAND, FILL);
423 _box->pack_start (*t, false, false);
426 void parameter_changed (string const &)
428 /* XXX: these aren't really config options... */
431 void set_state_from_config ()
433 /* XXX: these aren't really config options... */
438 void bindings_changed ()
440 string const txt = _keyboard_layout_selector.get_active_text();
442 /* XXX: config...? for all this keyboard stuff */
444 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
445 if (txt == i->first) {
446 if (Keyboard::load_keybindings (i->second)) {
447 Keyboard::save_keybindings ();
453 void edit_modifier_chosen ()
455 string const txt = _edit_modifier_combo.get_active_text();
457 for (int i = 0; modifiers[i].name; ++i) {
458 if (txt == _(modifiers[i].name)) {
459 Keyboard::set_edit_modifier (modifiers[i].modifier);
465 void delete_modifier_chosen ()
467 string const txt = _delete_modifier_combo.get_active_text();
469 for (int i = 0; modifiers[i].name; ++i) {
470 if (txt == _(modifiers[i].name)) {
471 Keyboard::set_delete_modifier (modifiers[i].modifier);
477 void insert_note_modifier_chosen ()
479 string const txt = _insert_note_modifier_combo.get_active_text();
481 for (int i = 0; modifiers[i].name; ++i) {
482 if (txt == _(modifiers[i].name)) {
483 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
489 void snap_modifier_chosen ()
491 string const txt = _snap_modifier_combo.get_active_text();
493 for (int i = 0; modifiers[i].name; ++i) {
494 if (txt == _(modifiers[i].name)) {
495 Keyboard::set_snap_modifier (modifiers[i].modifier);
501 void delete_button_changed ()
503 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
506 void edit_button_changed ()
508 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
511 void insert_note_button_changed ()
513 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
516 ComboBoxText _keyboard_layout_selector;
517 ComboBoxText _edit_modifier_combo;
518 ComboBoxText _delete_modifier_combo;
519 ComboBoxText _insert_note_modifier_combo;
520 ComboBoxText _snap_modifier_combo;
521 Adjustment _delete_button_adjustment;
522 SpinButton _delete_button_spin;
523 Adjustment _edit_button_adjustment;
524 SpinButton _edit_button_spin;
525 Adjustment _insert_note_button_adjustment;
526 SpinButton _insert_note_button_spin;
530 class FontScalingOptions : public OptionEditorBox
533 FontScalingOptions (RCConfiguration* c) :
535 _dpi_adjustment (50, 50, 250, 1, 10),
536 _dpi_slider (_dpi_adjustment)
538 _dpi_adjustment.set_value (floor ((double)(_rc_config->get_font_scale () / 1024)));
540 Label* l = manage (new Label (_("Font scaling:")));
541 l->set_name ("OptionsLabel");
543 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
544 HBox* h = manage (new HBox);
546 h->pack_start (*l, false, false);
547 h->pack_start (_dpi_slider, true, true);
549 _box->pack_start (*h, false, false);
551 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
554 void parameter_changed (string const & p)
556 if (p == "font-scale") {
557 _dpi_adjustment.set_value (floor ((double)(_rc_config->get_font_scale() / 1024)));
561 void set_state_from_config ()
563 parameter_changed ("font-scale");
570 _rc_config->set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024));
571 /* XXX: should be triggered from the parameter changed signal */
575 RCConfiguration* _rc_config;
576 Adjustment _dpi_adjustment;
580 class ClipLevelOptions : public OptionEditorBox
583 ClipLevelOptions (RCConfiguration* c)
585 , _clip_level_adjustment (0, -128.0, 2.0, 0.1, 1.0) /* units of dB */
586 , _clip_level_slider (_clip_level_adjustment)
588 _clip_level_adjustment.set_value (_rc_config->get_waveform_clip_level ());
590 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
591 l->set_name ("OptionsLabel");
593 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
594 HBox* h = manage (new HBox);
596 h->pack_start (*l, false, false);
597 h->pack_start (_clip_level_slider, true, true);
599 _box->pack_start (*h, false, false);
601 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
604 void parameter_changed (string const & p)
606 if (p == "waveform-clip-level") {
607 _clip_level_adjustment.set_value (_rc_config->get_waveform_clip_level());
611 void set_state_from_config ()
613 parameter_changed ("waveform-clip-level");
618 void clip_level_changed ()
620 _rc_config->set_waveform_clip_level (_clip_level_adjustment.get_value());
621 /* XXX: should be triggered from the parameter changed signal */
622 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
625 RCConfiguration* _rc_config;
626 Adjustment _clip_level_adjustment;
627 HScale _clip_level_slider;
630 class BufferingOptions : public OptionEditorBox
633 BufferingOptions (RCConfiguration* c)
635 , _playback_adjustment (5, 1, 60, 1, 4)
636 , _capture_adjustment (5, 1, 60, 1, 4)
637 , _playback_slider (_playback_adjustment)
638 , _capture_slider (_capture_adjustment)
640 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
642 Label* l = manage (new Label (_("Playback (seconds of buffering):")));
643 l->set_name ("OptionsLabel");
645 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
646 HBox* h = manage (new HBox);
648 h->pack_start (*l, false, false);
649 h->pack_start (_playback_slider, true, true);
651 _box->pack_start (*h, false, false);
653 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
655 l = manage (new Label (_("Recording (seconds of buffering):")));
656 l->set_name ("OptionsLabel");
658 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
659 h = manage (new HBox);
661 h->pack_start (*l, false, false);
662 h->pack_start (_capture_slider, true, true);
664 _box->pack_start (*h, false, false);
666 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
667 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
670 void parameter_changed (string const & p)
672 if (p == "playback-buffer-seconds") {
673 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
674 } else if (p == "capture-buffer-seconds") {
675 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
679 void set_state_from_config ()
681 parameter_changed ("playback-buffer-seconds");
682 parameter_changed ("capture-buffer-seconds");
687 void playback_changed ()
689 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
692 void capture_changed ()
694 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
697 RCConfiguration* _rc_config;
698 Adjustment _playback_adjustment;
699 Adjustment _capture_adjustment;
700 HScale _playback_slider;
701 HScale _capture_slider;
704 class ControlSurfacesOptions : public OptionEditorBox
707 ControlSurfacesOptions (Gtk::Window& parent)
709 , _ignore_view_change (0)
711 _store = ListStore::create (_model);
712 _view.set_model (_store);
713 _view.append_column (_("Control Surface Protocol"), _model.name);
714 _view.get_column(0)->set_resizable (true);
715 _view.get_column(0)->set_expand (true);
716 _view.append_column_editable (_("Enabled"), _model.enabled);
717 _view.append_column_editable (_("Feedback"), _model.feedback);
719 _box->pack_start (_view, false, false);
721 Label* label = manage (new Label);
722 label->set_markup (string_compose (X_("<i>%1</i>"), _("Double-click on a name to edit settings for an enabled protocol")));
724 _box->pack_start (*label, false, false);
727 ControlProtocolManager& m = ControlProtocolManager::instance ();
728 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
729 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
731 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
732 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
735 void parameter_changed (std::string const &)
740 void set_state_from_config ()
744 ControlProtocolManager& m = ControlProtocolManager::instance ();
745 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
747 if (!(*i)->mandatory) {
748 TreeModel::Row r = *_store->append ();
749 r[_model.name] = (*i)->name;
750 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
751 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
752 r[_model.protocol_info] = *i;
759 void protocol_status_changed (ControlProtocolInfo* cpi) {
761 TreeModel::Children rows = _store->children();
763 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
764 string n = ((*x)[_model.name]);
766 if ((*x)[_model.protocol_info] == cpi) {
767 _ignore_view_change++;
768 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
769 _ignore_view_change--;
775 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
777 TreeModel::Row r = *i;
779 if (_ignore_view_change) {
783 ControlProtocolInfo* cpi = r[_model.protocol_info];
788 bool const was_enabled = (cpi->protocol != 0);
789 bool const is_enabled = r[_model.enabled];
792 if (was_enabled != is_enabled) {
795 ControlProtocolManager::instance().activate (*cpi);
797 Gtk::Window* win = r[_model.editor];
802 ControlProtocolManager::instance().deactivate (*cpi);
806 r[_model.editor] = 0;
811 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
812 bool const is_feedback = r[_model.feedback];
814 if (was_feedback != is_feedback && cpi->protocol) {
815 cpi->protocol->set_feedback (is_feedback);
819 void edit_clicked (GdkEventButton* ev)
821 if (ev->type != GDK_2BUTTON_PRESS) {
826 ControlProtocolInfo* cpi;
829 row = *(_view.get_selection()->get_selected());
831 Window* win = row[_model.editor];
832 if (win && !win->is_visible()) {
835 cpi = row[_model.protocol_info];
837 if (cpi && cpi->protocol && cpi->protocol->has_editor ()) {
838 Box* box = (Box*) cpi->protocol->get_gui ();
840 string title = row[_model.name];
841 ArdourWindow* win = new ArdourWindow (_parent, title);
842 win->set_title ("Control Protocol Options");
846 row[_model.editor] = win;
852 class ControlSurfacesModelColumns : public TreeModelColumnRecord
856 ControlSurfacesModelColumns ()
865 TreeModelColumn<string> name;
866 TreeModelColumn<bool> enabled;
867 TreeModelColumn<bool> feedback;
868 TreeModelColumn<ControlProtocolInfo*> protocol_info;
869 TreeModelColumn<Gtk::Window*> editor;
872 Glib::RefPtr<ListStore> _store;
873 ControlSurfacesModelColumns _model;
875 Gtk::Window& _parent;
876 PBD::ScopedConnection protocol_status_connection;
877 uint32_t _ignore_view_change;
880 class VideoTimelineOptions : public OptionEditorBox
883 VideoTimelineOptions (RCConfiguration* c)
885 , _show_video_export_info_button (_("Show Video Export Info before export"))
886 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
887 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
889 Table* t = manage (new Table (2, 6));
892 t->attach (_video_advanced_setup_button, 0, 2, 0, 1);
893 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
894 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
895 _("<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."));
897 Label* l = manage (new Label (_("Video Server URL:")));
898 l->set_alignment (0, 0.5);
899 t->attach (*l, 0, 1, 1, 2, FILL);
900 t->attach (_video_server_url_entry, 1, 2, 1, 2, FILL);
901 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
902 _("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"));
904 l = manage (new Label (_("Video Folder:")));
905 l->set_alignment (0, 0.5);
906 t->attach (*l, 0, 1, 2, 3, FILL);
907 t->attach (_video_server_docroot_entry, 1, 2, 2, 3);
908 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
909 _("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."));
911 /* small vspace y=3..4 */
913 t->attach (_show_video_export_info_button, 0, 2, 4, 5);
914 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
915 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
916 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
918 t->attach (_show_video_server_dialog_button, 0, 2, 5, 6);
919 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
920 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
921 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
923 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
924 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
925 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
926 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
928 _box->pack_start (*t,true,true);
931 void server_url_changed ()
933 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
936 void server_docroot_changed ()
938 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
941 void show_video_export_info_toggled ()
943 bool const x = _show_video_export_info_button.get_active ();
944 _rc_config->set_show_video_export_info (x);
947 void show_video_server_dialog_toggled ()
949 bool const x = _show_video_server_dialog_button.get_active ();
950 _rc_config->set_show_video_server_dialog (x);
953 void video_advanced_setup_toggled ()
955 bool const x = _video_advanced_setup_button.get_active ();
956 _rc_config->set_video_advanced_setup(x);
959 void parameter_changed (string const & p)
961 if (p == "video-server-url") {
962 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
963 } else if (p == "video-server-docroot") {
964 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
965 } else if (p == "show-video-export-info") {
966 bool const x = _rc_config->get_show_video_export_info();
967 _show_video_export_info_button.set_active (x);
968 } else if (p == "show-video-server-dialog") {
969 bool const x = _rc_config->get_show_video_server_dialog();
970 _show_video_server_dialog_button.set_active (x);
971 } else if (p == "video-advanced-setup") {
972 bool const x = _rc_config->get_video_advanced_setup();
973 _video_advanced_setup_button.set_active(x);
974 _video_server_docroot_entry.set_sensitive(x);
975 _video_server_url_entry.set_sensitive(x);
979 void set_state_from_config ()
981 parameter_changed ("video-server-url");
982 parameter_changed ("video-server-docroot");
983 parameter_changed ("video-monitor-setup-dialog");
984 parameter_changed ("show-video-export-info");
985 parameter_changed ("show-video-server-dialog");
986 parameter_changed ("video-advanced-setup");
990 RCConfiguration* _rc_config;
991 Entry _video_server_url_entry;
992 Entry _video_server_docroot_entry;
993 CheckButton _show_video_export_info_button;
994 CheckButton _show_video_server_dialog_button;
995 CheckButton _video_advanced_setup_button;
998 class PluginOptions : public OptionEditorBox
1001 PluginOptions (RCConfiguration* c)
1003 , _display_plugin_scan_progress (_("Always Display Plugin Scan Progress"))
1004 , _discover_vst_on_start (_("Scan for new VST Plugins on Application Start"))
1005 , _timeout_adjustment (0, 0, 3000, 50, 50)
1006 , _timeout_slider (_timeout_adjustment)
1009 std::stringstream ss;
1010 Table* t = manage (new Table (2, 6));
1011 t->set_spacings (4);
1015 ss << "<b>" << _("General") << "</b>";
1016 l = manage (left_aligned_label (ss.str()));
1017 l->set_use_markup (true);
1018 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1019 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1021 b = manage (new Button (_("Scan for Plugins")));
1022 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::refresh_clicked));
1023 t->attach (*b, 0, 2, n, n+1, FILL); ++n;
1025 t->attach (_display_plugin_scan_progress, 0, 2, n, n+1); ++n;
1026 _display_plugin_scan_progress.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::display_plugin_scan_progress_toggled));
1027 Gtkmm2ext::UI::instance()->set_tip (_display_plugin_scan_progress,
1028 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
1030 _timeout_slider.set_digits (0);
1031 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &PluginOptions::timeout_changed));
1033 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1034 _("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."));
1036 l = manage (left_aligned_label (_("Scan Time Out [deciseconds]")));;
1037 HBox* h = manage (new HBox);
1039 h->pack_start (*l, false, false);
1040 h->pack_start (_timeout_slider, true, true);
1041 t->attach (*h, 0, 2, n, n+1); ++n;
1044 ss << "<b>" << _("VST") << "</b>";
1045 l = manage (left_aligned_label (ss.str()));
1046 l->set_use_markup (true);
1047 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1048 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1050 b = manage (new Button (_("Clear VST Cache")));
1051 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_cache_clicked));
1052 t->attach (*b, 0, 1, n, n+1, FILL);
1054 b = manage (new Button (_("Clear VST Blacklist")));
1055 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_blacklist_clicked));
1056 t->attach (*b, 1, 2, n, n+1, FILL);
1059 t->attach (_discover_vst_on_start, 0, 2, n, n+1); ++n;
1060 _discover_vst_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_vst_on_start_toggled));
1061 Gtkmm2ext::UI::instance()->set_tip (_discover_vst_on_start,
1062 _("<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"));
1064 #ifdef LXVST_SUPPORT
1065 t->attach (*manage (left_aligned_label (_("Linux VST Path:"))), 0, 1, n, n+1);
1066 b = manage (new Button (_("Edit")));
1067 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_lxvst_path_clicked));
1068 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1071 #ifdef WINDOWS_VST_SUPPORT
1072 t->attach (*manage (left_aligned_label (_("Windows VST Path:"))), 0, 1, n, n+1);
1073 b = manage (new Button (_("Edit")));
1074 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_vst_path_clicked));
1075 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1078 _box->pack_start (*t,true,true);
1081 void parameter_changed (string const & p) {
1082 if (p == "show-plugin-scan-window") {
1083 bool const x = _rc_config->get_show_plugin_scan_window();
1084 _display_plugin_scan_progress.set_active (x);
1086 else if (p == "discover-vst-on-start") {
1087 bool const x = _rc_config->get_discover_vst_on_start();
1088 _discover_vst_on_start.set_active (x);
1090 else if (p == "vst-scan-timeout") {
1091 int const x = _rc_config->get_vst_scan_timeout();
1092 _timeout_adjustment.set_value (x);
1096 void set_state_from_config () {
1097 parameter_changed ("show-plugin-scan-window");
1098 parameter_changed ("discover-vst-on-start");
1099 parameter_changed ("vst-scan-timeout");
1103 RCConfiguration* _rc_config;
1104 CheckButton _display_plugin_scan_progress;
1105 CheckButton _discover_vst_on_start;
1106 Adjustment _timeout_adjustment;
1107 HScale _timeout_slider;
1109 void display_plugin_scan_progress_toggled () {
1110 bool const x = _display_plugin_scan_progress.get_active();
1111 _rc_config->set_show_plugin_scan_window(x);
1114 void discover_vst_on_start_toggled () {
1115 bool const x = _discover_vst_on_start.get_active();
1116 _rc_config->set_discover_vst_on_start(x);
1119 void timeout_changed () {
1120 int x = floor(_timeout_adjustment.get_value());
1121 _rc_config->set_vst_scan_timeout(x);
1124 void clear_vst_cache_clicked () {
1125 PluginManager::instance().clear_vst_cache();
1128 void clear_vst_blacklist_clicked () {
1129 PluginManager::instance().clear_vst_blacklist();
1132 void edit_vst_path_clicked () {
1133 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1134 _("Set Windows VST Search Path"),
1135 _rc_config->get_plugin_path_vst(),
1136 PluginManager::instance().get_default_windows_vst_path()
1138 ResponseType r = (ResponseType) pd->run ();
1140 if (r == RESPONSE_ACCEPT) {
1141 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
1146 // todo consolidate with edit_vst_path_clicked..
1147 void edit_lxvst_path_clicked () {
1148 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1149 _("Set Linux VST Search Path"),
1150 _rc_config->get_plugin_path_lxvst(),
1151 PluginManager::instance().get_default_lxvst_path()
1153 ResponseType r = (ResponseType) pd->run ();
1155 if (r == RESPONSE_ACCEPT) {
1156 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
1161 void refresh_clicked () {
1162 PluginManager::instance().refresh();
1167 /** A class which allows control of visibility of some editor components usign
1168 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1169 * which has the correct members, but with null widget pointers. This
1170 * class allows the user to set visibility of the members, the details
1171 * of which are stored in a configuration variable which can be watched
1172 * by parts of the editor that actually contain the widgets whose visibility
1173 * is being controlled.
1176 class VisibilityOption : public Option
1179 /** @param name User-visible name for this group.
1180 * @param g `Dummy' VisibilityGroup (as described above).
1181 * @param get Method to get the value of the appropriate configuration variable.
1182 * @param set Method to set the value of the appropriate configuration variable.
1184 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1185 : Option (g->get_state_name(), name)
1187 , _visibility_group (g)
1191 /* Watch for changes made by the user to our members */
1192 _visibility_group->VisibilityChanged.connect_same_thread (
1193 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1197 void set_state_from_config ()
1199 /* Set our state from the current configuration */
1200 _visibility_group->set_state (_get ());
1203 void add_to_page (OptionEditorPage* p)
1205 _heading.add_to_page (p);
1206 add_widget_to_page (p, _visibility_group->list_view ());
1209 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1214 /* The user has changed something, so reflect this change
1215 in the RCConfiguration.
1217 _set (_visibility_group->get_state_value ());
1220 OptionEditorHeading _heading;
1221 VisibilityGroup* _visibility_group;
1222 sigc::slot<std::string> _get;
1223 sigc::slot<bool, std::string> _set;
1224 PBD::ScopedConnection _visibility_group_connection;
1229 RCOptionEditor::RCOptionEditor ()
1230 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1231 , _rc_config (Config)
1232 , _mixer_strip_visibility ("mixer-strip-visibility")
1236 uint32_t hwcpus = hardware_concurrency ();
1238 BoolComboOption* bco;
1241 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1243 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1245 _("Signal processing uses"),
1246 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1247 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1250 procs->add (-1, _("all but one processor"));
1251 procs->add (0, _("all available processors"));
1253 for (uint32_t i = 1; i <= hwcpus; ++i) {
1254 procs->add (i, string_compose (_("%1 processors"), i));
1257 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1259 add_option (_("Misc"), procs);
1262 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1264 add_option (_("Misc"), new UndoOptions (_rc_config));
1266 add_option (_("Misc"),
1268 "verify-remove-last-capture",
1269 _("Verify removal of last capture"),
1270 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1271 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1274 add_option (_("Misc"),
1276 "periodic-safety-backups",
1277 _("Make periodic backups of the session file"),
1278 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1279 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1282 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1284 add_option (_("Misc"),
1286 "only-copy-imported-files",
1287 _("Always copy imported files"),
1288 sigc::mem_fun (*_rc_config, &RCConfiguration::get_only_copy_imported_files),
1289 sigc::mem_fun (*_rc_config, &RCConfiguration::set_only_copy_imported_files)
1292 add_option (_("Misc"), new DirectoryOption (
1293 X_("default-session-parent-dir"),
1294 _("Default folder for new sessions:"),
1295 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1296 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1299 add_option (_("Misc"),
1300 new SpinOption<uint32_t> (
1301 "max-recent-sessions",
1302 _("Maximum number of recent sessions"),
1303 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1304 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1308 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1310 add_option (_("Misc"), new ClickOptions (_rc_config, this));
1312 add_option (_("Misc"),
1315 _("Click gain level"),
1316 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1317 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1320 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1322 add_option (_("Misc"),
1323 new SpinOption<double> (
1324 "automation-thinning-factor",
1325 _("Thinning factor (larger value => less data)"),
1326 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1327 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1331 add_option (_("Misc"),
1332 new SpinOption<double> (
1333 "automation-interval-msecs",
1334 _("Automation sampling interval (milliseconds)"),
1335 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1336 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1344 tsf = new BoolOption (
1345 "latched-record-enable",
1346 _("Keep record-enable engaged on stop"),
1347 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1348 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1350 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1351 add_option (_("Transport"), tsf);
1353 tsf = new BoolOption (
1354 "stop-recording-on-xrun",
1355 _("Stop recording when an xrun occurs"),
1356 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
1357 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
1359 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1360 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
1363 tsf = new BoolOption (
1365 _("Play loop is a transport mode"),
1366 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1367 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1369 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1370 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1371 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1372 add_option (_("Transport"), tsf);
1374 tsf = new BoolOption (
1375 "create-xrun-marker",
1376 _("Create markers where xruns occur"),
1377 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
1378 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
1380 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1381 add_option (_("Transport"), tsf);
1383 tsf = new BoolOption (
1384 "stop-at-session-end",
1385 _("Stop at the end of the session"),
1386 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
1387 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
1389 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1390 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
1391 "when it reaches the current session end marker\n\n"
1392 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
1394 add_option (_("Transport"), tsf);
1396 tsf = new BoolOption (
1398 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
1399 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
1400 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
1402 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1403 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
1404 "preventing any need to do a transport locate at the end of the loop\n\n"
1405 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
1406 "which will often cause a small click or delay"), PROGRAM_NAME));
1407 add_option (_("Transport"), tsf);
1409 tsf = new BoolOption (
1410 "disable-disarm-during-roll",
1411 _("Disable per-track record disarm while rolling"),
1412 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
1413 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
1415 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"));
1416 add_option (_("Transport"), tsf);
1418 tsf = new BoolOption (
1420 _("12dB gain reduction during fast-forward and fast-rewind"),
1421 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
1422 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
1424 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
1425 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
1426 add_option (_("Transport"), tsf);
1428 add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
1430 _sync_source = new ComboOption<SyncSource> (
1432 _("External timecode source"),
1433 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
1434 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
1437 populate_sync_options ();
1438 add_option (_("Transport"), _sync_source);
1440 _sync_framerate = new BoolOption (
1441 "timecode-sync-frame-rate",
1442 _("Match session video frame rate to external timecode"),
1443 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
1444 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
1446 Gtkmm2ext::UI::instance()->set_tip
1447 (_sync_framerate->tip_widget(),
1448 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
1449 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
1450 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
1451 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
1452 "timecode standard and the session standard."), PROGRAM_NAME));
1454 add_option (_("Transport"), _sync_framerate);
1456 _sync_genlock = new BoolOption (
1457 "timecode-source-is-synced",
1458 _("External timecode is sync locked"),
1459 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
1460 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
1462 Gtkmm2ext::UI::instance()->set_tip
1463 (_sync_genlock->tip_widget(),
1464 _("<b>When enabled</b> indicates that the selected external timecode source shares sync (Black & Burst, Wordclock, etc) with the audio interface."));
1467 add_option (_("Transport"), _sync_genlock);
1469 _sync_source_2997 = new BoolOption (
1470 "timecode-source-2997",
1471 _("Lock to 29.9700 fps instead of 30000/1001"),
1472 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
1473 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
1475 Gtkmm2ext::UI::instance()->set_tip
1476 (_sync_source_2997->tip_widget(),
1477 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
1478 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
1479 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
1480 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
1481 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
1482 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
1485 add_option (_("Transport"), _sync_source_2997);
1487 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
1489 _ltc_port = new ComboStringOption (
1491 _("LTC incoming port"),
1492 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
1493 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
1496 vector<string> physical_inputs;
1497 physical_inputs.push_back (_("None"));
1498 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
1499 _ltc_port->set_popdown_strings (physical_inputs);
1501 add_option (_("Transport"), _ltc_port);
1503 // TODO; rather disable this button than not compile it..
1504 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
1506 add_option (_("Transport"),
1509 _("Enable LTC generator"),
1510 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
1511 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
1514 _ltc_send_continuously = new BoolOption (
1515 "ltc-send-continuously",
1516 _("Send LTC while stopped"),
1517 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
1518 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
1520 Gtkmm2ext::UI::instance()->set_tip
1521 (_ltc_send_continuously->tip_widget(),
1522 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
1523 add_option (_("Transport"), _ltc_send_continuously);
1525 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
1526 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
1527 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
1528 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
1530 Gtkmm2ext::UI::instance()->set_tip
1531 (_ltc_volume_slider->tip_widget(),
1532 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
1534 add_option (_("Transport"), _ltc_volume_slider);
1535 parameter_changed ("send-ltc");
1537 parameter_changed ("sync-source");
1541 add_option (_("Editor"),
1543 "link-region-and-track-selection",
1544 _("Link selection of regions and tracks"),
1545 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_region_and_track_selection),
1546 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_region_and_track_selection)
1549 add_option (_("Editor"),
1551 "automation-follows-regions",
1552 _("Move relevant automation when audio regions are moved"),
1553 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
1554 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
1557 add_option (_("Editor"),
1559 "show-track-meters",
1560 _("Show meters on tracks in the editor"),
1561 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_track_meters),
1562 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_track_meters)
1565 add_option (_("Editor"),
1567 "show-editor-meter",
1568 _("Display master-meter in the toolbar"),
1569 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_editor_meter),
1570 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_editor_meter)
1573 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
1574 "default-fade-shape",
1575 _("Default fade shape"),
1576 sigc::mem_fun (*_rc_config,
1577 &RCConfiguration::get_default_fade_shape),
1578 sigc::mem_fun (*_rc_config,
1579 &RCConfiguration::set_default_fade_shape)
1582 fadeshape->add (FadeLinear,
1583 _("Linear (for highly correlated material)"));
1584 fadeshape->add (FadeConstantPower, _("Constant power"));
1585 fadeshape->add (FadeSymmetric, _("Symmetric"));
1586 fadeshape->add (FadeSlow, _("Slow"));
1587 fadeshape->add (FadeFast, _("Fast"));
1589 add_option (_("Editor"), fadeshape);
1592 bco = new BoolComboOption (
1593 "use-overlap-equivalency",
1594 _("Regions in active edit groups are edited together"),
1595 _("whenever they overlap in time"),
1596 _("only if they have identical length, position and origin"),
1597 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
1598 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
1601 add_option (_("Editor"), bco);
1603 add_option (_("Editor"),
1605 "rubberbanding-snaps-to-grid",
1606 _("Make rubberband selection rectangle snap to the grid"),
1607 sigc::mem_fun (*_rc_config, &RCConfiguration::get_rubberbanding_snaps_to_grid),
1608 sigc::mem_fun (*_rc_config, &RCConfiguration::set_rubberbanding_snaps_to_grid)
1611 add_option (_("Editor"),
1614 _("Show waveforms in regions"),
1615 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms),
1616 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms)
1619 add_option (_("Editor"),
1620 new BoolComboOption (
1621 "show-region-gain-envelopes",
1622 _("Show gain envelopes in audio regions"),
1624 _("only in region gain mode"),
1625 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_region_gain),
1626 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_region_gain)
1629 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
1631 _("Waveform scale"),
1632 sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_scale),
1633 sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_scale)
1636 wfs->add (Linear, _("linear"));
1637 wfs->add (Logarithmic, _("logarithmic"));
1639 add_option (_("Editor"), wfs);
1641 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
1643 _("Waveform shape"),
1644 sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_shape),
1645 sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_shape)
1648 wfsh->add (Traditional, _("traditional"));
1649 wfsh->add (Rectified, _("rectified"));
1651 add_option (_("Editor"), wfsh);
1653 add_option (_("Editor"), new ClipLevelOptions (_rc_config));
1655 add_option (_("Editor"),
1657 "show-waveforms-while-recording",
1658 _("Show waveforms for audio while it is being recorded"),
1659 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms_while_recording),
1660 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms_while_recording)
1663 add_option (_("Editor"),
1666 _("Show zoom toolbar"),
1667 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_zoom_tools),
1668 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_zoom_tools)
1671 add_option (_("Editor"),
1673 "update-editor-during-summary-drag",
1674 _("Update editor window during drags of the summary"),
1675 sigc::mem_fun (*_rc_config, &RCConfiguration::get_update_editor_during_summary_drag),
1676 sigc::mem_fun (*_rc_config, &RCConfiguration::set_update_editor_during_summary_drag)
1679 add_option (_("Editor"),
1681 "link-editor-and-mixer-selection",
1682 _("Synchronise editor and mixer selection"),
1683 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_editor_and_mixer_selection),
1684 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_editor_and_mixer_selection)
1687 bo = new BoolOption (
1689 _("Name new markers"),
1690 sigc::mem_fun (*_rc_config, &RCConfiguration::get_name_new_markers),
1691 sigc::mem_fun (*_rc_config, &RCConfiguration::set_name_new_markers)
1694 add_option (_("Editor"), bo);
1695 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."
1696 "\n\nYou can always rename markers by right-clicking on them"));
1698 add_option (_("Editor"),
1700 "autoscroll-editor",
1701 _("Auto-scroll editor window when dragging near its edges"),
1702 sigc::mem_fun (*_rc_config, &RCConfiguration::get_autoscroll_editor),
1703 sigc::mem_fun (*_rc_config, &RCConfiguration::set_autoscroll_editor)
1708 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
1710 add_option (_("Audio"), new BufferingOptions (_rc_config));
1712 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
1714 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
1716 _("Record monitoring handled by"),
1717 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
1718 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
1721 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
1722 mm->add (HardwareMonitoring, _("via Audio Driver"));
1725 string prog (PROGRAM_NAME);
1726 boost::algorithm::to_lower (prog);
1727 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
1728 mm->add (ExternalMonitoring, _("audio hardware"));
1730 add_option (_("Audio"), mm);
1732 add_option (_("Audio"),
1734 "tape-machine-mode",
1735 _("Tape machine mode"),
1736 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
1737 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
1740 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
1742 add_option (_("Audio"),
1744 "auto-connect-standard-busses",
1745 _("Auto-connect master/monitor busses"),
1746 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
1747 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
1750 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
1751 "input-auto-connect",
1752 _("Connect track inputs"),
1753 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
1754 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
1757 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
1758 iac->add (ManualConnect, _("manually"));
1760 add_option (_("Audio"), iac);
1762 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
1763 "output-auto-connect",
1764 _("Connect track and bus outputs"),
1765 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
1766 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
1769 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
1770 oac->add (AutoConnectMaster, _("automatically to master bus"));
1771 oac->add (ManualConnect, _("manually"));
1773 add_option (_("Audio"), oac);
1775 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
1777 add_option (_("Audio"),
1779 "denormal-protection",
1780 _("Use DC bias to protect against denormals"),
1781 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
1782 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
1785 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
1787 _("Processor handling"),
1788 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
1789 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
1792 dm->add (DenormalNone, _("no processor handling"));
1796 if (fpu.has_flush_to_zero()) {
1797 dm->add (DenormalFTZ, _("use FlushToZero"));
1800 if (fpu.has_denormals_are_zero()) {
1801 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
1804 if (fpu.has_flush_to_zero() && fpu.has_denormals_are_zero()) {
1805 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
1808 add_option (_("Audio"), dm);
1810 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
1812 add_option (_("Audio"),
1814 "plugins-stop-with-transport",
1815 _("Silence plugins when the transport is stopped"),
1816 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
1817 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
1820 add_option (_("Audio"),
1822 "new-plugins-active",
1823 _("Make new plugins active"),
1824 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
1825 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
1828 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
1830 add_option (_("Audio"),
1832 "auto-analyse-audio",
1833 _("Enable automatic analysis of audio"),
1834 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
1835 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
1838 add_option (_("Audio"),
1840 "replicate-missing-region-channels",
1841 _("Replicate missing region channels"),
1842 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
1843 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
1848 add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
1850 add_option (_("Solo / mute"),
1853 _("Solo-in-place mute cut (dB)"),
1854 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
1855 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
1858 _solo_control_is_listen_control = new BoolOption (
1859 "solo-control-is-listen-control",
1860 _("Solo controls are Listen controls"),
1861 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
1862 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
1865 add_option (_("Solo / mute"), _solo_control_is_listen_control);
1867 _listen_position = new ComboOption<ListenPosition> (
1869 _("Listen Position"),
1870 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
1871 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
1874 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
1875 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
1877 add_option (_("Solo / mute"), _listen_position);
1879 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
1881 _("PFL signals come from"),
1882 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
1883 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
1886 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
1887 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
1889 add_option (_("Solo / mute"), pp);
1891 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
1893 _("AFL signals come from"),
1894 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
1895 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
1898 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
1899 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
1901 add_option (_("Solo / mute"), pa);
1903 parameter_changed ("use-monitor-bus");
1905 add_option (_("Solo / mute"),
1908 _("Exclusive solo"),
1909 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
1910 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
1913 add_option (_("Solo / mute"),
1916 _("Show solo muting"),
1917 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
1918 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
1921 add_option (_("Solo / mute"),
1923 "solo-mute-override",
1924 _("Soloing overrides muting"),
1925 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
1926 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
1929 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
1931 add_option (_("Solo / mute"),
1933 "mute-affects-pre-fader",
1934 _("Mute affects pre-fader sends"),
1935 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
1936 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
1939 add_option (_("Solo / mute"),
1941 "mute-affects-post-fader",
1942 _("Mute affects post-fader sends"),
1943 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
1944 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
1947 add_option (_("Solo / mute"),
1949 "mute-affects-control-outs",
1950 _("Mute affects control outputs"),
1951 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
1952 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
1955 add_option (_("Solo / mute"),
1957 "mute-affects-main-outs",
1958 _("Mute affects main outputs"),
1959 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
1960 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
1963 add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
1965 add_option (_("Solo / mute"),
1967 "link-send-and-route-panner",
1968 _("Link panners of Aux and External Sends with main panner by default"),
1969 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
1970 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
1973 add_option (_("MIDI"),
1976 _("Send MIDI Clock"),
1977 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
1978 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
1981 add_option (_("MIDI"),
1984 _("Send MIDI Time Code"),
1985 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
1986 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
1989 add_option (_("MIDI"),
1990 new SpinOption<int> (
1991 "mtc-qf-speed-tolerance",
1992 _("Percentage either side of normal transport speed to transmit MTC"),
1993 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
1994 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
1998 add_option (_("MIDI"),
2001 _("Obey MIDI Machine Control commands"),
2002 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2003 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2006 add_option (_("MIDI"),
2009 _("Send MIDI Machine Control commands"),
2010 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2011 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2014 add_option (_("MIDI"),
2017 _("Send MIDI control feedback"),
2018 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2019 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2022 add_option (_("MIDI"),
2023 new SpinOption<uint8_t> (
2024 "mmc-receive-device-id",
2025 _("Inbound MMC device ID"),
2026 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2027 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2031 add_option (_("MIDI"),
2032 new SpinOption<uint8_t> (
2033 "mmc-send-device-id",
2034 _("Outbound MMC device ID"),
2035 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2036 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2040 add_option (_("MIDI"),
2041 new SpinOption<int32_t> (
2042 "initial-program-change",
2043 _("Initial program change"),
2044 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2045 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2049 add_option (_("MIDI"),
2051 "display-first-midi-bank-as-zero",
2052 _("Display first MIDI bank/program as 0"),
2053 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2054 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2057 add_option (_("MIDI"),
2059 "never-display-periodic-midi",
2060 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2061 sigc::mem_fun (*_rc_config, &RCConfiguration::get_never_display_periodic_midi),
2062 sigc::mem_fun (*_rc_config, &RCConfiguration::set_never_display_periodic_midi)
2065 add_option (_("MIDI"),
2068 _("Sound MIDI notes as they are selected"),
2069 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sound_midi_notes),
2070 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sound_midi_notes)
2073 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2075 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2076 "midi-audition-synth-uri",
2077 _("Midi Audition Synth (LV2)"),
2078 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2079 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2082 audition_synth->add(X_(""), _("None"));
2083 PluginInfoList all_plugs;
2084 PluginManager& manager (PluginManager::instance());
2086 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2088 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2089 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2090 if (!(*i)->is_instrument()) continue;
2091 if ((*i)->type != ARDOUR::LV2) continue;
2092 audition_synth->add((*i)->unique_id, (*i)->name);
2096 add_option (_("MIDI"), audition_synth);
2098 /* USER INTERACTION */
2100 if (getenv ("ARDOUR_BUNDLED")) {
2101 add_option (_("User interaction"),
2103 "enable-translation",
2104 string_compose (_("Use translations of %1 messages\n"
2105 " <i>(requires a restart of %1 to take effect)</i>\n"
2106 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2107 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2108 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2111 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2113 add_option (_("User interaction"), new KeyboardOptions);
2115 /* Control Surfaces */
2117 add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this));
2119 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2121 _("Control surface remote ID"),
2122 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2123 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2126 rm->add (UserOrdered, _("assigned by user"));
2127 rm->add (MixerOrdered, _("follows order of mixer"));
2129 add_option (_("Control Surfaces"), rm);
2131 /* VIDEO Timeline */
2132 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2134 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
2135 /* Plugin options (currrently VST only) */
2136 add_option (_("Plugins"), new PluginOptions (_rc_config));
2141 add_option (S_("Preferences|GUI"),
2144 _("Graphically indicate mouse pointer hovering over various widgets"),
2145 sigc::mem_fun (*_rc_config, &RCConfiguration::get_widget_prelight),
2146 sigc::mem_fun (*_rc_config, &RCConfiguration::set_widget_prelight)
2149 add_option (S_("Preferences|GUI"),
2152 _("Show tooltips if mouse hovers over a control"),
2153 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_tooltips),
2154 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_tooltips)
2157 add_option (S_("Preferences|GUI"),
2159 "show-name-highlight",
2160 _("Use name highlight bars in region displays"),
2161 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_name_highlight),
2162 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_name_highlight)
2166 /* font scaling does nothing with GDK/Quartz */
2167 add_option (S_("Preferences|GUI"), new FontScalingOptions (_rc_config));
2170 add_option (S_("GUI"),
2172 "super-rapid-clock-update",
2173 _("update transport clock display every 40ms instead of every 100ms"),
2174 sigc::mem_fun (*_rc_config, &RCConfiguration::get_super_rapid_clock_update),
2175 sigc::mem_fun (*_rc_config, &RCConfiguration::set_super_rapid_clock_update)
2178 /* Lock GUI timeout */
2180 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
2181 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2182 _("Lock timeout (seconds)"),
2184 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_lock_gui_after_seconds),
2185 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_lock_gui_after_seconds)
2187 slts->scale().set_digits (0);
2188 Gtkmm2ext::UI::instance()->set_tip
2189 (slts->tip_widget(),
2190 _("Lock GUI after this many idle seconds (zero to never lock)"));
2191 add_option (S_("Preferences|GUI"), slts);
2193 /* The names of these controls must be the same as those given in MixerStrip
2194 for the actual widgets being controlled.
2196 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
2197 _mixer_strip_visibility.add (0, X_("SoloSafe"), _("Solo Safe"));
2198 _mixer_strip_visibility.add (0, X_("SoloIsolated"), _("Solo Isolated"));
2199 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
2200 _mixer_strip_visibility.add (0, X_("Group"), _("Group"));
2201 _mixer_strip_visibility.add (0, X_("MeterPoint"), _("Meter Point"));
2204 S_("Preferences|GUI"),
2205 new VisibilityOption (
2207 &_mixer_strip_visibility,
2208 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mixer_strip_visibility),
2209 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mixer_strip_visibility)
2213 add_option (S_("Preferences|GUI"),
2215 "default-narrow_ms",
2216 _("Use narrow strips in the mixer by default"),
2217 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_narrow_ms),
2218 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_narrow_ms)
2221 add_option (S_("Preferences|GUI"), new OptionEditorHeading (_("Metering")));
2223 ComboOption<float>* mht = new ComboOption<float> (
2225 _("Peak hold time"),
2226 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_hold),
2227 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_hold)
2230 mht->add (MeterHoldOff, _("off"));
2231 mht->add (MeterHoldShort, _("short"));
2232 mht->add (MeterHoldMedium, _("medium"));
2233 mht->add (MeterHoldLong, _("long"));
2235 add_option (S_("Preferences|GUI"), mht);
2237 ComboOption<float>* mfo = new ComboOption<float> (
2240 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2241 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2244 mfo->add (METER_FALLOFF_OFF, _("off"));
2245 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2246 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2247 mfo->add (METER_FALLOFF_SLOWISH, _("slowish [12.0dB/sec] (DIN)"));
2248 mfo->add (METER_FALLOFF_MODERATE, _("moderate [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2249 mfo->add (METER_FALLOFF_MEDIUM, _("medium [20dB/sec]"));
2250 mfo->add (METER_FALLOFF_FAST, _("fast [32dB/sec]"));
2251 mfo->add (METER_FALLOFF_FASTER, _("faster [46dB/sec]"));
2252 mfo->add (METER_FALLOFF_FASTEST, _("fastest [70dB/sec]"));
2254 add_option (S_("Preferences|GUI"), mfo);
2256 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2257 "meter-line-up-level",
2258 _("Meter line-up level; 0dBu"),
2259 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_line_up_level),
2260 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_line_up_level)
2263 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2264 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2265 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2266 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2268 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."));
2270 add_option (S_("Preferences|GUI"), mlu);
2272 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2273 "meter-line-up-din",
2274 _("IEC1/DIN Meter line-up level; 0dBu"),
2275 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_line_up_din),
2276 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_line_up_din)
2279 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2280 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2281 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2282 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2284 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2286 add_option (S_("Preferences|GUI"), mld);
2288 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2289 "meter-vu-standard",
2290 _("VU Meter standard"),
2291 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_vu_standard),
2292 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_vu_standard)
2295 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2296 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2297 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2298 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2300 add_option (S_("Preferences|GUI"), mvu);
2302 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
2303 HSliderOption *mpks = new HSliderOption("meter-peak",
2304 _("Peak threshold [dBFS]"),
2306 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_peak),
2307 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_peak)
2310 Gtkmm2ext::UI::instance()->set_tip
2311 (mpks->tip_widget(),
2312 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
2314 add_option (S_("Preferences|GUI"), mpks);
2316 add_option (S_("Preferences|GUI"),
2319 _("LED meter style"),
2320 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_style_led),
2321 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_style_led)
2327 RCOptionEditor::parameter_changed (string const & p)
2329 OptionEditor::parameter_changed (p);
2331 if (p == "use-monitor-bus") {
2332 bool const s = Config->get_use_monitor_bus ();
2334 /* we can't use this if we don't have a monitor bus */
2335 Config->set_solo_control_is_listen_control (false);
2337 _solo_control_is_listen_control->set_sensitive (s);
2338 _listen_position->set_sensitive (s);
2339 } else if (p == "sync-source") {
2340 _sync_source->set_sensitive (true);
2342 _sync_source->set_sensitive (!_session->config.get_external_sync());
2344 switch(Config->get_sync_source()) {
2347 _sync_genlock->set_sensitive (true);
2348 _sync_framerate->set_sensitive (true);
2349 _sync_source_2997->set_sensitive (true);
2352 _sync_genlock->set_sensitive (false);
2353 _sync_framerate->set_sensitive (false);
2354 _sync_source_2997->set_sensitive (false);
2357 } else if (p == "send-ltc") {
2358 bool const s = Config->get_send_ltc ();
2359 _ltc_send_continuously->set_sensitive (s);
2360 _ltc_volume_slider->set_sensitive (s);
2364 void RCOptionEditor::ltc_generator_volume_changed () {
2365 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
2369 RCOptionEditor::populate_sync_options ()
2371 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
2373 _sync_source->clear ();
2375 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
2376 _sync_source->add (*i, sync_source_to_string (*i));