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