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