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