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