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