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