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