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