Re-expose timecode offset in the session option editor.
[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 #include "ardour/io.h"
22 #include "ardour/auditioner.h"
23 #include "ardour/audioengine.h"
24 #include "ardour/port.h"
25
26 #include "gui_thread.h"
27 #include "session_option_editor.h"
28 #include "search_path_option.h"
29 #include "i18n.h"
30
31 using namespace std;
32 using namespace ARDOUR;
33
34 SessionOptionEditor::SessionOptionEditor (Session* s)
35         : OptionEditor (&(s->config), _("Session Properties"))
36         , _session_config (&(s->config))
37 {
38         set_session (s);
39         
40         set_name ("SessionProperties");
41
42         /* SYNC */
43
44         ComboOption<uint32_t>* spf = new ComboOption<uint32_t> (
45                 "subframes-per-frame",
46                 _("Subframes per frame"),
47                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_subframes_per_frame),
48                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_subframes_per_frame)
49                 );
50
51         spf->add (80, _("80"));
52         spf->add (100, _("100"));
53
54         add_option (_("Sync"), spf);
55
56         ComboOption<SyncSource>* ssrc = new ComboOption<SyncSource> (
57                 "sync-source",
58                 _("External sync source"),
59                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_sync_source),
60                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_sync_source)
61                 );
62         
63         s->config.ParameterChanged.connect (_session_connections, invalidator (*this), ui_bind (&SessionOptionEditor::follow_sync_state, this, _1, s, ssrc), gui_context());
64
65         populate_sync_options (s, ssrc);
66         follow_sync_state (string ("external-sync"), s, ssrc);
67
68         add_option (_("Sync"), ssrc);
69
70         ComboOption<TimecodeFormat>* smf = new ComboOption<TimecodeFormat> (
71                 "timecode-format",
72                 _("Timecode frames-per-second"),
73                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_timecode_format),
74                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_timecode_format)
75                 );
76
77         smf->add (timecode_23976, _("23.976"));
78         smf->add (timecode_24, _("24"));
79         smf->add (timecode_24976, _("24.976"));
80         smf->add (timecode_25, _("25"));
81         smf->add (timecode_2997, _("29.97"));
82         smf->add (timecode_2997drop, _("29.97 drop"));
83         smf->add (timecode_30, _("30"));
84         smf->add (timecode_30drop, _("30 drop"));
85         smf->add (timecode_5994, _("59.94"));
86         smf->add (timecode_60, _("60"));
87
88         add_option (_("Sync"), smf);
89
90         add_option (_("Sync"), new BoolOption (
91                             "timecode-source-is-synced",
92                             _("Timecode source shares sample clock with audio interface"),
93                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_timecode_source_is_synced),
94                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_timecode_source_is_synced)
95                             ));
96
97         ComboOption<float>* vpu = new ComboOption<float> (
98                 "video-pullup",
99                 _("Pull-up / pull-down"),
100                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_video_pullup),
101                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_video_pullup)
102                 );
103
104         vpu->add (4.1667 + 0.1, _("4.1667 + 0.1%"));
105         vpu->add (4.1667, _("4.1667"));
106         vpu->add (4.1667 - 0.1, _("4.1667 - 0.1%"));
107         vpu->add (0.1, _("0.1"));
108         vpu->add (0, _("none"));
109         vpu->add (-0.1, _("-0.1"));
110         vpu->add (-4.1667 + 0.1, _("-4.1667 + 0.1%"));
111         vpu->add (-4.1667, _("-4.1667"));
112         vpu->add (-4.1667 - 0.1, _("-4.1667 - 0.1%"));
113
114         add_option (_("Sync"), vpu);
115
116         ClockOption* co = new ClockOption (
117                 "timecode-offset",
118                 _("Timecode Offset"),
119                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_timecode_offset),
120                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_timecode_offset)
121                 );
122
123         co->set_session (_session);
124         
125         add_option (_("Sync"), co);
126
127         add_option (_("Sync"), new BoolOption (
128                             "timecode-offset-negative",
129                             _("Timecode Offset Negative"),
130                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_timecode_offset_negative),
131                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_timecode_offset_negative)
132                             ));
133
134         /* FADES */
135
136         ComboOption<CrossfadeModel>* cfm = new ComboOption<CrossfadeModel> (
137                 "xfade-model",
138                 _("Crossfades are created"),
139                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_xfade_model),
140                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_xfade_model)
141                 );
142
143         cfm->add (FullCrossfade, _("to span entire overlap"));
144         cfm->add (ShortCrossfade, _("short"));
145
146         add_option (_("Fades"), cfm);
147
148         add_option (_("Fades"), new SpinOption<float> (
149                 _("short-xfade-seconds"),
150                 _("Short crossfade length"),
151                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_short_xfade_seconds),
152                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_short_xfade_seconds),
153                 0, 1000, 1, 10,
154                 _("ms"), 0.001
155                             ));
156
157         add_option (_("Fades"), new SpinOption<float> (
158                 _("destructive-xfade-seconds"),
159                 _("Destructive crossfade length"),
160                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_destructive_xfade_msecs),
161                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_destructive_xfade_msecs),
162                 0, 1000, 1, 10,
163                 _("ms")
164                             ));
165
166         add_option (_("Fades"), new BoolOption (
167                             "auto-xfade",
168                             _("Create crossfades automatically"),
169                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_auto_xfade),
170                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_auto_xfade)
171                             ));
172
173         add_option (_("Fades"), new BoolOption (
174                             "xfades-active",
175                             _("Crossfades active"),
176                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_xfades_active),
177                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_xfades_active)
178                             ));
179
180         add_option (_("Fades"), new BoolOption (
181                             "xfades-visible",
182                             _("Crossfades visible"),
183                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_xfades_visible),
184                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_xfades_visible)
185                             ));
186
187         add_option (_("Fades"), new BoolOption (
188                             "use-region-fades",
189                             _("Region fades active"),
190                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_use_region_fades),
191                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_use_region_fades)
192                             ));
193
194         add_option (_("Fades"), new BoolOption (
195                             "show-region-fades",
196                             _("Region fades visible"),
197                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_show_region_fades),
198                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_show_region_fades)
199                             ));
200
201         /* Media */
202
203         add_option (_("Media"), new OptionEditorHeading (_("Audio file format")));
204
205         ComboOption<SampleFormat>* sf = new ComboOption<SampleFormat> (
206                 "native-file-data-format",
207                 _("Sample format"),
208                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_native_file_data_format),
209                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_native_file_data_format)
210                 );
211
212         sf->add (FormatFloat, _("32-bit floating point"));
213         sf->add (FormatInt24, _("24-bit integer"));
214         sf->add (FormatInt16, _("16-bit integer"));
215
216         add_option (_("Media"), sf);
217
218         ComboOption<HeaderFormat>* hf = new ComboOption<HeaderFormat> (
219                 "native-file-header-format",
220                 _("File type"),
221                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_native_file_header_format),
222                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_native_file_header_format)
223                 );
224
225         hf->add (BWF, _("Broadcast WAVE"));
226         hf->add (WAVE, _("WAVE"));
227         hf->add (WAVE64, _("WAVE-64"));
228         hf->add (CAF, _("CAF"));
229
230         add_option (_("Media"), hf);
231         
232         add_option (_("Media"), new OptionEditorHeading (_("File locations")));
233
234         SearchPathOption* spo = new SearchPathOption ("audio-search-path", _("Search for audio files in:"),
235                                                       sigc::mem_fun (*_session_config, &SessionConfiguration::get_audio_search_path),
236                                                       sigc::mem_fun (*_session_config, &SessionConfiguration::set_audio_search_path));
237         add_option (_("Media"), spo);
238
239         spo = new SearchPathOption ("midi-search-path", _("Search for MIDI files in:"),
240                                     sigc::mem_fun (*_session_config, &SessionConfiguration::get_midi_search_path),
241                                     sigc::mem_fun (*_session_config, &SessionConfiguration::set_midi_search_path));
242
243         add_option (_("Media"), spo);
244
245         /* Misc */
246
247         add_option (_("Misc"), new OptionEditorHeading (_("Layering (in overlaid mode)")));
248
249         ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
250                 "layer-model",
251                 _("Layering model"),
252                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_layer_model),
253                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_layer_model)
254                 );
255
256         lm->add (LaterHigher, _("later is higher"));
257         lm->add (MoveAddHigher, _("most recently moved or added is higher"));
258         lm->add (AddHigher, _("most recently added is higher"));
259
260         add_option (_("Misc"), lm);
261
262         add_option (_("Misc"), new OptionEditorHeading (_("MIDI Note Overlaps")));
263
264         ComboOption<InsertMergePolicy>* li = new ComboOption<InsertMergePolicy> (
265                 "insert-merge-policy",
266                 _("Policy for handling same note\nand channel overlaps"),
267                 sigc::mem_fun (*_session_config, &SessionConfiguration::get_insert_merge_policy),
268                 sigc::mem_fun (*_session_config, &SessionConfiguration::set_insert_merge_policy)
269                 );
270
271         li->add (InsertMergeReject, _("never allow them"));
272         li->add (InsertMergeRelax, _("don't do anything in particular"));
273         li->add (InsertMergeReplace, _("replace any overlapped existing note"));
274         li->add (InsertMergeTruncateExisting, _("shorten the overlapped existing note"));
275         li->add (InsertMergeTruncateAddition, _("shorten the overlapping new note"));
276         li->add (InsertMergeExtend, _("replace both overlapping notes with a single note"));
277
278         add_option (_("Misc"), li);
279
280         add_option (_("Misc"), new OptionEditorHeading (_("Broadcast WAVE metadata")));
281
282         add_option (_("Misc"), new EntryOption (
283                             "bwf-country-code",
284                             _("Country code"),
285                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_bwf_country_code),
286                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_bwf_country_code)
287                             ));
288
289         add_option (_("Misc"), new EntryOption (
290                             "bwf-organization-code",
291                             _("Organization code"),
292                             sigc::mem_fun (*_session_config, &SessionConfiguration::get_bwf_organization_code),
293                             sigc::mem_fun (*_session_config, &SessionConfiguration::set_bwf_organization_code)
294                             ));
295 }
296
297 void
298 SessionOptionEditor::populate_sync_options (Session* s, Option* opt)
299 {
300         ComboOption<SyncSource>* sync_opt = dynamic_cast<ComboOption<SyncSource>* > (opt);
301
302         vector<SyncSource> sync_opts = s->get_available_sync_options ();
303
304         sync_opt->clear ();
305
306         for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
307                 sync_opt->add (*i, sync_source_to_string (*i));
308         }
309 }
310
311 void
312 SessionOptionEditor::follow_sync_state (std::string p, Session* s, Option* opt)
313 {
314         ComboOption<SyncSource>* sync_opt = dynamic_cast<ComboOption<SyncSource>* > (opt);
315         if (p == "external-sync") {
316                 if (s->config.get_external_sync()) {
317                         sync_opt->set_sensitive (false);
318                 } else {
319                         sync_opt->set_sensitive (true);
320                 }
321         }
322 }