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