Fix MIDI region loading.
[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 Control
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         if ((prop = node.property ("name")) == 0) {
1401                 cerr << "no name for this region\n";
1402                 abort ();
1403         }
1404         
1405         if ((prop = node.property (X_("source-0"))) == 0) {
1406                 if ((prop = node.property ("source")) == 0) {
1407                         error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1408                         return boost::shared_ptr<AudioRegion>();
1409                 }
1410         }
1411
1412         PBD::ID s_id (prop->value());
1413
1414         if ((source = source_by_id (s_id)) == 0) {
1415                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1416                 return boost::shared_ptr<AudioRegion>();
1417         }
1418         
1419         as = boost::dynamic_pointer_cast<AudioSource>(source);
1420         if (!as) {
1421                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1422                 return boost::shared_ptr<AudioRegion>();
1423         }
1424
1425         sources.push_back (as);
1426
1427         /* pickup other channels */
1428
1429         for (uint32_t n=1; n < nchans; ++n) {
1430                 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1431                 if ((prop = node.property (buf)) != 0) {
1432                         
1433                         PBD::ID id2 (prop->value());
1434                         
1435                         if ((source = source_by_id (id2)) == 0) {
1436                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1437                                 return boost::shared_ptr<AudioRegion>();
1438                         }
1439                         
1440                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1441                         if (!as) {
1442                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1443                                 return boost::shared_ptr<AudioRegion>();
1444                         }
1445                         sources.push_back (as);
1446                 }
1447         }
1448         
1449         try {
1450                 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1451
1452                 /* a final detail: this is the one and only place that we know how long missing files are */
1453
1454                 if (region->whole_file()) {
1455                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1456                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1457                                 if (sfp) {
1458                                         sfp->set_length (region->length());
1459                                 }
1460                         }
1461                 }
1462
1463                 return region;
1464                                                        
1465         }
1466
1467         catch (failed_constructor& err) {
1468                 return boost::shared_ptr<AudioRegion>();
1469         }
1470 }
1471
1472 boost::shared_ptr<MidiRegion>
1473 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1474 {
1475         const XMLProperty* prop;
1476         boost::shared_ptr<Source> source;
1477         boost::shared_ptr<MidiSource> ms;
1478         SourceList sources;
1479         uint32_t nchans = 1;
1480         
1481         if (node.name() != X_("Region")) {
1482                 return boost::shared_ptr<MidiRegion>();
1483         }
1484
1485         if ((prop = node.property (X_("channels"))) != 0) {
1486                 nchans = atoi (prop->value().c_str());
1487         }
1488         
1489         if ((prop = node.property ("name")) == 0) {
1490                 cerr << "no name for this region\n";
1491                 abort ();
1492         }
1493
1494         // Multiple midi channels?  that's just crazy talk
1495         assert(nchans == 1);
1496
1497         if ((prop = node.property (X_("source-0"))) == 0) {
1498                 if ((prop = node.property ("source")) == 0) {
1499                         error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1500                         return boost::shared_ptr<MidiRegion>();
1501                 }
1502         }
1503
1504         PBD::ID s_id (prop->value());
1505
1506         if ((source = source_by_id (s_id)) == 0) {
1507                 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1508                 return boost::shared_ptr<MidiRegion>();
1509         }
1510
1511         ms = boost::dynamic_pointer_cast<MidiSource>(source);
1512         if (!ms) {
1513                 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1514                 return boost::shared_ptr<MidiRegion>();
1515         }
1516
1517         sources.push_back (ms);
1518
1519         try {
1520                 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1521                 /* a final detail: this is the one and only place that we know how long missing files are */
1522
1523                 if (region->whole_file()) {
1524                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1525                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1526                                 if (sfp) {
1527                                         sfp->set_length (region->length());
1528                                 }
1529                         }
1530                 }
1531
1532                 return region;
1533         }
1534
1535         catch (failed_constructor& err) {
1536                 return boost::shared_ptr<MidiRegion>();
1537         }
1538 }
1539
1540 XMLNode&
1541 Session::get_sources_as_xml ()
1542
1543 {
1544         XMLNode* node = new XMLNode (X_("Sources"));
1545         Glib::Mutex::Lock lm (source_lock);
1546
1547         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1548                 node->add_child_nocopy (i->second->get_state());
1549         }
1550
1551         return *node;
1552 }
1553
1554 string
1555 Session::path_from_region_name (string name, string identifier)
1556 {
1557         char buf[PATH_MAX+1];
1558         uint32_t n;
1559         string dir = discover_best_sound_dir ();
1560
1561         for (n = 0; n < 999999; ++n) {
1562                 if (identifier.length()) {
1563                         snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(), 
1564                                   identifier.c_str(), n);
1565                 } else {
1566                         snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1567                 }
1568
1569                 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1570                         return buf;
1571                 }
1572         }
1573
1574         error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1575                                  name, identifier)
1576               << endmsg;
1577
1578         return "";
1579 }
1580         
1581
1582 int
1583 Session::load_sources (const XMLNode& node)
1584 {
1585         XMLNodeList nlist;
1586         XMLNodeConstIterator niter;
1587         boost::shared_ptr<Source> source;
1588
1589         nlist = node.children();
1590
1591         set_dirty();
1592
1593         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1594
1595                 try {
1596                         if ((source = XMLSourceFactory (**niter)) == 0) {
1597                                 error << _("Session: cannot create Source from XML description.") << endmsg;
1598                         }
1599                 }
1600
1601                 catch (non_existent_source& err) {
1602                         warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1603                         source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1604                 }
1605         }
1606
1607         return 0;
1608 }
1609
1610 boost::shared_ptr<Source>
1611 Session::XMLSourceFactory (const XMLNode& node)
1612 {
1613         if (node.name() != "Source") {
1614                 return boost::shared_ptr<Source>();
1615         }
1616
1617         try {
1618                 return SourceFactory::create (*this, node);
1619         }
1620
1621         catch (failed_constructor& err) {
1622                 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1623                 return boost::shared_ptr<Source>();
1624         }
1625 }
1626
1627 int
1628 Session::save_template (string template_name)
1629 {
1630         XMLTree tree;
1631         string xml_path, bak_path, template_path;
1632
1633         if (_state_of_the_state & CannotSave) {
1634                 return -1;
1635         }
1636
1637         DIR* dp;
1638         string dir = template_dir();
1639
1640         if ((dp = opendir (dir.c_str()))) {
1641                 closedir (dp);
1642         } else {
1643                 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1644                         error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1645                         return -1;
1646                 }
1647         }
1648
1649         tree.set_root (&get_template());
1650
1651         xml_path = dir;
1652         xml_path += template_name;
1653         xml_path += template_suffix;
1654
1655         ifstream in(xml_path.c_str());
1656         
1657         if (in) {
1658                 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1659                 return -1;
1660         } else {
1661                 in.close();
1662         }
1663
1664         if (!tree.write (xml_path)) {
1665                 error << _("mix template not saved") << endmsg;
1666                 return -1;
1667         }
1668
1669         return 0;
1670 }
1671
1672 int
1673 Session::rename_template (string old_name, string new_name) 
1674 {
1675         string old_path = template_dir() + old_name + template_suffix;
1676         string new_path = template_dir() + new_name + template_suffix;
1677
1678         return rename (old_path.c_str(), new_path.c_str());
1679 }
1680
1681 int
1682 Session::delete_template (string name) 
1683 {
1684         string template_path = template_dir();
1685         template_path += name;
1686         template_path += template_suffix;
1687
1688         return remove (template_path.c_str());
1689 }
1690
1691 void
1692 Session::refresh_disk_space ()
1693 {
1694 #if HAVE_SYS_VFS_H
1695         struct statfs statfsbuf;
1696         vector<space_and_path>::iterator i;
1697         Glib::Mutex::Lock lm (space_lock);
1698         double scale;
1699
1700         /* get freespace on every FS that is part of the session path */
1701
1702         _total_free_4k_blocks = 0;
1703         
1704         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1705                 statfs ((*i).path.c_str(), &statfsbuf);
1706
1707                 scale = statfsbuf.f_bsize/4096.0;
1708
1709                 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1710                 _total_free_4k_blocks += (*i).blocks;
1711         }
1712 #endif
1713 }
1714
1715 int
1716 Session::ensure_sound_dir (string path, string& result)
1717 {
1718         string dead;
1719         string peak;
1720
1721         /* Ensure that the parent directory exists */
1722         
1723         if (g_mkdir_with_parents (path.c_str(), 0775)) {
1724                 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1725                 return -1;
1726         }
1727         
1728         /* Ensure that the sounds directory exists */
1729         
1730         result = path;
1731         result += '/';
1732         result += sound_dir_name;
1733         
1734         if (g_mkdir_with_parents (result.c_str(), 0775)) {
1735                 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1736                 return -1;
1737         }
1738
1739         dead = path;
1740         dead += '/';
1741         dead += dead_sound_dir_name;
1742         
1743         if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1744                 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1745                 return -1;
1746         }
1747
1748         peak = path;
1749         peak += '/';
1750         peak += peak_dir_name;
1751         
1752         if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1753                 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1754                 return -1;
1755         }
1756         
1757         /* callers expect this to be terminated ... */
1758                         
1759         result += '/';
1760         return 0;
1761 }       
1762
1763 string
1764 Session::discover_best_sound_dir (bool destructive)
1765 {
1766         vector<space_and_path>::iterator i;
1767         string result;
1768
1769         /* handle common case without system calls */
1770
1771         if (session_dirs.size() == 1) {
1772                 return sound_dir();
1773         }
1774
1775         /* OK, here's the algorithm we're following here:
1776            
1777         We want to select which directory to use for 
1778         the next file source to be created. Ideally,
1779         we'd like to use a round-robin process so as to
1780         get maximum performance benefits from splitting
1781         the files across multiple disks.
1782
1783         However, in situations without much diskspace, an
1784         RR approach may end up filling up a filesystem
1785         with new files while others still have space.
1786         Its therefore important to pay some attention to
1787         the freespace in the filesystem holding each
1788         directory as well. However, if we did that by
1789         itself, we'd keep creating new files in the file
1790         system with the most space until it was as full
1791         as all others, thus negating any performance
1792         benefits of this RAID-1 like approach.
1793
1794         So, we use a user-configurable space threshold. If
1795         there are at least 2 filesystems with more than this
1796         much space available, we use RR selection between them. 
1797         If not, then we pick the filesystem with the most space.
1798
1799         This gets a good balance between the two
1800         approaches.  
1801         */
1802         
1803         refresh_disk_space ();
1804         
1805         int free_enough = 0;
1806
1807         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1808                 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1809                         free_enough++;
1810                 }
1811         }
1812
1813         if (free_enough >= 2) {
1814
1815                 bool found_it = false;
1816
1817                 /* use RR selection process, ensuring that the one
1818                    picked works OK.
1819                 */
1820
1821                 i = last_rr_session_dir;
1822
1823                 do {
1824                         if (++i == session_dirs.end()) {
1825                                 i = session_dirs.begin();
1826                         }
1827
1828                         if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1829                                 if (ensure_sound_dir ((*i).path, result) == 0) {
1830                                         last_rr_session_dir = i;
1831                                         found_it = true;
1832                                         break;
1833                                 }
1834                         }
1835
1836                 } while (i != last_rr_session_dir);
1837
1838                 if (!found_it) {
1839                         result = sound_dir();
1840                 }
1841
1842         } else {
1843
1844                 /* pick FS with the most freespace (and that
1845                    seems to actually work ...)
1846                 */
1847                 
1848                 vector<space_and_path> sorted;
1849                 space_and_path_ascending_cmp cmp;
1850
1851                 sorted = session_dirs;
1852                 sort (sorted.begin(), sorted.end(), cmp);
1853                 
1854                 for (i = sorted.begin(); i != sorted.end(); ++i) {
1855                         if (ensure_sound_dir ((*i).path, result) == 0) {
1856                                 last_rr_session_dir = i;
1857                                 break;
1858                         }
1859                 }
1860                 
1861                 /* if the above fails, fall back to the most simplistic solution */
1862                 
1863                 if (i == sorted.end()) {
1864                         return sound_dir();
1865                 } 
1866         }
1867
1868         return result;
1869 }
1870
1871 int
1872 Session::load_playlists (const XMLNode& node)
1873 {
1874         XMLNodeList nlist;
1875         XMLNodeConstIterator niter;
1876         boost::shared_ptr<Playlist> playlist;
1877
1878         nlist = node.children();
1879
1880         set_dirty();
1881
1882         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1883                 
1884                 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1885                         error << _("Session: cannot create Playlist from XML description.") << endmsg;
1886                 }
1887         }
1888
1889         return 0;
1890 }
1891
1892 int
1893 Session::load_unused_playlists (const XMLNode& node)
1894 {
1895         XMLNodeList nlist;
1896         XMLNodeConstIterator niter;
1897         boost::shared_ptr<Playlist> playlist;
1898
1899         nlist = node.children();
1900
1901         set_dirty();
1902
1903         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1904                 
1905                 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1906                         error << _("Session: cannot create Playlist from XML description.") << endmsg;
1907                         continue;
1908                 }
1909
1910                 // now manually untrack it
1911
1912                 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1913         }
1914
1915         return 0;
1916 }
1917
1918 boost::shared_ptr<Playlist>
1919 Session::XMLPlaylistFactory (const XMLNode& node)
1920 {
1921         try {
1922                 return PlaylistFactory::create (*this, node);
1923         }
1924
1925         catch (failed_constructor& err) {
1926                 return boost::shared_ptr<Playlist>();
1927         }
1928 }
1929
1930 int
1931 Session::load_named_selections (const XMLNode& node)
1932 {
1933         XMLNodeList nlist;
1934         XMLNodeConstIterator niter;
1935         NamedSelection *ns;
1936
1937         nlist = node.children();
1938
1939         set_dirty();
1940
1941         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1942                 
1943                 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1944                         error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1945                 }
1946         }
1947
1948         return 0;
1949 }
1950
1951 NamedSelection *
1952 Session::XMLNamedSelectionFactory (const XMLNode& node)
1953 {
1954         try {
1955                 return new NamedSelection (*this, node);
1956         }
1957
1958         catch (failed_constructor& err) {
1959                 return 0;
1960         }
1961 }
1962
1963 string
1964 Session::dead_sound_dir () const
1965 {
1966         string res = _path;
1967         res += dead_sound_dir_name;
1968
1969         return res;
1970 }
1971
1972 string
1973 Session::old_sound_dir (bool with_path) const
1974 {
1975         string res;
1976
1977         if (with_path) {
1978                 res = _path;
1979         }
1980
1981         res += old_sound_dir_name;
1982
1983         return res;
1984 }
1985
1986 string
1987 Session::sound_dir (bool with_path) const
1988 {
1989         string res;
1990         string full;
1991
1992         if (with_path) {
1993                 res = _path;
1994         } else {
1995                 full = _path;
1996         }
1997
1998         res += interchange_dir_name;
1999         res += '/';
2000         res += legalize_for_path (_name);
2001         res += '/';
2002         res += sound_dir_name;
2003
2004         if (with_path) {
2005                 full = res;
2006         } else {
2007                 full += res;
2008         }
2009         
2010         /* if this already exists, don't check for the old session sound directory */
2011
2012         if (Glib::file_test (full, Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
2013                 return res;
2014         }
2015                 
2016         /* possibly support old session structure */
2017
2018         string old_nopath;
2019         string old_withpath;
2020
2021         old_nopath += old_sound_dir_name;
2022         old_nopath += '/';
2023         
2024         old_withpath = _path;
2025         old_withpath += old_sound_dir_name;
2026         
2027         if (Glib::file_test (old_withpath.c_str(), Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
2028                 if (with_path)
2029                         return old_withpath;
2030                 
2031                 return old_nopath;
2032         }
2033         
2034         /* ok, old "sounds" directory isn't there, return the new path */
2035
2036         return res;
2037 }
2038
2039 string
2040 Session::peak_dir () const
2041 {
2042         string res = _path;
2043         res += peak_dir_name;
2044         res += '/';
2045         return res;
2046 }
2047         
2048 string
2049 Session::automation_dir () const
2050 {
2051         string res = _path;
2052         res += "automation/";
2053         return res;
2054 }
2055
2056 string
2057 Session::template_dir ()
2058 {
2059         string path = get_user_ardour_path();
2060         path += "templates/";
2061
2062         return path;
2063 }
2064
2065 string
2066 Session::export_dir () const
2067 {
2068         string res = _path;
2069         res += export_dir_name;
2070         res += '/';
2071         return res;
2072 }
2073
2074 string
2075 Session::suffixed_search_path (string suffix, bool data)
2076 {
2077         string path;
2078
2079         path += get_user_ardour_path();
2080         if (path[path.length()-1] != ':') {
2081                 path += ':';
2082         }
2083
2084         if (data) {
2085                 path += get_system_data_path();
2086         } else {
2087                 path += get_system_module_path();
2088         }
2089
2090         vector<string> split_path;
2091         
2092         split (path, split_path, ':');
2093         path = "";
2094
2095         for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2096                 path += *i;
2097                 path += suffix;
2098                 path += '/';
2099                 
2100                 if (distance (i, split_path.end()) != 1) {
2101                         path += ':';
2102                 }
2103         }
2104                 
2105         return path;
2106 }
2107
2108 string
2109 Session::template_path ()
2110 {
2111         return suffixed_search_path (X_("templates"), true);
2112 }
2113
2114 string
2115 Session::control_protocol_path ()
2116 {
2117         return suffixed_search_path (X_("surfaces"), false);
2118 }
2119
2120 int
2121 Session::load_bundles (const XMLNode& node)
2122 {
2123         XMLNodeList nlist = node.children();
2124         XMLNodeConstIterator niter;
2125
2126         set_dirty();
2127
2128         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2129                 if ((*niter)->name() == "InputConnection") {
2130                         add_bundle (new ARDOUR::InputBundle (**niter));
2131                 } else if ((*niter)->name() == "OutputConnection") {
2132                         add_bundle (new ARDOUR::OutputBundle (**niter));
2133                 } else {
2134                         error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2135                         return -1;
2136                 }
2137         }
2138
2139         return 0;
2140 }                               
2141
2142 int
2143 Session::load_edit_groups (const XMLNode& node)
2144 {
2145         return load_route_groups (node, true);
2146 }
2147
2148 int
2149 Session::load_mix_groups (const XMLNode& node)
2150 {
2151         return load_route_groups (node, false);
2152 }
2153
2154 int
2155 Session::load_route_groups (const XMLNode& node, bool edit)
2156 {
2157         XMLNodeList nlist = node.children();
2158         XMLNodeConstIterator niter;
2159         RouteGroup* rg;
2160
2161         set_dirty();
2162
2163         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2164                 if ((*niter)->name() == "RouteGroup") {
2165                         if (edit) {
2166                                 rg = add_edit_group ("");
2167                                 rg->set_state (**niter);
2168                         } else {
2169                                 rg = add_mix_group ("");
2170                                 rg->set_state (**niter);
2171                         }
2172                 }
2173         }
2174         
2175         return 0;
2176 }                               
2177
2178 static bool
2179 state_file_filter (const string &str, void *arg)
2180 {
2181         return (str.length() > strlen(statefile_suffix) &&
2182                 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2183 }
2184
2185 struct string_cmp {
2186         bool operator()(const string* a, const string* b) {
2187                 return *a < *b;
2188         }
2189 };
2190
2191 static string*
2192 remove_end(string* state)
2193 {
2194         string statename(*state);
2195         
2196         string::size_type start,end;
2197         if ((start = statename.find_last_of ('/')) != string::npos) {
2198                 statename = statename.substr (start+1);
2199         }
2200                 
2201         if ((end = statename.rfind(".ardour")) == string::npos) {
2202                 end = statename.length();
2203         }
2204
2205         return new string(statename.substr (0, end));
2206 }
2207
2208 vector<string *> *
2209 Session::possible_states (string path) 
2210 {
2211         PathScanner scanner;
2212         vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2213         
2214         transform(states->begin(), states->end(), states->begin(), remove_end);
2215         
2216         string_cmp cmp;
2217         sort (states->begin(), states->end(), cmp);
2218         
2219         return states;
2220 }
2221
2222 vector<string *> *
2223 Session::possible_states () const
2224 {
2225         return possible_states(_path);
2226 }
2227
2228 void
2229 Session::auto_save()
2230 {
2231         save_state (_current_snapshot_name);
2232 }
2233
2234 RouteGroup *
2235 Session::add_edit_group (string name)
2236 {
2237         RouteGroup* rg = new RouteGroup (*this, name);
2238         edit_groups.push_back (rg);
2239         edit_group_added (rg); /* EMIT SIGNAL */
2240         set_dirty();
2241         return rg;
2242 }
2243
2244 RouteGroup *
2245 Session::add_mix_group (string name)
2246 {
2247         RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2248         mix_groups.push_back (rg);
2249         mix_group_added (rg); /* EMIT SIGNAL */
2250         set_dirty();
2251         return rg;
2252 }
2253
2254 void
2255 Session::remove_edit_group (RouteGroup& rg)
2256 {
2257         list<RouteGroup*>::iterator i;
2258
2259         if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2260                 (*i)->apply (&Route::drop_edit_group, this);
2261                 edit_groups.erase (i);
2262                 edit_group_removed (); /* EMIT SIGNAL */
2263         }
2264
2265         delete &rg;
2266 }
2267
2268 void
2269 Session::remove_mix_group (RouteGroup& rg)
2270 {
2271         list<RouteGroup*>::iterator i;
2272
2273         if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2274                 (*i)->apply (&Route::drop_mix_group, this);
2275                 mix_groups.erase (i);
2276                 mix_group_removed (); /* EMIT SIGNAL */
2277         }
2278
2279         delete &rg;
2280 }
2281
2282 RouteGroup *
2283 Session::mix_group_by_name (string name)
2284 {
2285         list<RouteGroup *>::iterator i;
2286
2287         for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2288                 if ((*i)->name() == name) {
2289                         return* i;
2290                 }
2291         }
2292         return 0;
2293 }
2294
2295 RouteGroup *
2296 Session::edit_group_by_name (string name)
2297 {
2298         list<RouteGroup *>::iterator i;
2299
2300         for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2301                 if ((*i)->name() == name) {
2302                         return* i;
2303                 }
2304         }
2305         return 0;
2306 }
2307
2308 void
2309 Session::begin_reversible_command (string name)
2310 {
2311         current_trans = new UndoTransaction;
2312         current_trans->set_name (name);
2313 }
2314
2315 void
2316 Session::commit_reversible_command (Command *cmd)
2317 {
2318         struct timeval now;
2319
2320         if (cmd) {
2321                 current_trans->add_command (cmd);
2322         }
2323
2324         gettimeofday (&now, 0);
2325         current_trans->set_timestamp (now);
2326
2327         _history.add (current_trans);
2328 }
2329
2330 Session::GlobalRouteBooleanState 
2331 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2332 {
2333         GlobalRouteBooleanState s;
2334         boost::shared_ptr<RouteList> r = routes.reader ();
2335
2336         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2337                 if (!(*i)->hidden()) {
2338                         RouteBooleanState v;
2339                         
2340                         v.first =* i;
2341                         Route* r = (*i).get();
2342                         v.second = (r->*method)();
2343                         
2344                         s.push_back (v);
2345                 }
2346         }
2347
2348         return s;
2349 }
2350
2351 Session::GlobalRouteMeterState
2352 Session::get_global_route_metering ()
2353 {
2354         GlobalRouteMeterState s;
2355         boost::shared_ptr<RouteList> r = routes.reader ();
2356
2357         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2358                 if (!(*i)->hidden()) {
2359                         RouteMeterState v;
2360                         
2361                         v.first =* i;
2362                         v.second = (*i)->meter_point();
2363                         
2364                         s.push_back (v);
2365                 }
2366         }
2367
2368         return s;
2369 }
2370
2371 void
2372 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg) 
2373 {
2374         for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2375
2376                 boost::shared_ptr<Route> r = (i->first.lock());
2377
2378                 if (r) {
2379                         r->set_meter_point (i->second, arg);
2380                 }
2381         }
2382 }
2383
2384 void
2385 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2386 {
2387         for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2388
2389                 boost::shared_ptr<Route> r = (i->first.lock());
2390
2391                 if (r) {
2392                         Route* rp = r.get();
2393                         (rp->*method) (i->second, arg);
2394                 }
2395         }
2396 }
2397
2398 void
2399 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2400 {
2401         set_global_route_boolean (s, &Route::set_mute, src);
2402 }
2403
2404 void
2405 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2406 {
2407         set_global_route_boolean (s, &Route::set_solo, src);
2408 }
2409
2410 void
2411 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2412 {
2413         set_global_route_boolean (s, &Route::set_record_enable, src);
2414 }
2415
2416 #if 0
2417 UndoAction
2418 Session::global_mute_memento (void* src)
2419 {
2420         return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2421 }
2422
2423 UndoAction
2424 Session::global_metering_memento (void* src)
2425 {
2426         return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2427 }
2428
2429 UndoAction
2430 Session::global_solo_memento (void* src)
2431 {
2432         return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2433 }
2434
2435 UndoAction
2436 Session::global_record_enable_memento (void* src)
2437 {
2438         return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2439 }
2440 #endif
2441
2442 static bool
2443 template_filter (const string &str, void *arg)
2444 {
2445         return (str.length() > strlen(template_suffix) &&
2446                 str.find (template_suffix) == (str.length() - strlen (template_suffix)));
2447 }
2448
2449 void
2450 Session::get_template_list (list<string> &template_names)
2451 {
2452         vector<string *> *templates;
2453         PathScanner scanner;
2454         string path;
2455
2456         path = template_path ();
2457
2458         templates = scanner (path, template_filter, 0, false, true);
2459         
2460         vector<string*>::iterator i;
2461         for (i = templates->begin(); i != templates->end(); ++i) {
2462                 string fullpath = *(*i);
2463                 int start, end;
2464
2465                 start = fullpath.find_last_of ('/') + 1;
2466                 if ((end = fullpath.find_last_of ('.')) <0) {
2467                         end = fullpath.length();
2468                 }
2469                 
2470                 template_names.push_back(fullpath.substr(start, (end-start)));
2471         }
2472 }
2473
2474 int
2475 Session::read_favorite_dirs (FavoriteDirs & favs)
2476 {
2477         string path = get_user_ardour_path();
2478         path += "/favorite_dirs";
2479
2480         ifstream fav (path.c_str());
2481
2482         favs.clear();
2483         
2484         if (!fav) {
2485                 if (errno != ENOENT) {
2486                         //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2487                         return -1;
2488                 } else {
2489                         return 1;
2490                 }
2491         }
2492
2493         while (true) {
2494
2495                 string newfav;
2496
2497                 getline(fav, newfav);
2498
2499                 if (!fav.good()) {
2500                         break;
2501                 }
2502
2503                 favs.push_back (newfav);
2504         }
2505
2506         return 0;
2507 }
2508
2509 int
2510 Session::write_favorite_dirs (FavoriteDirs & favs)
2511 {
2512         string path = get_user_ardour_path();
2513         path += "/favorite_dirs";
2514
2515         ofstream fav (path.c_str());
2516
2517         if (!fav) {
2518                 return -1;
2519         }
2520
2521         for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2522                 fav << (*i) << endl;
2523         }
2524         
2525         return 0;
2526 }
2527
2528 static bool
2529 accept_all_non_peak_files (const string& path, void *arg)
2530 {
2531         return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2532 }
2533
2534 static bool
2535 accept_all_state_files (const string& path, void *arg)
2536 {
2537         return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2538 }
2539
2540 int 
2541 Session::find_all_sources (string path, set<string>& result)
2542 {
2543         XMLTree tree;
2544         XMLNode* node;
2545
2546         if (!tree.read (path)) {
2547                 return -1;
2548         }
2549
2550         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2551                 return -2;
2552         }
2553
2554         XMLNodeList nlist;
2555         XMLNodeConstIterator niter;
2556
2557         nlist = node->children();
2558
2559         set_dirty();
2560
2561         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2562                 
2563                 XMLProperty* prop;
2564
2565                 if ((prop = (*niter)->property (X_("name"))) == 0) {
2566                         continue;
2567                 }
2568
2569                 if (prop->value()[0] == '/') {
2570                         /* external file, ignore */
2571                         continue;
2572                 }
2573
2574                 string path = _path; /* /-terminated */
2575                 path += sound_dir_name;
2576                 path += '/';
2577                 path += prop->value();
2578
2579                 result.insert (path);
2580         }
2581
2582         return 0;
2583 }
2584
2585 int
2586 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2587 {
2588         PathScanner scanner;
2589         vector<string*>* state_files;
2590         string ripped;
2591         string this_snapshot_path;
2592
2593         result.clear ();
2594
2595         ripped = _path;
2596
2597         if (ripped[ripped.length()-1] == '/') {
2598                 ripped = ripped.substr (0, ripped.length() - 1);
2599         }
2600
2601         state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2602         
2603         if (state_files == 0) {
2604                 /* impossible! */
2605                 return 0;
2606         }
2607
2608         this_snapshot_path = _path;
2609         this_snapshot_path += _current_snapshot_name;
2610         this_snapshot_path += statefile_suffix;
2611
2612         for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2613
2614                 if (exclude_this_snapshot && **i == this_snapshot_path) {
2615                         continue;
2616                 }
2617
2618                 if (find_all_sources (**i, result) < 0) {
2619                         return -1;
2620                 }
2621         }
2622
2623         return 0;
2624 }
2625
2626 struct RegionCounter {
2627     typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2628     AudioSourceList::iterator iter;
2629     boost::shared_ptr<Region> region;
2630     uint32_t count;
2631     
2632     RegionCounter() : count (0) {}
2633 };
2634
2635 int
2636 Session::cleanup_sources (Session::cleanup_report& rep)
2637 {
2638         vector<boost::shared_ptr<Source> > dead_sources;
2639         vector<boost::shared_ptr<Playlist> > playlists_tbd;
2640         PathScanner scanner;
2641         string sound_path;
2642         vector<space_and_path>::iterator i;
2643         vector<space_and_path>::iterator nexti;
2644         vector<string*>* soundfiles;
2645         vector<string> unused;
2646         set<string> all_sources;
2647         bool used;
2648         string spath;
2649         int ret = -1;
2650                 
2651         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2652         
2653         /* step 1: consider deleting all unused playlists */
2654
2655         for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2656                 int status;
2657
2658                 status = AskAboutPlaylistDeletion (*x);
2659
2660                 switch (status) {
2661                 case -1:
2662                         ret = 0;
2663                         goto out;
2664                         break;
2665
2666                 case 0:
2667                         playlists_tbd.push_back (*x);
2668                         break;
2669
2670                 default:
2671                         /* leave it alone */
2672                         break;
2673                 }
2674         }
2675
2676         /* now delete any that were marked for deletion */
2677
2678         for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2679                 (*x)->drop_references ();
2680         }
2681
2682         playlists_tbd.clear ();
2683
2684         /* step 2: find all un-used sources */
2685
2686         rep.paths.clear ();
2687         rep.space = 0;
2688
2689         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2690                 
2691                 SourceMap::iterator tmp;
2692
2693                 tmp = i;
2694                 ++tmp;
2695
2696                 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2697                    capture files.
2698                 */
2699
2700                 if (!i->second->used() && i->second->length() > 0) {
2701                         dead_sources.push_back (i->second);
2702                         i->second->GoingAway();
2703                 } 
2704
2705                 i = tmp;
2706         }
2707
2708         /* build a list of all the possible sound directories for the session */
2709
2710         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2711
2712                 nexti = i;
2713                 ++nexti;
2714
2715                 sound_path += (*i).path;
2716                 sound_path += sound_dir (false);
2717
2718                 if (nexti != session_dirs.end()) {
2719                         sound_path += ':';
2720                 }
2721
2722                 i = nexti;
2723         }
2724
2725         /* now do the same thing for the files that ended up in the sounds dir(s) 
2726            but are not referenced as sources in any snapshot.
2727         */
2728
2729         soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2730
2731         if (soundfiles == 0) {
2732                 return 0;
2733         }
2734
2735         /* find all sources, but don't use this snapshot because the
2736            state file on disk still references sources we may have already
2737            dropped.
2738         */
2739         
2740         find_all_sources_across_snapshots (all_sources, true);
2741
2742         /*  add our current source list
2743          */
2744         
2745         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2746                 boost::shared_ptr<AudioFileSource> fs;
2747                 
2748                 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2749                         all_sources.insert (fs->path());
2750                 } 
2751         }
2752
2753         char tmppath1[PATH_MAX+1];
2754         char tmppath2[PATH_MAX+1];
2755         
2756         for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2757
2758                 used = false;
2759                 spath = **x;
2760
2761                 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2762
2763                         realpath(spath.c_str(), tmppath1);
2764                         realpath((*i).c_str(),  tmppath2);
2765
2766                         if (strcmp(tmppath1, tmppath2) == 0) {
2767                                 used = true;
2768                                 break;
2769                         }
2770                 }
2771
2772                 if (!used) {
2773                         unused.push_back (spath);
2774                 }
2775         }
2776
2777         /* now try to move all unused files into the "dead_sounds" directory(ies) */
2778
2779         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2780                 struct stat statbuf;
2781
2782                 rep.paths.push_back (*x);
2783                 if (stat ((*x).c_str(), &statbuf) == 0) {
2784                         rep.space += statbuf.st_size;
2785                 }
2786
2787                 string newpath;
2788                 
2789                 /* don't move the file across filesystems, just
2790                    stick it in the `dead_sound_dir_name' directory
2791                    on whichever filesystem it was already on.
2792                 */
2793
2794                 if ((*x).find ("/sounds/") != string::npos) {
2795
2796                         /* old school, go up 1 level */
2797
2798                         newpath = Glib::path_get_dirname (*x);      // "sounds" 
2799                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2800
2801                 } else {
2802
2803                         /* new school, go up 4 levels */
2804                         
2805                         newpath = Glib::path_get_dirname (*x);      // "audiofiles" 
2806                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2807                         newpath = Glib::path_get_dirname (newpath); // "interchange"
2808                         newpath = Glib::path_get_dirname (newpath); // "session-dir"
2809                 }
2810
2811                 newpath += '/';
2812                 newpath += dead_sound_dir_name;
2813
2814                 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2815                         error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2816                         return -1;
2817                 }
2818
2819                 newpath += '/';
2820                 newpath += Glib::path_get_basename ((*x));
2821                 
2822                 if (access (newpath.c_str(), F_OK) == 0) {
2823                         
2824                         /* the new path already exists, try versioning */
2825                         
2826                         char buf[PATH_MAX+1];
2827                         int version = 1;
2828                         string newpath_v;
2829                         
2830                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2831                         newpath_v = buf;
2832
2833                         while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2834                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2835                                 newpath_v = buf;
2836                         }
2837                         
2838                         if (version == 999) {
2839                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2840                                                   newpath)
2841                                       << endmsg;
2842                         } else {
2843                                 newpath = newpath_v;
2844                         }
2845                         
2846                 } else {
2847                         
2848                         /* it doesn't exist, or we can't read it or something */
2849                         
2850                 }
2851
2852                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2853                         error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2854                                           (*x), newpath, strerror (errno))
2855                               << endmsg;
2856                         goto out;
2857                 }
2858
2859                 /* see if there an easy to find peakfile for this file, and remove it.
2860                  */
2861
2862                 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2863                 peakpath += ".peak";
2864
2865                 if (access (peakpath.c_str(), W_OK) == 0) {
2866                         if (::unlink (peakpath.c_str()) != 0) {
2867                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2868                                                   peakpath, _path, strerror (errno))
2869                                       << endmsg;
2870                                 /* try to back out */
2871                                 rename (newpath.c_str(), _path.c_str());
2872                                 goto out;
2873                         }
2874                 }
2875         }
2876
2877         ret = 0;
2878
2879         /* dump the history list */
2880
2881         _history.clear ();
2882
2883         /* save state so we don't end up a session file
2884            referring to non-existent sources.
2885         */
2886         
2887         save_state ("");
2888
2889   out:
2890         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2891         return ret;
2892 }
2893
2894 int
2895 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2896 {
2897         vector<space_and_path>::iterator i;
2898         string dead_sound_dir;
2899         struct dirent* dentry;
2900         struct stat statbuf;
2901         DIR* dead;
2902
2903         rep.paths.clear ();
2904         rep.space = 0;
2905
2906         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2907                 
2908                 dead_sound_dir = (*i).path;
2909                 dead_sound_dir += dead_sound_dir_name;
2910
2911                 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2912                         continue;
2913                 }
2914
2915                 while ((dentry = readdir (dead)) != 0) {
2916
2917                         /* avoid '.' and '..' */
2918                         
2919                         if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') || 
2920                             (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2921                                 continue;
2922                         }
2923
2924                         string fullpath;
2925
2926                         fullpath = dead_sound_dir;
2927                         fullpath += '/';
2928                         fullpath += dentry->d_name;
2929
2930                         if (stat (fullpath.c_str(), &statbuf)) {
2931                                 continue;
2932                         }
2933
2934                         if (!S_ISREG (statbuf.st_mode)) {
2935                                 continue;
2936                         }
2937
2938                         if (unlink (fullpath.c_str())) {
2939                                 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2940                                                   fullpath, strerror (errno))
2941                                       << endmsg;
2942                         }
2943
2944                         rep.paths.push_back (dentry->d_name);
2945                         rep.space += statbuf.st_size;
2946                 }
2947
2948                 closedir (dead);
2949                 
2950         }
2951
2952         return 0;
2953 }
2954
2955 void
2956 Session::set_dirty ()
2957 {
2958         bool was_dirty = dirty();
2959
2960         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2961
2962         if (!was_dirty) {
2963                 DirtyChanged(); /* EMIT SIGNAL */
2964         }
2965 }
2966
2967
2968 void
2969 Session::set_clean ()
2970 {
2971         bool was_dirty = dirty();
2972         
2973         _state_of_the_state = Clean;
2974
2975         if (was_dirty) {
2976                 DirtyChanged(); /* EMIT SIGNAL */
2977         }
2978 }
2979
2980 void
2981 Session::set_deletion_in_progress ()
2982 {
2983         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2984 }
2985
2986 void
2987 Session::add_controllable (Controllable* c)
2988 {
2989         /* this adds a controllable to the list managed by the Session.
2990            this is a subset of those managed by the Controllable class
2991            itself, and represents the only ones whose state will be saved
2992            as part of the session.
2993         */
2994
2995         Glib::Mutex::Lock lm (controllables_lock);
2996         controllables.insert (c);
2997 }
2998
2999 void
3000 Session::remove_controllable (Controllable* c)
3001 {
3002         if (_state_of_the_state | Deletion) {
3003                 return;
3004         }
3005
3006         Glib::Mutex::Lock lm (controllables_lock);
3007
3008         Controllables::iterator x = controllables.find (c);
3009
3010         if (x != controllables.end()) {
3011                 controllables.erase (x);
3012         }
3013 }       
3014
3015 Controllable*
3016 Session::controllable_by_id (const PBD::ID& id)
3017 {
3018         Glib::Mutex::Lock lm (controllables_lock);
3019         
3020         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3021                 if ((*i)->id() == id) {
3022                         return *i;
3023                 }
3024         }
3025
3026         return 0;
3027 }
3028
3029 void 
3030 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3031 {
3032         Stateful::add_instant_xml (node, dir);
3033         Config->add_instant_xml (node, get_user_ardour_path());
3034 }
3035
3036
3037 int 
3038 Session::save_history (string snapshot_name)
3039 {
3040     XMLTree tree;
3041     string xml_path;
3042     string bak_path;
3043
3044     tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3045
3046     if (snapshot_name.empty()) {
3047         snapshot_name = _current_snapshot_name;
3048     }
3049
3050     xml_path = _path + snapshot_name + ".history"; 
3051
3052     bak_path = xml_path + ".bak";
3053
3054     if ((access (xml_path.c_str(), F_OK) == 0) &&
3055         (rename (xml_path.c_str(), bak_path.c_str())))
3056     {
3057         error << _("could not backup old history file, current history not saved.") << endmsg;
3058         return -1;
3059     }
3060
3061     if (!tree.write (xml_path))
3062     {
3063         error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3064
3065         /* don't leave a corrupt file lying around if it is
3066          * possible to fix.
3067          */
3068
3069         if (unlink (xml_path.c_str())) {
3070                 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
3071         } else {
3072                 if (rename (bak_path.c_str(), xml_path.c_str())) 
3073                 {
3074                         error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
3075                 }
3076         }
3077
3078         return -1;
3079     }
3080
3081     return 0;
3082 }
3083
3084 int
3085 Session::restore_history (string snapshot_name)
3086 {
3087     XMLTree tree;
3088     string xmlpath;
3089
3090     if (snapshot_name.empty()) {
3091             snapshot_name = _current_snapshot_name;
3092     }
3093
3094     /* read xml */
3095     xmlpath = _path + snapshot_name + ".history";
3096     cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
3097
3098     if (access (xmlpath.c_str(), F_OK)) {
3099             info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
3100             return 1;
3101     }
3102
3103     if (!tree.read (xmlpath)) {
3104             error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
3105             return -1;
3106     }
3107
3108     /* replace history */
3109     _history.clear();
3110
3111     for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3112             
3113             XMLNode *t = *it;
3114             UndoTransaction* ut = new UndoTransaction ();
3115             struct timeval tv;
3116             
3117             ut->set_name(t->property("name")->value());
3118             stringstream ss(t->property("tv_sec")->value());
3119             ss >> tv.tv_sec;
3120             ss.str(t->property("tv_usec")->value());
3121             ss >> tv.tv_usec;
3122             ut->set_timestamp(tv);
3123             
3124             for (XMLNodeConstIterator child_it  = t->children().begin();
3125                  child_it != t->children().end();
3126                  child_it++)
3127             {
3128                     XMLNode *n = *child_it;
3129                     Command *c;
3130         
3131                     if (n->name() == "MementoCommand" ||
3132                         n->name() == "MementoUndoCommand" ||
3133                         n->name() == "MementoRedoCommand") {
3134
3135                             if ((c = memento_command_factory(n))) {
3136                                     ut->add_command(c);
3137                             }
3138                             
3139                     } else if (n->name() == X_("GlobalRouteStateCommand")) {
3140
3141                             if ((c = global_state_command_factory (*n))) {
3142                                     ut->add_command (c);
3143                             }
3144                             
3145                     } else {
3146
3147                             error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3148                     }
3149             }
3150
3151             _history.add (ut);
3152     }
3153
3154     return 0;
3155 }
3156
3157 void
3158 Session::config_changed (const char* parameter_name)
3159 {
3160 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3161
3162         if (PARAM_IS ("seamless-loop")) {
3163                 
3164         } else if (PARAM_IS ("rf-speed")) {
3165                 
3166         } else if (PARAM_IS ("auto-loop")) {
3167                 
3168         } else if (PARAM_IS ("auto-input")) {
3169
3170                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3171                         /* auto-input only makes a difference if we're rolling */
3172                         
3173                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3174                         
3175                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3176                                 if ((*i)->record_enabled ()) {
3177                                         (*i)->monitor_input (!Config->get_auto_input());
3178                                 }
3179                         }
3180                 }
3181
3182         } else if (PARAM_IS ("punch-in")) {
3183
3184                 Location* location;
3185                 
3186                 if ((location = _locations.auto_punch_location()) != 0) {
3187                         
3188                         if (Config->get_punch_in ()) {
3189                                 replace_event (Event::PunchIn, location->start());
3190                         } else {
3191                                 remove_event (location->start(), Event::PunchIn);
3192                         }
3193                 }
3194                 
3195         } else if (PARAM_IS ("punch-out")) {
3196
3197                 Location* location;
3198                 
3199                 if ((location = _locations.auto_punch_location()) != 0) {
3200                         
3201                         if (Config->get_punch_out()) {
3202                                 replace_event (Event::PunchOut, location->end());
3203                         } else {
3204                                 clear_events (Event::PunchOut);
3205                         }
3206                 }
3207
3208         } else if (PARAM_IS ("edit-mode")) {
3209
3210                 Glib::Mutex::Lock lm (playlist_lock);
3211                 
3212                 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3213                         (*i)->set_edit_mode (Config->get_edit_mode ());
3214                 }
3215
3216         } else if (PARAM_IS ("use-video-sync")) {
3217
3218                 waiting_for_sync_offset = Config->get_use_video_sync();
3219
3220         } else if (PARAM_IS ("mmc-control")) {
3221
3222                 //poke_midi_thread ();
3223
3224         } else if (PARAM_IS ("mmc-device-id")) {
3225
3226                 if (mmc) {
3227                         mmc->set_device_id (Config->get_mmc_device_id());
3228                 }
3229
3230         } else if (PARAM_IS ("midi-control")) {
3231                 
3232                 //poke_midi_thread ();
3233
3234         } else if (PARAM_IS ("raid-path")) {
3235
3236                 setup_raid_path (Config->get_raid_path());
3237
3238         } else if (PARAM_IS ("smpte-format")) {
3239
3240                 sync_time_vars ();
3241
3242         } else if (PARAM_IS ("video-pullup")) {
3243
3244                 sync_time_vars ();
3245
3246         } else if (PARAM_IS ("seamless-loop")) {
3247
3248                 if (play_loop && transport_rolling()) {
3249                         // to reset diskstreams etc
3250                         request_play_loop (true);
3251                 }
3252
3253         } else if (PARAM_IS ("rf-speed")) {
3254
3255                 cumulative_rf_motion = 0;
3256                 reset_rf_scale (0);
3257
3258         } else if (PARAM_IS ("click-sound")) {
3259
3260                 setup_click_sounds (1);
3261
3262         } else if (PARAM_IS ("click-emphasis-sound")) {
3263
3264                 setup_click_sounds (-1);
3265
3266         } else if (PARAM_IS ("clicking")) {
3267
3268                 if (Config->get_clicking()) {
3269                         if (_click_io && click_data) { // don't require emphasis data
3270                                 _clicking = true;
3271                         }
3272                 } else {
3273                         _clicking = false;
3274                 }
3275
3276         } else if (PARAM_IS ("send-mtc")) {
3277                 
3278                 /* only set the internal flag if we have
3279                    a port.
3280                 */
3281                 
3282                 if (_mtc_port != 0) {
3283                         session_send_mtc = Config->get_send_mtc();
3284                         if (session_send_mtc) {
3285                                 /* mark us ready to send */
3286                                 next_quarter_frame_to_send = 0;
3287                         }
3288                 } else {
3289                         session_send_mtc = false;
3290                 }
3291
3292         } else if (PARAM_IS ("send-mmc")) {
3293                 
3294                 /* only set the internal flag if we have
3295                    a port.
3296                 */
3297                 
3298                 if (_mmc_port != 0) {
3299                         session_send_mmc = Config->get_send_mmc();
3300                 } else {
3301                         mmc = 0;
3302                         session_send_mmc = false; 
3303                 }
3304
3305         } else if (PARAM_IS ("midi-feedback")) {
3306                 
3307                 /* only set the internal flag if we have
3308                    a port.
3309                 */
3310                 
3311                 if (_mtc_port != 0) {
3312                         session_midi_feedback = Config->get_midi_feedback();
3313                 }
3314
3315         } else if (PARAM_IS ("jack-time-master")) {
3316
3317                 engine().reset_timebase ();
3318
3319         } else if (PARAM_IS ("native-file-header-format")) {
3320
3321                 if (!first_file_header_format_reset) {
3322                         reset_native_file_format ();
3323                 }
3324
3325                 first_file_header_format_reset = false;
3326
3327         } else if (PARAM_IS ("native-file-data-format")) {
3328
3329                 if (!first_file_data_format_reset) {
3330                         reset_native_file_format ();
3331                 }
3332
3333                 first_file_data_format_reset = false;
3334
3335         } else if (PARAM_IS ("slave-source")) {
3336                 set_slave_source (Config->get_slave_source());
3337         } else if (PARAM_IS ("remote-model")) {
3338                 set_remote_control_ids ();
3339         }  else if (PARAM_IS ("denormal-model")) {
3340                 setup_fpu ();
3341         }
3342
3343         set_dirty ();
3344                    
3345 #undef PARAM_IS
3346
3347 }