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