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