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