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