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