Add session option to enable count-in
[ardour.git] / gtk2_ardour / session_option_editor.cc
1 /*
2     Copyright (C) 2000-2010 Paul Davis
3
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.
8
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.
13
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.
17
18 */
19
20 #include "ardour/session.h"
21
22 #include "gui_thread.h"
23 #include "session_option_editor.h"
24 #include "search_path_option.h"
25 #include "pbd/i18n.h"
26
27 using namespace std;
28 using namespace ARDOUR;
29 using namespace Timecode;
30
31 SessionOptionEditor::SessionOptionEditor (Session* s)
32         : OptionEditorWindow (&(s->config), _("Session Properties"))
33         , _session_config (&(s->config))
34 {
35         set_session (s);
36
37         set_name ("SessionProperties");
38
39         /* TIMECODE*/
40
41         add_option (_("Timecode"), new OptionEditorHeading (_("Timecode Settings")));
42
43         ComboOption<TimecodeFormat>* smf = new ComboOption<TimecodeFormat> (
44                 "timecode-format",
45                 _("Timecode frames-per-second"),
46                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_timecode_format),
47                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_timecode_format)
48                 );
49
50         smf->add (timecode_23976, _("23.976"));
51         smf->add (timecode_24, _("24"));
52         smf->add (timecode_24976, _("24.975"));
53         smf->add (timecode_25, _("25"));
54         smf->add (timecode_2997, _("29.97"));
55         smf->add (timecode_2997drop, _("29.97 drop"));
56         smf->add (timecode_30, _("30"));
57         smf->add (timecode_30drop, _("30 drop"));
58         smf->add (timecode_5994, _("59.94"));
59         smf->add (timecode_60, _("60"));
60
61         add_option (_("Timecode"), smf);
62
63         _vpu = new ComboOption<float> (
64                 "video-pullup",
65                 _("Pull-up / pull-down"),
66                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_video_pullup),
67                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_video_pullup)
68                 );
69
70         _vpu->add (4.1667 + 0.1, _("4.1667 + 0.1%"));
71         _vpu->add (4.1667, _("4.1667"));
72         _vpu->add (4.1667 - 0.1, _("4.1667 - 0.1%"));
73         _vpu->add (0.1, _("0.1"));
74         _vpu->add (0, _("none"));
75         _vpu->add (-0.1, _("-0.1"));
76         _vpu->add (-4.1667 + 0.1, _("-4.1667 + 0.1%"));
77         _vpu->add (-4.1667, _("-4.1667"));
78         _vpu->add (-4.1667 - 0.1, _("-4.1667 - 0.1%"));
79
80         add_option (_("Timecode"), _vpu);
81         add_option (_("Timecode"), new OptionEditorHeading (_("Ext Timecode Offsets")));
82
83         ClockOption* sco = new ClockOption (
84                 "slave-timecode-offset",
85                 _("Slave Timecode offset"),
86                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_slave_timecode_offset),
87                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_slave_timecode_offset)
88                 );
89
90         sco->set_session (_session);
91         sco->clock().set_negative_allowed (true);
92         Gtkmm2ext::UI::instance()->set_tip (sco->tip_widget(), _("The specified offset is added to the received timecode (MTC or LTC)."));
93
94         add_option (_("Timecode"), sco);
95
96         ClockOption* gco = new ClockOption (
97                 "timecode-generator-offset",
98                 _("Timecode Generator offset"),
99                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_timecode_generator_offset),
100                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_timecode_generator_offset)
101                 );
102
103         gco->set_session (_session);
104         gco->clock().set_negative_allowed (true);
105         Gtkmm2ext::UI::instance()->set_tip (gco->tip_widget(), _("Specify an offset which is added to the generated timecode (so far only LTC)."));
106
107         add_option (_("Timecode"), gco);
108
109         add_option (_("Timecode"), new OptionEditorHeading (_("JACK Transport/Time Settings")));
110
111         add_option (_("Timecode"), new BoolOption (
112                             "jack-time-master",
113                             string_compose (_("%1 is JACK Time Master (provides Bar|Beat|Tick and other information to JACK)"), PROGRAM_NAME),
114                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_jack_time_master),
115                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_jack_time_master)
116                             ));
117
118         /* Sync */
119
120         add_option (_("Sync"), new OptionEditorHeading (_("A/V Synchronization")));
121         add_option (_("Sync"), new BoolOption (
122                             "use-video-file-fps",
123                             _("Use Video File's FPS Instead of Timecode Value for Timeline and Video Monitor."),
124                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_use_video_file_fps),
125                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_use_video_file_fps)
126                             ));
127
128         add_option (_("Sync"), new BoolOption (
129                             "videotimeline-pullup",
130                             _("Apply Pull-Up/Down to Video Timeline and Video Monitor (Unless using JACK-sync)."),
131                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_videotimeline_pullup),
132                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_videotimeline_pullup)
133                             ));
134
135         add_option (_("Sync"), new OptionEditorBlank ());
136
137         /* FADES */
138
139         add_option (_("Fades"), new OptionEditorHeading (_("Audio Fades")));
140         add_option (_("Fades"), new SpinOption<float> (
141                 _("destructive-xfade-seconds"),
142                 _("Destructive crossfade length"),
143                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_destructive_xfade_msecs),
144                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_destructive_xfade_msecs),
145                 0, 1000, 1, 10,
146                 _("ms")
147                             ));
148
149         add_option (_("Fades"), new BoolOption (
150                             "use-transport-fades",
151                             _("Declick when transport starts and stops"),
152                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_use_transport_fades),
153                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_use_transport_fades)
154                             ));
155
156         add_option (_("Fades"), new BoolOption (
157                             "use-monitor-fades",
158                             _("Declick when monitor state changes"),
159                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_use_monitor_fades),
160                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_use_monitor_fades)
161                             ));
162
163         add_option (_("Fades"), new BoolOption (
164                             "use-region-fades",
165                             _("Region fades active"),
166                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_use_region_fades),
167                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_use_region_fades)
168                             ));
169
170         add_option (_("Fades"), new BoolOption (
171                             "show-region-fades",
172                             _("Region fades visible"),
173                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_show_region_fades),
174                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_show_region_fades)
175                             ));
176
177         /* Media */
178
179         add_option (_("Media"), new OptionEditorHeading (_("Audio File Format")));
180
181         ComboOption<SampleFormat>* sf = new ComboOption<SampleFormat> (
182                 "native-file-data-format",
183                 _("Sample format"),
184                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_native_file_data_format),
185                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_native_file_data_format)
186                 );
187
188         sf->add (FormatFloat, _("32-bit floating point"));
189         sf->add (FormatInt24, _("24-bit integer"));
190         sf->add (FormatInt16, _("16-bit integer"));
191
192         add_option (_("Media"), sf);
193
194         ComboOption<HeaderFormat>* hf = new ComboOption<HeaderFormat> (
195                 "native-file-header-format",
196                 _("File type"),
197                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_native_file_header_format),
198                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_native_file_header_format)
199                 );
200
201         hf->add (BWF, _("Broadcast WAVE (4GB size limit)"));
202 #ifdef HAVE_RF64_RIFF
203         hf->add (MBWF, _("Broadcast RF64"));
204 #endif
205         hf->add (WAVE, _("WAVE (4GB size limit)"));
206         hf->add (WAVE64, _("WAVE-64"));
207         hf->add (CAF, _("CAF"));
208         hf->add (RF64, _("RF64"));
209 #ifdef HAVE_RF64_RIFF
210         hf->add (RF64_WAV, _("RF64 (WAV compatible)"));
211 #endif
212
213         add_option (_("Media"), hf);
214
215         add_option (S_("Files|Locations"), new OptionEditorHeading (_("File Locations")));
216
217         SearchPathOption* spo = new SearchPathOption ("audio-search-path", _("Search for audio files in:"),
218                         _session->path(),
219                         sigc::mem_fun (*_session_config, &SessionConfiguration::get_audio_search_path),
220                         sigc::mem_fun (*_session_config, &SessionConfiguration::set_audio_search_path));
221         add_option (S_("Files|Locations"), spo);
222
223         spo = new SearchPathOption ("midi-search-path", _("Search for MIDI files in:"),
224                         _session->path(),
225                         sigc::mem_fun (*_session_config, &SessionConfiguration::get_midi_search_path),
226                         sigc::mem_fun (*_session_config, &SessionConfiguration::set_midi_search_path));
227
228         add_option (S_("Files|Locations"), spo);
229
230         /* File Naming  */
231
232         add_option (_("Filenames"), new OptionEditorHeading (_("File Naming")));
233
234         BoolOption *bo;
235
236         bo = new RouteDisplayBoolOption (
237                         "track-name-number",
238                         _("Prefix Track number"),
239                         sigc::mem_fun (*_session_config, &SessionConfiguration::get_track_name_number),
240                         sigc::mem_fun (*_session_config, &SessionConfiguration::set_track_name_number)
241                         );
242         Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
243                         _("Adds the current track number to the beginning of the recorded file name."));
244         add_option (_("Filenames"), bo);
245
246         bo = new BoolOption (
247                         "track-name-take",
248                         _("Prefix Take Name"),
249                         sigc::mem_fun (*_session_config, &SessionConfiguration::get_track_name_take),
250                         sigc::mem_fun (*_session_config, &SessionConfiguration::set_track_name_take)
251                         );
252         Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
253                         _("Adds the Take Name to the beginning of the recorded file name."));
254         add_option (_("Filenames"), bo);
255
256         _take_name = new EntryOption (
257                 "take-name",
258                 _("Take Name"),
259                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_take_name),
260                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_take_name)
261                 );
262         _take_name->set_invalid_chars(".");
263         _take_name->set_sensitive(_session_config->get_track_name_take());
264
265         add_option (_("Filenames"), _take_name);
266
267         /* Monitoring */
268
269         add_option (_("Monitoring"), new OptionEditorHeading (_("Monitoring")));
270         add_option (_("Monitoring"), new BoolOption (
271                                 "auto-input",
272                                 _("Track Input Monitoring automatically follows transport state (\"auto-input\")"),
273                                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_auto_input),
274                                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_auto_input)
275                                 ));
276
277         add_option (_("Monitoring"), new BoolOption (
278                                 "have-monitor-section",
279                                 _("Use monitor section in this session"),
280                                 sigc::mem_fun (*this, &SessionOptionEditor::get_use_monitor_section),
281                                 sigc::mem_fun (*this, &SessionOptionEditor::set_use_monitor_section)
282                                 ));
283
284         add_option (_("Monitoring"), new OptionEditorBlank ());
285
286         /* Meterbridge */
287         add_option (_("Meterbridge"), new OptionEditorHeading (_("Route Display")));
288
289         add_option (_("Meterbridge"), new BoolOption (
290                             "show-midi-on-meterbridge",
291                             _("Show Midi Tracks"),
292                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_show_midi_on_meterbridge),
293                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_show_midi_on_meterbridge)
294                             ));
295
296         add_option (_("Meterbridge"), new BoolOption (
297                             "show-busses-on-meterbridge",
298                             _("Show Busses"),
299                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_show_busses_on_meterbridge),
300                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_show_busses_on_meterbridge)
301                             ));
302
303         add_option (_("Meterbridge"), new BoolOption (
304                             "show-master-on-meterbridge",
305                             _("Include Master Bus"),
306                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_show_master_on_meterbridge),
307                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_show_master_on_meterbridge)
308                             ));
309
310         add_option (_("Meterbridge"), new OptionEditorHeading (_("Button Area")));
311
312         add_option (_("Meterbridge"), new BoolOption (
313                             "show-rec-on-meterbridge",
314                             _("Rec-enable Button"),
315                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_show_rec_on_meterbridge),
316                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_show_rec_on_meterbridge)
317                             ));
318
319         add_option (_("Meterbridge"), new BoolOption (
320                             "show-mute-on-meterbridge",
321                             _("Mute Button"),
322                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_show_mute_on_meterbridge),
323                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_show_mute_on_meterbridge)
324                             ));
325
326         add_option (_("Meterbridge"), new BoolOption (
327                             "show-solo-on-meterbridge",
328                             _("Solo Button"),
329                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_show_solo_on_meterbridge),
330                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_show_solo_on_meterbridge)
331                             ));
332
333         add_option (_("Meterbridge"), new BoolOption (
334                             "show-monitor-on-meterbridge",
335                             _("Monitor Buttons"),
336                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_show_monitor_on_meterbridge),
337                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_show_monitor_on_meterbridge)
338                             ));
339
340         add_option (_("Meterbridge"), new OptionEditorHeading (_("Name Labels")));
341
342         add_option (_("Meterbridge"), new BoolOption (
343                             "show-name-on-meterbridge",
344                             _("Track Name"),
345                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_show_name_on_meterbridge),
346                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_show_name_on_meterbridge)
347                             ));
348
349         add_option (_("Meterbridge"), new OptionEditorBlank ());
350
351         /* Misc */
352
353         add_option (_("Misc"), new OptionEditorHeading (_("MIDI Options")));
354
355         add_option (_("Misc"), new BoolOption (
356                                 "midi-copy-is-fork",
357                                 _("MIDI region copies are independent"),
358                                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_midi_copy_is_fork),
359                                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_midi_copy_is_fork)
360                                 ));
361
362         ComboOption<InsertMergePolicy>* li = new ComboOption<InsertMergePolicy> (
363                         "insert-merge-policy",
364                         _("Policy for handling overlapping notes\n on the same MIDI channel"),
365                         sigc::mem_fun (*_session_config, &SessionConfiguration::get_insert_merge_policy),
366                         sigc::mem_fun (*_session_config, &SessionConfiguration::set_insert_merge_policy)
367                         );
368
369         li->add (InsertMergeReject, _("never allow them"));
370         li->add (InsertMergeRelax, _("don't do anything in particular"));
371         li->add (InsertMergeReplace, _("replace any overlapped existing note"));
372         li->add (InsertMergeTruncateExisting, _("shorten the overlapped existing note"));
373         li->add (InsertMergeTruncateAddition, _("shorten the overlapping new note"));
374         li->add (InsertMergeExtend, _("replace both overlapping notes with a single note"));
375
376         add_option (_("Misc"), li);
377
378         add_option (_("Misc"), new OptionEditorHeading (_("Glue to Bars and Beats")));
379
380         add_option (_("Misc"), new BoolOption (
381                                 "glue-new-markers-to-bars-and-beats",
382                                 _("Glue new markers to bars and beats"),
383                                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_glue_new_markers_to_bars_and_beats),
384                                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_glue_new_markers_to_bars_and_beats)
385                                 ));
386
387         add_option (_("Misc"), new BoolOption (
388                                 "glue-new-regions-to-bars-and-beats",
389                                 _("Glue new regions to bars and beats"),
390                                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_glue_new_regions_to_bars_and_beats),
391                                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_glue_new_regions_to_bars_and_beats)
392                                 ));
393
394         add_option (_("Misc"), new OptionEditorHeading (_("Metronome")));
395
396         add_option (_("Misc"), new BoolOption (
397                                 "count-in",
398                                 _("Count in before recording"),
399                                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_count_in),
400                                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_count_in)
401                                 ));
402
403         add_option (_("Misc"), new OptionEditorHeading (_("Defaults")));
404
405         Gtk::Button* btn = Gtk::manage (new Gtk::Button (_("Use these settings as defaults")));
406         btn->signal_clicked().connect (sigc::mem_fun (*this, &SessionOptionEditor::save_defaults));
407         add_option (_("Misc"), new FooOption (btn));
408
409         set_current_page (_("Timecode"));
410 }
411
412 void
413 SessionOptionEditor::parameter_changed (std::string const & p)
414 {
415         OptionEditor::parameter_changed (p);
416         if (p == "external-sync") {
417                 if (Config->get_sync_source() == Engine) {
418                         _vpu->set_sensitive(!_session_config->get_external_sync());
419                 } else {
420                         _vpu->set_sensitive(true);
421                 }
422         }
423         else if (p == "timecode-format") {
424                 /* update offset clocks */
425                 parameter_changed("timecode-generator-offset");
426                 parameter_changed("slave-timecode-offset");
427         }
428         else if (p == "track-name-take") {
429                 _take_name->set_sensitive(_session_config->get_track_name_take());
430         }
431 }
432
433 /* the presence of absence of a monitor section is not really a regular session
434  * property so we provide these two functions to act as setter/getter slots
435  */
436
437 bool
438 SessionOptionEditor::set_use_monitor_section (bool yn)
439 {
440         bool had_monitor_section = _session->monitor_out() != 0;
441
442         if (yn) {
443                 _session->add_monitor_section ();
444         } else {
445                 _session->remove_monitor_section ();
446         }
447
448         /* store this choice for any new sessions */
449
450         Config->set_use_monitor_bus (yn);
451
452         return had_monitor_section != (_session->monitor_out() != 0);
453 }
454
455 bool
456 SessionOptionEditor::get_use_monitor_section ()
457 {
458         return _session->monitor_out() != 0;
459 }
460
461 void
462 SessionOptionEditor::save_defaults ()
463 {
464         _session->save_default_options();
465 }