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