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