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