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