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