make text to describe timecode-source-is-synced option hopelessly more verbose
[ardour.git] / gtk2_ardour / session_option_editor.cc
1 #include "ardour/session.h"
2 #include "ardour/io.h"
3 #include "ardour/auditioner.h"
4 #include "ardour/audioengine.h"
5 #include "ardour/port.h"
6 #include "session_option_editor.h"
7 #include "port_matrix.h"
8 #include "i18n.h"
9
10 using namespace std;
11 using namespace sigc;
12 using namespace ARDOUR;
13
14 class OptionsPortMatrix : public PortMatrix
15 {
16 public:
17         OptionsPortMatrix (Gtk::Window* parent, ARDOUR::Session& session)
18                 : PortMatrix (parent, session, DataType::AUDIO)
19         {
20                 _port_group.reset (new PortGroup (""));
21                 _ports[OURS].add_group (_port_group);
22
23                 setup_all_ports ();
24                 init ();
25         }
26
27         void setup_ports (int dim)
28         {
29                 cerr << _session.the_auditioner()->output()->n_ports() << "\n";
30
31                 if (dim == OURS) {
32                         _port_group->clear ();
33                         _port_group->add_bundle (_session.click_io()->bundle());
34                         _port_group->add_bundle (_session.the_auditioner()->output()->bundle());
35                 } else {
36                         _ports[OTHER].gather (_session, true, false);
37                 }
38         }
39
40         void set_state (ARDOUR::BundleChannel c[2], bool s)
41         {
42                 Bundle::PortList const & our_ports = c[OURS].bundle->channel_ports (c[OURS].channel);
43                 Bundle::PortList const & other_ports = c[OTHER].bundle->channel_ports (c[OTHER].channel);
44
45                 if (c[OURS].bundle == _session.click_io()->bundle()) {
46
47                         for (ARDOUR::Bundle::PortList::const_iterator i = our_ports.begin(); i != our_ports.end(); ++i) {
48                                 for (ARDOUR::Bundle::PortList::const_iterator j = other_ports.begin(); j != other_ports.end(); ++j) {
49
50                                         Port* f = _session.engine().get_port_by_name (*i);
51                                         assert (f);
52
53                                         if (s) {
54                                                 _session.click_io()->connect (f, *j, 0);
55                                         } else {
56                                                 _session.click_io()->disconnect (f, *j, 0);
57                                         }
58                                 }
59                         }
60                 }
61         }
62
63         PortMatrixNode::State get_state (ARDOUR::BundleChannel c[2]) const
64         {
65                 Bundle::PortList const & our_ports = c[OURS].bundle->channel_ports (c[OURS].channel);
66                 Bundle::PortList const & other_ports = c[OTHER].bundle->channel_ports (c[OTHER].channel);
67
68                 if (c[OURS].bundle == _session.click_io()->bundle()) {
69
70                         for (ARDOUR::Bundle::PortList::const_iterator i = our_ports.begin(); i != our_ports.end(); ++i) {
71                                 for (ARDOUR::Bundle::PortList::const_iterator j = other_ports.begin(); j != other_ports.end(); ++j) {
72                                         Port* f = _session.engine().get_port_by_name (*i);
73                                         assert (f);
74
75                                         if (f->connected_to (*j)) {
76                                                 return PortMatrixNode::ASSOCIATED;
77                                         } else {
78                                                 return PortMatrixNode::NOT_ASSOCIATED;
79                                         }
80                                 }
81                         }
82
83                 } else {
84
85                         /* XXX */
86
87                 }
88
89                 return PortMatrixNode::NOT_ASSOCIATED;
90         }
91
92         bool list_is_global (int dim) const {
93                 return (dim == OTHER);
94         }
95
96         bool can_remove_channels (boost::shared_ptr<Bundle>) const {
97                 return false;
98         }
99
100         void remove_channel (ARDOUR::BundleChannel) {}
101
102         std::string disassociation_verb () const {
103                 return _("Disassociate");
104         }
105
106 private:
107         /* see PortMatrix: signal flow from 0 to 1 (out to in) */
108         enum {
109                 OURS = 0,
110                 OTHER = 1,
111         };
112
113         boost::shared_ptr<PortGroup> _port_group;
114
115 };
116
117
118 class ConnectionOptions : public OptionEditorBox
119 {
120 public:
121         ConnectionOptions (Gtk::Window* parent, ARDOUR::Session* s)
122                 : _port_matrix (parent, *s)
123         {
124                 _box->pack_start (_port_matrix);
125         }
126
127         void parameter_changed (string const &)
128         {
129
130         }
131
132         void set_state_from_config ()
133         {
134
135         }
136
137 private:
138         OptionsPortMatrix _port_matrix;
139 };
140
141 SessionOptionEditor::SessionOptionEditor (Session* s)
142         : OptionEditor (&(s->config), _("Session Preferences"))
143         , _session_config (&(s->config))
144 {
145         /* SYNC */
146
147         ComboOption<uint32_t>* spf = new ComboOption<uint32_t> (
148                 "subframes-per-frame",
149                 _("Subframes per frame"),
150                 mem_fun (*_session_config, &SessionConfiguration::get_subframes_per_frame),
151                 mem_fun (*_session_config, &SessionConfiguration::set_subframes_per_frame)
152                 );
153
154         spf->add (80, _("80"));
155         spf->add (100, _("100"));
156
157         add_option (_("Sync"), spf);
158
159         ComboOption<SyncSource>* ssrc = new ComboOption<SyncSource> (
160                 "sync-source",
161                 _("External sync source"),
162                 mem_fun (*_session_config, &SessionConfiguration::get_sync_source),
163                 mem_fun (*_session_config, &SessionConfiguration::set_sync_source)
164                 );
165         
166         s->MTC_PortChanged.connect (bind (mem_fun (*this, &SessionOptionEditor::populate_sync_options), s, ssrc));
167         s->MIDIClock_PortChanged.connect (bind (mem_fun (*this, &SessionOptionEditor::populate_sync_options), s, ssrc));
168         s->config.ParameterChanged.connect (bind (mem_fun (*this, &SessionOptionEditor::follow_sync_state), s, ssrc));
169
170         populate_sync_options (s, ssrc);
171         follow_sync_state (string ("external-sync"), s, ssrc);
172
173         add_option (_("Sync"), ssrc);
174
175         ComboOption<TimecodeFormat>* smf = new ComboOption<TimecodeFormat> (
176                 "timecode-format",
177                 _("Timecode frames-per-second"),
178                 mem_fun (*_session_config, &SessionConfiguration::get_timecode_format),
179                 mem_fun (*_session_config, &SessionConfiguration::set_timecode_format)
180                 );
181
182         smf->add (timecode_23976, _("23.976"));
183         smf->add (timecode_24, _("24"));
184         smf->add (timecode_24976, _("24.976"));
185         smf->add (timecode_25, _("25"));
186         smf->add (timecode_2997, _("29.97"));
187         smf->add (timecode_2997drop, _("29.97 drop"));
188         smf->add (timecode_30, _("30"));
189         smf->add (timecode_30drop, _("30 drop"));
190         smf->add (timecode_5994, _("59.94"));
191         smf->add (timecode_60, _("60"));
192
193         add_option (_("Sync"), smf);
194
195         add_option (_("Sync"), new BoolOption (
196                             "timecode-source-is-synced",
197                             _("Timecode source shares sample clock with audio interface"),
198                             mem_fun (*_session_config, &SessionConfiguration::get_timecode_source_is_synced),
199                             mem_fun (*_session_config, &SessionConfiguration::set_timecode_source_is_synced)
200                             ));
201
202         ComboOption<float>* vpu = new ComboOption<float> (
203                 "video-pullup",
204                 _("Pull-up / pull-down"),
205                 mem_fun (*_session_config, &SessionConfiguration::get_video_pullup),
206                 mem_fun (*_session_config, &SessionConfiguration::set_video_pullup)
207                 );
208
209         vpu->add (4.1667 + 0.1, _("4.1667 + 0.1%"));
210         vpu->add (4.1667, _("4.1667"));
211         vpu->add (4.1667 - 0.1, _("4.1667 - 0.1%"));
212         vpu->add (0.1, _("0.1"));
213         vpu->add (0, _("none"));
214         vpu->add (-0.1, _("-0.1"));
215         vpu->add (-4.1667 + 0.1, _("-4.1667 + 0.1%"));
216         vpu->add (-4.1667, _("-4.1667"));
217         vpu->add (-4.1667 - 0.1, _("-4.1667 - 0.1%"));
218
219         add_option (_("Sync"), vpu);
220
221         /* FADES */
222
223         ComboOption<CrossfadeModel>* cfm = new ComboOption<CrossfadeModel> (
224                 "xfade-model",
225                 _("Crossfades are created"),
226                 mem_fun (*_session_config, &SessionConfiguration::get_xfade_model),
227                 mem_fun (*_session_config, &SessionConfiguration::set_xfade_model)
228                 );
229
230         cfm->add (FullCrossfade, _("to span entire overlap"));
231         cfm->add (ShortCrossfade, _("short"));
232
233         add_option (_("Fades"), cfm);
234
235         add_option (_("Fades"), new SpinOption<float> (
236                 _("short-xfade-seconds"),
237                 _("Short crossfade length"),
238                 mem_fun (*_session_config, &SessionConfiguration::get_short_xfade_seconds),
239                 mem_fun (*_session_config, &SessionConfiguration::set_short_xfade_seconds),
240                 0, 1000, 1, 10,
241                 _("ms"), 0.001
242                             ));
243
244         add_option (_("Fades"), new SpinOption<float> (
245                 _("destructive-xfade-seconds"),
246                 _("Destructive crossfade length"),
247                 mem_fun (*_session_config, &SessionConfiguration::get_destructive_xfade_msecs),
248                 mem_fun (*_session_config, &SessionConfiguration::set_destructive_xfade_msecs),
249                 0, 1000, 1, 10,
250                 _("ms")
251                             ));
252
253         add_option (_("Fades"), new BoolOption (
254                             "auto-xfade",
255                             _("Create crossfades automatically"),
256                             mem_fun (*_session_config, &SessionConfiguration::get_auto_xfade),
257                             mem_fun (*_session_config, &SessionConfiguration::set_auto_xfade)
258                             ));
259
260         add_option (_("Fades"), new BoolOption (
261                             "xfades-active",
262                             _("Crossfades active"),
263                             mem_fun (*_session_config, &SessionConfiguration::get_xfades_active),
264                             mem_fun (*_session_config, &SessionConfiguration::set_xfades_active)
265                             ));
266
267         add_option (_("Fades"), new BoolOption (
268                             "xfades-visible",
269                             _("Crossfades visible"),
270                             mem_fun (*_session_config, &SessionConfiguration::get_xfades_visible),
271                             mem_fun (*_session_config, &SessionConfiguration::set_xfades_visible)
272                             ));
273
274         add_option (_("Fades"), new BoolOption (
275                             "use-region-fades",
276                             _("Region fades active"),
277                             mem_fun (*_session_config, &SessionConfiguration::get_use_region_fades),
278                             mem_fun (*_session_config, &SessionConfiguration::set_use_region_fades)
279                             ));
280
281         add_option (_("Fades"), new BoolOption (
282                             "show-region-fades",
283                             _("Region fades visible"),
284                             mem_fun (*_session_config, &SessionConfiguration::get_show_region_fades),
285                             mem_fun (*_session_config, &SessionConfiguration::set_show_region_fades)
286                             ));
287
288         /* MISC */
289
290         add_option (_("Misc"), new OptionEditorHeading (_("Audio file format")));
291
292         ComboOption<SampleFormat>* sf = new ComboOption<SampleFormat> (
293                 "native-file-data-format",
294                 _("Sample format"),
295                 mem_fun (*_session_config, &SessionConfiguration::get_native_file_data_format),
296                 mem_fun (*_session_config, &SessionConfiguration::set_native_file_data_format)
297                 );
298
299         sf->add (FormatFloat, _("32-bit floating point"));
300         sf->add (FormatInt24, _("24-bit integer"));
301         sf->add (FormatInt16, _("16-bit integer"));
302
303         add_option (_("Misc"), sf);
304
305         ComboOption<HeaderFormat>* hf = new ComboOption<HeaderFormat> (
306                 "native-file-header-format",
307                 _("File type"),
308                 mem_fun (*_session_config, &SessionConfiguration::get_native_file_header_format),
309                 mem_fun (*_session_config, &SessionConfiguration::set_native_file_header_format)
310                 );
311
312         hf->add (BWF, _("Broadcast WAVE"));
313         hf->add (WAVE, _("WAVE"));
314         hf->add (WAVE64, _("WAVE-64"));
315         hf->add (CAF, _("CAF"));
316
317         add_option (_("Misc"), hf);
318
319         add_option (_("Misc"), new OptionEditorHeading (_("Layering")));
320
321         ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
322                 "layer-model",
323                 _("Layering model in overlaid mode"),
324                 mem_fun (*_session_config, &SessionConfiguration::get_layer_model),
325                 mem_fun (*_session_config, &SessionConfiguration::set_layer_model)
326                 );
327
328         lm->add (LaterHigher, _("later is higher"));
329         lm->add (MoveAddHigher, _("most recently moved or added is higher"));
330         lm->add (AddHigher, _("most recently added is higher"));
331
332         add_option (_("Misc"), lm);
333
334         add_option (_("Misc"), new OptionEditorHeading (_("Broadcast WAVE metadata")));
335
336         add_option (_("Misc"), new EntryOption (
337                             "bwf-country-code",
338                             _("Country code"),
339                             mem_fun (*_session_config, &SessionConfiguration::get_bwf_country_code),
340                             mem_fun (*_session_config, &SessionConfiguration::set_bwf_country_code)
341                             ));
342
343         add_option (_("Misc"), new EntryOption (
344                             "bwf-organization-code",
345                             _("Organization code"),
346                             mem_fun (*_session_config, &SessionConfiguration::get_bwf_organization_code),
347                             mem_fun (*_session_config, &SessionConfiguration::set_bwf_organization_code)
348                             ));
349
350         add_option (_("Connections"), new ConnectionOptions (this, s));
351 }
352
353 void
354 SessionOptionEditor::populate_sync_options (Session* s, Option* opt)
355 {
356         ComboOption<SyncSource>* sync_opt = dynamic_cast<ComboOption<SyncSource>* > (opt);
357
358         vector<SyncSource> sync_opts = s->get_available_sync_options ();
359
360         sync_opt->clear ();
361
362         for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
363                 sync_opt->add (*i, sync_source_to_string (*i));
364         }
365 }
366
367 void
368 SessionOptionEditor::follow_sync_state (std::string p, Session* s, Option* opt)
369 {
370         ComboOption<SyncSource>* sync_opt = dynamic_cast<ComboOption<SyncSource>* > (opt);
371         if (p == "external-sync") {
372                 if (s->config.get_external_sync()) {
373                         sync_opt->set_sensitive (false);
374                 } else {
375                         sync_opt->set_sensitive (true);
376                 }
377         }
378 }