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