3f9a48134067834e2c4bfbdd6c3c1424cc9c938b
[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         current_trans = 0;
209         first_file_data_format_reset = true;
210         first_file_header_format_reset = true;
211         butler_thread = (pthread_t) 0;
212         //midi_thread = (pthread_t) 0;
213
214         AudioDiskstream::allocate_working_buffers();
215
216         /* default short fade = 15ms */
217
218         Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
219         SndFileSource::setup_standard_crossfades (frame_rate());
220
221         last_mmc_step.tv_sec = 0;
222         last_mmc_step.tv_usec = 0;
223         step_speed = 0.0;
224
225         /* click sounds are unset by default, which causes us to internal
226            waveforms for clicks.
227         */
228         
229         click_length = 0;
230         click_emphasis_length = 0;
231         _clicking = false;
232
233         process_function = &Session::process_with_events;
234
235         if (Config->get_use_video_sync()) {
236                 waiting_for_sync_offset = true;
237         } else {
238                 waiting_for_sync_offset = false;
239         }
240
241         last_smpte_when = 0;
242         _smpte_offset = 0;
243         _smpte_offset_negative = true;
244         last_smpte_valid = false;
245
246         sync_time_vars ();
247
248         last_rr_session_dir = session_dirs.begin();
249         refresh_disk_space ();
250
251         // set_default_fade (0.2, 5.0); /* steepness, millisecs */
252
253         /* slave stuff */
254
255         average_slave_delta = 1800; // !!! why 1800 ????
256         have_first_delta_accumulator = false;
257         delta_accumulator_cnt = 0;
258         slave_state = Stopped;
259
260         _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
261
262         /* These are all static "per-class" signals */
263
264         RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
265         SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
266         PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
267         Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor));
268         NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
269         AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
270
271         Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
272
273         IO::PortCountChanged.connect (mem_fun (*this, &Session::ensure_buffers));
274
275         /* stop IO objects from doing stuff until we're ready for them */
276
277         IO::disable_panners ();
278         IO::disable_ports ();
279         IO::disable_connecting ();
280 }
281
282 int
283 Session::second_stage_init (bool new_session)
284 {
285         AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
286
287         if (!new_session) {
288                 if (load_state (_current_snapshot_name)) {
289                         return -1;
290                 }
291                 remove_empty_sounds ();
292         }
293
294         if (start_butler_thread()) {
295                 return -1;
296         }
297
298         if (start_midi_thread ()) {
299                 return -1;
300         }
301
302         // set_state() will call setup_raid_path(), but if it's a new session we need
303         // to call setup_raid_path() here.
304
305         if (state_tree) {
306                 if (set_state (*state_tree->root())) {
307                         return -1;
308                 }
309         } else {
310                 setup_raid_path(_path);
311         }
312
313         /* we can't save till after ::when_engine_running() is called,
314            because otherwise we save state with no connections made.
315            therefore, we reset _state_of_the_state because ::set_state()
316            will have cleared it.
317
318            we also have to include Loading so that any events that get
319            generated between here and the end of ::when_engine_running()
320            will be processed directly rather than queued.
321         */
322
323         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
324
325
326         _locations.changed.connect (mem_fun (this, &Session::locations_changed));
327         _locations.added.connect (mem_fun (this, &Session::locations_added));
328         setup_click_sounds (0);
329         setup_midi_control ();
330
331         /* Pay attention ... */
332
333         _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
334         _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
335
336         try {
337                 when_engine_running();
338         }
339
340         /* handle this one in a different way than all others, so that its clear what happened */
341         
342         catch (AudioEngine::PortRegistrationFailure& err) {
343                 error << _("Unable to create all required ports")
344                       << endmsg;
345                 return -1;
346         }
347
348         catch (...) {
349                 return -1;
350         }
351
352         BootMessage (_("Reset Remote Controls"));
353
354         send_full_time_code (0);
355         _engine.transport_locate (0);
356         deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
357         deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
358         
359         MidiClockTicker::instance().set_session(*this);
360         MIDI::Name::MidiPatchManager::instance().set_session(*this);
361
362         /* initial program change will be delivered later; see ::config_changed() */
363
364         BootMessage (_("Reset Control Protocols"));
365
366         ControlProtocolManager::instance().set_session (*this);
367
368         if (new_session) {
369                 _end_location_is_free = true;
370         } else {
371                 _end_location_is_free = false;
372         }
373
374         _state_of_the_state = Clean;
375         
376         DirtyChanged (); /* EMIT SIGNAL */
377
378         if (state_was_pending) {
379                 save_state (_current_snapshot_name);
380                 remove_pending_capture_state ();
381                 state_was_pending = false;
382         }
383         
384         BootMessage (_("Session loading complete"));
385
386         return 0;
387 }
388
389 string
390 Session::raid_path () const
391 {
392         SearchPath raid_search_path;
393
394         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
395                 raid_search_path += sys::path((*i).path);
396         }
397         
398         return raid_search_path.to_string ();
399 }
400
401 void
402 Session::setup_raid_path (string path)
403 {
404         if (path.empty()) {
405                 return;
406         }
407         
408         space_and_path sp;
409         string fspath;
410
411         session_dirs.clear ();
412
413         SearchPath search_path(path);
414         SearchPath sound_search_path;
415         SearchPath midi_search_path;
416
417         for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
418                 sp.path = (*i).to_string ();
419                 sp.blocks = 0; // not needed
420                 session_dirs.push_back (sp);
421
422                 SessionDirectory sdir(sp.path);
423
424                 sound_search_path += sdir.sound_path ();
425                 midi_search_path += sdir.midi_path ();
426         }
427
428         // set the search path for each data type
429         FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
430         SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
431
432         // reset the round-robin soundfile path thingie
433         last_rr_session_dir = session_dirs.begin();
434 }
435
436 int
437 Session::ensure_subdirs ()
438 {
439         string dir;
440
441         dir = session_directory().peak_path().to_string();
442
443         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
444                 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
445                 return -1;
446         }
447
448         dir = session_directory().sound_path().to_string();
449
450         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
451                 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
452                 return -1;
453         }
454         
455         dir = session_directory().midi_path().to_string();
456
457         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
458                 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
459                 return -1;
460         }
461
462         dir = session_directory().dead_sound_path().to_string();
463
464         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
465                 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
466                 return -1;
467         }
468
469         dir = session_directory().export_path().to_string();
470
471         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
472                 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
473                 return -1;
474         }
475
476         dir = analysis_dir ();
477
478         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
479                 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
480                 return -1;
481         }
482
483         return 0;
484 }
485
486 int
487 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
488 {
489
490         if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
491                 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
492                 return -1;
493         }
494
495         if (ensure_subdirs ()) {
496                 return -1;
497         }
498
499         /* check new_session so we don't overwrite an existing one */
500
501         if (!mix_template.empty()) {
502                 std::string in_path = mix_template;
503
504                 ifstream in(in_path.c_str());
505
506                 if (in){
507                         string out_path = _path;
508                         out_path += _name;
509                         out_path += statefile_suffix;
510
511                         ofstream out(out_path.c_str());
512
513                         if (out){
514                                 out << in.rdbuf();
515
516                                 // okay, session is set up.  Treat like normal saved
517                                 // session from now on.
518
519                                 new_session = false;
520                                 return 0;
521
522                         } else {
523                                 error << string_compose (_("Could not open %1 for writing mix template"), out_path) 
524                                         << endmsg;
525                                 return -1;
526                         }
527
528                 } else {
529                         error << string_compose (_("Could not open mix template %1 for reading"), in_path) 
530                                 << endmsg;
531                         return -1;
532                 }
533
534         }
535         
536         /* Instantiate metadata */
537         
538         _metadata = new SessionMetadata ();
539
540         /* set initial start + end point */
541
542         start_location->set_end (0);
543         _locations.add (start_location);
544
545         end_location->set_end (initial_length);
546         _locations.add (end_location);
547
548         _state_of_the_state = Clean;
549
550         save_state ("");
551
552         return 0;
553 }
554
555
556 int
557 Session::load_diskstreams (const XMLNode& node)
558 {
559         XMLNodeList          clist;
560         XMLNodeConstIterator citer;
561         
562         clist = node.children();
563
564         for (citer = clist.begin(); citer != clist.end(); ++citer) {
565
566                 try {
567                         /* diskstreams added automatically by DiskstreamCreated handler */
568                         if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
569                                 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
570                                 add_diskstream (dstream);
571                         } else if ((*citer)->name() == "MidiDiskstream") {
572                                 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
573                                 add_diskstream (dstream);
574                         } else {
575                                 error << _("Session: unknown diskstream type in XML") << endmsg;
576                         }
577                 } 
578                 
579                 catch (failed_constructor& err) {
580                         error << _("Session: could not load diskstream via XML state") << endmsg;
581                         return -1;
582                 }
583         }
584
585         return 0;
586 }
587
588 void
589 Session::maybe_write_autosave()
590 {
591         if (dirty() && record_status() != Recording) {
592                 save_state("", true);
593         }
594 }
595
596 void
597 Session::remove_pending_capture_state ()
598 {
599         sys::path pending_state_file_path(_session_dir->root_path());
600         
601         pending_state_file_path /= _current_snapshot_name + pending_suffix;
602
603         try
604         {
605                 sys::remove (pending_state_file_path);
606         }
607         catch(sys::filesystem_error& ex)
608         {
609                 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
610                                 pending_state_file_path.to_string(), ex.what()) << endmsg;
611         }
612 }
613
614 /** Rename a state file.
615  * @param snapshot_name Snapshot name.
616  */
617 void
618 Session::rename_state (string old_name, string new_name)
619 {
620         if (old_name == _current_snapshot_name || old_name == _name) {
621                 /* refuse to rename the current snapshot or the "main" one */
622                 return;
623         }
624
625         const string old_xml_filename = old_name + statefile_suffix;
626         const string new_xml_filename = new_name + statefile_suffix;
627
628         const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
629         const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
630
631         try
632         {
633                 sys::rename (old_xml_path, new_xml_path);
634         }
635         catch (const sys::filesystem_error& err)
636         {
637                 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
638                                 old_name, new_name, err.what()) << endmsg;
639         }
640 }
641
642 /** Remove a state file.
643  * @param snapshot_name Snapshot name.
644  */
645 void
646 Session::remove_state (string snapshot_name)
647 {
648         if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
649                 // refuse to remove the current snapshot or the "main" one
650                 return;
651         }
652
653         sys::path xml_path(_session_dir->root_path());
654
655         xml_path /= snapshot_name + statefile_suffix;
656
657         if (!create_backup_file (xml_path)) {
658                 // don't remove it if a backup can't be made
659                 // create_backup_file will log the error.
660                 return;
661         }
662
663         // and delete it
664         sys::remove (xml_path);
665 }
666
667 int
668 Session::save_state (string snapshot_name, bool pending)
669 {
670         XMLTree tree;
671         sys::path xml_path(_session_dir->root_path());
672
673         if (_state_of_the_state & CannotSave) {
674                 return 1;
675         }
676
677         if (!_engine.connected ()) {
678                 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
679                       << endmsg;
680                 return 1;
681         }
682
683         /* tell sources we're saving first, in case they write out to a new file
684          * which should be saved with the state rather than the old one */
685         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
686                 i->second->session_saved();
687
688         tree.set_root (&get_state());
689
690         if (snapshot_name.empty()) {
691                 snapshot_name = _current_snapshot_name;
692         }
693
694         if (!pending) {
695
696                 /* proper save: use statefile_suffix (.ardour in English) */
697                 
698                 xml_path /= snapshot_name + statefile_suffix;
699
700                 /* make a backup copy of the old file */
701
702                 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
703                         // create_backup_file will log the error
704                         return -1;
705                 }
706
707         } else {
708
709                 /* pending save: use pending_suffix (.pending in English) */
710                 xml_path /= snapshot_name + pending_suffix;
711         }
712
713         sys::path tmp_path(_session_dir->root_path());
714
715         tmp_path /= snapshot_name + temp_suffix;
716
717         // cerr << "actually writing state to " << xml_path.to_string() << endl;
718
719         if (!tree.write (tmp_path.to_string())) {
720                 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
721                 sys::remove (tmp_path);
722                 return -1;
723
724         } else {
725
726                 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
727                         error << string_compose (_("could not rename temporary session file %1 to %2"),
728                                         tmp_path.to_string(), xml_path.to_string()) << endmsg;
729                         sys::remove (tmp_path);
730                         return -1;
731                 }
732         }
733
734         if (!pending) {
735
736                 save_history (snapshot_name);
737
738                 bool was_dirty = dirty();
739
740                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
741                 
742                 if (was_dirty) {
743                         DirtyChanged (); /* EMIT SIGNAL */
744                 }
745
746                 StateSaved (snapshot_name); /* EMIT SIGNAL */
747         }
748
749         return 0;
750 }
751
752 int
753 Session::restore_state (string snapshot_name)
754 {
755         if (load_state (snapshot_name) == 0) {
756                 set_state (*state_tree->root());
757         }
758         
759         return 0;
760 }
761
762 int
763 Session::load_state (string snapshot_name)
764 {
765         delete state_tree;
766         state_tree = 0;
767
768         state_was_pending = false;
769
770         /* check for leftover pending state from a crashed capture attempt */
771
772         sys::path xmlpath(_session_dir->root_path());
773         xmlpath /= snapshot_name + pending_suffix;
774
775         if (sys::exists (xmlpath)) {
776
777                 /* there is pending state from a crashed capture attempt */
778
779                 if (AskAboutPendingState()) {
780                         state_was_pending = true;
781                 } 
782         } 
783
784         if (!state_was_pending) {
785                 xmlpath = _session_dir->root_path();
786                 xmlpath /= snapshot_name + statefile_suffix;
787         }
788         
789         if (!sys::exists (xmlpath)) {
790                 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
791                 return 1;
792         }
793
794         state_tree = new XMLTree;
795
796         set_dirty();
797
798         if (!state_tree->read (xmlpath.to_string())) {
799                 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
800                 delete state_tree;
801                 state_tree = 0;
802                 return -1;
803         }
804
805         XMLNode& root (*state_tree->root());
806         
807         if (root.name() != X_("Session")) {
808                 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
809                 delete state_tree;
810                 state_tree = 0;
811                 return -1;
812         }
813
814         const XMLProperty* prop;
815         bool is_old = false; // session is _very_ old (pre-2.0)
816
817         if ((prop = root.property ("version")) == 0) {
818                 /* no version implies very old version of Ardour */
819                 is_old = true;
820         } else {
821                 int major_version;
822                 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
823                 if (major_version < 2) {
824                         is_old = true;
825                 }
826         }
827
828         if (is_old) {
829
830                 sys::path backup_path(_session_dir->root_path());
831
832                 backup_path /= snapshot_name + "-1" + statefile_suffix;
833
834                 // only create a backup once
835                 if (sys::exists (backup_path)) {
836                         return 0;
837                 }
838
839                 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
840                                         xmlpath.to_string(), backup_path.to_string()) 
841                      << endmsg;
842
843                 try
844                 {
845                         sys::copy_file (xmlpath, backup_path);
846                 }
847                 catch(sys::filesystem_error& ex)
848                 {
849                         error << string_compose (_("Unable to make backup of state file %1 (%2)"),
850                                         xmlpath.to_string(), ex.what())
851                                 << endmsg;
852                         return -1;
853                 }
854         }
855
856         return 0;
857 }
858
859 int
860 Session::load_options (const XMLNode& node)
861 {
862         XMLNode* child;
863         XMLProperty* prop;
864         LocaleGuard lg (X_("POSIX"));
865
866         Config->set_variables (node, ConfigVariableBase::Session);
867
868         /* now reset MIDI ports because the session can have its own 
869            MIDI configuration.
870         */
871
872         setup_midi ();
873
874         if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
875                 if ((prop = child->property ("val")) != 0) {
876                         _end_location_is_free = (prop->value() == "yes");
877                 }
878         }
879
880         return 0;
881 }
882
883 bool
884 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
885 {
886         const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
887                 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
888
889         return owner & modified_by_session_or_user;
890 }
891
892 XMLNode&
893 Session::get_options () const
894 {
895         XMLNode* child;
896         LocaleGuard lg (X_("POSIX"));
897
898         XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
899
900         child = option_root.add_child ("end-marker-is-free");
901         child->add_property ("val", _end_location_is_free ? "yes" : "no");
902
903         return option_root;
904 }
905
906 XMLNode&
907 Session::get_state()
908 {
909         return state(true);
910 }
911
912 XMLNode&
913 Session::get_template()
914 {
915         /* if we don't disable rec-enable, diskstreams
916            will believe they need to store their capture
917            sources in their state node. 
918         */
919         
920         disable_record (false);
921
922         return state(false);
923 }
924
925 XMLNode&
926 Session::state(bool full_state)
927 {
928         XMLNode* node = new XMLNode("Session");
929         XMLNode* child;
930
931         // store libardour version, just in case
932         char buf[16];
933         snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
934         node->add_property("version", string(buf));
935                 
936         /* store configuration settings */
937
938         if (full_state) {
939         
940                 node->add_property ("name", _name);
941                 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
942                 node->add_property ("sample-rate", buf);
943
944                 if (session_dirs.size() > 1) {
945
946                         string p;
947
948                         vector<space_and_path>::iterator i = session_dirs.begin();
949                         vector<space_and_path>::iterator next;
950
951                         ++i; /* skip the first one */
952                         next = i;
953                         ++next;
954
955                         while (i != session_dirs.end()) {
956
957                                 p += (*i).path;
958
959                                 if (next != session_dirs.end()) {
960                                         p += ':';
961                                 } else {
962                                         break;
963                                 }
964
965                                 ++next;
966                                 ++i;
967                         }
968                         
969                         child = node->add_child ("Path");
970                         child->add_content (p);
971                 }
972         }
973
974         /* save the ID counter */
975         
976         snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
977         node->add_property ("id-counter", buf);
978
979         /* various options */
980
981         node->add_child_nocopy (get_options());
982
983         node->add_child_nocopy (_metadata->get_state());
984
985         child = node->add_child ("Sources");
986
987         if (full_state) {
988                 Glib::Mutex::Lock sl (source_lock);
989
990                 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
991                         
992                         /* Don't save information about non-destructive file sources that are empty */
993                         /* FIXME: MIDI breaks if this is made FileSource like it should be... */
994                         
995                         boost::shared_ptr<AudioFileSource> fs;
996                         if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
997                                 if (!fs->destructive()) {
998                                         if (fs->length() == 0) {
999                                                 continue;
1000                                         }
1001                                 }
1002                         }
1003                         
1004                         child->add_child_nocopy (siter->second->get_state());
1005                 }
1006         }
1007
1008         child = node->add_child ("Regions");
1009
1010         if (full_state) { 
1011                 Glib::Mutex::Lock rl (region_lock);
1012
1013                 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
1014                         
1015                         /* only store regions not attached to playlists */
1016
1017                         if (i->second->playlist() == 0) {
1018                                 child->add_child_nocopy (i->second->state (true));
1019                         }
1020                 }
1021         }
1022
1023         child = node->add_child ("DiskStreams");
1024
1025         { 
1026                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1027                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1028                         if (!(*i)->hidden()) {
1029                                 child->add_child_nocopy ((*i)->get_state());
1030                         }
1031                 }
1032         }
1033
1034         if (full_state) {
1035                 node->add_child_nocopy (_locations.get_state());
1036         } else {
1037                 // for a template, just create a new Locations, populate it
1038                 // with the default start and end, and get the state for that.
1039                 Locations loc;
1040                 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1041                 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1042                 start->set_end(0);
1043                 loc.add (start);
1044                 end->set_end(compute_initial_length());
1045                 loc.add (end);
1046                 node->add_child_nocopy (loc.get_state());
1047         }
1048         
1049         child = node->add_child ("Bundles");
1050         {
1051                 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1052                 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1053                         boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1054                         if (b) {
1055                                 child->add_child_nocopy (b->get_state());
1056                         }
1057                 }
1058         }
1059
1060         child = node->add_child ("Routes");
1061         {
1062                 boost::shared_ptr<RouteList> r = routes.reader ();
1063                 
1064                 RoutePublicOrderSorter cmp;
1065                 RouteList public_order (*r);
1066                 public_order.sort (cmp);
1067                 
1068                 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1069                         if (!(*i)->is_hidden()) {
1070                                 if (full_state) {
1071                                         child->add_child_nocopy ((*i)->get_state());
1072                                 } else {
1073                                         child->add_child_nocopy ((*i)->get_template());
1074                                 }
1075                         }
1076                 }
1077         }
1078
1079         
1080         child = node->add_child ("EditGroups");
1081         for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1082                 child->add_child_nocopy ((*i)->get_state());
1083         }
1084
1085         child = node->add_child ("MixGroups");
1086         for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1087                 child->add_child_nocopy ((*i)->get_state());
1088         }
1089
1090         child = node->add_child ("Playlists");
1091         for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1092                 if (!(*i)->hidden()) {
1093                         if (!(*i)->empty()) {
1094                                 if (full_state) {
1095                                         child->add_child_nocopy ((*i)->get_state());
1096                                 } else {
1097                                         child->add_child_nocopy ((*i)->get_template());
1098                                 }
1099                         }
1100                 }
1101         }
1102
1103         child = node->add_child ("UnusedPlaylists");
1104         for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1105                 if (!(*i)->hidden()) {
1106                         if (!(*i)->empty()) {
1107                                 if (full_state) {
1108                                         child->add_child_nocopy ((*i)->get_state());
1109                                 } else {
1110                                         child->add_child_nocopy ((*i)->get_template());
1111                                 }
1112                         }
1113                 }
1114         }
1115         
1116         
1117         if (_click_io) {
1118                 child = node->add_child ("Click");
1119                 child->add_child_nocopy (_click_io->state (full_state));
1120         }
1121
1122         if (full_state) {
1123                 child = node->add_child ("NamedSelections");
1124                 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1125                         if (full_state) {
1126                                 child->add_child_nocopy ((*i)->get_state());
1127                         } 
1128                 }
1129         }
1130
1131         node->add_child_nocopy (_tempo_map->get_state());
1132
1133         node->add_child_nocopy (get_control_protocol_state());
1134
1135         if (_extra_xml) {
1136                 node->add_child_copy (*_extra_xml);
1137         }
1138
1139         return *node;
1140 }
1141
1142 XMLNode&
1143 Session::get_control_protocol_state ()
1144 {
1145         ControlProtocolManager& cpm (ControlProtocolManager::instance());
1146         return cpm.get_state();
1147 }
1148
1149 int
1150 Session::set_state (const XMLNode& node)
1151 {
1152         XMLNodeList nlist;
1153         XMLNode* child;
1154         const XMLProperty* prop;
1155         int ret = -1;
1156
1157         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1158         
1159         if (node.name() != X_("Session")){
1160                 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1161                 return -1;
1162         }
1163
1164         if ((prop = node.property ("name")) != 0) {
1165                 _name = prop->value ();
1166         }
1167
1168         if ((prop = node.property (X_("sample-rate"))) != 0) {
1169
1170                 _nominal_frame_rate = atoi (prop->value());
1171
1172                 if (_nominal_frame_rate != _current_frame_rate) {
1173                         if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1174                                 return -1;
1175                         }
1176                 }
1177         }
1178
1179         setup_raid_path(_session_dir->root_path().to_string());
1180
1181         if ((prop = node.property (X_("id-counter"))) != 0) {
1182                 uint64_t x;
1183                 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1184                 ID::init_counter (x);
1185         } else {
1186                 /* old sessions used a timebased counter, so fake
1187                    the startup ID counter based on a standard
1188                    timestamp.
1189                 */
1190                 time_t now;
1191                 time (&now);
1192                 ID::init_counter (now);
1193         }
1194
1195         
1196         IO::disable_ports ();
1197         IO::disable_connecting ();
1198
1199         /* Object loading order:
1200
1201         Path
1202         Extra
1203         Options/Config
1204         MIDI Control // relies on data from Options/Config
1205         Metadata
1206         Locations
1207         Sources
1208         AudioRegions
1209         AudioDiskstreams
1210         Connections
1211         Routes
1212         EditGroups
1213         MixGroups
1214         Click
1215         ControlProtocols
1216         */
1217
1218         if ((child = find_named_node (node, "Extra")) != 0) {
1219                 _extra_xml = new XMLNode (*child);
1220         }
1221
1222         if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1223                 load_options (*child);
1224         } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1225                 load_options (*child);
1226         } else {
1227                 error << _("Session: XML state has no options section") << endmsg;
1228         }
1229
1230         if (use_config_midi_ports ()) {
1231         }
1232
1233         if ((child = find_named_node (node, "Metadata")) == 0) {
1234                 warning << _("Session: XML state has no metadata section (2.0 session?)") << endmsg;
1235         } else if (_metadata->set_state (*child)) {
1236                 goto out;
1237         }
1238
1239         if ((child = find_named_node (node, "Locations")) == 0) {
1240                 error << _("Session: XML state has no locations section") << endmsg;
1241                 goto out;
1242         } else if (_locations.set_state (*child)) {
1243                 goto out;
1244         }
1245
1246         Location* location;
1247
1248         if ((location = _locations.auto_loop_location()) != 0) {
1249                 set_auto_loop_location (location);
1250         }
1251
1252         if ((location = _locations.auto_punch_location()) != 0) {
1253                 set_auto_punch_location (location);
1254         }
1255
1256         if ((location = _locations.end_location()) == 0) {
1257                 _locations.add (end_location);
1258         } else {
1259                 delete end_location;
1260                 end_location = location;
1261         }
1262
1263         if ((location = _locations.start_location()) == 0) {
1264                 _locations.add (start_location);
1265         } else {
1266                 delete start_location;
1267                 start_location = location;
1268         }
1269
1270         AudioFileSource::set_header_position_offset (start_location->start());
1271
1272         if ((child = find_named_node (node, "Sources")) == 0) {
1273                 error << _("Session: XML state has no sources section") << endmsg;
1274                 goto out;
1275         } else if (load_sources (*child)) {
1276                 goto out;
1277         }
1278
1279         if ((child = find_named_node (node, "Regions")) == 0) {
1280                 error << _("Session: XML state has no Regions section") << endmsg;
1281                 goto out;
1282         } else if (load_regions (*child)) {
1283                 goto out;
1284         }
1285
1286         if ((child = find_named_node (node, "Playlists")) == 0) {
1287                 error << _("Session: XML state has no playlists section") << endmsg;
1288                 goto out;
1289         } else if (load_playlists (*child)) {
1290                 goto out;
1291         }
1292
1293         if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1294                 // this is OK
1295         } else if (load_unused_playlists (*child)) {
1296                 goto out;
1297         }
1298         
1299         if ((child = find_named_node (node, "NamedSelections")) != 0) {
1300                 if (load_named_selections (*child)) {
1301                         goto out;
1302                 }
1303         }
1304
1305         if ((child = find_named_node (node, "DiskStreams")) == 0) {
1306                 error << _("Session: XML state has no diskstreams section") << endmsg;
1307                 goto out;
1308         } else if (load_diskstreams (*child)) {
1309                 goto out;
1310         }
1311
1312         if ((child = find_named_node (node, "Bundles")) == 0) {
1313                 warning << _("Session: XML state has no bundles section (2.0 session?)") << endmsg;
1314                 //goto out;
1315         } else {
1316                 /* We can't load Bundles yet as they need to be able
1317                    to convert from port names to Port objects, which can't happen until
1318                    later */
1319                 _bundle_xml_node = new XMLNode (*child);
1320         }
1321         
1322         if ((child = find_named_node (node, "EditGroups")) == 0) {
1323                 error << _("Session: XML state has no edit groups section") << endmsg;
1324                 goto out;
1325         } else if (load_edit_groups (*child)) {
1326                 goto out;
1327         }
1328
1329         if ((child = find_named_node (node, "MixGroups")) == 0) {
1330                 error << _("Session: XML state has no mix groups section") << endmsg;
1331                 goto out;
1332         } else if (load_mix_groups (*child)) {
1333                 goto out;
1334         }
1335
1336         if ((child = find_named_node (node, "TempoMap")) == 0) {
1337                 error << _("Session: XML state has no Tempo Map section") << endmsg;
1338                 goto out;
1339         } else if (_tempo_map->set_state (*child)) {
1340                 goto out;
1341         }
1342
1343         if ((child = find_named_node (node, "Routes")) == 0) {
1344                 error << _("Session: XML state has no routes section") << endmsg;
1345                 goto out;
1346         } else if (load_routes (*child)) {
1347                 goto out;
1348         }
1349
1350         if ((child = find_named_node (node, "Click")) == 0) {
1351                 warning << _("Session: XML state has no click section") << endmsg;
1352         } else if (_click_io) {
1353                 _click_io->set_state (*child);
1354         }
1355
1356         if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1357                 ControlProtocolManager::instance().set_protocol_states (*child);
1358         }
1359
1360         /* here beginneth the second phase ... */
1361
1362         StateReady (); /* EMIT SIGNAL */
1363
1364         return 0;
1365
1366   out:
1367         return ret;
1368 }
1369
1370 int
1371 Session::load_routes (const XMLNode& node)
1372 {
1373         XMLNodeList nlist;
1374         XMLNodeConstIterator niter;
1375         RouteList new_routes;
1376
1377         nlist = node.children();
1378
1379         set_dirty();
1380
1381         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1382
1383                 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1384
1385                 if (route == 0) {
1386                         error << _("Session: cannot create Route from XML description.") << endmsg;
1387                         return -1;
1388                 }
1389
1390                 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1391
1392                 new_routes.push_back (route);
1393         }
1394
1395         add_routes (new_routes, false);
1396
1397         return 0;
1398 }
1399
1400 boost::shared_ptr<Route>
1401 Session::XMLRouteFactory (const XMLNode& node)
1402 {
1403         if (node.name() != "Route") {
1404                 return boost::shared_ptr<Route> ((Route*) 0);
1405         }
1406
1407         bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1408         
1409         DataType type = DataType::AUDIO;
1410         const XMLProperty* prop = node.property("default-type");
1411         if (prop)
1412                 type = DataType(prop->value());
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         current_trans = new UndoTransaction;
2255         current_trans->set_name (name);
2256 }
2257
2258 void
2259 Session::commit_reversible_command (Command *cmd)
2260 {
2261         struct timeval now;
2262
2263         if (cmd) {
2264                 current_trans->add_command (cmd);
2265         }
2266
2267         if (current_trans->empty()) {
2268                 return;
2269         }
2270
2271         gettimeofday (&now, 0);
2272         current_trans->set_timestamp (now);
2273
2274         _history.add (current_trans);
2275 }
2276
2277 Session::GlobalRouteBooleanState 
2278 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2279 {
2280         GlobalRouteBooleanState s;
2281         boost::shared_ptr<RouteList> r = routes.reader ();
2282
2283         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2284                 if (!(*i)->is_hidden()) {
2285                         RouteBooleanState v;
2286                         
2287                         v.first =* i;
2288                         Route* r = (*i).get();
2289                         v.second = (r->*method)();
2290                         
2291                         s.push_back (v);
2292                 }
2293         }
2294
2295         return s;
2296 }
2297
2298 Session::GlobalRouteMeterState
2299 Session::get_global_route_metering ()
2300 {
2301         GlobalRouteMeterState s;
2302         boost::shared_ptr<RouteList> r = routes.reader ();
2303
2304         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2305                 if (!(*i)->is_hidden()) {
2306                         RouteMeterState v;
2307                         
2308                         v.first =* i;
2309                         v.second = (*i)->meter_point();
2310                         
2311                         s.push_back (v);
2312                 }
2313         }
2314
2315         return s;
2316 }
2317
2318 void
2319 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg) 
2320 {
2321         for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2322
2323                 boost::shared_ptr<Route> r = (i->first.lock());
2324
2325                 if (r) {
2326                         r->set_meter_point (i->second, arg);
2327                 }
2328         }
2329 }
2330
2331 void
2332 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2333 {
2334         for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2335
2336                 boost::shared_ptr<Route> r = (i->first.lock());
2337
2338                 if (r) {
2339                         Route* rp = r.get();
2340                         (rp->*method) (i->second, arg);
2341                 }
2342         }
2343 }
2344
2345 void
2346 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2347 {
2348         set_global_route_boolean (s, &Route::set_mute, src);
2349 }
2350
2351 void
2352 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2353 {
2354         set_global_route_boolean (s, &Route::set_solo, src);
2355 }
2356
2357 void
2358 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2359 {
2360         set_global_route_boolean (s, &Route::set_record_enable, src);
2361 }
2362
2363 #if 0
2364 UndoAction
2365 Session::global_mute_memento (void* src)
2366 {
2367         return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2368 }
2369
2370 UndoAction
2371 Session::global_metering_memento (void* src)
2372 {
2373         return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2374 }
2375
2376 UndoAction
2377 Session::global_solo_memento (void* src)
2378 {
2379         return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2380 }
2381
2382 UndoAction
2383 Session::global_record_enable_memento (void* src)
2384 {
2385         return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2386 }
2387 #endif
2388
2389 static bool
2390 accept_all_non_peak_files (const string& path, void *arg)
2391 {
2392         return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2393 }
2394
2395 static bool
2396 accept_all_state_files (const string& path, void *arg)
2397 {
2398         return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2399 }
2400
2401 int 
2402 Session::find_all_sources (string path, set<string>& result)
2403 {
2404         XMLTree tree;
2405         XMLNode* node;
2406
2407         if (!tree.read (path)) {
2408                 return -1;
2409         }
2410
2411         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2412                 return -2;
2413         }
2414
2415         XMLNodeList nlist;
2416         XMLNodeConstIterator niter;
2417
2418         nlist = node->children();
2419
2420         set_dirty();
2421
2422         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2423                 
2424                 XMLProperty* prop;
2425
2426                 if ((prop = (*niter)->property (X_("name"))) == 0) {
2427                         continue;
2428                 }
2429
2430                 if (prop->value()[0] == '/') {
2431                         /* external file, ignore */
2432                         continue;
2433                 }
2434
2435                 sys::path source_path = _session_dir->sound_path ();
2436
2437                 source_path /= prop->value ();
2438
2439                 result.insert (source_path.to_string ());
2440         }
2441
2442         return 0;
2443 }
2444
2445 int
2446 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2447 {
2448         PathScanner scanner;
2449         vector<string*>* state_files;
2450         string ripped;
2451         string this_snapshot_path;
2452
2453         result.clear ();
2454
2455         ripped = _path;
2456
2457         if (ripped[ripped.length()-1] == '/') {
2458                 ripped = ripped.substr (0, ripped.length() - 1);
2459         }
2460
2461         state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2462         
2463         if (state_files == 0) {
2464                 /* impossible! */
2465                 return 0;
2466         }
2467
2468         this_snapshot_path = _path;
2469         this_snapshot_path += _current_snapshot_name;
2470         this_snapshot_path += statefile_suffix;
2471
2472         for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2473
2474                 if (exclude_this_snapshot && **i == this_snapshot_path) {
2475                         continue;
2476                 }
2477
2478                 if (find_all_sources (**i, result) < 0) {
2479                         return -1;
2480                 }
2481         }
2482
2483         return 0;
2484 }
2485
2486 struct RegionCounter {
2487     typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2488     AudioSourceList::iterator iter;
2489     boost::shared_ptr<Region> region;
2490     uint32_t count;
2491     
2492     RegionCounter() : count (0) {}
2493 };
2494
2495 int
2496 Session::cleanup_sources (Session::cleanup_report& rep)
2497 {
2498         // FIXME: needs adaptation to midi
2499         
2500         vector<boost::shared_ptr<Source> > dead_sources;
2501         vector<boost::shared_ptr<Playlist> > playlists_tbd;
2502         PathScanner scanner;
2503         string sound_path;
2504         vector<space_and_path>::iterator i;
2505         vector<space_and_path>::iterator nexti;
2506         vector<string*>* soundfiles;
2507         vector<string> unused;
2508         set<string> all_sources;
2509         bool used;
2510         string spath;
2511         int ret = -1;
2512                 
2513         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2514
2515         
2516         /* step 1: consider deleting all unused playlists */
2517
2518         for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2519                 int status;
2520
2521                 status = AskAboutPlaylistDeletion (*x);
2522
2523                 switch (status) {
2524                 case -1:
2525                         ret = 0;
2526                         goto out;
2527                         break;
2528
2529                 case 0:
2530                         playlists_tbd.push_back (*x);
2531                         break;
2532
2533                 default:
2534                         /* leave it alone */
2535                         break;
2536                 }
2537         }
2538
2539         /* now delete any that were marked for deletion */
2540
2541         for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2542                 (*x)->drop_references ();
2543         }
2544
2545         playlists_tbd.clear ();
2546
2547         /* step 2: find all un-used sources */
2548
2549         rep.paths.clear ();
2550         rep.space = 0;
2551
2552         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2553                 
2554                 SourceMap::iterator tmp;
2555
2556                 tmp = i;
2557                 ++tmp;
2558
2559                 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2560                    capture files.
2561                 */
2562
2563                 if (!i->second->used() && i->second->length() > 0) {
2564                         dead_sources.push_back (i->second);
2565                         i->second->GoingAway();
2566                 } 
2567
2568                 i = tmp;
2569         }
2570
2571         /* build a list of all the possible sound directories for the session */
2572
2573         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2574
2575                 nexti = i;
2576                 ++nexti;
2577
2578                 SessionDirectory sdir ((*i).path);
2579                 sound_path += sdir.sound_path().to_string();
2580
2581                 if (nexti != session_dirs.end()) {
2582                         sound_path += ':';
2583                 }
2584
2585                 i = nexti;
2586         }
2587
2588         /* now do the same thing for the files that ended up in the sounds dir(s) 
2589            but are not referenced as sources in any snapshot.
2590         */
2591
2592         soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2593
2594         if (soundfiles == 0) {
2595                 return 0;
2596         }
2597
2598         /* find all sources, but don't use this snapshot because the
2599            state file on disk still references sources we may have already
2600            dropped.
2601         */
2602         
2603         find_all_sources_across_snapshots (all_sources, true);
2604
2605         /*  add our current source list
2606          */
2607         
2608         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2609                 boost::shared_ptr<FileSource> fs;
2610                 
2611                 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2612                         all_sources.insert (fs->path());
2613                 } 
2614         }
2615
2616         char tmppath1[PATH_MAX+1];
2617         char tmppath2[PATH_MAX+1];
2618         
2619         for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2620
2621                 used = false;
2622                 spath = **x;
2623
2624                 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2625
2626                         realpath(spath.c_str(), tmppath1);
2627                         realpath((*i).c_str(),  tmppath2);
2628
2629                         if (strcmp(tmppath1, tmppath2) == 0) {
2630                                 used = true;
2631                                 break;
2632                         }
2633                 }
2634
2635                 if (!used) {
2636                         unused.push_back (spath);
2637                 }
2638         }
2639
2640         /* now try to move all unused files into the "dead_sounds" directory(ies) */
2641
2642         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2643                 struct stat statbuf;
2644
2645                 rep.paths.push_back (*x);
2646                 if (stat ((*x).c_str(), &statbuf) == 0) {
2647                         rep.space += statbuf.st_size;
2648                 }
2649
2650                 string newpath;
2651                 
2652                 /* don't move the file across filesystems, just
2653                    stick it in the `dead_sound_dir_name' directory
2654                    on whichever filesystem it was already on.
2655                 */
2656
2657                 if ((*x).find ("/sounds/") != string::npos) {
2658
2659                         /* old school, go up 1 level */
2660
2661                         newpath = Glib::path_get_dirname (*x);      // "sounds" 
2662                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2663
2664                 } else {
2665
2666                         /* new school, go up 4 levels */
2667                         
2668                         newpath = Glib::path_get_dirname (*x);      // "audiofiles" 
2669                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2670                         newpath = Glib::path_get_dirname (newpath); // "interchange"
2671                         newpath = Glib::path_get_dirname (newpath); // "session-dir"
2672                 }
2673
2674                 newpath += '/';
2675                 newpath += dead_sound_dir_name;
2676
2677                 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2678                         error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2679                         return -1;
2680                 }
2681
2682                 newpath += '/';
2683                 newpath += Glib::path_get_basename ((*x));
2684                 
2685                 if (access (newpath.c_str(), F_OK) == 0) {
2686                         
2687                         /* the new path already exists, try versioning */
2688                         
2689                         char buf[PATH_MAX+1];
2690                         int version = 1;
2691                         string newpath_v;
2692                         
2693                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2694                         newpath_v = buf;
2695
2696                         while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2697                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2698                                 newpath_v = buf;
2699                         }
2700                         
2701                         if (version == 999) {
2702                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2703                                                   newpath)
2704                                       << endmsg;
2705                         } else {
2706                                 newpath = newpath_v;
2707                         }
2708                         
2709                 } else {
2710                         
2711                         /* it doesn't exist, or we can't read it or something */
2712                         
2713                 }
2714
2715                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2716                         error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2717                                           (*x), newpath, strerror (errno))
2718                               << endmsg;
2719                         goto out;
2720                 }
2721
2722                 /* see if there an easy to find peakfile for this file, and remove it.
2723                  */
2724
2725                 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2726                 peakpath += peakfile_suffix;
2727
2728                 if (access (peakpath.c_str(), W_OK) == 0) {
2729                         if (::unlink (peakpath.c_str()) != 0) {
2730                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2731                                                   peakpath, _path, strerror (errno))
2732                                       << endmsg;
2733                                 /* try to back out */
2734                                 rename (newpath.c_str(), _path.c_str());
2735                                 goto out;
2736                         }
2737                 }
2738         }
2739
2740         ret = 0;
2741
2742         /* dump the history list */
2743
2744         _history.clear ();
2745
2746         /* save state so we don't end up a session file
2747            referring to non-existent sources.
2748         */
2749         
2750         save_state ("");
2751
2752   out:
2753         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2754
2755         return ret;
2756 }
2757
2758 int
2759 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2760 {
2761         // FIXME: needs adaptation for MIDI
2762         
2763         vector<space_and_path>::iterator i;
2764         string dead_sound_dir;
2765         struct dirent* dentry;
2766         struct stat statbuf;
2767         DIR* dead;
2768
2769         rep.paths.clear ();
2770         rep.space = 0;
2771
2772         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2773                 
2774                 dead_sound_dir = (*i).path;
2775                 dead_sound_dir += dead_sound_dir_name;
2776
2777                 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2778                         continue;
2779                 }
2780
2781                 while ((dentry = readdir (dead)) != 0) {
2782
2783                         /* avoid '.' and '..' */
2784                         
2785                         if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') || 
2786                             (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2787                                 continue;
2788                         }
2789
2790                         string fullpath;
2791
2792                         fullpath = dead_sound_dir;
2793                         fullpath += '/';
2794                         fullpath += dentry->d_name;
2795
2796                         if (stat (fullpath.c_str(), &statbuf)) {
2797                                 continue;
2798                         }
2799
2800                         if (!S_ISREG (statbuf.st_mode)) {
2801                                 continue;
2802                         }
2803
2804                         if (unlink (fullpath.c_str())) {
2805                                 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2806                                                   fullpath, strerror (errno))
2807                                       << endmsg;
2808                         }
2809
2810                         rep.paths.push_back (dentry->d_name);
2811                         rep.space += statbuf.st_size;
2812                 }
2813
2814                 closedir (dead);
2815                 
2816         }
2817
2818         return 0;
2819 }
2820
2821 void
2822 Session::set_dirty ()
2823 {
2824         bool was_dirty = dirty();
2825
2826         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2827
2828
2829         if (!was_dirty) {
2830                 DirtyChanged(); /* EMIT SIGNAL */
2831         }
2832 }
2833
2834
2835 void
2836 Session::set_clean ()
2837 {
2838         bool was_dirty = dirty();
2839         
2840         _state_of_the_state = Clean;
2841
2842
2843         if (was_dirty) {
2844                 DirtyChanged(); /* EMIT SIGNAL */
2845         }
2846 }
2847
2848 void
2849 Session::set_deletion_in_progress ()
2850 {
2851         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2852
2853 }
2854
2855 void
2856 Session::add_controllable (boost::shared_ptr<Controllable> c)
2857 {
2858         /* this adds a controllable to the list managed by the Session.
2859            this is a subset of those managed by the Controllable class
2860            itself, and represents the only ones whose state will be saved
2861            as part of the session.
2862         */
2863
2864         Glib::Mutex::Lock lm (controllables_lock);
2865         controllables.insert (c);
2866 }
2867         
2868 struct null_deleter { void operator()(void const *) const {} };
2869
2870 void
2871 Session::remove_controllable (Controllable* c)
2872 {
2873         if (_state_of_the_state | Deletion) {
2874                 return;
2875         }
2876
2877         Glib::Mutex::Lock lm (controllables_lock);
2878
2879         Controllables::iterator x = controllables.find(
2880                  boost::shared_ptr<Controllable>(c, null_deleter()));
2881
2882         if (x != controllables.end()) {
2883                 controllables.erase (x);
2884         }
2885 }       
2886
2887 boost::shared_ptr<Controllable>
2888 Session::controllable_by_id (const PBD::ID& id)
2889 {
2890         Glib::Mutex::Lock lm (controllables_lock);
2891         
2892         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2893                 if ((*i)->id() == id) {
2894                         return *i;
2895                 }
2896         }
2897
2898         return boost::shared_ptr<Controllable>();
2899 }
2900
2901 void 
2902 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2903 {
2904         Stateful::add_instant_xml (node, _path);
2905         if (write_to_config) {
2906                 Config->add_instant_xml (node);
2907         }
2908 }
2909
2910 XMLNode*
2911 Session::instant_xml (const string& node_name)
2912 {
2913         return Stateful::instant_xml (node_name, _path);
2914 }
2915
2916 int 
2917 Session::save_history (string snapshot_name)
2918 {
2919         XMLTree tree;
2920         
2921         if (snapshot_name.empty()) {
2922                 snapshot_name = _current_snapshot_name;
2923         }
2924   
2925         const string history_filename = snapshot_name + history_suffix;
2926         const string backup_filename = history_filename + backup_suffix;
2927         const sys::path xml_path = _session_dir->root_path() / history_filename;
2928         const sys::path backup_path = _session_dir->root_path() / backup_filename;
2929
2930         if (sys::exists (xml_path)) {
2931                 try
2932                 {
2933                         sys::rename (xml_path, backup_path);
2934                 }
2935                 catch (const sys::filesystem_error& err)
2936                 {
2937                         error << _("could not backup old history file, current history not saved") << endmsg;
2938                         return -1;
2939                 }
2940         }
2941
2942
2943         if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2944                 return 0;
2945         }
2946
2947         tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2948
2949         if (!tree.write (xml_path.to_string()))
2950         {
2951                 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2952
2953                 try
2954                 {
2955                         sys::remove (xml_path);
2956                         sys::rename (backup_path, xml_path);
2957                 }
2958                 catch (const sys::filesystem_error& err)
2959                 {
2960                         error << string_compose (_("could not restore history file from backup %1 (%2)"),
2961                                         backup_path.to_string(), err.what()) << endmsg;
2962                 }
2963
2964                 return -1;
2965         }
2966
2967         return 0;
2968 }
2969
2970 int
2971 Session::restore_history (string snapshot_name)
2972 {
2973         XMLTree tree;
2974
2975         if (snapshot_name.empty()) {
2976                 snapshot_name = _current_snapshot_name;
2977         }
2978
2979         const string xml_filename = snapshot_name + history_suffix;
2980         const sys::path xml_path = _session_dir->root_path() / xml_filename;
2981
2982     cerr << "Loading history from " << xml_path.to_string() << endmsg;
2983
2984         if (!sys::exists (xml_path)) {
2985                 info << string_compose (_("%1: no history file \"%2\" for this session."),
2986                                 _name, xml_path.to_string()) << endmsg;
2987                 return 1;
2988         }
2989
2990         if (!tree.read (xml_path.to_string())) {
2991                 error << string_compose (_("Could not understand session history file \"%1\""),
2992                                 xml_path.to_string()) << endmsg;
2993                 return -1;
2994         }
2995
2996         // replace history
2997         _history.clear();
2998
2999     for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3000             
3001             XMLNode *t = *it;
3002             UndoTransaction* ut = new UndoTransaction ();
3003             struct timeval tv;
3004             
3005             ut->set_name(t->property("name")->value());
3006             stringstream ss(t->property("tv-sec")->value());
3007             ss >> tv.tv_sec;
3008             ss.str(t->property("tv-usec")->value());
3009             ss >> tv.tv_usec;
3010             ut->set_timestamp(tv);
3011             
3012             for (XMLNodeConstIterator child_it  = t->children().begin();
3013                                 child_it != t->children().end(); child_it++)
3014             {
3015                     XMLNode *n = *child_it;
3016                     Command *c;
3017         
3018                     if (n->name() == "MementoCommand" ||
3019                                         n->name() == "MementoUndoCommand" ||
3020                                         n->name() == "MementoRedoCommand") {
3021
3022                             if ((c = memento_command_factory(n))) {
3023                                     ut->add_command(c);
3024                             }
3025                             
3026                     } else if (n->name() == X_("GlobalRouteStateCommand")) {
3027
3028                             if ((c = global_state_command_factory (*n))) {
3029                                     ut->add_command (c);
3030                             }
3031                             
3032                     } else if (n->name() == "DeltaCommand") {
3033                          PBD::ID  id(n->property("midi-source")->value());
3034                          boost::shared_ptr<MidiSource> midi_source = 
3035                                  boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3036                          if(midi_source) {
3037                                  ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));                                 
3038                          } else {
3039                                  error << "FIXME: Failed to downcast MidiSource for DeltaCommand" << endmsg;
3040                          }
3041                     } else {
3042                             error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3043                     }
3044             }
3045
3046             _history.add (ut);
3047     }
3048
3049     return 0;
3050 }
3051
3052 void
3053 Session::config_changed (const char* parameter_name)
3054 {
3055 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3056
3057         if (PARAM_IS ("seamless-loop")) {
3058                 
3059         } else if (PARAM_IS ("rf-speed")) {
3060                 
3061         } else if (PARAM_IS ("auto-loop")) {
3062                 
3063         } else if (PARAM_IS ("auto-input")) {
3064
3065                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3066                         /* auto-input only makes a difference if we're rolling */
3067                         
3068                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3069                         
3070                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3071                                 if ((*i)->record_enabled ()) {
3072                                         (*i)->monitor_input (!Config->get_auto_input());
3073                                 }
3074                         }
3075                 }
3076
3077         } else if (PARAM_IS ("punch-in")) {
3078
3079                 Location* location;
3080                 
3081                 if ((location = _locations.auto_punch_location()) != 0) {
3082                         
3083                         if (Config->get_punch_in ()) {
3084                                 replace_event (Event::PunchIn, location->start());
3085                         } else {
3086                                 remove_event (location->start(), Event::PunchIn);
3087                         }
3088                 }
3089                 
3090         } else if (PARAM_IS ("punch-out")) {
3091
3092                 Location* location;
3093                 
3094                 if ((location = _locations.auto_punch_location()) != 0) {
3095                         
3096                         if (Config->get_punch_out()) {
3097                                 replace_event (Event::PunchOut, location->end());
3098                         } else {
3099                                 clear_events (Event::PunchOut);
3100                         }
3101                 }
3102
3103         } else if (PARAM_IS ("edit-mode")) {
3104
3105                 Glib::Mutex::Lock lm (playlist_lock);
3106                 
3107                 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3108                         (*i)->set_edit_mode (Config->get_edit_mode ());
3109                 }
3110
3111         } else if (PARAM_IS ("use-video-sync")) {
3112
3113                 waiting_for_sync_offset = Config->get_use_video_sync();
3114
3115         } else if (PARAM_IS ("mmc-control")) {
3116
3117                 //poke_midi_thread ();
3118
3119         } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
3120
3121                 if (mmc) {
3122                         mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3123                 }
3124
3125         } else if (PARAM_IS ("mmc-send-id")) {
3126
3127                 if (mmc) {
3128                         mmc->set_send_device_id (Config->get_mmc_send_device_id());
3129                 }
3130
3131         } else if (PARAM_IS ("midi-control")) {
3132                 
3133                 //poke_midi_thread ();
3134
3135         } else if (PARAM_IS ("raid-path")) {
3136
3137                 setup_raid_path (Config->get_raid_path());
3138
3139         } else if (PARAM_IS ("smpte-format")) {
3140
3141                 sync_time_vars ();
3142
3143         } else if (PARAM_IS ("video-pullup")) {
3144
3145                 sync_time_vars ();
3146
3147         } else if (PARAM_IS ("seamless-loop")) {
3148
3149                 if (play_loop && transport_rolling()) {
3150                         // to reset diskstreams etc
3151                         request_play_loop (true);
3152                 }
3153
3154         } else if (PARAM_IS ("rf-speed")) {
3155
3156                 cumulative_rf_motion = 0;
3157                 reset_rf_scale (0);
3158
3159         } else if (PARAM_IS ("click-sound")) {
3160
3161                 setup_click_sounds (1);
3162
3163         } else if (PARAM_IS ("click-emphasis-sound")) {
3164
3165                 setup_click_sounds (-1);
3166
3167         } else if (PARAM_IS ("clicking")) {
3168
3169                 if (Config->get_clicking()) {
3170                         if (_click_io && click_data) { // don't require emphasis data
3171                                 _clicking = true;
3172                         }
3173                 } else {
3174                         _clicking = false;
3175                 }
3176
3177         } else if (PARAM_IS ("send-mtc")) {
3178                 
3179                 /* only set the internal flag if we have
3180                    a port.
3181                 */
3182                 
3183                 if (_mtc_port != 0) {
3184                         session_send_mtc = Config->get_send_mtc();
3185                         if (session_send_mtc) {
3186                                 /* mark us ready to send */
3187                                 next_quarter_frame_to_send = 0;
3188                         }
3189                 } else {
3190                         session_send_mtc = false;
3191                 }
3192
3193         } else if (PARAM_IS ("send-mmc")) {
3194                 
3195                 /* only set the internal flag if we have
3196                    a port.
3197                 */
3198                 
3199                 if (_mmc_port != 0) {
3200                         session_send_mmc = Config->get_send_mmc();
3201                 } else {
3202                         mmc = 0;
3203                         session_send_mmc = false; 
3204                 }
3205
3206         } else if (PARAM_IS ("midi-feedback")) {
3207                 
3208                 /* only set the internal flag if we have
3209                    a port.
3210                 */
3211                 
3212                 if (_mtc_port != 0) {
3213                         session_midi_feedback = Config->get_midi_feedback();
3214                 }
3215
3216         } else if (PARAM_IS ("jack-time-master")) {
3217
3218                 engine().reset_timebase ();
3219
3220         } else if (PARAM_IS ("native-file-header-format")) {
3221
3222                 if (!first_file_header_format_reset) {
3223                         reset_native_file_format ();
3224                 }
3225
3226                 first_file_header_format_reset = false;
3227
3228         } else if (PARAM_IS ("native-file-data-format")) {
3229
3230                 if (!first_file_data_format_reset) {
3231                         reset_native_file_format ();
3232                 }
3233
3234                 first_file_data_format_reset = false;
3235
3236         } else if (PARAM_IS ("slave-source")) {
3237                 set_slave_source (Config->get_slave_source());
3238         } else if (PARAM_IS ("remote-model")) {
3239                 set_remote_control_ids ();
3240         }  else if (PARAM_IS ("denormal-model")) {
3241                 setup_fpu ();
3242         } else if (PARAM_IS ("history-depth")) {
3243                 set_history_depth (Config->get_history_depth());
3244         } else if (PARAM_IS ("sync-all-route-ordering")) {
3245                 sync_order_keys ("session");
3246         } else if (PARAM_IS ("initial-program-change")) {
3247
3248                 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3249                         MIDI::byte buf[2];
3250                         
3251                         buf[0] = MIDI::program; // channel zero by default
3252                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3253
3254                         _mmc_port->midimsg (buf, sizeof (buf), 0);
3255                 }
3256         } else if (PARAM_IS ("initial-program-change")) {
3257
3258                 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3259                         MIDI::byte* buf = new MIDI::byte[2];
3260                         
3261                         buf[0] = MIDI::program; // channel zero by default
3262                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3263                         // deliver_midi (_mmc_port, buf, 2);
3264                 }
3265         } else if (PARAM_IS ("solo-mute-override")) {
3266                 catch_up_on_solo_mute_override ();
3267         }
3268
3269         set_dirty ();
3270                    
3271 #undef PARAM_IS
3272
3273 }
3274
3275 void
3276 Session::set_history_depth (uint32_t d)
3277 {
3278         _history.set_depth (d);
3279 }