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_window.h"
48 #include "ardour_dialog.h"
49 #include "gui_thread.h"
50 #include "midi_tracer.h"
51 #include "rc_option_editor.h"
53 #include "midi_port_dialog.h"
60 using namespace Gtkmm2ext;
62 using namespace ARDOUR;
64 class ClickOptions : public OptionEditorBox
67 ClickOptions (RCConfiguration* c, Gtk::Window* p)
71 Table* t = manage (new Table (2, 3));
74 Label* l = manage (left_aligned_label (_("Click audio file:")));
75 t->attach (*l, 0, 1, 0, 1, FILL);
76 t->attach (_click_path_entry, 1, 2, 0, 1, FILL);
77 Button* b = manage (new Button (_("Browse...")));
78 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
79 t->attach (*b, 2, 3, 0, 1, FILL);
81 l = manage (left_aligned_label (_("Click emphasis audio file:")));
82 t->attach (*l, 0, 1, 1, 2, FILL);
83 t->attach (_click_emphasis_path_entry, 1, 2, 1, 2, FILL);
84 b = manage (new Button (_("Browse...")));
85 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
86 t->attach (*b, 2, 3, 1, 2, FILL);
88 _box->pack_start (*t, false, false);
90 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
91 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
94 void parameter_changed (string const & p)
96 if (p == "click-sound") {
97 _click_path_entry.set_text (_rc_config->get_click_sound());
98 } else if (p == "click-emphasis-sound") {
99 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
103 void set_state_from_config ()
105 parameter_changed ("click-sound");
106 parameter_changed ("click-emphasis-sound");
111 void click_browse_clicked ()
113 SoundFileChooser sfdb (_("Choose Click"));
115 if (sfdb.run () == RESPONSE_OK) {
116 click_chosen (sfdb.get_filename());
120 void click_chosen (string const & path)
122 _click_path_entry.set_text (path);
123 _rc_config->set_click_sound (path);
126 void click_changed ()
128 click_chosen (_click_path_entry.get_text ());
131 void click_emphasis_browse_clicked ()
133 SoundFileChooser sfdb (_("Choose Click Emphasis"));
138 if (sfdb.run () == RESPONSE_OK) {
139 click_emphasis_chosen (sfdb.get_filename());
143 void click_emphasis_chosen (string const & path)
145 _click_emphasis_path_entry.set_text (path);
146 _rc_config->set_click_emphasis_sound (path);
149 void click_emphasis_changed ()
151 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
154 RCConfiguration* _rc_config;
155 Gtk::Window* _parent;
156 Entry _click_path_entry;
157 Entry _click_emphasis_path_entry;
160 class UndoOptions : public OptionEditorBox
163 UndoOptions (RCConfiguration* c) :
165 _limit_undo_button (_("Limit undo history to")),
166 _save_undo_button (_("Save undo history of"))
168 Table* t = new Table (2, 3);
171 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
172 _limit_undo_spin.set_range (0, 512);
173 _limit_undo_spin.set_increments (1, 10);
174 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
175 Label* l = manage (left_aligned_label (_("commands")));
176 t->attach (*l, 2, 3, 0, 1);
178 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
179 _save_undo_spin.set_range (0, 512);
180 _save_undo_spin.set_increments (1, 10);
181 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
182 l = manage (left_aligned_label (_("commands")));
183 t->attach (*l, 2, 3, 1, 2);
185 _box->pack_start (*t);
187 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
188 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
189 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
190 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
193 void parameter_changed (string const & p)
195 if (p == "history-depth") {
196 int32_t const d = _rc_config->get_history_depth();
197 _limit_undo_button.set_active (d != 0);
198 _limit_undo_spin.set_sensitive (d != 0);
199 _limit_undo_spin.set_value (d);
200 } else if (p == "save-history") {
201 bool const x = _rc_config->get_save_history ();
202 _save_undo_button.set_active (x);
203 _save_undo_spin.set_sensitive (x);
204 } else if (p == "save-history-depth") {
205 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
209 void set_state_from_config ()
211 parameter_changed ("save-history");
212 parameter_changed ("history-depth");
213 parameter_changed ("save-history-depth");
216 void limit_undo_toggled ()
218 bool const x = _limit_undo_button.get_active ();
219 _limit_undo_spin.set_sensitive (x);
220 int32_t const n = x ? 16 : 0;
221 _limit_undo_spin.set_value (n);
222 _rc_config->set_history_depth (n);
225 void limit_undo_changed ()
227 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
230 void save_undo_toggled ()
232 bool const x = _save_undo_button.get_active ();
233 _rc_config->set_save_history (x);
236 void save_undo_changed ()
238 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
242 RCConfiguration* _rc_config;
243 CheckButton _limit_undo_button;
244 SpinButton _limit_undo_spin;
245 CheckButton _save_undo_button;
246 SpinButton _save_undo_spin;
251 static const struct {
263 { "Key|Shift", GDK_SHIFT_MASK },
264 { "Command", GDK_META_MASK },
265 { "Control", GDK_CONTROL_MASK },
266 { "Option", GDK_MOD1_MASK },
267 { "Command-Shift", GDK_META_MASK|GDK_SHIFT_MASK },
268 { "Command-Option", GDK_MOD1_MASK|GDK_META_MASK },
269 { "Shift-Option", GDK_SHIFT_MASK|GDK_MOD1_MASK },
270 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_META_MASK },
273 { "Key|Shift", GDK_SHIFT_MASK },
274 { "Control", GDK_CONTROL_MASK },
275 { "Alt (Mod1)", GDK_MOD1_MASK },
276 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
277 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
278 { "Shift-Alt", GDK_SHIFT_MASK|GDK_MOD1_MASK },
279 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
280 { "Mod2", GDK_MOD2_MASK },
281 { "Mod3", GDK_MOD3_MASK },
282 { "Mod4", GDK_MOD4_MASK },
283 { "Mod5", GDK_MOD5_MASK },
289 class KeyboardOptions : public OptionEditorBox
293 _delete_button_adjustment (3, 1, 12),
294 _delete_button_spin (_delete_button_adjustment),
295 _edit_button_adjustment (3, 1, 5),
296 _edit_button_spin (_edit_button_adjustment),
297 _insert_note_button_adjustment (3, 1, 5),
298 _insert_note_button_spin (_insert_note_button_adjustment)
300 /* internationalize and prepare for use with combos */
303 for (int i = 0; modifiers[i].name; ++i) {
304 dumb.push_back (S_(modifiers[i].name));
307 set_popdown_strings (_edit_modifier_combo, dumb);
308 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
310 for (int x = 0; modifiers[x].name; ++x) {
311 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
312 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
317 Table* t = manage (new Table (4, 4));
320 Label* l = manage (left_aligned_label (_("Edit using:")));
321 l->set_name ("OptionsLabel");
323 t->attach (*l, 0, 1, 0, 1, FILL | EXPAND, FILL);
324 t->attach (_edit_modifier_combo, 1, 2, 0, 1, FILL | EXPAND, FILL);
326 l = manage (new Label (_("+ button")));
327 l->set_name ("OptionsLabel");
329 t->attach (*l, 3, 4, 0, 1, FILL | EXPAND, FILL);
330 t->attach (_edit_button_spin, 4, 5, 0, 1, FILL | EXPAND, FILL);
332 _edit_button_spin.set_name ("OptionsEntry");
333 _edit_button_adjustment.set_value (Keyboard::edit_button());
334 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
336 set_popdown_strings (_delete_modifier_combo, dumb);
337 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
339 for (int x = 0; modifiers[x].name; ++x) {
340 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
341 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
346 l = manage (left_aligned_label (_("Delete using:")));
347 l->set_name ("OptionsLabel");
349 t->attach (*l, 0, 1, 1, 2, FILL | EXPAND, FILL);
350 t->attach (_delete_modifier_combo, 1, 2, 1, 2, FILL | EXPAND, FILL);
352 l = manage (new Label (_("+ button")));
353 l->set_name ("OptionsLabel");
355 t->attach (*l, 3, 4, 1, 2, FILL | EXPAND, FILL);
356 t->attach (_delete_button_spin, 4, 5, 1, 2, FILL | EXPAND, FILL);
358 _delete_button_spin.set_name ("OptionsEntry");
359 _delete_button_adjustment.set_value (Keyboard::delete_button());
360 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
363 set_popdown_strings (_insert_note_modifier_combo, dumb);
364 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
366 for (int x = 0; modifiers[x].name; ++x) {
367 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
368 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
373 l = manage (left_aligned_label (_("Insert note using:")));
374 l->set_name ("OptionsLabel");
376 t->attach (*l, 0, 1, 2, 3, FILL | EXPAND, FILL);
377 t->attach (_insert_note_modifier_combo, 1, 2, 2, 3, FILL | EXPAND, FILL);
379 l = manage (new Label (_("+ button")));
380 l->set_name ("OptionsLabel");
382 t->attach (*l, 3, 4, 2, 3, FILL | EXPAND, FILL);
383 t->attach (_insert_note_button_spin, 4, 5, 2, 3, FILL | EXPAND, FILL);
385 _insert_note_button_spin.set_name ("OptionsEntry");
386 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
387 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
390 set_popdown_strings (_snap_modifier_combo, dumb);
391 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
393 for (int x = 0; modifiers[x].name; ++x) {
394 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
395 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
400 l = manage (left_aligned_label (_("Ignore snap using:")));
401 l->set_name ("OptionsLabel");
403 t->attach (*l, 0, 1, 3, 4, FILL | EXPAND, FILL);
404 t->attach (_snap_modifier_combo, 1, 2, 3, 4, FILL | EXPAND, FILL);
408 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
409 strs.push_back (bf->first);
412 set_popdown_strings (_keyboard_layout_selector, strs);
413 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
414 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
416 l = manage (left_aligned_label (_("Keyboard layout:")));
417 l->set_name ("OptionsLabel");
419 t->attach (*l, 0, 1, 4, 5, FILL | EXPAND, FILL);
420 t->attach (_keyboard_layout_selector, 1, 2, 4, 5, FILL | EXPAND, FILL);
422 _box->pack_start (*t, false, false);
425 void parameter_changed (string const &)
427 /* XXX: these aren't really config options... */
430 void set_state_from_config ()
432 /* XXX: these aren't really config options... */
437 void bindings_changed ()
439 string const txt = _keyboard_layout_selector.get_active_text();
441 /* XXX: config...? for all this keyboard stuff */
443 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
444 if (txt == i->first) {
445 if (Keyboard::load_keybindings (i->second)) {
446 Keyboard::save_keybindings ();
452 void edit_modifier_chosen ()
454 string const txt = _edit_modifier_combo.get_active_text();
456 for (int i = 0; modifiers[i].name; ++i) {
457 if (txt == _(modifiers[i].name)) {
458 Keyboard::set_edit_modifier (modifiers[i].modifier);
464 void delete_modifier_chosen ()
466 string const txt = _delete_modifier_combo.get_active_text();
468 for (int i = 0; modifiers[i].name; ++i) {
469 if (txt == _(modifiers[i].name)) {
470 Keyboard::set_delete_modifier (modifiers[i].modifier);
476 void insert_note_modifier_chosen ()
478 string const txt = _insert_note_modifier_combo.get_active_text();
480 for (int i = 0; modifiers[i].name; ++i) {
481 if (txt == _(modifiers[i].name)) {
482 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
488 void snap_modifier_chosen ()
490 string const txt = _snap_modifier_combo.get_active_text();
492 for (int i = 0; modifiers[i].name; ++i) {
493 if (txt == _(modifiers[i].name)) {
494 Keyboard::set_snap_modifier (modifiers[i].modifier);
500 void delete_button_changed ()
502 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
505 void edit_button_changed ()
507 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
510 void insert_note_button_changed ()
512 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
515 ComboBoxText _keyboard_layout_selector;
516 ComboBoxText _edit_modifier_combo;
517 ComboBoxText _delete_modifier_combo;
518 ComboBoxText _insert_note_modifier_combo;
519 ComboBoxText _snap_modifier_combo;
520 Adjustment _delete_button_adjustment;
521 SpinButton _delete_button_spin;
522 Adjustment _edit_button_adjustment;
523 SpinButton _edit_button_spin;
524 Adjustment _insert_note_button_adjustment;
525 SpinButton _insert_note_button_spin;
529 class FontScalingOptions : public OptionEditorBox
532 FontScalingOptions (RCConfiguration* c) :
534 _dpi_adjustment (50, 50, 250, 1, 10),
535 _dpi_slider (_dpi_adjustment)
537 _dpi_adjustment.set_value (floor ((double)(_rc_config->get_font_scale () / 1024)));
539 Label* l = manage (new Label (_("Font scaling:")));
540 l->set_name ("OptionsLabel");
542 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
543 HBox* h = manage (new HBox);
545 h->pack_start (*l, false, false);
546 h->pack_start (_dpi_slider, true, true);
548 _box->pack_start (*h, false, false);
550 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
553 void parameter_changed (string const & p)
555 if (p == "font-scale") {
556 _dpi_adjustment.set_value (floor ((double)(_rc_config->get_font_scale() / 1024)));
560 void set_state_from_config ()
562 parameter_changed ("font-scale");
569 _rc_config->set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024));
570 /* XXX: should be triggered from the parameter changed signal */
574 RCConfiguration* _rc_config;
575 Adjustment _dpi_adjustment;
579 class ClipLevelOptions : public OptionEditorBox
582 ClipLevelOptions (RCConfiguration* c)
584 , _clip_level_adjustment (0, -128.0, 2.0, 0.1, 1.0) /* units of dB */
585 , _clip_level_slider (_clip_level_adjustment)
587 _clip_level_adjustment.set_value (_rc_config->get_waveform_clip_level ());
589 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
590 l->set_name ("OptionsLabel");
592 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
593 HBox* h = manage (new HBox);
595 h->pack_start (*l, false, false);
596 h->pack_start (_clip_level_slider, true, true);
598 _box->pack_start (*h, false, false);
600 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
603 void parameter_changed (string const & p)
605 if (p == "waveform-clip-level") {
606 _clip_level_adjustment.set_value (_rc_config->get_waveform_clip_level());
610 void set_state_from_config ()
612 parameter_changed ("waveform-clip-level");
617 void clip_level_changed ()
619 _rc_config->set_waveform_clip_level (_clip_level_adjustment.get_value());
620 /* XXX: should be triggered from the parameter changed signal */
621 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
624 RCConfiguration* _rc_config;
625 Adjustment _clip_level_adjustment;
626 HScale _clip_level_slider;
629 class BufferingOptions : public OptionEditorBox
632 BufferingOptions (RCConfiguration* c)
634 , _playback_adjustment (5, 1, 60, 1, 4)
635 , _capture_adjustment (5, 1, 60, 1, 4)
636 , _playback_slider (_playback_adjustment)
637 , _capture_slider (_capture_adjustment)
639 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
641 Label* l = manage (new Label (_("Playback (seconds of buffering):")));
642 l->set_name ("OptionsLabel");
644 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
645 HBox* h = manage (new HBox);
647 h->pack_start (*l, false, false);
648 h->pack_start (_playback_slider, true, true);
650 _box->pack_start (*h, false, false);
652 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
654 l = manage (new Label (_("Recording (seconds of buffering):")));
655 l->set_name ("OptionsLabel");
657 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
658 h = manage (new HBox);
660 h->pack_start (*l, false, false);
661 h->pack_start (_capture_slider, true, true);
663 _box->pack_start (*h, false, false);
665 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
666 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
669 void parameter_changed (string const & p)
671 if (p == "playback-buffer-seconds") {
672 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
673 } else if (p == "capture-buffer-seconds") {
674 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
678 void set_state_from_config ()
680 parameter_changed ("playback-buffer-seconds");
681 parameter_changed ("capture-buffer-seconds");
686 void playback_changed ()
688 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
691 void capture_changed ()
693 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
696 RCConfiguration* _rc_config;
697 Adjustment _playback_adjustment;
698 Adjustment _capture_adjustment;
699 HScale _playback_slider;
700 HScale _capture_slider;
703 class ControlSurfacesOptions : public OptionEditorBox
706 ControlSurfacesOptions (Gtk::Window& parent)
708 , _ignore_view_change (0)
710 _store = ListStore::create (_model);
711 _view.set_model (_store);
712 _view.append_column (_("Control Surface Protocol"), _model.name);
713 _view.get_column(0)->set_resizable (true);
714 _view.get_column(0)->set_expand (true);
715 _view.append_column_editable (_("Enabled"), _model.enabled);
716 _view.append_column_editable (_("Feedback"), _model.feedback);
718 _box->pack_start (_view, false, false);
720 Label* label = manage (new Label);
721 label->set_markup (string_compose (X_("<i>%1</i>"), _("Double-click on a name to edit settings for an enabled protocol")));
723 _box->pack_start (*label, false, false);
726 ControlProtocolManager& m = ControlProtocolManager::instance ();
727 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
728 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
730 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
731 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
734 void parameter_changed (std::string const &)
739 void set_state_from_config ()
743 ControlProtocolManager& m = ControlProtocolManager::instance ();
744 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
746 if (!(*i)->mandatory) {
747 TreeModel::Row r = *_store->append ();
748 r[_model.name] = (*i)->name;
749 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
750 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
751 r[_model.protocol_info] = *i;
758 void protocol_status_changed (ControlProtocolInfo* cpi) {
760 TreeModel::Children rows = _store->children();
762 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
763 string n = ((*x)[_model.name]);
765 if ((*x)[_model.protocol_info] == cpi) {
766 _ignore_view_change++;
767 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
768 _ignore_view_change--;
774 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
776 TreeModel::Row r = *i;
778 if (_ignore_view_change) {
782 ControlProtocolInfo* cpi = r[_model.protocol_info];
787 bool const was_enabled = (cpi->protocol != 0);
788 bool const is_enabled = r[_model.enabled];
791 if (was_enabled != is_enabled) {
794 ControlProtocolManager::instance().activate (*cpi);
796 Gtk::Window* win = r[_model.editor];
801 ControlProtocolManager::instance().deactivate (*cpi);
805 r[_model.editor] = 0;
810 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
811 bool const is_feedback = r[_model.feedback];
813 if (was_feedback != is_feedback && cpi->protocol) {
814 cpi->protocol->set_feedback (is_feedback);
818 void edit_clicked (GdkEventButton* ev)
820 if (ev->type != GDK_2BUTTON_PRESS) {
825 ControlProtocolInfo* cpi;
828 row = *(_view.get_selection()->get_selected());
830 Window* win = row[_model.editor];
831 if (win && !win->is_visible()) {
834 cpi = row[_model.protocol_info];
836 if (cpi && cpi->protocol && cpi->protocol->has_editor ()) {
837 Box* box = (Box*) cpi->protocol->get_gui ();
839 string title = row[_model.name];
840 ArdourWindow* win = new ArdourWindow (_parent, title);
841 win->set_title ("Control Protocol Options");
845 row[_model.editor] = win;
851 class ControlSurfacesModelColumns : public TreeModelColumnRecord
855 ControlSurfacesModelColumns ()
864 TreeModelColumn<string> name;
865 TreeModelColumn<bool> enabled;
866 TreeModelColumn<bool> feedback;
867 TreeModelColumn<ControlProtocolInfo*> protocol_info;
868 TreeModelColumn<Gtk::Window*> editor;
871 Glib::RefPtr<ListStore> _store;
872 ControlSurfacesModelColumns _model;
874 Gtk::Window& _parent;
875 PBD::ScopedConnection protocol_status_connection;
876 uint32_t _ignore_view_change;
879 class VideoTimelineOptions : public OptionEditorBox
882 VideoTimelineOptions (RCConfiguration* c)
884 , _show_video_export_info_button (_("Show Video Export Info before export"))
885 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
886 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
888 Table* t = manage (new Table (2, 6));
891 t->attach (_video_advanced_setup_button, 0, 2, 0, 1);
892 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
893 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
894 _("<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."));
896 Label* l = manage (new Label (_("Video Server URL:")));
897 l->set_alignment (0, 0.5);
898 t->attach (*l, 0, 1, 1, 2, FILL);
899 t->attach (_video_server_url_entry, 1, 2, 1, 2, FILL);
900 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
901 _("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"));
903 l = manage (new Label (_("Video Folder:")));
904 l->set_alignment (0, 0.5);
905 t->attach (*l, 0, 1, 2, 3, FILL);
906 t->attach (_video_server_docroot_entry, 1, 2, 2, 3);
907 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
908 _("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."));
910 /* small vspace y=3..4 */
912 t->attach (_show_video_export_info_button, 0, 2, 4, 5);
913 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
914 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
915 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
917 t->attach (_show_video_server_dialog_button, 0, 2, 5, 6);
918 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
919 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
920 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
922 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
923 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
924 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
925 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
927 _box->pack_start (*t,true,true);
930 void server_url_changed ()
932 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
935 void server_docroot_changed ()
937 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
940 void show_video_export_info_toggled ()
942 bool const x = _show_video_export_info_button.get_active ();
943 _rc_config->set_show_video_export_info (x);
946 void show_video_server_dialog_toggled ()
948 bool const x = _show_video_server_dialog_button.get_active ();
949 _rc_config->set_show_video_server_dialog (x);
952 void video_advanced_setup_toggled ()
954 bool const x = _video_advanced_setup_button.get_active ();
955 _rc_config->set_video_advanced_setup(x);
958 void parameter_changed (string const & p)
960 if (p == "video-server-url") {
961 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
962 } else if (p == "video-server-docroot") {
963 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
964 } else if (p == "show-video-export-info") {
965 bool const x = _rc_config->get_show_video_export_info();
966 _show_video_export_info_button.set_active (x);
967 } else if (p == "show-video-server-dialog") {
968 bool const x = _rc_config->get_show_video_server_dialog();
969 _show_video_server_dialog_button.set_active (x);
970 } else if (p == "video-advanced-setup") {
971 bool const x = _rc_config->get_video_advanced_setup();
972 _video_advanced_setup_button.set_active(x);
973 _video_server_docroot_entry.set_sensitive(x);
974 _video_server_url_entry.set_sensitive(x);
978 void set_state_from_config ()
980 parameter_changed ("video-server-url");
981 parameter_changed ("video-server-docroot");
982 parameter_changed ("video-monitor-setup-dialog");
983 parameter_changed ("show-video-export-info");
984 parameter_changed ("show-video-server-dialog");
985 parameter_changed ("video-advanced-setup");
989 RCConfiguration* _rc_config;
990 Entry _video_server_url_entry;
991 Entry _video_server_docroot_entry;
992 CheckButton _show_video_export_info_button;
993 CheckButton _show_video_server_dialog_button;
994 CheckButton _video_advanced_setup_button;
997 class PluginOptions : public OptionEditorBox
1000 PluginOptions (RCConfiguration* c)
1002 , _display_plugin_scan_progress (_("Always Display Plugin Scan Progress"))
1003 , _discover_vst_on_start (_("Scan for new VST Plugins on Application Start"))
1004 , _timeout_adjustment (0, 0, 3000, 50, 50)
1005 , _timeout_slider (_timeout_adjustment)
1008 std::stringstream ss;
1009 Table* t = manage (new Table (2, 6));
1010 t->set_spacings (4);
1014 ss << "<b>" << _("General") << "</b>";
1015 l = manage (left_aligned_label (ss.str()));
1016 l->set_use_markup (true);
1017 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1018 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1020 b = manage (new Button (_("Scan for Plugins")));
1021 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::refresh_clicked));
1022 t->attach (*b, 0, 2, n, n+1, FILL); ++n;
1024 t->attach (_display_plugin_scan_progress, 0, 2, n, n+1); ++n;
1025 _display_plugin_scan_progress.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::display_plugin_scan_progress_toggled));
1026 Gtkmm2ext::UI::instance()->set_tip (_display_plugin_scan_progress,
1027 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
1029 _timeout_slider.set_digits (0);
1030 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &PluginOptions::timeout_changed));
1032 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1033 _("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."));
1035 l = manage (left_aligned_label (_("Scan Time Out [deciseconds]")));;
1036 HBox* h = manage (new HBox);
1038 h->pack_start (*l, false, false);
1039 h->pack_start (_timeout_slider, true, true);
1040 t->attach (*h, 0, 2, n, n+1); ++n;
1043 ss << "<b>" << _("VST") << "</b>";
1044 l = manage (left_aligned_label (ss.str()));
1045 l->set_use_markup (true);
1046 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1047 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1049 b = manage (new Button (_("Clear VST Cache")));
1050 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_cache_clicked));
1051 t->attach (*b, 0, 1, n, n+1, FILL);
1053 b = manage (new Button (_("Clear VST Blacklist")));
1054 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_blacklist_clicked));
1055 t->attach (*b, 1, 2, n, n+1, FILL);
1058 t->attach (_discover_vst_on_start, 0, 2, n, n+1); ++n;
1059 _discover_vst_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_vst_on_start_toggled));
1060 Gtkmm2ext::UI::instance()->set_tip (_discover_vst_on_start,
1061 _("<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"));
1063 #ifdef LXVST_SUPPORT
1064 t->attach (*manage (left_aligned_label (_("Linux VST Path:"))), 0, 1, n, n+1);
1065 b = manage (new Button (_("Edit")));
1066 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_lxvst_path_clicked));
1067 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1070 #ifdef WINDOWS_VST_SUPPORT
1071 t->attach (*manage (left_aligned_label (_("Windows VST Path:"))), 0, 1, n, n+1);
1072 b = manage (new Button (_("Edit")));
1073 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_vst_path_clicked));
1074 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1077 _box->pack_start (*t,true,true);
1080 void parameter_changed (string const & p) {
1081 if (p == "show-plugin-scan-window") {
1082 bool const x = _rc_config->get_show_plugin_scan_window();
1083 _display_plugin_scan_progress.set_active (x);
1085 else if (p == "discover-vst-on-start") {
1086 bool const x = _rc_config->get_discover_vst_on_start();
1087 _discover_vst_on_start.set_active (x);
1089 else if (p == "vst-scan-timeout") {
1090 int const x = _rc_config->get_vst_scan_timeout();
1091 _timeout_adjustment.set_value (x);
1095 void set_state_from_config () {
1096 parameter_changed ("show-plugin-scan-window");
1097 parameter_changed ("discover-vst-on-start");
1098 parameter_changed ("vst-scan-timeout");
1102 RCConfiguration* _rc_config;
1103 CheckButton _display_plugin_scan_progress;
1104 CheckButton _discover_vst_on_start;
1105 Adjustment _timeout_adjustment;
1106 HScale _timeout_slider;
1108 void display_plugin_scan_progress_toggled () {
1109 bool const x = _display_plugin_scan_progress.get_active();
1110 _rc_config->set_show_plugin_scan_window(x);
1113 void discover_vst_on_start_toggled () {
1114 bool const x = _discover_vst_on_start.get_active();
1115 _rc_config->set_discover_vst_on_start(x);
1118 void timeout_changed () {
1119 int x = floor(_timeout_adjustment.get_value());
1120 _rc_config->set_vst_scan_timeout(x);
1123 void clear_vst_cache_clicked () {
1124 PluginManager::instance().clear_vst_cache();
1127 void clear_vst_blacklist_clicked () {
1128 PluginManager::instance().clear_vst_blacklist();
1131 void edit_vst_path_clicked () {
1132 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1133 _("Set Windows VST Search Path"),
1134 _rc_config->get_plugin_path_vst(),
1135 PluginManager::instance().get_default_windows_vst_path()
1137 ResponseType r = (ResponseType) pd->run ();
1139 if (r == RESPONSE_ACCEPT) {
1140 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
1145 // todo consolidate with edit_vst_path_clicked..
1146 void edit_lxvst_path_clicked () {
1147 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1148 _("Set Linux VST Search Path"),
1149 _rc_config->get_plugin_path_lxvst(),
1150 PluginManager::instance().get_default_lxvst_path()
1152 ResponseType r = (ResponseType) pd->run ();
1154 if (r == RESPONSE_ACCEPT) {
1155 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
1160 void refresh_clicked () {
1161 PluginManager::instance().refresh();
1166 /** A class which allows control of visibility of some editor components usign
1167 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1168 * which has the correct members, but with null widget pointers. This
1169 * class allows the user to set visibility of the members, the details
1170 * of which are stored in a configuration variable which can be watched
1171 * by parts of the editor that actually contain the widgets whose visibility
1172 * is being controlled.
1175 class VisibilityOption : public Option
1178 /** @param name User-visible name for this group.
1179 * @param g `Dummy' VisibilityGroup (as described above).
1180 * @param get Method to get the value of the appropriate configuration variable.
1181 * @param set Method to set the value of the appropriate configuration variable.
1183 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1184 : Option (g->get_state_name(), name)
1186 , _visibility_group (g)
1190 /* Watch for changes made by the user to our members */
1191 _visibility_group->VisibilityChanged.connect_same_thread (
1192 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1196 void set_state_from_config ()
1198 /* Set our state from the current configuration */
1199 _visibility_group->set_state (_get ());
1202 void add_to_page (OptionEditorPage* p)
1204 _heading.add_to_page (p);
1205 add_widget_to_page (p, _visibility_group->list_view ());
1208 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1213 /* The user has changed something, so reflect this change
1214 in the RCConfiguration.
1216 _set (_visibility_group->get_state_value ());
1219 OptionEditorHeading _heading;
1220 VisibilityGroup* _visibility_group;
1221 sigc::slot<std::string> _get;
1222 sigc::slot<bool, std::string> _set;
1223 PBD::ScopedConnection _visibility_group_connection;
1228 RCOptionEditor::RCOptionEditor ()
1229 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1230 , _rc_config (Config)
1231 , _mixer_strip_visibility ("mixer-strip-visibility")
1235 uint32_t hwcpus = hardware_concurrency ();
1237 BoolComboOption* bco;
1240 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1242 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1244 _("Signal processing uses"),
1245 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1246 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1249 procs->add (-1, _("all but one processor"));
1250 procs->add (0, _("all available processors"));
1252 for (uint32_t i = 1; i <= hwcpus; ++i) {
1253 procs->add (i, string_compose (_("%1 processors"), i));
1256 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1258 add_option (_("Misc"), procs);
1261 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1263 add_option (_("Misc"), new UndoOptions (_rc_config));
1265 add_option (_("Misc"),
1267 "verify-remove-last-capture",
1268 _("Verify removal of last capture"),
1269 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1270 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1273 add_option (_("Misc"),
1275 "periodic-safety-backups",
1276 _("Make periodic backups of the session file"),
1277 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1278 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1281 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1283 add_option (_("Misc"),
1285 "only-copy-imported-files",
1286 _("Always copy imported files"),
1287 sigc::mem_fun (*_rc_config, &RCConfiguration::get_only_copy_imported_files),
1288 sigc::mem_fun (*_rc_config, &RCConfiguration::set_only_copy_imported_files)
1291 add_option (_("Misc"), new DirectoryOption (
1292 X_("default-session-parent-dir"),
1293 _("Default folder for new sessions:"),
1294 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1295 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1298 add_option (_("Misc"),
1299 new SpinOption<uint32_t> (
1300 "max-recent-sessions",
1301 _("Maximum number of recent sessions"),
1302 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1303 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1307 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1309 add_option (_("Misc"), new ClickOptions (_rc_config, this));
1311 add_option (_("Misc"),
1314 _("Click gain level"),
1315 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1316 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1319 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1321 add_option (_("Misc"),
1322 new SpinOption<double> (
1323 "automation-thinning-factor",
1324 _("Thinning factor (larger value => less data)"),
1325 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1326 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1330 add_option (_("Misc"),
1331 new SpinOption<double> (
1332 "automation-interval-msecs",
1333 _("Automation sampling interval (milliseconds)"),
1334 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1335 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1343 tsf = new BoolOption (
1344 "latched-record-enable",
1345 _("Keep record-enable engaged on stop"),
1346 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1347 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1349 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1350 add_option (_("Transport"), tsf);
1352 tsf = new BoolOption (
1353 "stop-recording-on-xrun",
1354 _("Stop recording when an xrun occurs"),
1355 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
1356 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
1358 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1359 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
1362 tsf = new BoolOption (
1364 _("Play loop is a transport mode"),
1365 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1366 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1368 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1369 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1370 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1371 add_option (_("Transport"), tsf);
1373 tsf = new BoolOption (
1374 "create-xrun-marker",
1375 _("Create markers where xruns occur"),
1376 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
1377 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
1379 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1380 add_option (_("Transport"), tsf);
1382 tsf = new BoolOption (
1383 "stop-at-session-end",
1384 _("Stop at the end of the session"),
1385 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
1386 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
1388 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1389 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
1390 "when it reaches the current session end marker\n\n"
1391 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
1393 add_option (_("Transport"), tsf);
1395 tsf = new BoolOption (
1397 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
1398 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
1399 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
1401 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1402 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
1403 "preventing any need to do a transport locate at the end of the loop\n\n"
1404 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
1405 "which will often cause a small click or delay"), PROGRAM_NAME));
1406 add_option (_("Transport"), tsf);
1408 tsf = new BoolOption (
1409 "disable-disarm-during-roll",
1410 _("Disable per-track record disarm while rolling"),
1411 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
1412 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
1414 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"));
1415 add_option (_("Transport"), tsf);
1417 tsf = new BoolOption (
1419 _("12dB gain reduction during fast-forward and fast-rewind"),
1420 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
1421 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
1423 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
1424 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
1425 add_option (_("Transport"), tsf);
1427 add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
1429 _sync_source = new ComboOption<SyncSource> (
1431 _("External timecode source"),
1432 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
1433 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
1436 populate_sync_options ();
1437 add_option (_("Transport"), _sync_source);
1439 _sync_framerate = new BoolOption (
1440 "timecode-sync-frame-rate",
1441 _("Match session video frame rate to external timecode"),
1442 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
1443 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
1445 Gtkmm2ext::UI::instance()->set_tip
1446 (_sync_framerate->tip_widget(),
1447 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
1448 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
1449 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
1450 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
1451 "timecode standard and the session standard."), PROGRAM_NAME));
1453 add_option (_("Transport"), _sync_framerate);
1455 _sync_genlock = new BoolOption (
1456 "timecode-source-is-synced",
1457 _("External timecode is sync locked"),
1458 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
1459 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
1461 Gtkmm2ext::UI::instance()->set_tip
1462 (_sync_genlock->tip_widget(),
1463 _("<b>When enabled</b> indicates that the selected external timecode source shares sync (Black & Burst, Wordclock, etc) with the audio interface."));
1466 add_option (_("Transport"), _sync_genlock);
1468 _sync_source_2997 = new BoolOption (
1469 "timecode-source-2997",
1470 _("Lock to 29.9700 fps instead of 30000/1001"),
1471 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
1472 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
1474 Gtkmm2ext::UI::instance()->set_tip
1475 (_sync_source_2997->tip_widget(),
1476 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
1477 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
1478 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
1479 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
1480 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
1481 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
1484 add_option (_("Transport"), _sync_source_2997);
1486 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
1488 _ltc_port = new ComboStringOption (
1490 _("LTC incoming port"),
1491 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
1492 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
1495 vector<string> physical_inputs;
1496 physical_inputs.push_back (_("None"));
1497 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
1498 _ltc_port->set_popdown_strings (physical_inputs);
1500 add_option (_("Transport"), _ltc_port);
1502 // TODO; rather disable this button than not compile it..
1503 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
1505 add_option (_("Transport"),
1508 _("Enable LTC generator"),
1509 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
1510 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
1513 _ltc_send_continuously = new BoolOption (
1514 "ltc-send-continuously",
1515 _("Send LTC while stopped"),
1516 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
1517 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
1519 Gtkmm2ext::UI::instance()->set_tip
1520 (_ltc_send_continuously->tip_widget(),
1521 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
1522 add_option (_("Transport"), _ltc_send_continuously);
1524 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
1525 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
1526 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
1527 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
1529 Gtkmm2ext::UI::instance()->set_tip
1530 (_ltc_volume_slider->tip_widget(),
1531 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
1533 add_option (_("Transport"), _ltc_volume_slider);
1534 parameter_changed ("send-ltc");
1536 parameter_changed ("sync-source");
1540 add_option (_("Editor"),
1542 "link-region-and-track-selection",
1543 _("Link selection of regions and tracks"),
1544 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_region_and_track_selection),
1545 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_region_and_track_selection)
1548 add_option (_("Editor"),
1550 "automation-follows-regions",
1551 _("Move relevant automation when audio regions are moved"),
1552 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
1553 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
1556 add_option (_("Editor"),
1558 "show-track-meters",
1559 _("Show meters on tracks in the editor"),
1560 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_track_meters),
1561 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_track_meters)
1564 add_option (_("Editor"),
1566 "show-editor-meter",
1567 _("Display master-meter in the toolbar"),
1568 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_editor_meter),
1569 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_editor_meter)
1572 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
1573 "default-fade-shape",
1574 _("Default fade shape"),
1575 sigc::mem_fun (*_rc_config,
1576 &RCConfiguration::get_default_fade_shape),
1577 sigc::mem_fun (*_rc_config,
1578 &RCConfiguration::set_default_fade_shape)
1581 fadeshape->add (FadeLinear,
1582 _("Linear (for highly correlated material)"));
1583 fadeshape->add (FadeConstantPower, _("Constant power"));
1584 fadeshape->add (FadeSymmetric, _("Symmetric"));
1585 fadeshape->add (FadeSlow, _("Slow"));
1586 fadeshape->add (FadeFast, _("Fast"));
1588 add_option (_("Editor"), fadeshape);
1591 bco = new BoolComboOption (
1592 "use-overlap-equivalency",
1593 _("Regions in active edit groups are edited together"),
1594 _("whenever they overlap in time"),
1595 _("only if they have identical length, position and origin"),
1596 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
1597 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
1600 add_option (_("Editor"), bco);
1602 add_option (_("Editor"),
1604 "rubberbanding-snaps-to-grid",
1605 _("Make rubberband selection rectangle snap to the grid"),
1606 sigc::mem_fun (*_rc_config, &RCConfiguration::get_rubberbanding_snaps_to_grid),
1607 sigc::mem_fun (*_rc_config, &RCConfiguration::set_rubberbanding_snaps_to_grid)
1610 add_option (_("Editor"),
1613 _("Show waveforms in regions"),
1614 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms),
1615 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms)
1618 add_option (_("Editor"),
1619 new BoolComboOption (
1620 "show-region-gain-envelopes",
1621 _("Show gain envelopes in audio regions"),
1623 _("only in region gain mode"),
1624 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_region_gain),
1625 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_region_gain)
1628 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
1630 _("Waveform scale"),
1631 sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_scale),
1632 sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_scale)
1635 wfs->add (Linear, _("linear"));
1636 wfs->add (Logarithmic, _("logarithmic"));
1638 add_option (_("Editor"), wfs);
1640 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
1642 _("Waveform shape"),
1643 sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_shape),
1644 sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_shape)
1647 wfsh->add (Traditional, _("traditional"));
1648 wfsh->add (Rectified, _("rectified"));
1650 add_option (_("Editor"), wfsh);
1652 add_option (_("Editor"), new ClipLevelOptions (_rc_config));
1654 add_option (_("Editor"),
1656 "show-waveforms-while-recording",
1657 _("Show waveforms for audio while it is being recorded"),
1658 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms_while_recording),
1659 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms_while_recording)
1662 add_option (_("Editor"),
1665 _("Show zoom toolbar"),
1666 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_zoom_tools),
1667 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_zoom_tools)
1670 add_option (_("Editor"),
1672 "update-editor-during-summary-drag",
1673 _("Update editor window during drags of the summary"),
1674 sigc::mem_fun (*_rc_config, &RCConfiguration::get_update_editor_during_summary_drag),
1675 sigc::mem_fun (*_rc_config, &RCConfiguration::set_update_editor_during_summary_drag)
1678 add_option (_("Editor"),
1680 "link-editor-and-mixer-selection",
1681 _("Synchronise editor and mixer selection"),
1682 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_editor_and_mixer_selection),
1683 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_editor_and_mixer_selection)
1686 bo = new BoolOption (
1688 _("Name new markers"),
1689 sigc::mem_fun (*_rc_config, &RCConfiguration::get_name_new_markers),
1690 sigc::mem_fun (*_rc_config, &RCConfiguration::set_name_new_markers)
1693 add_option (_("Editor"), bo);
1694 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."
1695 "\n\nYou can always rename markers by right-clicking on them"));
1697 add_option (_("Editor"),
1699 "autoscroll-editor",
1700 _("Auto-scroll editor window when dragging near its edges"),
1701 sigc::mem_fun (*_rc_config, &RCConfiguration::get_autoscroll_editor),
1702 sigc::mem_fun (*_rc_config, &RCConfiguration::set_autoscroll_editor)
1707 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
1709 add_option (_("Audio"), new BufferingOptions (_rc_config));
1711 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
1713 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
1715 _("Record monitoring handled by"),
1716 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
1717 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
1720 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
1721 mm->add (HardwareMonitoring, _("via Audio Driver"));
1724 string prog (PROGRAM_NAME);
1725 boost::algorithm::to_lower (prog);
1726 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
1727 mm->add (ExternalMonitoring, _("audio hardware"));
1729 add_option (_("Audio"), mm);
1731 add_option (_("Audio"),
1733 "tape-machine-mode",
1734 _("Tape machine mode"),
1735 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
1736 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
1739 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
1741 add_option (_("Audio"),
1743 "auto-connect-standard-busses",
1744 _("Auto-connect master/monitor busses"),
1745 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
1746 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
1749 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
1750 "input-auto-connect",
1751 _("Connect track inputs"),
1752 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
1753 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
1756 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
1757 iac->add (ManualConnect, _("manually"));
1759 add_option (_("Audio"), iac);
1761 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
1762 "output-auto-connect",
1763 _("Connect track and bus outputs"),
1764 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
1765 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
1768 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
1769 oac->add (AutoConnectMaster, _("automatically to master bus"));
1770 oac->add (ManualConnect, _("manually"));
1772 add_option (_("Audio"), oac);
1774 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
1776 add_option (_("Audio"),
1778 "denormal-protection",
1779 _("Use DC bias to protect against denormals"),
1780 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
1781 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
1784 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
1786 _("Processor handling"),
1787 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
1788 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
1791 dm->add (DenormalNone, _("no processor handling"));
1795 if (fpu.has_flush_to_zero()) {
1796 dm->add (DenormalFTZ, _("use FlushToZero"));
1799 if (fpu.has_denormals_are_zero()) {
1800 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
1803 if (fpu.has_flush_to_zero() && fpu.has_denormals_are_zero()) {
1804 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
1807 add_option (_("Audio"), dm);
1809 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
1811 add_option (_("Audio"),
1813 "plugins-stop-with-transport",
1814 _("Silence plugins when the transport is stopped"),
1815 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
1816 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
1819 add_option (_("Audio"),
1821 "new-plugins-active",
1822 _("Make new plugins active"),
1823 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
1824 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
1827 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
1829 add_option (_("Audio"),
1831 "auto-analyse-audio",
1832 _("Enable automatic analysis of audio"),
1833 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
1834 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
1837 add_option (_("Audio"),
1839 "replicate-missing-region-channels",
1840 _("Replicate missing region channels"),
1841 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
1842 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
1847 add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
1849 add_option (_("Solo / mute"),
1852 _("Solo-in-place mute cut (dB)"),
1853 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
1854 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
1857 _solo_control_is_listen_control = new BoolOption (
1858 "solo-control-is-listen-control",
1859 _("Solo controls are Listen controls"),
1860 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
1861 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
1864 add_option (_("Solo / mute"), _solo_control_is_listen_control);
1866 _listen_position = new ComboOption<ListenPosition> (
1868 _("Listen Position"),
1869 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
1870 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
1873 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
1874 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
1876 add_option (_("Solo / mute"), _listen_position);
1878 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
1880 _("PFL signals come from"),
1881 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
1882 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
1885 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
1886 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
1888 add_option (_("Solo / mute"), pp);
1890 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
1892 _("AFL signals come from"),
1893 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
1894 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
1897 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
1898 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
1900 add_option (_("Solo / mute"), pa);
1902 parameter_changed ("use-monitor-bus");
1904 add_option (_("Solo / mute"),
1907 _("Exclusive solo"),
1908 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
1909 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
1912 add_option (_("Solo / mute"),
1915 _("Show solo muting"),
1916 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
1917 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
1920 add_option (_("Solo / mute"),
1922 "solo-mute-override",
1923 _("Soloing overrides muting"),
1924 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
1925 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
1928 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
1930 add_option (_("Solo / mute"),
1932 "mute-affects-pre-fader",
1933 _("Mute affects pre-fader sends"),
1934 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
1935 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
1938 add_option (_("Solo / mute"),
1940 "mute-affects-post-fader",
1941 _("Mute affects post-fader sends"),
1942 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
1943 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
1946 add_option (_("Solo / mute"),
1948 "mute-affects-control-outs",
1949 _("Mute affects control outputs"),
1950 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
1951 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
1954 add_option (_("Solo / mute"),
1956 "mute-affects-main-outs",
1957 _("Mute affects main outputs"),
1958 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
1959 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
1962 add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
1964 add_option (_("Solo / mute"),
1966 "link-send-and-route-panner",
1967 _("Link panners of Aux and External Sends with main panner by default"),
1968 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
1969 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
1972 add_option (_("MIDI"),
1975 _("Send MIDI Clock"),
1976 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
1977 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
1980 add_option (_("MIDI"),
1983 _("Send MIDI Time Code"),
1984 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
1985 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
1988 add_option (_("MIDI"),
1989 new SpinOption<int> (
1990 "mtc-qf-speed-tolerance",
1991 _("Percentage either side of normal transport speed to transmit MTC"),
1992 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
1993 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
1997 add_option (_("MIDI"),
2000 _("Obey MIDI Machine Control commands"),
2001 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2002 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2005 add_option (_("MIDI"),
2008 _("Send MIDI Machine Control commands"),
2009 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2010 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2013 add_option (_("MIDI"),
2016 _("Send MIDI control feedback"),
2017 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2018 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2021 add_option (_("MIDI"),
2022 new SpinOption<uint8_t> (
2023 "mmc-receive-device-id",
2024 _("Inbound MMC device ID"),
2025 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2026 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2030 add_option (_("MIDI"),
2031 new SpinOption<uint8_t> (
2032 "mmc-send-device-id",
2033 _("Outbound MMC device ID"),
2034 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2035 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2039 add_option (_("MIDI"),
2040 new SpinOption<int32_t> (
2041 "initial-program-change",
2042 _("Initial program change"),
2043 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2044 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2048 add_option (_("MIDI"),
2050 "display-first-midi-bank-as-zero",
2051 _("Display first MIDI bank/program as 0"),
2052 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2053 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2056 add_option (_("MIDI"),
2058 "never-display-periodic-midi",
2059 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2060 sigc::mem_fun (*_rc_config, &RCConfiguration::get_never_display_periodic_midi),
2061 sigc::mem_fun (*_rc_config, &RCConfiguration::set_never_display_periodic_midi)
2064 add_option (_("MIDI"),
2067 _("Sound MIDI notes as they are selected"),
2068 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sound_midi_notes),
2069 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sound_midi_notes)
2072 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2074 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2075 "midi-audition-synth-uri",
2076 _("Midi Audition Synth (LV2)"),
2077 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2078 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2081 audition_synth->add(X_(""), _("None"));
2082 PluginInfoList all_plugs;
2083 PluginManager& manager (PluginManager::instance());
2085 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2087 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2088 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2089 if (!(*i)->is_instrument()) continue;
2090 if ((*i)->type != ARDOUR::LV2) continue;
2091 audition_synth->add((*i)->unique_id, (*i)->name);
2095 add_option (_("MIDI"), audition_synth);
2097 /* USER INTERACTION */
2099 if (getenv ("ARDOUR_BUNDLED")) {
2100 add_option (_("User interaction"),
2102 "enable-translation",
2103 string_compose (_("Use translations of %1 messages\n"
2104 " <i>(requires a restart of %1 to take effect)</i>\n"
2105 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2106 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2107 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2110 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2112 add_option (_("User interaction"), new KeyboardOptions);
2114 /* Control Surfaces */
2116 add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this));
2118 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2120 _("Control surface remote ID"),
2121 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2122 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2125 rm->add (UserOrdered, _("assigned by user"));
2126 rm->add (MixerOrdered, _("follows order of mixer"));
2128 add_option (_("Control Surfaces"), rm);
2130 /* VIDEO Timeline */
2131 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2133 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
2134 /* Plugin options (currrently VST only) */
2135 add_option (_("Plugins"), new PluginOptions (_rc_config));
2140 add_option (S_("Preferences|GUI"),
2143 _("Graphically indicate mouse pointer hovering over various widgets"),
2144 sigc::mem_fun (*_rc_config, &RCConfiguration::get_widget_prelight),
2145 sigc::mem_fun (*_rc_config, &RCConfiguration::set_widget_prelight)
2148 add_option (S_("Preferences|GUI"),
2151 _("Show tooltips if mouse hovers over a control"),
2152 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_tooltips),
2153 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_tooltips)
2156 add_option (S_("Preferences|GUI"),
2158 "show-name-highlight",
2159 _("Use name highlight bars in region displays"),
2160 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_name_highlight),
2161 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_name_highlight)
2165 /* font scaling does nothing with GDK/Quartz */
2166 add_option (S_("Preferences|GUI"), new FontScalingOptions (_rc_config));
2169 add_option (S_("GUI"),
2171 "super-rapid-clock-update",
2172 _("update transport clock display every 40ms instead of every 100ms"),
2173 sigc::mem_fun (*_rc_config, &RCConfiguration::get_super_rapid_clock_update),
2174 sigc::mem_fun (*_rc_config, &RCConfiguration::set_super_rapid_clock_update)
2177 /* The names of these controls must be the same as those given in MixerStrip
2178 for the actual widgets being controlled.
2180 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
2181 _mixer_strip_visibility.add (0, X_("SoloSafe"), _("Solo Safe"));
2182 _mixer_strip_visibility.add (0, X_("SoloIsolated"), _("Solo Isolated"));
2183 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
2184 _mixer_strip_visibility.add (0, X_("Group"), _("Group"));
2185 _mixer_strip_visibility.add (0, X_("MeterPoint"), _("Meter Point"));
2188 S_("Preferences|GUI"),
2189 new VisibilityOption (
2191 &_mixer_strip_visibility,
2192 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mixer_strip_visibility),
2193 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mixer_strip_visibility)
2197 add_option (S_("Preferences|GUI"),
2199 "default-narrow_ms",
2200 _("Use narrow strips in the mixer by default"),
2201 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_narrow_ms),
2202 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_narrow_ms)
2205 add_option (S_("Preferences|GUI"), new OptionEditorHeading (_("Metering")));
2207 ComboOption<float>* mht = new ComboOption<float> (
2209 _("Peak hold time"),
2210 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_hold),
2211 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_hold)
2214 mht->add (MeterHoldOff, _("off"));
2215 mht->add (MeterHoldShort, _("short"));
2216 mht->add (MeterHoldMedium, _("medium"));
2217 mht->add (MeterHoldLong, _("long"));
2219 add_option (S_("Preferences|GUI"), mht);
2221 ComboOption<float>* mfo = new ComboOption<float> (
2224 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2225 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2228 mfo->add (METER_FALLOFF_OFF, _("off"));
2229 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2230 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2231 mfo->add (METER_FALLOFF_SLOWISH, _("slowish [12.0dB/sec] (DIN)"));
2232 mfo->add (METER_FALLOFF_MODERATE, _("moderate [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2233 mfo->add (METER_FALLOFF_MEDIUM, _("medium [20dB/sec]"));
2234 mfo->add (METER_FALLOFF_FAST, _("fast [32dB/sec]"));
2235 mfo->add (METER_FALLOFF_FASTER, _("faster [46dB/sec]"));
2236 mfo->add (METER_FALLOFF_FASTEST, _("fastest [70dB/sec]"));
2238 add_option (S_("Preferences|GUI"), mfo);
2240 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2241 "meter-line-up-level",
2242 _("Meter line-up level; 0dBu"),
2243 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_line_up_level),
2244 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_line_up_level)
2247 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2248 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2249 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2250 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2252 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."));
2254 add_option (S_("Preferences|GUI"), mlu);
2256 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2257 "meter-line-up-din",
2258 _("IEC1/DIN Meter line-up level; 0dBu"),
2259 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_line_up_din),
2260 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_line_up_din)
2263 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2264 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2265 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2266 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2268 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2270 add_option (S_("Preferences|GUI"), mld);
2272 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2273 "meter-vu-standard",
2274 _("VU Meter standard"),
2275 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_vu_standard),
2276 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_vu_standard)
2279 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2280 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2281 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2282 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2284 add_option (S_("Preferences|GUI"), mvu);
2286 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
2287 HSliderOption *mpks = new HSliderOption("meter-peak",
2288 _("Peak threshold [dBFS]"),
2290 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_peak),
2291 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_peak)
2294 Gtkmm2ext::UI::instance()->set_tip
2295 (mpks->tip_widget(),
2296 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
2298 add_option (S_("Preferences|GUI"), mpks);
2300 add_option (S_("Preferences|GUI"),
2303 _("LED meter style"),
2304 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_style_led),
2305 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_style_led)
2311 RCOptionEditor::parameter_changed (string const & p)
2313 OptionEditor::parameter_changed (p);
2315 if (p == "use-monitor-bus") {
2316 bool const s = Config->get_use_monitor_bus ();
2318 /* we can't use this if we don't have a monitor bus */
2319 Config->set_solo_control_is_listen_control (false);
2321 _solo_control_is_listen_control->set_sensitive (s);
2322 _listen_position->set_sensitive (s);
2323 } else if (p == "sync-source") {
2324 _sync_source->set_sensitive (true);
2326 _sync_source->set_sensitive (!_session->config.get_external_sync());
2328 switch(Config->get_sync_source()) {
2331 _sync_genlock->set_sensitive (true);
2332 _sync_framerate->set_sensitive (true);
2333 _sync_source_2997->set_sensitive (true);
2336 _sync_genlock->set_sensitive (false);
2337 _sync_framerate->set_sensitive (false);
2338 _sync_source_2997->set_sensitive (false);
2341 } else if (p == "send-ltc") {
2342 bool const s = Config->get_send_ltc ();
2343 _ltc_send_continuously->set_sensitive (s);
2344 _ltc_volume_slider->set_sensitive (s);
2348 void RCOptionEditor::ltc_generator_volume_changed () {
2349 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
2353 RCOptionEditor::populate_sync_options ()
2355 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
2357 _sync_source->clear ();
2359 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
2360 _sync_source->add (*i, sync_source_to_string (*i));