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