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