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