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