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