1 #include "ardour/session.h"
3 #include "ardour/auditioner.h"
4 #include "ardour/audioengine.h"
5 #include "ardour/port.h"
7 #include "gui_thread.h"
8 #include "session_option_editor.h"
9 #include "port_matrix.h"
13 using namespace ARDOUR
;
15 class OptionsPortMatrix
: public PortMatrix
18 OptionsPortMatrix (Gtk::Window
* parent
, ARDOUR::Session
* session
)
19 : PortMatrix (parent
, session
, DataType::AUDIO
)
21 _port_group
.reset (new PortGroup (""));
22 _ports
[OURS
].add_group (_port_group
);
28 void setup_ports (int dim
)
31 _port_group
->clear ();
32 _port_group
->add_bundle (_session
->click_io()->bundle());
33 _port_group
->add_bundle (_session
->the_auditioner()->output()->bundle());
35 _ports
[OTHER
].gather (_session
, true, false);
39 void set_state (ARDOUR::BundleChannel c
[2], bool s
)
41 Bundle::PortList
const & our_ports
= c
[OURS
].bundle
->channel_ports (c
[OURS
].channel
);
42 Bundle::PortList
const & other_ports
= c
[OTHER
].bundle
->channel_ports (c
[OTHER
].channel
);
44 if (c
[OURS
].bundle
== _session
->click_io()->bundle()) {
46 for (ARDOUR::Bundle::PortList::const_iterator i
= our_ports
.begin(); i
!= our_ports
.end(); ++i
) {
47 for (ARDOUR::Bundle::PortList::const_iterator j
= other_ports
.begin(); j
!= other_ports
.end(); ++j
) {
49 Port
* f
= _session
->engine().get_port_by_name (*i
);
53 _session
->click_io()->connect (f
, *j
, 0);
55 _session
->click_io()->disconnect (f
, *j
, 0);
62 PortMatrixNode::State
get_state (ARDOUR::BundleChannel c
[2]) const
64 Bundle::PortList
const & our_ports
= c
[OURS
].bundle
->channel_ports (c
[OURS
].channel
);
65 Bundle::PortList
const & other_ports
= c
[OTHER
].bundle
->channel_ports (c
[OTHER
].channel
);
67 if (c
[OURS
].bundle
== _session
->click_io()->bundle()) {
69 for (ARDOUR::Bundle::PortList::const_iterator i
= our_ports
.begin(); i
!= our_ports
.end(); ++i
) {
70 for (ARDOUR::Bundle::PortList::const_iterator j
= other_ports
.begin(); j
!= other_ports
.end(); ++j
) {
71 Port
* f
= _session
->engine().get_port_by_name (*i
);
74 if (f
->connected_to (*j
)) {
75 return PortMatrixNode::ASSOCIATED
;
77 return PortMatrixNode::NOT_ASSOCIATED
;
88 return PortMatrixNode::NOT_ASSOCIATED
;
91 bool list_is_global (int dim
) const {
92 return (dim
== OTHER
);
95 bool can_remove_channels (boost::shared_ptr
<Bundle
>) const {
99 void remove_channel (ARDOUR::BundleChannel
) {}
101 std::string
disassociation_verb () const {
102 return _("Disassociate");
106 /* see PortMatrix: signal flow from 0 to 1 (out to in) */
112 boost::shared_ptr
<PortGroup
> _port_group
;
117 class ConnectionOptions
: public OptionEditorBox
120 ConnectionOptions (Gtk::Window
* parent
, ARDOUR::Session
* s
)
121 : _port_matrix (parent
, s
)
123 _box
->pack_start (_port_matrix
);
126 void parameter_changed (string
const &)
131 void set_state_from_config ()
137 OptionsPortMatrix _port_matrix
;
140 SessionOptionEditor::SessionOptionEditor (Session
* s
)
141 : OptionEditor (&(s
->config
), _("Session Properties"))
142 , _session_config (&(s
->config
))
144 set_name ("SessionProperties");
148 ComboOption
<uint32_t>* spf
= new ComboOption
<uint32_t> (
149 "subframes-per-frame",
150 _("Subframes per frame"),
151 sigc::mem_fun (*_session_config
, &SessionConfiguration::get_subframes_per_frame
),
152 sigc::mem_fun (*_session_config
, &SessionConfiguration::set_subframes_per_frame
)
155 spf
->add (80, _("80"));
156 spf
->add (100, _("100"));
158 add_option (_("Sync"), spf
);
160 ComboOption
<SyncSource
>* ssrc
= new ComboOption
<SyncSource
> (
162 _("External sync source"),
163 sigc::mem_fun (*_session_config
, &SessionConfiguration::get_sync_source
),
164 sigc::mem_fun (*_session_config
, &SessionConfiguration::set_sync_source
)
167 s
->MTC_PortChanged
.connect (_session_connections
, invalidator (*this), boost::bind (&SessionOptionEditor::populate_sync_options
, this, s
, ssrc
), gui_context());
168 s
->MIDIClock_PortChanged
.connect (_session_connections
, invalidator (*this), boost::bind (&SessionOptionEditor::populate_sync_options
, this, s
, ssrc
), gui_context());
169 s
->config
.ParameterChanged
.connect (_session_connections
, invalidator (*this), ui_bind (&SessionOptionEditor::follow_sync_state
, this, _1
, s
, ssrc
), gui_context());
171 populate_sync_options (s
, ssrc
);
172 follow_sync_state (string ("external-sync"), s
, ssrc
);
174 add_option (_("Sync"), ssrc
);
176 ComboOption
<TimecodeFormat
>* smf
= new ComboOption
<TimecodeFormat
> (
178 _("Timecode frames-per-second"),
179 sigc::mem_fun (*_session_config
, &SessionConfiguration::get_timecode_format
),
180 sigc::mem_fun (*_session_config
, &SessionConfiguration::set_timecode_format
)
183 smf
->add (timecode_23976
, _("23.976"));
184 smf
->add (timecode_24
, _("24"));
185 smf
->add (timecode_24976
, _("24.976"));
186 smf
->add (timecode_25
, _("25"));
187 smf
->add (timecode_2997
, _("29.97"));
188 smf
->add (timecode_2997drop
, _("29.97 drop"));
189 smf
->add (timecode_30
, _("30"));
190 smf
->add (timecode_30drop
, _("30 drop"));
191 smf
->add (timecode_5994
, _("59.94"));
192 smf
->add (timecode_60
, _("60"));
194 add_option (_("Sync"), smf
);
196 add_option (_("Sync"), new BoolOption (
197 "timecode-source-is-synced",
198 _("Timecode source shares sample clock with audio interface"),
199 sigc::mem_fun (*_session_config
, &SessionConfiguration::get_timecode_source_is_synced
),
200 sigc::mem_fun (*_session_config
, &SessionConfiguration::set_timecode_source_is_synced
)
203 ComboOption
<float>* vpu
= new ComboOption
<float> (
205 _("Pull-up / pull-down"),
206 sigc::mem_fun (*_session_config
, &SessionConfiguration::get_video_pullup
),
207 sigc::mem_fun (*_session_config
, &SessionConfiguration::set_video_pullup
)
210 vpu
->add (4.1667 + 0.1, _("4.1667 + 0.1%"));
211 vpu
->add (4.1667, _("4.1667"));
212 vpu
->add (4.1667 - 0.1, _("4.1667 - 0.1%"));
213 vpu
->add (0.1, _("0.1"));
214 vpu
->add (0, _("none"));
215 vpu
->add (-0.1, _("-0.1"));
216 vpu
->add (-4.1667 + 0.1, _("-4.1667 + 0.1%"));
217 vpu
->add (-4.1667, _("-4.1667"));
218 vpu
->add (-4.1667 - 0.1, _("-4.1667 - 0.1%"));
220 add_option (_("Sync"), vpu
);
224 ComboOption
<CrossfadeModel
>* cfm
= new ComboOption
<CrossfadeModel
> (
226 _("Crossfades are created"),
227 sigc::mem_fun (*_session_config
, &SessionConfiguration::get_xfade_model
),
228 sigc::mem_fun (*_session_config
, &SessionConfiguration::set_xfade_model
)
231 cfm
->add (FullCrossfade
, _("to span entire overlap"));
232 cfm
->add (ShortCrossfade
, _("short"));
234 add_option (_("Fades"), cfm
);
236 add_option (_("Fades"), new SpinOption
<float> (
237 _("short-xfade-seconds"),
238 _("Short crossfade length"),
239 sigc::mem_fun (*_session_config
, &SessionConfiguration::get_short_xfade_seconds
),
240 sigc::mem_fun (*_session_config
, &SessionConfiguration::set_short_xfade_seconds
),
245 add_option (_("Fades"), new SpinOption
<float> (
246 _("destructive-xfade-seconds"),
247 _("Destructive crossfade length"),
248 sigc::mem_fun (*_session_config
, &SessionConfiguration::get_destructive_xfade_msecs
),
249 sigc::mem_fun (*_session_config
, &SessionConfiguration::set_destructive_xfade_msecs
),
254 add_option (_("Fades"), new BoolOption (
256 _("Create crossfades automatically"),
257 sigc::mem_fun (*_session_config
, &SessionConfiguration::get_auto_xfade
),
258 sigc::mem_fun (*_session_config
, &SessionConfiguration::set_auto_xfade
)
261 add_option (_("Fades"), new BoolOption (
263 _("Crossfades active"),
264 sigc::mem_fun (*_session_config
, &SessionConfiguration::get_xfades_active
),
265 sigc::mem_fun (*_session_config
, &SessionConfiguration::set_xfades_active
)
268 add_option (_("Fades"), new BoolOption (
270 _("Crossfades visible"),
271 sigc::mem_fun (*_session_config
, &SessionConfiguration::get_xfades_visible
),
272 sigc::mem_fun (*_session_config
, &SessionConfiguration::set_xfades_visible
)
275 add_option (_("Fades"), new BoolOption (
277 _("Region fades active"),
278 sigc::mem_fun (*_session_config
, &SessionConfiguration::get_use_region_fades
),
279 sigc::mem_fun (*_session_config
, &SessionConfiguration::set_use_region_fades
)
282 add_option (_("Fades"), new BoolOption (
284 _("Region fades visible"),
285 sigc::mem_fun (*_session_config
, &SessionConfiguration::get_show_region_fades
),
286 sigc::mem_fun (*_session_config
, &SessionConfiguration::set_show_region_fades
)
291 add_option (_("Misc"), new OptionEditorHeading (_("Audio file format")));
293 ComboOption
<SampleFormat
>* sf
= new ComboOption
<SampleFormat
> (
294 "native-file-data-format",
296 sigc::mem_fun (*_session_config
, &SessionConfiguration::get_native_file_data_format
),
297 sigc::mem_fun (*_session_config
, &SessionConfiguration::set_native_file_data_format
)
300 sf
->add (FormatFloat
, _("32-bit floating point"));
301 sf
->add (FormatInt24
, _("24-bit integer"));
302 sf
->add (FormatInt16
, _("16-bit integer"));
304 add_option (_("Misc"), sf
);
306 ComboOption
<HeaderFormat
>* hf
= new ComboOption
<HeaderFormat
> (
307 "native-file-header-format",
309 sigc::mem_fun (*_session_config
, &SessionConfiguration::get_native_file_header_format
),
310 sigc::mem_fun (*_session_config
, &SessionConfiguration::set_native_file_header_format
)
313 hf
->add (BWF
, _("Broadcast WAVE"));
314 hf
->add (WAVE
, _("WAVE"));
315 hf
->add (WAVE64
, _("WAVE-64"));
316 hf
->add (CAF
, _("CAF"));
318 add_option (_("Misc"), hf
);
320 add_option (_("Misc"), new OptionEditorHeading (_("Layering")));
322 ComboOption
<LayerModel
>* lm
= new ComboOption
<LayerModel
> (
324 _("Layering model in overlaid mode"),
325 sigc::mem_fun (*_session_config
, &SessionConfiguration::get_layer_model
),
326 sigc::mem_fun (*_session_config
, &SessionConfiguration::set_layer_model
)
329 lm
->add (LaterHigher
, _("later is higher"));
330 lm
->add (MoveAddHigher
, _("most recently moved or added is higher"));
331 lm
->add (AddHigher
, _("most recently added is higher"));
333 add_option (_("Misc"), lm
);
335 add_option (_("Misc"), new OptionEditorHeading (_("MIDI Note Overlaps")));
337 ComboOption
<InsertMergePolicy
>* li
= new ComboOption
<InsertMergePolicy
> (
338 "insert-merge-policy",
339 _("Handle same note+channel overlaps by"),
340 sigc::mem_fun (*_session_config
, &SessionConfiguration::get_insert_merge_policy
),
341 sigc::mem_fun (*_session_config
, &SessionConfiguration::set_insert_merge_policy
)
344 li
->add (InsertMergeReject
, _("Never allowing them"));
345 li
->add (InsertMergeRelax
, _("Don't do anything in particular"));
346 li
->add (InsertMergeReplace
, _("Replace any overlapped existing note"));
347 li
->add (InsertMergeTruncateExisting
, _("Shorten the overlapped existing note"));
348 li
->add (InsertMergeTruncateAddition
, _("Shorten the overlapping new note"));
349 li
->add (InsertMergeExtend
, _("Replace both overlapping notes with a single note"));
351 add_option (_("Misc"), li
);
353 add_option (_("Misc"), new OptionEditorHeading (_("Broadcast WAVE metadata")));
355 add_option (_("Misc"), new EntryOption (
358 sigc::mem_fun (*_session_config
, &SessionConfiguration::get_bwf_country_code
),
359 sigc::mem_fun (*_session_config
, &SessionConfiguration::set_bwf_country_code
)
362 add_option (_("Misc"), new EntryOption (
363 "bwf-organization-code",
364 _("Organization code"),
365 sigc::mem_fun (*_session_config
, &SessionConfiguration::get_bwf_organization_code
),
366 sigc::mem_fun (*_session_config
, &SessionConfiguration::set_bwf_organization_code
)
369 add_option (_("Connections"), new ConnectionOptions (this, s
));
373 SessionOptionEditor::populate_sync_options (Session
* s
, Option
* opt
)
375 ComboOption
<SyncSource
>* sync_opt
= dynamic_cast<ComboOption
<SyncSource
>* > (opt
);
377 vector
<SyncSource
> sync_opts
= s
->get_available_sync_options ();
381 for (vector
<SyncSource
>::iterator i
= sync_opts
.begin(); i
!= sync_opts
.end(); ++i
) {
382 sync_opt
->add (*i
, sync_source_to_string (*i
));
387 SessionOptionEditor::follow_sync_state (std::string p
, Session
* s
, Option
* opt
)
389 ComboOption
<SyncSource
>* sync_opt
= dynamic_cast<ComboOption
<SyncSource
>* > (opt
);
390 if (p
== "external-sync") {
391 if (s
->config
.get_external_sync()) {
392 sync_opt
->set_sensitive (false);
394 sync_opt
->set_sensitive (true);