Setup fixed ports for MIDI control data; hence remove configuration of those ports...
[ardour.git] / libs / ardour / session_state.cc
1 /*
2   Copyright (C) 1999-2002 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
21 #ifdef WAF_BUILD
22 #include "libardour-config.h"
23 #endif
24
25 #define __STDC_FORMAT_MACROS 1
26 #include <stdint.h>
27
28 #include <algorithm>
29 #include <fstream>
30 #include <string>
31 #include <cerrno>
32
33
34 #include <cstdio> /* snprintf(3) ... grrr */
35 #include <cmath>
36 #include <unistd.h>
37 #include <sys/stat.h>
38 #include <climits>
39 #include <fcntl.h>
40 #include <poll.h>
41 #include <signal.h>
42 #include <sys/mman.h>
43 #include <sys/time.h>
44 #include <dirent.h>
45
46 #ifdef HAVE_SYS_VFS_H
47 #include <sys/vfs.h>
48 #else
49 #include <sys/param.h>
50 #include <sys/mount.h>
51 #endif
52
53 #include <glibmm.h>
54 #include <glibmm/thread.h>
55
56 #include "midi++/mmc.h"
57 #include "midi++/port.h"
58 #include "midi++/manager.h"
59
60 #include "pbd/boost_debug.h"
61 #include "pbd/controllable_descriptor.h"
62 #include "pbd/enumwriter.h"
63 #include "pbd/error.h"
64 #include "pbd/pathscanner.h"
65 #include "pbd/pthread_utils.h"
66 #include "pbd/search_path.h"
67 #include "pbd/stacktrace.h"
68 #include "pbd/convert.h"
69
70 #include "ardour/amp.h"
71 #include "ardour/audio_diskstream.h"
72 #include "ardour/audio_track.h"
73 #include "ardour/audioengine.h"
74 #include "ardour/audiofilesource.h"
75 #include "ardour/audioplaylist.h"
76 #include "ardour/audioregion.h"
77 #include "ardour/auditioner.h"
78 #include "ardour/buffer.h"
79 #include "ardour/butler.h"
80 #include "ardour/configuration.h"
81 #include "ardour/control_protocol_manager.h"
82 #include "ardour/crossfade.h"
83 #include "ardour/cycle_timer.h"
84 #include "ardour/directory_names.h"
85 #include "ardour/filename_extensions.h"
86 #include "ardour/io_processor.h"
87 #include "ardour/location.h"
88 #include "ardour/midi_diskstream.h"
89 #include "ardour/midi_patch_manager.h"
90 #include "ardour/midi_playlist.h"
91 #include "ardour/midi_region.h"
92 #include "ardour/midi_source.h"
93 #include "ardour/midi_track.h"
94 #include "ardour/named_selection.h"
95 #include "ardour/processor.h"
96 #include "ardour/port.h"
97 #include "ardour/region_factory.h"
98 #include "ardour/route_group.h"
99 #include "ardour/send.h"
100 #include "ardour/session.h"
101 #include "ardour/session_directory.h"
102 #include "ardour/session_metadata.h"
103 #include "ardour/session_state_utils.h"
104 #include "ardour/session_playlists.h"
105 #include "ardour/session_utils.h"
106 #include "ardour/silentfilesource.h"
107 #include "ardour/slave.h"
108 #include "ardour/smf_source.h"
109 #include "ardour/sndfile_helpers.h"
110 #include "ardour/sndfilesource.h"
111 #include "ardour/source_factory.h"
112 #include "ardour/template_utils.h"
113 #include "ardour/tempo.h"
114 #include "ardour/ticker.h"
115 #include "ardour/user_bundle.h"
116 #include "ardour/utils.h"
117 #include "ardour/utils.h"
118 #include "ardour/version.h"
119 #include "ardour/playlist_factory.h"
120
121 #include "control_protocol/control_protocol.h"
122
123 #include "i18n.h"
124 #include <locale.h>
125
126 using namespace std;
127 using namespace ARDOUR;
128 using namespace PBD;
129
130 void
131 Session::first_stage_init (string fullpath, string snapshot_name)
132 {
133         if (fullpath.length() == 0) {
134                 destroy ();
135                 throw failed_constructor();
136         }
137
138         char buf[PATH_MAX+1];
139         if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
140                 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
141                 destroy ();
142                 throw failed_constructor();
143         }
144
145         _path = string(buf);
146
147         if (_path[_path.length()-1] != '/') {
148                 _path += '/';
149         }
150
151         if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS) && ::access (_path.c_str(), W_OK)) {
152                 _writable = false;
153         } else {
154                 _writable = true;
155         }
156
157         /* these two are just provisional settings. set_state()
158            will likely override them.
159         */
160
161         _name = _current_snapshot_name = snapshot_name;
162
163         set_history_depth (Config->get_history_depth());
164
165         _current_frame_rate = _engine.frame_rate ();
166         _nominal_frame_rate = _current_frame_rate;
167         _base_frame_rate = _current_frame_rate;
168
169         _tempo_map = new TempoMap (_current_frame_rate);
170         _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
171
172
173         _non_soloed_outs_muted = false;
174         _listen_cnt = 0;
175         _solo_isolated_cnt = 0;
176         g_atomic_int_set (&processing_prohibited, 0);
177         _transport_speed = 0;
178         _last_transport_speed = 0;
179         _target_transport_speed = 0;
180         auto_play_legal = false;
181         transport_sub_state = 0;
182         _transport_frame = 0;
183         _requested_return_frame = -1;
184         _session_range_location = 0;
185         g_atomic_int_set (&_record_status, Disabled);
186         loop_changing = false;
187         play_loop = false;
188         have_looped = false;
189         _last_roll_location = 0;
190         _last_roll_or_reversal_location = 0;
191         _last_record_location = 0;
192         pending_locate_frame = 0;
193         pending_locate_roll = false;
194         pending_locate_flush = false;
195         state_was_pending = false;
196         set_next_event ();
197         outbound_mtc_timecode_frame = 0;
198         next_quarter_frame_to_send = -1;
199         current_block_size = 0;
200         solo_update_disabled = false;
201         _have_captured = false;
202         _worst_output_latency = 0;
203         _worst_input_latency = 0;
204         _worst_track_latency = 0;
205         _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
206         _was_seamless = Config->get_seamless_loop ();
207         _slave = 0;
208         session_send_mtc = false;
209         g_atomic_int_set (&_playback_load, 100);
210         g_atomic_int_set (&_capture_load, 100);
211         _play_range = false;
212         _exporting = false;
213         pending_abort = false;
214         destructive_index = 0;
215         first_file_data_format_reset = true;
216         first_file_header_format_reset = true;
217         post_export_sync = false;
218         midi_control_ui = 0;
219
220         AudioDiskstream::allocate_working_buffers();
221
222         /* default short fade = 15ms */
223
224         Crossfade::set_short_xfade_length ((nframes_t) floor (config.get_short_xfade_seconds() * frame_rate()));
225         SndFileSource::setup_standard_crossfades (*this, frame_rate());
226
227         last_mmc_step.tv_sec = 0;
228         last_mmc_step.tv_usec = 0;
229         step_speed = 0.0;
230
231         /* click sounds are unset by default, which causes us to internal
232            waveforms for clicks.
233         */
234
235         click_length = 0;
236         click_emphasis_length = 0;
237         _clicking = false;
238
239         process_function = &Session::process_with_events;
240
241         if (config.get_use_video_sync()) {
242                 waiting_for_sync_offset = true;
243         } else {
244                 waiting_for_sync_offset = false;
245         }
246
247         last_timecode_when = 0;
248         _timecode_offset = 0;
249         _timecode_offset_negative = true;
250         last_timecode_valid = false;
251
252         sync_time_vars ();
253
254         last_rr_session_dir = session_dirs.begin();
255         refresh_disk_space ();
256
257         // set_default_fade (0.2, 5.0); /* steepness, millisecs */
258
259         /* slave stuff */
260
261         average_slave_delta = 1800; // !!! why 1800 ????
262         have_first_delta_accumulator = false;
263         delta_accumulator_cnt = 0;
264         _slave_state = Stopped;
265
266         _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
267
268         /* These are all static "per-class" signals */
269
270         SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
271         PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
272         AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
273         Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
274         IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
275
276         /* stop IO objects from doing stuff until we're ready for them */
277
278         Delivery::disable_panners ();
279         IO::disable_connecting ();
280
281         /* Create MIDI control ports */
282
283         MIDI::Manager* m = MIDI::Manager::instance ();
284
285         _mtc_input_port = m->add_port (new MIDI::Port ("MTC", O_RDONLY, _engine.jack()));
286         _mtc_output_port = m->add_port (new MIDI::Port ("MTC", O_WRONLY, _engine.jack()));
287         _midi_input_port = m->add_port (new MIDI::Port ("MIDI control", O_RDONLY, _engine.jack()));
288         _midi_output_port = m->add_port (new MIDI::Port ("MIDI control", O_WRONLY, _engine.jack()));
289         _midi_clock_input_port = m->add_port (new MIDI::Port ("MIDI clock", O_RDONLY, _engine.jack()));
290         _midi_clock_output_port = m->add_port (new MIDI::Port ("MIDI clock", O_WRONLY, _engine.jack()));
291 }
292
293 int
294 Session::second_stage_init ()
295 {
296         AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
297
298         if (!_is_new) {
299                 if (load_state (_current_snapshot_name)) {
300                         return -1;
301                 }
302                 remove_empty_sounds ();
303         }
304
305         if (_butler->start_thread()) {
306                 return -1;
307         }
308
309         if (start_midi_thread ()) {
310                 return -1;
311         }
312
313         setup_midi_machine_control ();
314
315         // set_state() will call setup_raid_path(), but if it's a new session we need
316         // to call setup_raid_path() here.
317
318         if (state_tree) {
319                 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
320                         return -1;
321                 }
322         } else {
323                 setup_raid_path(_path);
324         }
325
326         /* we can't save till after ::when_engine_running() is called,
327            because otherwise we save state with no connections made.
328            therefore, we reset _state_of_the_state because ::set_state()
329            will have cleared it.
330
331            we also have to include Loading so that any events that get
332            generated between here and the end of ::when_engine_running()
333            will be processed directly rather than queued.
334         */
335
336         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
337
338         _locations.changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
339         _locations.added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
340         setup_click_sounds (0);
341         setup_midi_control ();
342
343         /* Pay attention ... */
344
345         _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
346         _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
347
348         try {
349                 when_engine_running ();
350         }
351
352         /* handle this one in a different way than all others, so that its clear what happened */
353
354         catch (AudioEngine::PortRegistrationFailure& err) {
355                 error << err.what() << endmsg;
356                 return -1;
357         }
358
359         catch (...) {
360                 return -1;
361         }
362
363         BootMessage (_("Reset Remote Controls"));
364
365         send_full_time_code (0);
366         _engine.transport_locate (0);
367
368         _mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
369         _mmc->send (MIDI::MachineControlCommand (Timecode::Time ()));
370
371         MidiClockTicker::instance().set_session (this);
372         MIDI::Name::MidiPatchManager::instance().set_session (this);
373
374         /* initial program change will be delivered later; see ::config_changed() */
375
376         BootMessage (_("Reset Control Protocols"));
377
378         ControlProtocolManager::instance().set_session (this);
379
380         _state_of_the_state = Clean;
381
382         Port::set_connecting_blocked (false);
383
384         DirtyChanged (); /* EMIT SIGNAL */
385
386         if (state_was_pending) {
387                 save_state (_current_snapshot_name);
388                 remove_pending_capture_state ();
389                 state_was_pending = false;
390         }
391
392         BootMessage (_("Session loading complete"));
393
394         return 0;
395 }
396
397 string
398 Session::raid_path () const
399 {
400         SearchPath raid_search_path;
401
402         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
403                 raid_search_path += sys::path((*i).path);
404         }
405
406         return raid_search_path.to_string ();
407 }
408
409 void
410 Session::setup_raid_path (string path)
411 {
412         if (path.empty()) {
413                 return;
414         }
415
416         space_and_path sp;
417         string fspath;
418
419         session_dirs.clear ();
420
421         SearchPath search_path(path);
422         SearchPath sound_search_path;
423         SearchPath midi_search_path;
424
425         for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
426                 sp.path = (*i).to_string ();
427                 sp.blocks = 0; // not needed
428                 session_dirs.push_back (sp);
429
430                 SessionDirectory sdir(sp.path);
431
432                 sound_search_path += sdir.sound_path ();
433                 midi_search_path += sdir.midi_path ();
434         }
435
436         // set the search path for each data type
437         FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
438         SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
439
440         // reset the round-robin soundfile path thingie
441         last_rr_session_dir = session_dirs.begin();
442 }
443
444 bool
445 Session::path_is_within_session (const std::string& path)
446 {
447         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
448                 if (path.find ((*i).path) == 0) {
449                         return true;
450                 }
451         }
452         return false;
453 }
454
455 int
456 Session::ensure_subdirs ()
457 {
458         string dir;
459
460         dir = session_directory().peak_path().to_string();
461
462         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
463                 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
464                 return -1;
465         }
466
467         dir = session_directory().sound_path().to_string();
468
469         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
470                 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
471                 return -1;
472         }
473
474         dir = session_directory().midi_path().to_string();
475
476         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
477                 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
478                 return -1;
479         }
480
481         dir = session_directory().dead_sound_path().to_string();
482
483         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
484                 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
485                 return -1;
486         }
487
488         dir = session_directory().export_path().to_string();
489
490         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
491                 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
492                 return -1;
493         }
494
495         dir = analysis_dir ();
496
497         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
498                 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
499                 return -1;
500         }
501
502         return 0;
503 }
504
505 int
506 Session::create (const string& mix_template, BusProfile* bus_profile)
507 {
508
509         if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
510                 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
511                 return -1;
512         }
513
514         if (ensure_subdirs ()) {
515                 return -1;
516         }
517
518         if (!mix_template.empty()) {
519                 std::string in_path = mix_template;
520
521                 ifstream in(in_path.c_str());
522
523                 if (in){
524                         string out_path = _path;
525                         out_path += _name;
526                         out_path += statefile_suffix;
527
528                         ofstream out(out_path.c_str());
529
530                         if (out){
531                                 out << in.rdbuf();
532                                 _is_new = false;
533                                 return 0;
534
535                         } else {
536                                 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
537                                         << endmsg;
538                                 return -1;
539                         }
540
541                 } else {
542                         error << string_compose (_("Could not open mix template %1 for reading"), in_path)
543                                 << endmsg;
544                         return -1;
545                 }
546
547         }
548
549         /* Instantiate metadata */
550
551         _metadata = new SessionMetadata ();
552
553         /* set initial start + end point */
554
555         _state_of_the_state = Clean;
556         
557         /* set up Master Out and Control Out if necessary */
558
559         if (bus_profile) {
560
561                 RouteList rl;
562                 int control_id = 1;
563                 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
564
565                 if (bus_profile->master_out_channels) {
566                         Route* rt = new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO);
567                         if (rt->init ()) {
568                                 delete rt;
569                                 return -1;
570                         }
571                         boost_debug_shared_ptr_mark_interesting (rt, "Route");
572                         boost::shared_ptr<Route> r (rt);
573                         r->input()->ensure_io (count, false, this);
574                         r->output()->ensure_io (count, false, this);
575                         r->set_remote_control_id (control_id++);
576
577                         rl.push_back (r);
578
579                         if (Config->get_use_monitor_bus()) {
580                                 Route* rt = new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO);
581                                 if (rt->init ()) {
582                                         delete rt;
583                                         return -1;
584                                 }
585                                 boost_debug_shared_ptr_mark_interesting (rt, "Route");
586                                 boost::shared_ptr<Route> r (rt);
587                                 r->input()->ensure_io (count, false, this);
588                                 r->output()->ensure_io (count, false, this);
589                                 r->set_remote_control_id (control_id);
590                                 
591                                 rl.push_back (r);
592                         }
593
594                 } else {
595                         /* prohibit auto-connect to master, because there isn't one */
596                         bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
597                 }
598
599                 if (!rl.empty()) {
600                         add_routes (rl, false);
601                 }
602
603                 /* this allows the user to override settings with an environment variable.
604                  */
605
606                 if (no_auto_connect()) {
607                         bus_profile->input_ac = AutoConnectOption (0);
608                         bus_profile->output_ac = AutoConnectOption (0);
609                 }
610                 
611                 Config->set_input_auto_connect (bus_profile->input_ac);
612                 Config->set_output_auto_connect (bus_profile->output_ac);
613         }
614
615         save_state ("");
616
617         return 0;
618 }
619
620 void
621 Session::maybe_write_autosave()
622 {
623         if (dirty() && record_status() != Recording) {
624                 save_state("", true);
625         }
626 }
627
628 void
629 Session::remove_pending_capture_state ()
630 {
631         sys::path pending_state_file_path(_session_dir->root_path());
632
633         pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
634
635         try
636         {
637                 sys::remove (pending_state_file_path);
638         }
639         catch(sys::filesystem_error& ex)
640         {
641                 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
642                                 pending_state_file_path.to_string(), ex.what()) << endmsg;
643         }
644 }
645
646 /** Rename a state file.
647  * @param snapshot_name Snapshot name.
648  */
649 void
650 Session::rename_state (string old_name, string new_name)
651 {
652         if (old_name == _current_snapshot_name || old_name == _name) {
653                 /* refuse to rename the current snapshot or the "main" one */
654                 return;
655         }
656
657         const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
658         const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
659
660         const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
661         const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
662
663         try
664         {
665                 sys::rename (old_xml_path, new_xml_path);
666         }
667         catch (const sys::filesystem_error& err)
668         {
669                 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
670                                 old_name, new_name, err.what()) << endmsg;
671         }
672 }
673
674 /** Remove a state file.
675  * @param snapshot_name Snapshot name.
676  */
677 void
678 Session::remove_state (string snapshot_name)
679 {
680         if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
681                 // refuse to remove the current snapshot or the "main" one
682                 return;
683         }
684
685         sys::path xml_path(_session_dir->root_path());
686
687         xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
688
689         if (!create_backup_file (xml_path)) {
690                 // don't remove it if a backup can't be made
691                 // create_backup_file will log the error.
692                 return;
693         }
694
695         // and delete it
696         sys::remove (xml_path);
697 }
698
699 #ifdef HAVE_JACK_SESSION
700 void
701 Session::jack_session_event (jack_session_event_t * event)
702 {
703         char timebuf[128];
704         time_t n;
705         struct tm local_time;
706
707         time (&n);
708         localtime_r (&n, &local_time);
709         strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
710
711         if (event->type == JackSessionSaveTemplate)
712         {
713                 if (save_template( timebuf )) {
714                         event->flags = JackSessionSaveError; 
715                 } else {
716                         string cmd ("ardour3 -P -U ");
717                         cmd += event->client_uuid;
718                         cmd += " -T ";
719                         cmd += timebuf;
720
721                         event->command_line = strdup (cmd.c_str());
722                 }
723         }
724         else
725         {
726                 if (save_state (timebuf)) {
727                         event->flags = JackSessionSaveError; 
728                 } else {
729                         sys::path xml_path (_session_dir->root_path());
730                         xml_path /= legalize_for_path (timebuf) + statefile_suffix;
731
732                         string cmd ("ardour3 -P -U ");
733                         cmd += event->client_uuid;
734                         cmd += " \"";
735                         cmd += xml_path.to_string();
736                         cmd += '\"';
737
738                         event->command_line = strdup (cmd.c_str());
739                 }
740         }
741
742         jack_session_reply (_engine.jack(), event);
743
744         if (event->type == JackSessionSaveAndQuit) {
745                 // TODO: make ardour quit.
746         }
747
748         jack_session_event_free( event );
749 }
750 #endif
751
752 int
753 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
754 {
755         XMLTree tree;
756         sys::path xml_path(_session_dir->root_path());
757
758         if (!_writable || (_state_of_the_state & CannotSave)) {
759                 return 1;
760         }
761
762         if (!_engine.connected ()) {
763                 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
764                                          PROGRAM_NAME)
765                       << endmsg;
766                 return 1;
767         }
768
769         /* tell sources we're saving first, in case they write out to a new file
770          * which should be saved with the state rather than the old one */
771         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
772                 i->second->session_saved();
773         }
774
775         tree.set_root (&get_state());
776
777         if (snapshot_name.empty()) {
778                 snapshot_name = _current_snapshot_name;
779         } else if (switch_to_snapshot) {
780                 _current_snapshot_name = snapshot_name;
781         }
782
783         if (!pending) {
784
785                 /* proper save: use statefile_suffix (.ardour in English) */
786
787                 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
788
789                 /* make a backup copy of the old file */
790
791                 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
792                         // create_backup_file will log the error
793                         return -1;
794                 }
795
796         } else {
797
798                 /* pending save: use pending_suffix (.pending in English) */
799                 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
800         }
801
802         sys::path tmp_path(_session_dir->root_path());
803
804         tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
805
806         // cerr << "actually writing state to " << xml_path.to_string() << endl;
807
808         if (!tree.write (tmp_path.to_string())) {
809                 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
810                 sys::remove (tmp_path);
811                 return -1;
812
813         } else {
814
815                 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
816                         error << string_compose (_("could not rename temporary session file %1 to %2"),
817                                         tmp_path.to_string(), xml_path.to_string()) << endmsg;
818                         sys::remove (tmp_path);
819                         return -1;
820                 }
821         }
822
823         if (!pending) {
824
825                 save_history (snapshot_name);
826
827                 bool was_dirty = dirty();
828
829                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
830
831                 if (was_dirty) {
832                         DirtyChanged (); /* EMIT SIGNAL */
833                 }
834
835                 StateSaved (snapshot_name); /* EMIT SIGNAL */
836         }
837
838         return 0;
839 }
840
841 int
842 Session::restore_state (string snapshot_name)
843 {
844         if (load_state (snapshot_name) == 0) {
845                 set_state (*state_tree->root(), Stateful::loading_state_version);
846         }
847
848         return 0;
849 }
850
851 int
852 Session::load_state (string snapshot_name)
853 {
854         delete state_tree;
855         state_tree = 0;
856
857         state_was_pending = false;
858
859         /* check for leftover pending state from a crashed capture attempt */
860
861         sys::path xmlpath(_session_dir->root_path());
862         xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
863
864         if (sys::exists (xmlpath)) {
865
866                 /* there is pending state from a crashed capture attempt */
867
868                 boost::optional<int> r = AskAboutPendingState();
869                 if (r.get_value_or (1)) {
870                         state_was_pending = true;
871                 }
872         }
873
874         if (!state_was_pending) {
875                 xmlpath = _session_dir->root_path();
876                 xmlpath /= snapshot_name;
877         }
878
879         if (!sys::exists (xmlpath)) {
880                 xmlpath = _session_dir->root_path();
881                 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
882                 if (!sys::exists (xmlpath)) {
883                         error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
884                         return 1;
885                 }
886         }
887
888         state_tree = new XMLTree;
889
890         set_dirty();
891
892         /* writable() really reflects the whole folder, but if for any
893            reason the session state file can't be written to, still
894            make us unwritable.
895         */
896
897         if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
898                 _writable = false;
899         }
900
901         if (!state_tree->read (xmlpath.to_string())) {
902                 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
903                 delete state_tree;
904                 state_tree = 0;
905                 return -1;
906         }
907
908         XMLNode& root (*state_tree->root());
909
910         if (root.name() != X_("Session")) {
911                 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
912                 delete state_tree;
913                 state_tree = 0;
914                 return -1;
915         }
916
917         const XMLProperty* prop;
918
919         if ((prop = root.property ("version")) == 0) {
920                 /* no version implies very old version of Ardour */
921                 Stateful::loading_state_version = 1000;
922         } else {
923                 int major;
924                 int minor;
925                 int micro;
926
927                 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, &micro);
928                 Stateful::loading_state_version = (major * 1000) + minor;
929         }
930                 
931         if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
932
933                 sys::path backup_path(_session_dir->root_path());
934
935                 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
936
937                 // only create a backup once
938                 if (sys::exists (backup_path)) {
939                         return 0;
940                 }
941
942                 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
943                                         xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
944                      << endmsg;
945
946                 try
947                 {
948                         sys::copy_file (xmlpath, backup_path);
949                 }
950                 catch(sys::filesystem_error& ex)
951                 {
952                         error << string_compose (_("Unable to make backup of state file %1 (%2)"),
953                                         xmlpath.to_string(), ex.what())
954                                 << endmsg;
955                         return -1;
956                 }
957         }
958
959         return 0;
960 }
961
962 int
963 Session::load_options (const XMLNode& node)
964 {
965         LocaleGuard lg (X_("POSIX"));
966         config.set_variables (node);
967         return 0;
968 }
969
970 XMLNode&
971 Session::get_state()
972 {
973         return state(true);
974 }
975
976 XMLNode&
977 Session::get_template()
978 {
979         /* if we don't disable rec-enable, diskstreams
980            will believe they need to store their capture
981            sources in their state node.
982         */
983
984         disable_record (false);
985
986         return state(false);
987 }
988
989 XMLNode&
990 Session::state(bool full_state)
991 {
992         XMLNode* node = new XMLNode("Session");
993         XMLNode* child;
994
995         // store libardour version, just in case
996         char buf[16];
997         snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
998         node->add_property("version", string(buf));
999
1000         /* store configuration settings */
1001
1002         if (full_state) {
1003
1004                 node->add_property ("name", _name);
1005                 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
1006                 node->add_property ("sample-rate", buf);
1007
1008                 if (session_dirs.size() > 1) {
1009
1010                         string p;
1011
1012                         vector<space_and_path>::iterator i = session_dirs.begin();
1013                         vector<space_and_path>::iterator next;
1014
1015                         ++i; /* skip the first one */
1016                         next = i;
1017                         ++next;
1018
1019                         while (i != session_dirs.end()) {
1020
1021                                 p += (*i).path;
1022
1023                                 if (next != session_dirs.end()) {
1024                                         p += ':';
1025                                 } else {
1026                                         break;
1027                                 }
1028
1029                                 ++next;
1030                                 ++i;
1031                         }
1032
1033                         child = node->add_child ("Path");
1034                         child->add_content (p);
1035                 }
1036         }
1037
1038         /* save the ID counter */
1039
1040         snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1041         node->add_property ("id-counter", buf);
1042
1043         /* various options */
1044
1045         node->add_child_nocopy (config.get_variables ());
1046
1047         node->add_child_nocopy (_metadata->get_state());
1048
1049         child = node->add_child ("Sources");
1050
1051         if (full_state) {
1052                 Glib::Mutex::Lock sl (source_lock);
1053
1054                 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1055
1056                         /* Don't save information about non-destructive file sources that are empty
1057                            and unused by any regions.
1058                         */
1059
1060                         boost::shared_ptr<FileSource> fs;
1061                         if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1062                                 if (!fs->destructive()) {
1063                                         if (fs->empty() && !fs->used()) {
1064                                                 continue;
1065                                         }
1066                                 }
1067                         }
1068
1069                         child->add_child_nocopy (siter->second->get_state());
1070                 }
1071         }
1072
1073         child = node->add_child ("Regions");
1074
1075         if (full_state) {
1076                 Glib::Mutex::Lock rl (region_lock);
1077                 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1078                 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1079                         boost::shared_ptr<Region> r = i->second;
1080                         /* only store regions not attached to playlists */
1081                         if (r->playlist() == 0) {
1082                                 child->add_child_nocopy (r->state (true));
1083                         }
1084                 }
1085         }
1086
1087         if (full_state) {
1088                 node->add_child_nocopy (_locations.get_state());
1089         } else {
1090                 // for a template, just create a new Locations, populate it
1091                 // with the default start and end, and get the state for that.
1092                 Locations loc;
1093                 Location* range = new Location (0, 0, _("session"), Location::IsSessionRange);
1094                 range->set (max_frames, 0);
1095                 loc.add (range);
1096                 node->add_child_nocopy (loc.get_state());
1097         }
1098
1099         child = node->add_child ("Bundles");
1100         {
1101                 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1102                 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1103                         boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1104                         if (b) {
1105                                 child->add_child_nocopy (b->get_state());
1106                         }
1107                 }
1108         }
1109
1110         child = node->add_child ("Routes");
1111         {
1112                 boost::shared_ptr<RouteList> r = routes.reader ();
1113
1114                 RoutePublicOrderSorter cmp;
1115                 RouteList public_order (*r);
1116                 public_order.sort (cmp);
1117
1118                 /* the sort should have put control outs first */
1119
1120                 if (_monitor_out) {
1121                         assert (_monitor_out == public_order.front());
1122                 }
1123
1124                 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1125                         if (!(*i)->is_hidden()) {
1126                                 if (full_state) {
1127                                         child->add_child_nocopy ((*i)->get_state());
1128                                 } else {
1129                                         child->add_child_nocopy ((*i)->get_template());
1130                                 }
1131                         }
1132                 }
1133         }
1134
1135         playlists->add_state (node, full_state);
1136
1137         child = node->add_child ("RouteGroups");
1138         for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1139                 child->add_child_nocopy ((*i)->get_state());
1140         }
1141
1142         if (_click_io) {
1143                 child = node->add_child ("Click");
1144                 child->add_child_nocopy (_click_io->state (full_state));
1145         }
1146
1147         if (full_state) {
1148                 child = node->add_child ("NamedSelections");
1149                 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1150                         if (full_state) {
1151                                 child->add_child_nocopy ((*i)->get_state());
1152                         }
1153                 }
1154         }
1155
1156         node->add_child_nocopy (_tempo_map->get_state());
1157
1158         node->add_child_nocopy (get_control_protocol_state());
1159
1160         if (_extra_xml) {
1161                 node->add_child_copy (*_extra_xml);
1162         }
1163
1164         return *node;
1165 }
1166
1167 XMLNode&
1168 Session::get_control_protocol_state ()
1169 {
1170         ControlProtocolManager& cpm (ControlProtocolManager::instance());
1171         return cpm.get_state();
1172 }
1173
1174 int
1175 Session::set_state (const XMLNode& node, int version)
1176 {
1177         XMLNodeList nlist;
1178         XMLNode* child;
1179         const XMLProperty* prop;
1180         int ret = -1;
1181
1182         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1183
1184         if (node.name() != X_("Session")){
1185                 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1186                 return -1;
1187         }
1188
1189         if ((prop = node.property ("version")) != 0) {
1190                 version = atoi (prop->value ()) * 1000;
1191         }
1192
1193         if ((prop = node.property ("name")) != 0) {
1194                 _name = prop->value ();
1195         }
1196
1197         if ((prop = node.property (X_("sample-rate"))) != 0) {
1198
1199                 _nominal_frame_rate = atoi (prop->value());
1200
1201                 if (_nominal_frame_rate != _current_frame_rate) {
1202                         boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1203                         if (r.get_value_or (0)) {
1204                                 return -1;
1205                         }
1206                 }
1207         }
1208
1209         setup_raid_path(_session_dir->root_path().to_string());
1210
1211         if ((prop = node.property (X_("id-counter"))) != 0) {
1212                 uint64_t x;
1213                 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1214                 ID::init_counter (x);
1215         } else {
1216                 /* old sessions used a timebased counter, so fake
1217                    the startup ID counter based on a standard
1218                    timestamp.
1219                 */
1220                 time_t now;
1221                 time (&now);
1222                 ID::init_counter (now);
1223         }
1224
1225
1226         IO::disable_connecting ();
1227
1228         /* Object loading order:
1229
1230         Path
1231         Extra
1232         Options/Config
1233         MIDI Control // relies on data from Options/Config
1234         Metadata
1235         Locations
1236         Sources
1237         AudioRegions
1238         Connections
1239         Routes
1240         RouteGroups
1241         MixGroups
1242         Click
1243         ControlProtocols
1244         */
1245
1246         if ((child = find_named_node (node, "Extra")) != 0) {
1247                 _extra_xml = new XMLNode (*child);
1248         }
1249
1250         if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1251                 load_options (*child);
1252         } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1253                 load_options (*child);
1254         } else {
1255                 error << _("Session: XML state has no options section") << endmsg;
1256         }
1257
1258         if (version >= 3000) {
1259                 if ((child = find_named_node (node, "Metadata")) == 0) {
1260                         warning << _("Session: XML state has no metadata section") << endmsg;
1261                 } else if (_metadata->set_state (*child, version)) {
1262                         goto out;
1263                 }
1264         }
1265
1266         if ((child = find_named_node (node, "Locations")) == 0) {
1267                 error << _("Session: XML state has no locations section") << endmsg;
1268                 goto out;
1269         } else if (_locations.set_state (*child, version)) {
1270                 goto out;
1271         }
1272
1273         Location* location;
1274
1275         if ((location = _locations.auto_loop_location()) != 0) {
1276                 set_auto_loop_location (location);
1277         }
1278
1279         if ((location = _locations.auto_punch_location()) != 0) {
1280                 set_auto_punch_location (location);
1281         }
1282
1283         if ((location = _locations.session_range_location()) != 0) {
1284                 delete _session_range_location;
1285                 _session_range_location = location;
1286         }
1287
1288         if (_session_range_location) {
1289                 AudioFileSource::set_header_position_offset (_session_range_location->start());
1290         }
1291
1292         if ((child = find_named_node (node, "Sources")) == 0) {
1293                 error << _("Session: XML state has no sources section") << endmsg;
1294                 goto out;
1295         } else if (load_sources (*child)) {
1296                 goto out;
1297         }
1298
1299         if ((child = find_named_node (node, "Regions")) == 0) {
1300                 error << _("Session: XML state has no Regions section") << endmsg;
1301                 goto out;
1302         } else if (load_regions (*child)) {
1303                 goto out;
1304         }
1305
1306         if ((child = find_named_node (node, "Playlists")) == 0) {
1307                 error << _("Session: XML state has no playlists section") << endmsg;
1308                 goto out;
1309         } else if (playlists->load (*this, *child)) {
1310                 goto out;
1311         }
1312
1313         if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1314                 // this is OK
1315         } else if (playlists->load_unused (*this, *child)) {
1316                 goto out;
1317         }
1318         
1319         if ((child = find_named_node (node, "NamedSelections")) != 0) {
1320                 if (load_named_selections (*child)) {
1321                         goto out;
1322                 }
1323         }
1324
1325         if (version >= 3000) {
1326                 if ((child = find_named_node (node, "Bundles")) == 0) {
1327                         warning << _("Session: XML state has no bundles section") << endmsg;
1328                         //goto out;
1329                 } else {
1330                         /* We can't load Bundles yet as they need to be able
1331                            to convert from port names to Port objects, which can't happen until
1332                            later */
1333                         _bundle_xml_node = new XMLNode (*child);
1334                 }
1335         }
1336         
1337         if ((child = find_named_node (node, "TempoMap")) == 0) {
1338                 error << _("Session: XML state has no Tempo Map section") << endmsg;
1339                 goto out;
1340         } else if (_tempo_map->set_state (*child, version)) {
1341                 goto out;
1342         }
1343
1344         if (version < 3000) {
1345                 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1346                         error << _("Session: XML state has no diskstreams section") << endmsg;
1347                         goto out;
1348                 } else if (load_diskstreams_2X (*child, version)) {
1349                         goto out;
1350                 }
1351         }
1352
1353         if ((child = find_named_node (node, "Routes")) == 0) {
1354                 error << _("Session: XML state has no routes section") << endmsg;
1355                 goto out;
1356         } else if (load_routes (*child, version)) {
1357                 goto out;
1358         }
1359
1360         /* our diskstreams list is no longer needed as they are now all owned by their Route */
1361         _diskstreams_2X.clear ();
1362
1363         if (version >= 3000) {
1364                 
1365                 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1366                         error << _("Session: XML state has no route groups section") << endmsg;
1367                         goto out;
1368                 } else if (load_route_groups (*child, version)) {
1369                         goto out;
1370                 }
1371                 
1372         } else if (version < 3000) {
1373                 
1374                 if ((child = find_named_node (node, "EditGroups")) == 0) {
1375                         error << _("Session: XML state has no edit groups section") << endmsg;
1376                         goto out;
1377                 } else if (load_route_groups (*child, version)) {
1378                         goto out;
1379                 }
1380
1381                 if ((child = find_named_node (node, "MixGroups")) == 0) {
1382                         error << _("Session: XML state has no mix groups section") << endmsg;
1383                         goto out;
1384                 } else if (load_route_groups (*child, version)) {
1385                         goto out;
1386                 }
1387         }
1388
1389         if ((child = find_named_node (node, "Click")) == 0) {
1390                 warning << _("Session: XML state has no click section") << endmsg;
1391         } else if (_click_io) {
1392                 _click_io->set_state (*child, version);
1393         }
1394
1395         if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1396                 ControlProtocolManager::instance().set_protocol_states (*child);
1397         }
1398
1399         /* here beginneth the second phase ... */
1400
1401         StateReady (); /* EMIT SIGNAL */
1402
1403         return 0;
1404
1405   out:
1406         return ret;
1407 }
1408
1409 int
1410 Session::load_routes (const XMLNode& node, int version)
1411 {
1412         XMLNodeList nlist;
1413         XMLNodeConstIterator niter;
1414         RouteList new_routes;
1415
1416         nlist = node.children();
1417
1418         set_dirty();
1419
1420         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1421
1422                 boost::shared_ptr<Route> route;
1423                 if (version < 3000) {
1424                         route = XMLRouteFactory_2X (**niter, version);
1425                 } else {
1426                         route = XMLRouteFactory (**niter, version);
1427                 }
1428                 
1429                 if (route == 0) {
1430                         error << _("Session: cannot create Route from XML description.") << endmsg;
1431                         return -1;
1432                 }
1433
1434                 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1435
1436                 new_routes.push_back (route);
1437         }
1438
1439         add_routes (new_routes, false);
1440
1441         return 0;
1442 }
1443
1444 boost::shared_ptr<Route>
1445 Session::XMLRouteFactory (const XMLNode& node, int version)
1446 {
1447         boost::shared_ptr<Route> ret;
1448
1449         if (node.name() != "Route") {
1450                 return ret;
1451         }
1452
1453         XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1454
1455         DataType type = DataType::AUDIO;
1456         const XMLProperty* prop = node.property("default-type");
1457
1458         if (prop) {
1459                 type = DataType (prop->value());
1460         }
1461
1462         assert (type != DataType::NIL);
1463
1464         if (ds_child) {
1465
1466                 Track* track;
1467                 
1468                 if (type == DataType::AUDIO) {
1469                         track = new AudioTrack (*this, X_("toBeResetFroXML"));
1470                         
1471                 } else {
1472                         track = new MidiTrack (*this, X_("toBeResetFroXML"));
1473                 }
1474                 
1475                 if (track->init()) {
1476                         delete track;
1477                         return ret;
1478                 }
1479                 
1480                 if (track->set_state (node, version)) {
1481                         delete track;
1482                         return ret;
1483                 }
1484                 
1485                 boost_debug_shared_ptr_mark_interesting (track, "Track");
1486                 ret.reset (track);
1487                 
1488         } else {
1489                 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1490
1491                 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1492                         boost_debug_shared_ptr_mark_interesting (rt, "Route");
1493                         ret.reset (rt);
1494                 } else {
1495                         delete rt;
1496                 }
1497         }
1498
1499         return ret;
1500 }
1501
1502 boost::shared_ptr<Route>
1503 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1504 {
1505         boost::shared_ptr<Route> ret;
1506
1507         if (node.name() != "Route") {
1508                 return ret;
1509         }
1510
1511         XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1512         if (!ds_prop) {
1513                 ds_prop = node.property (X_("diskstream"));
1514         }
1515
1516         DataType type = DataType::AUDIO;
1517         const XMLProperty* prop = node.property("default-type");
1518
1519         if (prop) {
1520                 type = DataType (prop->value());
1521         }
1522
1523         assert (type != DataType::NIL);
1524
1525         if (ds_prop) {
1526
1527                 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1528                 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1529                         ++i;
1530                 }
1531
1532                 if (i == _diskstreams_2X.end()) {
1533                         error << _("Could not find diskstream for route") << endmsg;
1534                         return boost::shared_ptr<Route> ();
1535                 }
1536
1537                 Track* track;
1538                 
1539                 if (type == DataType::AUDIO) {
1540                         track = new AudioTrack (*this, X_("toBeResetFroXML"));
1541                         
1542                 } else {
1543                         track = new MidiTrack (*this, X_("toBeResetFroXML"));
1544                 }
1545                 
1546                 if (track->init()) {
1547                         delete track;
1548                         return ret;
1549                 }
1550                 
1551                 if (track->set_state (node, version)) {
1552                         delete track;
1553                         return ret;
1554                 }
1555
1556                 track->set_diskstream (*i);
1557                 
1558                 boost_debug_shared_ptr_mark_interesting (track, "Track");
1559                 ret.reset (track);
1560                 
1561         } else {
1562                 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1563
1564                 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1565                         boost_debug_shared_ptr_mark_interesting (rt, "Route");
1566                         ret.reset (rt);
1567                 } else {
1568                         delete rt;
1569                 }
1570         }
1571
1572         return ret;
1573 }
1574
1575 int
1576 Session::load_regions (const XMLNode& node)
1577 {
1578         XMLNodeList nlist;
1579         XMLNodeConstIterator niter;
1580         boost::shared_ptr<Region> region;
1581
1582         nlist = node.children();
1583
1584         set_dirty();
1585
1586         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1587                 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1588                         error << _("Session: cannot create Region from XML description.");
1589                         const XMLProperty *name = (**niter).property("name");
1590
1591                         if (name) {
1592                                 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1593                         }
1594
1595                         error << endmsg;
1596                 }
1597         }
1598
1599         return 0;
1600 }
1601
1602 boost::shared_ptr<Region>
1603 Session::XMLRegionFactory (const XMLNode& node, bool full)
1604 {
1605         const XMLProperty* type = node.property("type");
1606
1607         try {
1608
1609         if ( !type || type->value() == "audio" ) {
1610
1611                 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1612
1613         } else if (type->value() == "midi") {
1614
1615                 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1616
1617         }
1618
1619         } catch (failed_constructor& err) {
1620                 return boost::shared_ptr<Region> ();
1621         }
1622
1623         return boost::shared_ptr<Region> ();
1624 }
1625
1626 boost::shared_ptr<AudioRegion>
1627 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1628 {
1629         const XMLProperty* prop;
1630         boost::shared_ptr<Source> source;
1631         boost::shared_ptr<AudioSource> as;
1632         SourceList sources;
1633         SourceList master_sources;
1634         uint32_t nchans = 1;
1635         char buf[128];
1636
1637         if (node.name() != X_("Region")) {
1638                 return boost::shared_ptr<AudioRegion>();
1639         }
1640
1641         if ((prop = node.property (X_("channels"))) != 0) {
1642                 nchans = atoi (prop->value().c_str());
1643         }
1644
1645         if ((prop = node.property ("name")) == 0) {
1646                 cerr << "no name for this region\n";
1647                 abort ();
1648         }
1649
1650         if ((prop = node.property (X_("source-0"))) == 0) {
1651                 if ((prop = node.property ("source")) == 0) {
1652                         error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1653                         return boost::shared_ptr<AudioRegion>();
1654                 }
1655         }
1656
1657         PBD::ID s_id (prop->value());
1658
1659         if ((source = source_by_id (s_id)) == 0) {
1660                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1661                 return boost::shared_ptr<AudioRegion>();
1662         }
1663
1664         as = boost::dynamic_pointer_cast<AudioSource>(source);
1665         if (!as) {
1666                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1667                 return boost::shared_ptr<AudioRegion>();
1668         }
1669
1670         sources.push_back (as);
1671
1672         /* pickup other channels */
1673
1674         for (uint32_t n=1; n < nchans; ++n) {
1675                 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1676                 if ((prop = node.property (buf)) != 0) {
1677
1678                         PBD::ID id2 (prop->value());
1679
1680                         if ((source = source_by_id (id2)) == 0) {
1681                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1682                                 return boost::shared_ptr<AudioRegion>();
1683                         }
1684
1685                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1686                         if (!as) {
1687                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1688                                 return boost::shared_ptr<AudioRegion>();
1689                         }
1690                         sources.push_back (as);
1691                 }
1692         }
1693
1694         for (uint32_t n = 0; n < nchans; ++n) {
1695                 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1696                 if ((prop = node.property (buf)) != 0) {
1697
1698                         PBD::ID id2 (prop->value());
1699
1700                         if ((source = source_by_id (id2)) == 0) {
1701                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1702                                 return boost::shared_ptr<AudioRegion>();
1703                         }
1704
1705                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1706                         if (!as) {
1707                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1708                                 return boost::shared_ptr<AudioRegion>();
1709                         }
1710                         master_sources.push_back (as);
1711                 }
1712         }
1713
1714         try {
1715                 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1716
1717                 /* a final detail: this is the one and only place that we know how long missing files are */
1718
1719                 if (region->whole_file()) {
1720                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1721                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1722                                 if (sfp) {
1723                                         sfp->set_length (region->length());
1724                                 }
1725                         }
1726                 }
1727
1728                 if (!master_sources.empty()) {
1729                         if (master_sources.size() != nchans) {
1730                                 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1731                         } else {
1732                                 region->set_master_sources (master_sources);
1733                         }
1734                 }
1735
1736                 return region;
1737
1738         }
1739
1740         catch (failed_constructor& err) {
1741                 return boost::shared_ptr<AudioRegion>();
1742         }
1743 }
1744
1745 boost::shared_ptr<MidiRegion>
1746 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1747 {
1748         const XMLProperty* prop;
1749         boost::shared_ptr<Source> source;
1750         boost::shared_ptr<MidiSource> ms;
1751         SourceList sources;
1752         uint32_t nchans = 1;
1753
1754         if (node.name() != X_("Region")) {
1755                 return boost::shared_ptr<MidiRegion>();
1756         }
1757
1758         if ((prop = node.property (X_("channels"))) != 0) {
1759                 nchans = atoi (prop->value().c_str());
1760         }
1761
1762         if ((prop = node.property ("name")) == 0) {
1763                 cerr << "no name for this region\n";
1764                 abort ();
1765         }
1766
1767         // Multiple midi channels?  that's just crazy talk
1768         assert(nchans == 1);
1769
1770         if ((prop = node.property (X_("source-0"))) == 0) {
1771                 if ((prop = node.property ("source")) == 0) {
1772                         error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1773                         return boost::shared_ptr<MidiRegion>();
1774                 }
1775         }
1776
1777         PBD::ID s_id (prop->value());
1778
1779         if ((source = source_by_id (s_id)) == 0) {
1780                 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1781                 return boost::shared_ptr<MidiRegion>();
1782         }
1783
1784         ms = boost::dynamic_pointer_cast<MidiSource>(source);
1785         if (!ms) {
1786                 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1787                 return boost::shared_ptr<MidiRegion>();
1788         }
1789
1790         sources.push_back (ms);
1791
1792         try {
1793                 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1794                 /* a final detail: this is the one and only place that we know how long missing files are */
1795
1796                 if (region->whole_file()) {
1797                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1798                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1799                                 if (sfp) {
1800                                         sfp->set_length (region->length());
1801                                 }
1802                         }
1803                 }
1804
1805                 return region;
1806         }
1807
1808         catch (failed_constructor& err) {
1809                 return boost::shared_ptr<MidiRegion>();
1810         }
1811 }
1812
1813 XMLNode&
1814 Session::get_sources_as_xml ()
1815
1816 {
1817         XMLNode* node = new XMLNode (X_("Sources"));
1818         Glib::Mutex::Lock lm (source_lock);
1819
1820         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1821                 node->add_child_nocopy (i->second->get_state());
1822         }
1823
1824         return *node;
1825 }
1826
1827 string
1828 Session::path_from_region_name (DataType type, string name, string identifier)
1829 {
1830         char buf[PATH_MAX+1];
1831         uint32_t n;
1832         SessionDirectory sdir(get_best_session_directory_for_new_source());
1833         sys::path source_dir = ((type == DataType::AUDIO)
1834                 ? sdir.sound_path() : sdir.midi_path());
1835
1836         string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1837
1838         for (n = 0; n < 999999; ++n) {
1839                 if (identifier.length()) {
1840                         snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1841                                   identifier.c_str(), n, ext.c_str());
1842                 } else {
1843                         snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1844                                         n, ext.c_str());
1845                 }
1846
1847                 sys::path source_path = source_dir / buf;
1848
1849                 if (!sys::exists (source_path)) {
1850                         return source_path.to_string();
1851                 }
1852         }
1853
1854         error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1855                                  name, identifier)
1856               << endmsg;
1857
1858         return "";
1859 }
1860
1861
1862 int
1863 Session::load_sources (const XMLNode& node)
1864 {
1865         XMLNodeList nlist;
1866         XMLNodeConstIterator niter;
1867         boost::shared_ptr<Source> source;
1868
1869         nlist = node.children();
1870
1871         set_dirty();
1872
1873         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1874                 try {
1875                         if ((source = XMLSourceFactory (**niter)) == 0) {
1876                                 error << _("Session: cannot create Source from XML description.") << endmsg;
1877                         }
1878                 } catch (MissingSource& err) {
1879                         warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1880                         source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1881                 }
1882         }
1883
1884         return 0;
1885 }
1886
1887 boost::shared_ptr<Source>
1888 Session::XMLSourceFactory (const XMLNode& node)
1889 {
1890         if (node.name() != "Source") {
1891                 return boost::shared_ptr<Source>();
1892         }
1893
1894         try {
1895                 /* note: do peak building in another thread when loading session state */
1896                 return SourceFactory::create (*this, node, true);
1897         }
1898
1899         catch (failed_constructor& err) {
1900                 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1901                 return boost::shared_ptr<Source>();
1902         }
1903 }
1904
1905 int
1906 Session::save_template (string template_name)
1907 {
1908         XMLTree tree;
1909
1910         if (_state_of_the_state & CannotSave) {
1911                 return -1;
1912         }
1913
1914         sys::path user_template_dir(user_template_directory());
1915
1916         try
1917         {
1918                 sys::create_directories (user_template_dir);
1919         }
1920         catch(sys::filesystem_error& ex)
1921         {
1922                 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1923                                 user_template_dir.to_string(), ex.what()) << endmsg;
1924                 return -1;
1925         }
1926
1927         tree.set_root (&get_template());
1928
1929         sys::path template_file_path(user_template_dir);
1930         template_file_path /= template_name + template_suffix;
1931
1932         if (sys::exists (template_file_path))
1933         {
1934                 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1935                                 template_file_path.to_string()) << endmsg;
1936                 return -1;
1937         }
1938
1939         if (!tree.write (template_file_path.to_string())) {
1940                 error << _("mix template not saved") << endmsg;
1941                 return -1;
1942         }
1943
1944         return 0;
1945 }
1946
1947 int
1948 Session::rename_template (string old_name, string new_name)
1949 {
1950         sys::path old_path (user_template_directory());
1951         old_path /= old_name + template_suffix;
1952
1953         sys::path new_path(user_template_directory());
1954         new_path /= new_name + template_suffix;
1955
1956         if (sys::exists (new_path)) {
1957                 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1958                                           new_path.to_string()) << endmsg;
1959                 return -1;
1960         }
1961
1962         try {
1963                 sys::rename (old_path, new_path);
1964                 return 0;
1965         } catch (...) {
1966                 return -1;
1967         }
1968 }
1969
1970 int
1971 Session::delete_template (string name)
1972 {
1973         sys::path path = user_template_directory();
1974         path /= name + template_suffix;
1975
1976         try {
1977                 sys::remove (path);
1978                 return 0;
1979         } catch (...) {
1980                 return -1;
1981         }
1982 }
1983
1984 void
1985 Session::refresh_disk_space ()
1986 {
1987 #if HAVE_SYS_VFS_H
1988         struct statfs statfsbuf;
1989         vector<space_and_path>::iterator i;
1990         Glib::Mutex::Lock lm (space_lock);
1991         double scale;
1992
1993         /* get freespace on every FS that is part of the session path */
1994
1995         _total_free_4k_blocks = 0;
1996
1997         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1998                 statfs ((*i).path.c_str(), &statfsbuf);
1999
2000                 scale = statfsbuf.f_bsize/4096.0;
2001
2002                 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2003                 _total_free_4k_blocks += (*i).blocks;
2004         }
2005 #endif
2006 }
2007
2008 string
2009 Session::get_best_session_directory_for_new_source ()
2010 {
2011         vector<space_and_path>::iterator i;
2012         string result = _session_dir->root_path().to_string();
2013
2014         /* handle common case without system calls */
2015
2016         if (session_dirs.size() == 1) {
2017                 return result;
2018         }
2019
2020         /* OK, here's the algorithm we're following here:
2021
2022         We want to select which directory to use for
2023         the next file source to be created. Ideally,
2024         we'd like to use a round-robin process so as to
2025         get maximum performance benefits from splitting
2026         the files across multiple disks.
2027
2028         However, in situations without much diskspace, an
2029         RR approach may end up filling up a filesystem
2030         with new files while others still have space.
2031         Its therefore important to pay some attention to
2032         the freespace in the filesystem holding each
2033         directory as well. However, if we did that by
2034         itself, we'd keep creating new files in the file
2035         system with the most space until it was as full
2036         as all others, thus negating any performance
2037         benefits of this RAID-1 like approach.
2038
2039         So, we use a user-configurable space threshold. If
2040         there are at least 2 filesystems with more than this
2041         much space available, we use RR selection between them.
2042         If not, then we pick the filesystem with the most space.
2043
2044         This gets a good balance between the two
2045         approaches.
2046         */
2047
2048         refresh_disk_space ();
2049
2050         int free_enough = 0;
2051
2052         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2053                 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2054                         free_enough++;
2055                 }
2056         }
2057
2058         if (free_enough >= 2) {
2059                 /* use RR selection process, ensuring that the one
2060                    picked works OK.
2061                 */
2062
2063                 i = last_rr_session_dir;
2064
2065                 do {
2066                         if (++i == session_dirs.end()) {
2067                                 i = session_dirs.begin();
2068                         }
2069
2070                         if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2071                                 if (create_session_directory ((*i).path)) {
2072                                         result = (*i).path;
2073                                         last_rr_session_dir = i;
2074                                         return result;
2075                                 }
2076                         }
2077
2078                 } while (i != last_rr_session_dir);
2079
2080         } else {
2081
2082                 /* pick FS with the most freespace (and that
2083                    seems to actually work ...)
2084                 */
2085
2086                 vector<space_and_path> sorted;
2087                 space_and_path_ascending_cmp cmp;
2088
2089                 sorted = session_dirs;
2090                 sort (sorted.begin(), sorted.end(), cmp);
2091
2092                 for (i = sorted.begin(); i != sorted.end(); ++i) {
2093                         if (create_session_directory ((*i).path)) {
2094                                 result = (*i).path;
2095                                 last_rr_session_dir = i;
2096                                 return result;
2097                         }
2098                 }
2099         }
2100
2101         return result;
2102 }
2103
2104 int
2105 Session::load_named_selections (const XMLNode& node)
2106 {
2107         XMLNodeList nlist;
2108         XMLNodeConstIterator niter;
2109         NamedSelection *ns;
2110
2111         nlist = node.children();
2112
2113         set_dirty();
2114
2115         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2116
2117                 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2118                         error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2119                 }
2120         }
2121
2122         return 0;
2123 }
2124
2125 NamedSelection *
2126 Session::XMLNamedSelectionFactory (const XMLNode& node)
2127 {
2128         try {
2129                 return new NamedSelection (*this, node);
2130         }
2131
2132         catch (failed_constructor& err) {
2133                 return 0;
2134         }
2135 }
2136
2137 string
2138 Session::automation_dir () const
2139 {
2140         return Glib::build_filename (_path, "automation");
2141 }
2142
2143 string
2144 Session::analysis_dir () const
2145 {
2146         return Glib::build_filename (_path, "analysis");
2147 }
2148
2149 int
2150 Session::load_bundles (XMLNode const & node)
2151 {
2152         XMLNodeList nlist = node.children();
2153         XMLNodeConstIterator niter;
2154
2155         set_dirty();
2156
2157         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2158                 if ((*niter)->name() == "InputBundle") {
2159                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2160                 } else if ((*niter)->name() == "OutputBundle") {
2161                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2162                 } else {
2163                         error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2164                         return -1;
2165                 }
2166         }
2167
2168         return 0;
2169 }
2170
2171 int
2172 Session::load_route_groups (const XMLNode& node, int version)
2173 {
2174         XMLNodeList nlist = node.children();
2175         XMLNodeConstIterator niter;
2176
2177         set_dirty ();
2178
2179         if (version >= 3000) {
2180                 
2181                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2182                         if ((*niter)->name() == "RouteGroup") {
2183                                 RouteGroup* rg = new RouteGroup (*this, "");
2184                                 add_route_group (rg);
2185                                 rg->set_state (**niter, version);
2186                         }
2187                 }
2188
2189         } else if (version < 3000) {
2190
2191                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2192                         if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2193                                 RouteGroup* rg = new RouteGroup (*this, "");
2194                                 add_route_group (rg);
2195                                 rg->set_state (**niter, version);
2196                         }
2197                 }
2198         }
2199
2200         return 0;
2201 }
2202
2203 void
2204 Session::auto_save()
2205 {
2206         save_state (_current_snapshot_name);
2207 }
2208
2209 static bool
2210 state_file_filter (const string &str, void */*arg*/)
2211 {
2212         return (str.length() > strlen(statefile_suffix) &&
2213                 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2214 }
2215
2216 struct string_cmp {
2217         bool operator()(const string* a, const string* b) {
2218                 return *a < *b;
2219         }
2220 };
2221
2222 static string*
2223 remove_end(string* state)
2224 {
2225         string statename(*state);
2226
2227         string::size_type start,end;
2228         if ((start = statename.find_last_of ('/')) != string::npos) {
2229                 statename = statename.substr (start+1);
2230         }
2231
2232         if ((end = statename.rfind(".ardour")) == string::npos) {
2233                 end = statename.length();
2234         }
2235
2236         return new string(statename.substr (0, end));
2237 }
2238
2239 vector<string *> *
2240 Session::possible_states (string path)
2241 {
2242         PathScanner scanner;
2243         vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2244
2245         transform(states->begin(), states->end(), states->begin(), remove_end);
2246
2247         string_cmp cmp;
2248         sort (states->begin(), states->end(), cmp);
2249
2250         return states;
2251 }
2252
2253 vector<string *> *
2254 Session::possible_states () const
2255 {
2256         return possible_states(_path);
2257 }
2258
2259 void
2260 Session::add_route_group (RouteGroup* g)
2261 {
2262         _route_groups.push_back (g);
2263         route_group_added (g); /* EMIT SIGNAL */
2264
2265         g->MembershipChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2266         g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2267         
2268         set_dirty ();
2269 }
2270
2271 void
2272 Session::remove_route_group (RouteGroup& rg)
2273 {
2274         list<RouteGroup*>::iterator i;
2275
2276         if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2277                 _route_groups.erase (i);
2278                 delete &rg;
2279
2280                 route_group_removed (); /* EMIT SIGNAL */
2281         }
2282
2283 }
2284
2285 RouteGroup *
2286 Session::route_group_by_name (string name)
2287 {
2288         list<RouteGroup *>::iterator i;
2289
2290         for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2291                 if ((*i)->name() == name) {
2292                         return* i;
2293                 }
2294         }
2295         return 0;
2296 }
2297
2298 UndoTransaction*
2299 Session::start_reversible_command (const string& name)
2300 {
2301         UndoTransaction* trans = new UndoTransaction();
2302         trans->set_name(name);
2303         return trans;
2304 }
2305
2306 void
2307 Session::finish_reversible_command (UndoTransaction& ut)
2308 {
2309         struct timeval now;
2310         gettimeofday(&now, 0);
2311         ut.set_timestamp(now);
2312         _history.add (&ut);
2313 }
2314
2315 void
2316 Session::begin_reversible_command(const string& name)
2317 {
2318         UndoTransaction* trans = new UndoTransaction();
2319         trans->set_name(name);
2320
2321         if (!_current_trans.empty()) {
2322                 _current_trans.top()->add_command (trans);
2323         } else {
2324                 _current_trans.push(trans);
2325         }
2326 }
2327
2328 void
2329 Session::commit_reversible_command(Command *cmd)
2330 {
2331         assert(!_current_trans.empty());
2332         struct timeval now;
2333
2334         if (cmd) {
2335                 _current_trans.top()->add_command(cmd);
2336         }
2337
2338         if (_current_trans.top()->empty()) {
2339                 _current_trans.pop();
2340                 return;
2341         }
2342
2343         gettimeofday(&now, 0);
2344         _current_trans.top()->set_timestamp(now);
2345
2346         _history.add(_current_trans.top());
2347         _current_trans.pop();
2348 }
2349
2350 static bool
2351 accept_all_non_peak_files (const string& path, void */*arg*/)
2352 {
2353         return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2354 }
2355
2356 static bool
2357 accept_all_state_files (const string& path, void */*arg*/)
2358 {
2359         return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2360 }
2361
2362 int
2363 Session::find_all_sources (string path, set<string>& result)
2364 {
2365         XMLTree tree;
2366         XMLNode* node;
2367
2368         if (!tree.read (path)) {
2369                 return -1;
2370         }
2371
2372         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2373                 return -2;
2374         }
2375
2376         XMLNodeList nlist;
2377         XMLNodeConstIterator niter;
2378
2379         nlist = node->children();
2380
2381         set_dirty();
2382
2383         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2384
2385                 XMLProperty* prop;
2386
2387                 if ((prop = (*niter)->property (X_("type"))) == 0) {
2388                         continue;
2389                 }
2390
2391                 DataType type (prop->value());
2392
2393                 if ((prop = (*niter)->property (X_("name"))) == 0) {
2394                         continue;
2395                 }
2396
2397                 if (prop->value()[0] == '/') {
2398                         /* external file, ignore */
2399                         continue;
2400                 }
2401
2402                 Glib::ustring found_path;
2403                 bool is_new;
2404                 uint16_t chan;
2405
2406                 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2407                         result.insert (found_path);
2408                 }
2409         }
2410
2411         return 0;
2412 }
2413
2414 int
2415 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2416 {
2417         PathScanner scanner;
2418         vector<string*>* state_files;
2419         string ripped;
2420         string this_snapshot_path;
2421
2422         result.clear ();
2423
2424         ripped = _path;
2425
2426         if (ripped[ripped.length()-1] == '/') {
2427                 ripped = ripped.substr (0, ripped.length() - 1);
2428         }
2429
2430         state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2431
2432         if (state_files == 0) {
2433                 /* impossible! */
2434                 return 0;
2435         }
2436
2437         this_snapshot_path = _path;
2438         this_snapshot_path += legalize_for_path (_current_snapshot_name);
2439         this_snapshot_path += statefile_suffix;
2440
2441         for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2442
2443                 if (exclude_this_snapshot && **i == this_snapshot_path) {
2444                         continue;
2445                 }
2446
2447                 if (find_all_sources (**i, result) < 0) {
2448                         return -1;
2449                 }
2450         }
2451
2452         return 0;
2453 }
2454
2455 struct RegionCounter {
2456     typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2457     AudioSourceList::iterator iter;
2458     boost::shared_ptr<Region> region;
2459     uint32_t count;
2460
2461     RegionCounter() : count (0) {}
2462 };
2463
2464 int
2465 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2466 {
2467         boost::optional<int> r = AskAboutPlaylistDeletion (p);
2468         return r.get_value_or (1);
2469 }
2470
2471 int
2472 Session::cleanup_sources (CleanupReport& rep)
2473 {
2474         // FIXME: needs adaptation to midi
2475
2476         vector<boost::shared_ptr<Source> > dead_sources;
2477         PathScanner scanner;
2478         string sound_path;
2479         vector<space_and_path>::iterator i;
2480         vector<space_and_path>::iterator nexti;
2481         vector<string*>* soundfiles;
2482         vector<string> unused;
2483         set<string> all_sources;
2484         bool used;
2485         string spath;
2486         int ret = -1;
2487
2488         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2489
2490         /* step 1: consider deleting all unused playlists */
2491         
2492         if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2493                 ret = 0;
2494                 goto out;
2495         }
2496
2497         /* step 2: find all un-used sources */
2498
2499         rep.paths.clear ();
2500         rep.space = 0;
2501
2502         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2503
2504                 SourceMap::iterator tmp;
2505
2506                 tmp = i;
2507                 ++tmp;
2508
2509                 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2510                    capture files.
2511                 */
2512
2513                 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2514                         dead_sources.push_back (i->second);
2515                         i->second->drop_references ();
2516                 }
2517
2518                 i = tmp;
2519         }
2520
2521         /* build a list of all the possible sound directories for the session */
2522
2523         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2524
2525                 nexti = i;
2526                 ++nexti;
2527
2528                 SessionDirectory sdir ((*i).path);
2529                 sound_path += sdir.sound_path().to_string();
2530
2531                 if (nexti != session_dirs.end()) {
2532                         sound_path += ':';
2533                 }
2534
2535                 i = nexti;
2536         }
2537
2538         /* now do the same thing for the files that ended up in the sounds dir(s)
2539            but are not referenced as sources in any snapshot.
2540         */
2541
2542         soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2543
2544         if (soundfiles == 0) {
2545                 return 0;
2546         }
2547
2548         /* find all sources, but don't use this snapshot because the
2549            state file on disk still references sources we may have already
2550            dropped.
2551         */
2552
2553         find_all_sources_across_snapshots (all_sources, true);
2554
2555         /*  add our current source list
2556          */
2557
2558         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2559                 boost::shared_ptr<FileSource> fs;
2560
2561                 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2562                         all_sources.insert (fs->path());
2563                 }
2564         }
2565
2566         char tmppath1[PATH_MAX+1];
2567         char tmppath2[PATH_MAX+1];
2568
2569         for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2570
2571                 used = false;
2572                 spath = **x;
2573
2574                 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2575
2576                         if (realpath(spath.c_str(), tmppath1) == 0) {
2577                                 error << string_compose (_("Cannot expand path %1 (%2)"),
2578                                                          spath, strerror (errno)) << endmsg;
2579                                 continue;
2580                         }
2581
2582                         if (realpath((*i).c_str(),  tmppath2) == 0) {
2583                                 error << string_compose (_("Cannot expand path %1 (%2)"),
2584                                                          (*i), strerror (errno)) << endmsg;
2585                                 continue;
2586                         }
2587
2588                         if (strcmp(tmppath1, tmppath2) == 0) {
2589                                 used = true;
2590                                 break;
2591                         }
2592                 }
2593
2594                 if (!used) {
2595                         unused.push_back (spath);
2596                 }
2597         }
2598
2599         /* now try to move all unused files into the "dead_sounds" directory(ies) */
2600
2601         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2602                 struct stat statbuf;
2603
2604                 rep.paths.push_back (*x);
2605                 if (stat ((*x).c_str(), &statbuf) == 0) {
2606                         rep.space += statbuf.st_size;
2607                 }
2608
2609                 string newpath;
2610
2611                 /* don't move the file across filesystems, just
2612                    stick it in the `dead_sound_dir_name' directory
2613                    on whichever filesystem it was already on.
2614                 */
2615
2616                 if ((*x).find ("/sounds/") != string::npos) {
2617
2618                         /* old school, go up 1 level */
2619
2620                         newpath = Glib::path_get_dirname (*x);      // "sounds"
2621                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2622
2623                 } else {
2624
2625                         /* new school, go up 4 levels */
2626
2627                         newpath = Glib::path_get_dirname (*x);      // "audiofiles"
2628                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2629                         newpath = Glib::path_get_dirname (newpath); // "interchange"
2630                         newpath = Glib::path_get_dirname (newpath); // "session-dir"
2631                 }
2632
2633                 newpath += '/';
2634                 newpath += dead_sound_dir_name;
2635
2636                 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2637                         error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2638                         return -1;
2639                 }
2640
2641                 newpath += '/';
2642                 newpath += Glib::path_get_basename ((*x));
2643
2644                 if (access (newpath.c_str(), F_OK) == 0) {
2645
2646                         /* the new path already exists, try versioning */
2647
2648                         char buf[PATH_MAX+1];
2649                         int version = 1;
2650                         string newpath_v;
2651
2652                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2653                         newpath_v = buf;
2654
2655                         while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2656                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2657                                 newpath_v = buf;
2658                         }
2659
2660                         if (version == 999) {
2661                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2662                                                   newpath)
2663                                       << endmsg;
2664                         } else {
2665                                 newpath = newpath_v;
2666                         }
2667
2668                 } else {
2669
2670                         /* it doesn't exist, or we can't read it or something */
2671
2672                 }
2673
2674                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2675                         error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2676                                           (*x), newpath, strerror (errno))
2677                               << endmsg;
2678                         goto out;
2679                 }
2680
2681                 /* see if there an easy to find peakfile for this file, and remove it.
2682                  */
2683
2684                 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2685                 peakpath += peakfile_suffix;
2686
2687                 if (access (peakpath.c_str(), W_OK) == 0) {
2688                         if (::unlink (peakpath.c_str()) != 0) {
2689                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2690                                                   peakpath, _path, strerror (errno))
2691                                       << endmsg;
2692                                 /* try to back out */
2693                                 rename (newpath.c_str(), _path.c_str());
2694                                 goto out;
2695                         }
2696                 }
2697         }
2698
2699         ret = 0;
2700
2701         /* dump the history list */
2702
2703         _history.clear ();
2704
2705         /* save state so we don't end up a session file
2706            referring to non-existent sources.
2707         */
2708
2709         save_state ("");
2710
2711   out:
2712         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2713
2714         return ret;
2715 }
2716
2717 int
2718 Session::cleanup_trash_sources (CleanupReport& rep)
2719 {
2720         // FIXME: needs adaptation for MIDI
2721
2722         vector<space_and_path>::iterator i;
2723         string dead_sound_dir;
2724         struct dirent* dentry;
2725         struct stat statbuf;
2726         DIR* dead;
2727
2728         rep.paths.clear ();
2729         rep.space = 0;
2730
2731         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2732
2733                 dead_sound_dir = (*i).path;
2734                 dead_sound_dir += dead_sound_dir_name;
2735
2736                 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2737                         continue;
2738                 }
2739
2740                 while ((dentry = readdir (dead)) != 0) {
2741
2742                         /* avoid '.' and '..' */
2743
2744                         if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2745                             (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2746                                 continue;
2747                         }
2748
2749                         string fullpath;
2750
2751                         fullpath = dead_sound_dir;
2752                         fullpath += '/';
2753                         fullpath += dentry->d_name;
2754
2755                         if (stat (fullpath.c_str(), &statbuf)) {
2756                                 continue;
2757                         }
2758
2759                         if (!S_ISREG (statbuf.st_mode)) {
2760                                 continue;
2761                         }
2762
2763                         if (unlink (fullpath.c_str())) {
2764                                 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2765                                                   fullpath, strerror (errno))
2766                                       << endmsg;
2767                         }
2768
2769                         rep.paths.push_back (dentry->d_name);
2770                         rep.space += statbuf.st_size;
2771                 }
2772
2773                 closedir (dead);
2774
2775         }
2776
2777         return 0;
2778 }
2779
2780 void
2781 Session::set_dirty ()
2782 {
2783         bool was_dirty = dirty();
2784
2785         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2786
2787
2788         if (!was_dirty) {
2789                 DirtyChanged(); /* EMIT SIGNAL */
2790         }
2791 }
2792
2793
2794 void
2795 Session::set_clean ()
2796 {
2797         bool was_dirty = dirty();
2798
2799         _state_of_the_state = Clean;
2800
2801
2802         if (was_dirty) {
2803                 DirtyChanged(); /* EMIT SIGNAL */
2804         }
2805 }
2806
2807 void
2808 Session::set_deletion_in_progress ()
2809 {
2810         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2811 }
2812
2813 void
2814 Session::clear_deletion_in_progress ()
2815 {
2816         _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2817 }
2818
2819 void
2820 Session::add_controllable (boost::shared_ptr<Controllable> c)
2821 {
2822         /* this adds a controllable to the list managed by the Session.
2823            this is a subset of those managed by the Controllable class
2824            itself, and represents the only ones whose state will be saved
2825            as part of the session.
2826         */
2827
2828         Glib::Mutex::Lock lm (controllables_lock);
2829         controllables.insert (c);
2830 }
2831
2832 struct null_deleter { void operator()(void const *) const {} };
2833
2834 void
2835 Session::remove_controllable (Controllable* c)
2836 {
2837         if (_state_of_the_state | Deletion) {
2838                 return;
2839         }
2840
2841         Glib::Mutex::Lock lm (controllables_lock);
2842
2843         Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2844
2845         if (x != controllables.end()) {
2846                 controllables.erase (x);
2847         }
2848 }
2849
2850 boost::shared_ptr<Controllable>
2851 Session::controllable_by_id (const PBD::ID& id)
2852 {
2853         Glib::Mutex::Lock lm (controllables_lock);
2854
2855         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2856                 if ((*i)->id() == id) {
2857                         return *i;
2858                 }
2859         }
2860
2861         return boost::shared_ptr<Controllable>();
2862 }
2863
2864 boost::shared_ptr<Controllable>
2865 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2866 {
2867         boost::shared_ptr<Controllable> c;
2868         boost::shared_ptr<Route> r;
2869
2870         switch (desc.top_level_type()) {
2871         case ControllableDescriptor::NamedRoute:
2872         {
2873                 std::string str = desc.top_level_name();
2874                 if (str == "master") {
2875                         r = _master_out;
2876                 } else if (str == "control" || str == "listen") {
2877                         r = _monitor_out;
2878                 } else {
2879                         r = route_by_name (desc.top_level_name());
2880                 }
2881                 break;
2882         }
2883
2884         case ControllableDescriptor::RemoteControlID:
2885                 r = route_by_remote_id (desc.rid());
2886                 break;
2887         }
2888         
2889         if (!r) {
2890                 return c;
2891         }
2892
2893         switch (desc.subtype()) {
2894         case ControllableDescriptor::Gain:
2895                 c = r->gain_control ();
2896                 break;
2897
2898         case ControllableDescriptor::Solo:
2899                 c = r->solo_control();
2900                 break;
2901
2902         case ControllableDescriptor::Mute:
2903                 c = r->mute_control();
2904                 break;
2905
2906         case ControllableDescriptor::Recenable:
2907         {
2908                 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
2909                 
2910                 if (t) {
2911                         c = t->rec_enable_control ();
2912                 }
2913                 break;
2914         }
2915
2916         case ControllableDescriptor::Pan:
2917                 /* XXX pan control */
2918                 break;
2919
2920         case ControllableDescriptor::Balance:
2921                 /* XXX simple pan control */
2922                 break;
2923
2924         case ControllableDescriptor::PluginParameter:
2925         {
2926                 uint32_t plugin = desc.target (0);
2927                 uint32_t parameter_index = desc.target (1);
2928
2929                 /* revert to zero based counting */
2930                 
2931                 if (plugin > 0) {
2932                         --plugin;
2933                 }
2934                 
2935                 if (parameter_index > 0) {
2936                         --parameter_index;
2937                 }
2938
2939                 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
2940                 
2941                 if (p) {
2942                         c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
2943                                 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
2944                 }
2945                 break;
2946         }
2947
2948         case ControllableDescriptor::SendGain: 
2949         {
2950                 uint32_t send = desc.target (0);
2951
2952                 /* revert to zero-based counting */
2953                 
2954                 if (send > 0) {
2955                         --send;
2956                 }
2957                 
2958                 boost::shared_ptr<Processor> p = r->nth_send (send);
2959                 
2960                 if (p) {
2961                         boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
2962                         boost::shared_ptr<Amp> a = s->amp();
2963
2964                         if (a) {
2965                                 c = s->amp()->gain_control();
2966                         }
2967                 }
2968                 break;
2969         }
2970
2971         default:
2972                 /* relax and return a null pointer */
2973                 break;
2974         }
2975
2976         return c;
2977 }
2978
2979 void
2980 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2981 {
2982         if (_writable) {
2983                 Stateful::add_instant_xml (node, _path);
2984         }
2985
2986         if (write_to_config) {
2987                 Config->add_instant_xml (node);
2988         }
2989 }
2990
2991 XMLNode*
2992 Session::instant_xml (const string& node_name)
2993 {
2994         return Stateful::instant_xml (node_name, _path);
2995 }
2996
2997 int
2998 Session::save_history (string snapshot_name)
2999 {
3000         XMLTree tree;
3001
3002         if (!_writable) {
3003                 return 0;
3004         }
3005
3006         if (snapshot_name.empty()) {
3007                 snapshot_name = _current_snapshot_name;
3008         }
3009
3010         const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3011         const string backup_filename = history_filename + backup_suffix;
3012         const sys::path xml_path = _session_dir->root_path() / history_filename;
3013         const sys::path backup_path = _session_dir->root_path() / backup_filename;
3014
3015         if (sys::exists (xml_path)) {
3016                 try
3017                 {
3018                         sys::rename (xml_path, backup_path);
3019                 }
3020                 catch (const sys::filesystem_error& err)
3021                 {
3022                         error << _("could not backup old history file, current history not saved") << endmsg;
3023                         return -1;
3024                 }
3025         }
3026
3027         if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3028                 return 0;
3029         }
3030
3031         tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3032
3033         if (!tree.write (xml_path.to_string()))
3034         {
3035                 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3036
3037                 try
3038                 {
3039                         sys::remove (xml_path);
3040                         sys::rename (backup_path, xml_path);
3041                 }
3042                 catch (const sys::filesystem_error& err)
3043                 {
3044                         error << string_compose (_("could not restore history file from backup %1 (%2)"),
3045                                         backup_path.to_string(), err.what()) << endmsg;
3046                 }
3047
3048                 return -1;
3049         }
3050
3051         return 0;
3052 }
3053
3054 int
3055 Session::restore_history (string snapshot_name)
3056 {
3057         XMLTree tree;
3058
3059         if (snapshot_name.empty()) {
3060                 snapshot_name = _current_snapshot_name;
3061         }
3062
3063         const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3064         const sys::path xml_path = _session_dir->root_path() / xml_filename;
3065
3066         info << "Loading history from " << xml_path.to_string() << endmsg;
3067
3068         if (!sys::exists (xml_path)) {
3069                 info << string_compose (_("%1: no history file \"%2\" for this session."),
3070                                 _name, xml_path.to_string()) << endmsg;
3071                 return 1;
3072         }
3073
3074         if (!tree.read (xml_path.to_string())) {
3075                 error << string_compose (_("Could not understand session history file \"%1\""),
3076                                 xml_path.to_string()) << endmsg;
3077                 return -1;
3078         }
3079
3080         // replace history
3081         _history.clear();
3082
3083         for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3084
3085                 XMLNode *t = *it;
3086                 UndoTransaction* ut = new UndoTransaction ();
3087                 struct timeval tv;
3088
3089                 ut->set_name(t->property("name")->value());
3090                 stringstream ss(t->property("tv-sec")->value());
3091                 ss >> tv.tv_sec;
3092                 ss.str(t->property("tv-usec")->value());
3093                 ss >> tv.tv_usec;
3094                 ut->set_timestamp(tv);
3095
3096                 for (XMLNodeConstIterator child_it  = t->children().begin();
3097                                 child_it != t->children().end(); child_it++)
3098                 {
3099                         XMLNode *n = *child_it;
3100                         Command *c;
3101
3102                         if (n->name() == "MementoCommand" ||
3103                                         n->name() == "MementoUndoCommand" ||
3104                                         n->name() == "MementoRedoCommand") {
3105
3106                                 if ((c = memento_command_factory(n))) {
3107                                         ut->add_command(c);
3108                                 }
3109
3110                         } else if (n->name() == "DiffCommand") {
3111                                 PBD::ID  id(n->property("midi-source")->value());
3112                                 boost::shared_ptr<MidiSource> midi_source =
3113                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3114                                 if (midi_source) {
3115                                         ut->add_command(new MidiModel::DiffCommand(midi_source->model(), *n));
3116                                 } else {
3117                                         error << _("Failed to downcast MidiSource for DiffCommand") << endmsg;
3118                                 }
3119
3120                         } else if (n->name() == "StatefulDiffCommand") {
3121                                 if ((c = stateful_diff_command_factory (n))) {
3122                                         ut->add_command (c);
3123                                 }
3124                         } else {
3125                                 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3126                         }
3127                 }
3128
3129                 _history.add (ut);
3130         }
3131
3132         return 0;
3133 }
3134
3135 void
3136 Session::config_changed (std::string p, bool ours)
3137 {
3138         if (ours) {
3139                 set_dirty ();
3140         }
3141
3142         if (p == "seamless-loop") {
3143
3144         } else if (p == "rf-speed") {
3145
3146         } else if (p == "auto-loop") {
3147
3148         } else if (p == "auto-input") {
3149
3150                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3151                         /* auto-input only makes a difference if we're rolling */
3152
3153                         boost::shared_ptr<RouteList> rl = routes.reader ();
3154                         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3155                                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3156                                 if (tr && tr->record_enabled ()) {
3157                                         tr->monitor_input (!config.get_auto_input());
3158                                 }
3159                         }
3160                 }
3161
3162         } else if (p == "punch-in") {
3163
3164                 Location* location;
3165
3166                 if ((location = _locations.auto_punch_location()) != 0) {
3167
3168                         if (config.get_punch_in ()) {
3169                                 replace_event (SessionEvent::PunchIn, location->start());
3170                         } else {
3171                                 remove_event (location->start(), SessionEvent::PunchIn);
3172                         }
3173                 }
3174
3175         } else if (p == "punch-out") {
3176
3177                 Location* location;
3178
3179                 if ((location = _locations.auto_punch_location()) != 0) {
3180
3181                         if (config.get_punch_out()) {
3182                                 replace_event (SessionEvent::PunchOut, location->end());
3183                         } else {
3184                                 clear_events (SessionEvent::PunchOut);
3185                         }
3186                 }
3187
3188         } else if (p == "edit-mode") {
3189
3190                 Glib::Mutex::Lock lm (playlists->lock);
3191
3192                 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3193                         (*i)->set_edit_mode (Config->get_edit_mode ());
3194                 }
3195
3196         } else if (p == "use-video-sync") {
3197
3198                 waiting_for_sync_offset = config.get_use_video_sync();
3199
3200         } else if (p == "mmc-control") {
3201
3202                 //poke_midi_thread ();
3203
3204         } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3205
3206                 _mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3207
3208         } else if (p == "mmc-send-id") {
3209
3210                 _mmc->set_send_device_id (Config->get_mmc_send_device_id());
3211
3212         } else if (p == "midi-control") {
3213
3214                 //poke_midi_thread ();
3215
3216         } else if (p == "raid-path") {
3217
3218                 setup_raid_path (config.get_raid_path());
3219
3220         } else if (p == "timecode-format") {
3221
3222                 sync_time_vars ();
3223
3224         } else if (p == "video-pullup") {
3225
3226                 sync_time_vars ();
3227
3228         } else if (p == "seamless-loop") {
3229
3230                 if (play_loop && transport_rolling()) {
3231                         // to reset diskstreams etc
3232                         request_play_loop (true);
3233                 }
3234
3235         } else if (p == "rf-speed") {
3236
3237                 cumulative_rf_motion = 0;
3238                 reset_rf_scale (0);
3239
3240         } else if (p == "click-sound") {
3241
3242                 setup_click_sounds (1);
3243
3244         } else if (p == "click-emphasis-sound") {
3245
3246                 setup_click_sounds (-1);
3247
3248         } else if (p == "clicking") {
3249
3250                 if (Config->get_clicking()) {
3251                         if (_click_io && click_data) { // don't require emphasis data
3252                                 _clicking = true;
3253                         }
3254                 } else {
3255                         _clicking = false;
3256                 }
3257
3258         } else if (p == "send-mtc") {
3259
3260                 session_send_mtc = Config->get_send_mtc();
3261                 if (session_send_mtc) {
3262                         /* mark us ready to send */
3263                         next_quarter_frame_to_send = 0;
3264                 }
3265
3266         } else if (p == "send-mmc") {
3267
3268                 _mmc->enable_send (Config->get_send_mmc ());
3269
3270         } else if (p == "midi-feedback") {
3271
3272                 session_midi_feedback = Config->get_midi_feedback();
3273
3274         } else if (p == "jack-time-master") {
3275
3276                 engine().reset_timebase ();
3277
3278         } else if (p == "native-file-header-format") {
3279
3280                 if (!first_file_header_format_reset) {
3281                         reset_native_file_format ();
3282                 }
3283
3284                 first_file_header_format_reset = false;
3285
3286         } else if (p == "native-file-data-format") {
3287
3288                 if (!first_file_data_format_reset) {
3289                         reset_native_file_format ();
3290                 }
3291
3292                 first_file_data_format_reset = false;
3293
3294         } else if (p == "external-sync") {
3295                 if (!config.get_external_sync()) {
3296                         drop_sync_source ();
3297                 } else {
3298                         switch_to_sync_source (config.get_sync_source());
3299                 }
3300         } else if (p == "remote-model") {
3301                 set_remote_control_ids ();
3302         }  else if (p == "denormal-model") {
3303                 setup_fpu ();
3304         } else if (p == "history-depth") {
3305                 set_history_depth (Config->get_history_depth());
3306         } else if (p == "sync-all-route-ordering") {
3307                 sync_order_keys ("session");
3308         } else if (p == "initial-program-change") {
3309
3310                 if (_mmc->output_port() && Config->get_initial_program_change() >= 0) {
3311                         MIDI::byte buf[2];
3312
3313                         buf[0] = MIDI::program; // channel zero by default
3314                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3315
3316                         _mmc->output_port()->midimsg (buf, sizeof (buf), 0);
3317                 }
3318         } else if (p == "solo-mute-override") {
3319                 // catch_up_on_solo_mute_override ();
3320         } else if (p == "listen-position") {
3321                 listen_position_changed ();
3322         } else if (p == "solo-control-is-listen-control") {
3323                 solo_control_mode_changed ();
3324         }
3325
3326
3327         set_dirty ();
3328 }
3329
3330 void
3331 Session::set_history_depth (uint32_t d)
3332 {
3333         _history.set_depth (d);
3334 }
3335
3336 int
3337 Session::load_diskstreams_2X (XMLNode const & node, int)
3338 {
3339         XMLNodeList          clist;
3340         XMLNodeConstIterator citer;
3341
3342         clist = node.children();
3343
3344         for (citer = clist.begin(); citer != clist.end(); ++citer) {
3345
3346                 try {
3347                         /* diskstreams added automatically by DiskstreamCreated handler */
3348                         if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3349                                 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3350                                 _diskstreams_2X.push_back (dsp);
3351                         } else {
3352                                 error << _("Session: unknown diskstream type in XML") << endmsg;
3353                         }
3354                 }
3355
3356                 catch (failed_constructor& err) {
3357                         error << _("Session: could not load diskstream via XML state") << endmsg;
3358                         return -1;
3359                 }
3360         }
3361
3362         return 0;
3363 }
3364
3365 /** Create our MachineControl object and connect things to it */
3366 void
3367 Session::setup_midi_machine_control ()
3368 {
3369         _mmc = new MIDI::MachineControl (_engine.jack());
3370         
3371         _mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3372         _mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3373         _mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3374         _mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3375         _mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3376         _mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3377         _mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3378         _mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3379         _mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3380         _mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3381         _mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3382         _mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3383         _mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3384
3385         /* also handle MIDI SPP because its so common */
3386
3387         _mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this, _1, _2));
3388         _mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3389         _mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));
3390 }