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