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