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