Fixes case where audiofiles used wrong peakfiles
[ardour.git] / libs / ardour / session_state.cc
1 /*
2   Copyright (C) 1999-2013 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
21 #ifdef WAF_BUILD
22 #include "libardour-config.h"
23 #endif
24
25 #include <stdint.h>
26
27 #include <algorithm>
28 #include <fstream>
29 #include <string>
30 #include <cerrno>
31 #include <cstdio> /* snprintf(3) ... grrr */
32 #include <cmath>
33 #include <unistd.h>
34 #include <sys/stat.h>
35 #include <climits>
36 #include <signal.h>
37 #include <sys/time.h>
38
39 #ifdef HAVE_SYS_VFS_H
40 #include <sys/vfs.h>
41 #endif
42
43 #ifdef __APPLE__
44 #include <sys/param.h>
45 #include <sys/mount.h>
46 #endif
47
48 #ifdef HAVE_SYS_STATVFS_H
49 #include <sys/statvfs.h>
50 #endif
51
52 #include <glib.h>
53 #include <glib/gstdio.h>
54
55 #include <glibmm.h>
56 #include <glibmm/threads.h>
57 #include <glibmm/fileutils.h>
58
59 #include <boost/algorithm/string.hpp>
60
61 #include "midi++/mmc.h"
62 #include "midi++/port.h"
63
64 #include "evoral/SMF.hpp"
65
66 #include "pbd/boost_debug.h"
67 #include "pbd/basename.h"
68 #include "pbd/controllable_descriptor.h"
69 #include "pbd/debug.h"
70 #include "pbd/enumwriter.h"
71 #include "pbd/error.h"
72 #include "pbd/file_utils.h"
73 #include "pbd/pathexpand.h"
74 #include "pbd/pthread_utils.h"
75 #include "pbd/stacktrace.h"
76 #include "pbd/convert.h"
77 #include "pbd/localtime_r.h"
78
79 #include "ardour/amp.h"
80 #include "ardour/async_midi_port.h"
81 #include "ardour/audio_diskstream.h"
82 #include "ardour/audio_track.h"
83 #include "ardour/audioengine.h"
84 #include "ardour/audiofilesource.h"
85 #include "ardour/audioregion.h"
86 #include "ardour/automation_control.h"
87 #include "ardour/butler.h"
88 #include "ardour/control_protocol_manager.h"
89 #include "ardour/directory_names.h"
90 #include "ardour/filename_extensions.h"
91 #include "ardour/graph.h"
92 #include "ardour/location.h"
93 #include "ardour/midi_model.h"
94 #include "ardour/midi_patch_manager.h"
95 #include "ardour/midi_region.h"
96 #include "ardour/midi_scene_changer.h"
97 #include "ardour/midi_source.h"
98 #include "ardour/midi_track.h"
99 #include "ardour/pannable.h"
100 #include "ardour/playlist_factory.h"
101 #include "ardour/playlist_source.h"
102 #include "ardour/port.h"
103 #include "ardour/processor.h"
104 #include "ardour/profile.h"
105 #include "ardour/proxy_controllable.h"
106 #include "ardour/recent_sessions.h"
107 #include "ardour/region_factory.h"
108 #include "ardour/route_group.h"
109 #include "ardour/send.h"
110 #include "ardour/session.h"
111 #include "ardour/session_directory.h"
112 #include "ardour/session_metadata.h"
113 #include "ardour/session_playlists.h"
114 #include "ardour/session_state_utils.h"
115 #include "ardour/silentfilesource.h"
116 #include "ardour/sndfilesource.h"
117 #include "ardour/source_factory.h"
118 #include "ardour/speakers.h"
119 #include "ardour/template_utils.h"
120 #include "ardour/tempo.h"
121 #include "ardour/ticker.h"
122 #include "ardour/user_bundle.h"
123
124 #include "control_protocol/control_protocol.h"
125
126 #include "i18n.h"
127 #include <locale.h>
128
129 using namespace std;
130 using namespace ARDOUR;
131 using namespace PBD;
132
133 #define DEBUG_UNDO_HISTORY(msg) DEBUG_TRACE (PBD::DEBUG::UndoHistory, string_compose ("%1: %2\n", __LINE__, msg));
134
135 void
136 Session::pre_engine_init (string fullpath)
137 {
138         if (fullpath.empty()) {
139                 destroy ();
140                 throw failed_constructor();
141         }
142
143         /* discover canonical fullpath */
144
145         _path = canonical_path(fullpath);
146
147         /* is it new ? */
148         if (Profile->get_trx() ) {
149                 // Waves TracksLive has a usecase of session replacement with a new one.
150                 // We should check session state file (<session_name>.ardour) existance
151                 // to determine if the session is new or not
152
153                 string full_session_name = Glib::build_filename( fullpath, _name );
154                 full_session_name += statefile_suffix;
155                 
156                 _is_new = !Glib::file_test (full_session_name, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
157         } else {
158                 _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
159         }
160
161         /* finish initialization that can't be done in a normal C++ constructor
162            definition.
163         */
164
165         timerclear (&last_mmc_step);
166         g_atomic_int_set (&processing_prohibited, 0);
167         g_atomic_int_set (&_record_status, Disabled);
168         g_atomic_int_set (&_playback_load, 100);
169         g_atomic_int_set (&_capture_load, 100);
170         set_next_event ();
171         _all_route_group->set_active (true, this);
172         interpolation.add_channel_to (0, 0);
173
174         if (config.get_use_video_sync()) {
175                 waiting_for_sync_offset = true;
176         } else {
177                 waiting_for_sync_offset = false;
178         }
179
180         last_rr_session_dir = session_dirs.begin();
181
182         set_history_depth (Config->get_history_depth());
183         
184         /* default: assume simple stereo speaker configuration */
185
186         _speakers->setup_default_speakers (2);
187
188         _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
189                                                         boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
190                                                         boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
191         add_controllable (_solo_cut_control);
192
193         /* These are all static "per-class" signals */
194
195         SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
196         PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
197         AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
198         Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
199         IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
200
201         /* stop IO objects from doing stuff until we're ready for them */
202
203         Delivery::disable_panners ();
204         IO::disable_connecting ();
205
206         AudioFileSource::set_peak_dir (_session_dir->peak_path());
207 }
208
209 int
210 Session::post_engine_init ()
211 {
212         BootMessage (_("Set block size and sample rate"));
213
214         set_block_size (_engine.samples_per_cycle());
215         set_frame_rate (_engine.sample_rate());
216
217         BootMessage (_("Using configuration"));
218
219         _midi_ports = new MidiPortManager;
220         
221         MIDISceneChanger* msc;
222
223         _scene_changer = msc = new MIDISceneChanger (*this);
224         msc->set_input_port (scene_input_port());
225         msc->set_output_port (scene_out());
226
227         boost::function<framecnt_t(void)> timer_func (boost::bind (&Session::audible_frame, this));
228         boost::dynamic_pointer_cast<AsyncMIDIPort>(scene_in())->set_timer (timer_func);
229
230         setup_midi_machine_control ();
231         
232         if (_butler->start_thread()) {
233                 return -1;
234         }
235         
236         if (start_midi_thread ()) {
237                 return -1;
238         }
239         
240         setup_click_sounds (0);
241         setup_midi_control ();
242
243         _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
244         _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
245
246         try {
247                 /* tempo map requires sample rate knowledge */
248
249                 delete _tempo_map;
250                 _tempo_map = new TempoMap (_current_frame_rate);
251                 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
252                 
253                 /* MidiClock requires a tempo map */
254
255                 midi_clock = new MidiClockTicker ();
256                 midi_clock->set_session (this);
257
258                 /* crossfades require sample rate knowledge */
259
260                 SndFileSource::setup_standard_crossfades (*this, frame_rate());
261                 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
262                 
263                 AudioDiskstream::allocate_working_buffers();
264                 refresh_disk_space ();
265                 
266                 /* we're finally ready to call set_state() ... all objects have
267                  * been created, the engine is running.
268                  */
269                 
270                 if (state_tree) {
271                         if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
272                                 return -1;
273                         }
274                 } else {
275                         // set_state() will call setup_raid_path(), but if it's a new session we need
276                         // to call setup_raid_path() here.
277                         setup_raid_path (_path);
278                 }
279
280                 /* ENGINE */
281
282                 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
283                 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
284                 
285                 Config->map_parameters (ff);
286                 config.map_parameters (ft);
287                 _butler->map_parameters ();
288
289                 /* Reset all panners */
290                 
291                 Delivery::reset_panners ();
292                 
293                 /* this will cause the CPM to instantiate any protocols that are in use
294                  * (or mandatory), which will pass it this Session, and then call
295                  * set_state() on each instantiated protocol to match stored state.
296                  */
297                 
298                 ControlProtocolManager::instance().set_session (this);
299                 
300                 /* This must be done after the ControlProtocolManager set_session above,
301                    as it will set states for ports which the ControlProtocolManager creates.
302                 */
303                 
304                 // XXX set state of MIDI::Port's
305                 // MidiPortManager::instance()->set_port_states (Config->midi_port_states ());
306                 
307                 /* And this must be done after the MIDI::Manager::set_port_states as
308                  * it will try to make connections whose details are loaded by set_port_states.
309                  */
310                 
311                 hookup_io ();
312                 
313                 /* Let control protocols know that we are now all connected, so they
314                  * could start talking to surfaces if they want to.
315                  */
316                 
317                 ControlProtocolManager::instance().midi_connectivity_established ();
318                 
319                 if (_is_new && !no_auto_connect()) {
320                         Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock());
321                         auto_connect_master_bus ();
322                 }
323                 
324                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
325                 
326                 /* update latencies */
327                 
328                 initialize_latencies ();
329                 
330                 _locations->added.connect_same_thread (*this, boost::bind (&Session::location_added, this, _1));
331                 _locations->removed.connect_same_thread (*this, boost::bind (&Session::location_removed, this, _1));
332                 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
333                 
334         } catch (AudioEngine::PortRegistrationFailure& err) {
335                 /* handle this one in a different way than all others, so that its clear what happened */
336                 error << err.what() << endmsg;
337                 return -1;
338         } catch (...) {
339                 return -1;
340         }
341
342         BootMessage (_("Reset Remote Controls"));
343
344         // send_full_time_code (0);
345         _engine.transport_locate (0);
346
347         send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
348         send_immediate_mmc (MIDI::MachineControlCommand (Timecode::Time ()));
349
350         MIDI::Name::MidiPatchManager::instance().set_session (this);
351
352         ltc_tx_initialize();
353         /* initial program change will be delivered later; see ::config_changed() */
354
355         _state_of_the_state = Clean;
356
357         Port::set_connecting_blocked (false);
358
359         DirtyChanged (); /* EMIT SIGNAL */
360
361         if (_is_new) {
362                 save_state ("");
363         } else if (state_was_pending) {
364                 save_state ("");
365                 remove_pending_capture_state ();
366                 state_was_pending = false;
367         }
368
369         /* Now, finally, we can fill the playback buffers */
370     
371         BootMessage (_("Filling playback buffers"));
372     
373         boost::shared_ptr<RouteList> rl = routes.reader();
374         for (RouteList::iterator r = rl->begin(); r != rl->end(); ++r) {
375                 boost::shared_ptr<Track> trk = boost::dynamic_pointer_cast<Track> (*r);
376                 if (trk && !trk->hidden()) {
377                         trk->seek (_transport_frame, true);
378                 }
379         }
380
381         return 0;
382 }
383
384 void
385 Session::session_loaded ()
386 {
387         SessionLoaded();
388         
389         _state_of_the_state = Clean;
390         
391         DirtyChanged (); /* EMIT SIGNAL */
392         
393         if (_is_new) {
394                 save_state ("");
395         } else if (state_was_pending) {
396                 save_state ("");
397                 remove_pending_capture_state ();
398                 state_was_pending = false;
399         }
400         
401         /* Now, finally, we can fill the playback buffers */
402         
403         BootMessage (_("Filling playback buffers"));
404         force_locate (_transport_frame, false);
405 }
406
407 string
408 Session::raid_path () const
409 {
410         Searchpath raid_search_path;
411
412         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
413                 raid_search_path += (*i).path;
414         }
415
416         return raid_search_path.to_string ();
417 }
418
419 void
420 Session::setup_raid_path (string path)
421 {
422         if (path.empty()) {
423                 return;
424         }
425
426         space_and_path sp;
427         string fspath;
428
429         session_dirs.clear ();
430
431         Searchpath search_path(path);
432         Searchpath sound_search_path;
433         Searchpath midi_search_path;
434
435         for (Searchpath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
436                 sp.path = *i;
437                 sp.blocks = 0; // not needed
438                 session_dirs.push_back (sp);
439
440                 SessionDirectory sdir(sp.path);
441
442                 sound_search_path += sdir.sound_path ();
443                 midi_search_path += sdir.midi_path ();
444         }
445
446         // reset the round-robin soundfile path thingie
447         last_rr_session_dir = session_dirs.begin();
448 }
449
450 bool
451 Session::path_is_within_session (const std::string& path)
452 {
453         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
454                 if (PBD::path_is_within (i->path, path)) {
455                         return true;
456                 }
457         }
458         return false;
459 }
460
461 int
462 Session::ensure_subdirs ()
463 {
464         string dir;
465
466         dir = session_directory().peak_path();
467
468         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
469                 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
470                 return -1;
471         }
472
473         dir = session_directory().sound_path();
474
475         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
476                 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
477                 return -1;
478         }
479
480         dir = session_directory().midi_path();
481
482         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
483                 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
484                 return -1;
485         }
486
487         dir = session_directory().dead_path();
488
489         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
490                 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
491                 return -1;
492         }
493
494         dir = session_directory().export_path();
495
496         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
497                 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
498                 return -1;
499         }
500
501         dir = analysis_dir ();
502
503         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
504                 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
505                 return -1;
506         }
507
508         dir = plugins_dir ();
509
510         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
511                 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
512                 return -1;
513         }
514
515         dir = externals_dir ();
516
517         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
518                 error << string_compose(_("Session: cannot create session externals folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
519                 return -1;
520         }
521
522         return 0;
523 }
524
525 /** @param session_template directory containing session template, or empty.
526  *  Caller must not hold process lock.
527  */
528 int
529 Session::create (const string& session_template, BusProfile* bus_profile)
530 {
531         if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
532                 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
533                 return -1;
534         }
535
536         if (ensure_subdirs ()) {
537                 return -1;
538         }
539
540         _writable = exists_and_writable (_path);
541
542         if (!session_template.empty()) {
543                 std::string in_path = (ARDOUR::Profile->get_trx () ? session_template : session_template_dir_to_file (session_template));
544
545                 ifstream in(in_path.c_str());
546
547                 if (in) {
548                         /* no need to call legalize_for_path() since the string
549                          * in session_template is already a legal path name
550                          */
551                         string out_path = Glib::build_filename (_session_dir->root_path(), _name + statefile_suffix);
552
553                         ofstream out(out_path.c_str());
554
555                         if (out) {
556                                 out << in.rdbuf();
557                                 _is_new = false;
558
559                                 if (!ARDOUR::Profile->get_trx()) {
560                                         /* Copy plugin state files from template to new session */
561                                         std::string template_plugins = Glib::build_filename (session_template, X_("plugins"));
562                                         copy_recurse (template_plugins, plugins_dir ());
563                                 }
564                                 
565                                 return 0;
566
567                         } else {
568                                 error << string_compose (_("Could not open %1 for writing session template"), out_path)
569                                         << endmsg;
570                                 return -1;
571                         }
572
573                 } else {
574                         error << string_compose (_("Could not open session template %1 for reading"), in_path)
575                                 << endmsg;
576                         return -1;
577                 }
578
579         }
580
581         if (Profile->get_trx()) {
582         
583                 /* set initial start + end point : ARDOUR::Session::session_end_shift long.
584                    Remember that this is a brand new session. Sessions
585                    loaded from saved state will get this range from the saved state.
586                 */
587                 
588                 set_session_range_location (0, 0);
589                 
590                 /* Initial loop location, from absolute zero, length 10 seconds  */
591                 
592                 Location* loc = new Location (*this, 0, 10.0 * _engine.sample_rate(), _("Loop"),  Location::IsAutoLoop);
593                 _locations->add (loc, true);
594                 set_auto_loop_location (loc);
595         }
596
597         _state_of_the_state = Clean;
598
599         /* set up Master Out and Control Out if necessary */
600
601         if (bus_profile) {
602
603                 RouteList rl;
604                 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
605
606                 // Waves Tracks: always create master bus for Tracks
607                 if (ARDOUR::Profile->get_trx() || bus_profile->master_out_channels) {
608                         boost::shared_ptr<Route> r (new Route (*this, _("Master"), Route::MasterOut, DataType::AUDIO));
609                         if (r->init ()) {
610                                 return -1;
611                         }
612 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
613                         // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
614 #endif
615                         {
616                                 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
617                                 r->input()->ensure_io (count, false, this);
618                                 r->output()->ensure_io (count, false, this);
619                         }
620
621                         rl.push_back (r);
622
623                 } else {
624                         /* prohibit auto-connect to master, because there isn't one */
625                         bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
626                 }
627
628                 if (!rl.empty()) {
629                         add_routes (rl, false, false, false);
630                 }
631
632                 // Waves Tracks: Skip this. Always use autoconnection for Tracks
633                 if (!ARDOUR::Profile->get_trx()) {
634                         
635                         /* this allows the user to override settings with an environment variable.
636                          */
637                         
638                         if (no_auto_connect()) {
639                                 bus_profile->input_ac = AutoConnectOption (0);
640                                 bus_profile->output_ac = AutoConnectOption (0);
641                         }
642                         
643                         Config->set_input_auto_connect (bus_profile->input_ac);
644                         Config->set_output_auto_connect (bus_profile->output_ac);
645                 }
646         }
647
648         if (Config->get_use_monitor_bus() && bus_profile) {
649                 add_monitor_section ();
650         }
651
652         return 0;
653 }
654
655 void
656 Session::maybe_write_autosave()
657 {
658         if (dirty() && record_status() != Recording) {
659                 save_state("", true);
660         }
661 }
662
663 void
664 Session::remove_pending_capture_state ()
665 {
666         std::string pending_state_file_path(_session_dir->root_path());
667
668         pending_state_file_path = Glib::build_filename (pending_state_file_path, legalize_for_path (_current_snapshot_name) + pending_suffix);
669
670         if (!Glib::file_test (pending_state_file_path, Glib::FILE_TEST_EXISTS)) return;
671
672         if (g_remove (pending_state_file_path.c_str()) != 0) {
673                 error << string_compose(_("Could not remove pending capture state at path \"%1\" (%2)"),
674                                 pending_state_file_path, g_strerror (errno)) << endmsg;
675         }
676 }
677
678 /** Rename a state file.
679  *  @param old_name Old snapshot name.
680  *  @param new_name New snapshot name.
681  */
682 void
683 Session::rename_state (string old_name, string new_name)
684 {
685         if (old_name == _current_snapshot_name || old_name == _name) {
686                 /* refuse to rename the current snapshot or the "main" one */
687                 return;
688         }
689
690         const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
691         const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
692
693         const std::string old_xml_path(Glib::build_filename (_session_dir->root_path(), old_xml_filename));
694         const std::string new_xml_path(Glib::build_filename (_session_dir->root_path(), new_xml_filename));
695
696         if (::g_rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
697                 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
698                                 old_name, new_name, g_strerror(errno)) << endmsg;
699         }
700 }
701
702 /** Remove a state file.
703  *  @param snapshot_name Snapshot name.
704  */
705 void
706 Session::remove_state (string snapshot_name)
707 {
708         if (!_writable || snapshot_name == _current_snapshot_name || snapshot_name == _name) {
709                 // refuse to remove the current snapshot or the "main" one
710                 return;
711         }
712
713         std::string xml_path(_session_dir->root_path());
714
715         xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
716
717         if (!create_backup_file (xml_path)) {
718                 // don't remove it if a backup can't be made
719                 // create_backup_file will log the error.
720                 return;
721         }
722
723         // and delete it
724         if (g_remove (xml_path.c_str()) != 0) {
725                 error << string_compose(_("Could not remove session file at path \"%1\" (%2)"),
726                                 xml_path, g_strerror (errno)) << endmsg;
727         }
728 }
729
730 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
731 int
732 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot, bool template_only)
733 {
734         XMLTree tree;
735         std::string xml_path(_session_dir->root_path());
736
737         /* prevent concurrent saves from different threads */
738
739         Glib::Threads::Mutex::Lock lm (save_state_lock);
740
741         if (!_writable || (_state_of_the_state & CannotSave)) {
742                 return 1;
743         }
744
745         if (g_atomic_int_get(&_suspend_save)) {
746                 _save_queued = true;
747                 return 1;
748         }
749         _save_queued = false;
750
751         if (!_engine.connected ()) {
752                 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
753                                          PROGRAM_NAME)
754                       << endmsg;
755                 return 1;
756         }
757
758         /* tell sources we're saving first, in case they write out to a new file
759          * which should be saved with the state rather than the old one */
760         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
761                 try {
762                         i->second->session_saved();
763                 } catch (Evoral::SMF::FileError& e) {
764                         error << string_compose ("Could not write to MIDI file %1; MIDI data not saved.", e.file_name ()) << endmsg;
765                 }
766         }
767
768         SessionSaveUnderway (); /* EMIT SIGNAL */
769
770         if (template_only) {
771                 tree.set_root (&get_template());
772         } else {
773                 tree.set_root (&get_state());
774         }
775
776         if (snapshot_name.empty()) {
777                 snapshot_name = _current_snapshot_name;
778         } else if (switch_to_snapshot) {
779                 _current_snapshot_name = snapshot_name;
780         }
781
782         if (!pending) {
783
784                 /* proper save: use statefile_suffix (.ardour in English) */
785
786                 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
787
788                 /* make a backup copy of the old file */
789
790                 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && !create_backup_file (xml_path)) {
791                         // create_backup_file will log the error
792                         return -1;
793                 }
794
795         } else {
796
797                 /* pending save: use pending_suffix (.pending in English) */
798                 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + pending_suffix);
799         }
800
801         std::string tmp_path(_session_dir->root_path());
802         tmp_path = Glib::build_filename (tmp_path, legalize_for_path (snapshot_name) + temp_suffix);
803
804         cerr << "actually writing state to " << tmp_path << endl;
805         
806         if (!tree.write (tmp_path)) {
807                 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
808                 if (g_remove (tmp_path.c_str()) != 0) {
809                         error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
810                                         tmp_path, g_strerror (errno)) << endmsg;
811                 }
812                 return -1;
813
814         } else {
815
816                 cerr << "renaming state to " << xml_path << endl;
817                 
818                 if (::g_rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
819                         error << string_compose (_("could not rename temporary session file %1 to %2 (%3)"),
820                                         tmp_path, xml_path, g_strerror(errno)) << endmsg;
821                         if (g_remove (tmp_path.c_str()) != 0) {
822                                 error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
823                                                 tmp_path, g_strerror (errno)) << endmsg;
824                         }
825                         return -1;
826                 }
827         }
828
829         if (!pending) {
830
831                 save_history (snapshot_name);
832
833                 bool was_dirty = dirty();
834
835                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
836
837                 if (was_dirty) {
838                         DirtyChanged (); /* EMIT SIGNAL */
839                 }
840
841                 StateSaved (snapshot_name); /* EMIT SIGNAL */
842         }
843
844         return 0;
845 }
846
847 int
848 Session::restore_state (string snapshot_name)
849 {
850         if (load_state (snapshot_name) == 0) {
851                 set_state (*state_tree->root(), Stateful::loading_state_version);
852         }
853
854         return 0;
855 }
856
857 int
858 Session::load_state (string snapshot_name)
859 {
860         delete state_tree;
861         state_tree = 0;
862
863         state_was_pending = false;
864
865         /* check for leftover pending state from a crashed capture attempt */
866
867         std::string xmlpath(_session_dir->root_path());
868         xmlpath = Glib::build_filename (xmlpath, legalize_for_path (snapshot_name) + pending_suffix);
869
870         if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
871
872                 /* there is pending state from a crashed capture attempt */
873
874                 boost::optional<int> r = AskAboutPendingState();
875                 if (r.get_value_or (1)) {
876                         state_was_pending = true;
877                 }
878         }
879
880         if (!state_was_pending) {
881                 xmlpath = Glib::build_filename (_session_dir->root_path(), snapshot_name);
882         }
883
884         if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
885                 xmlpath = Glib::build_filename (_session_dir->root_path(), legalize_for_path (snapshot_name) + statefile_suffix);
886                 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
887                         error << string_compose(_("%1: session file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
888                         return 1;
889                 }
890         }
891
892         state_tree = new XMLTree;
893
894         set_dirty();
895
896         _writable = exists_and_writable (xmlpath) && exists_and_writable(Glib::path_get_dirname(xmlpath));
897
898         if (!state_tree->read (xmlpath)) {
899                 error << string_compose(_("Could not understand session file %1"), xmlpath) << endmsg;
900                 delete state_tree;
901                 state_tree = 0;
902                 return -1;
903         }
904
905         XMLNode& root (*state_tree->root());
906
907         if (root.name() != X_("Session")) {
908                 error << string_compose (_("Session file %1 is not a session"), xmlpath) << endmsg;
909                 delete state_tree;
910                 state_tree = 0;
911                 return -1;
912         }
913
914         const XMLProperty* prop;
915
916         if ((prop = root.property ("version")) == 0) {
917                 /* no version implies very old version of Ardour */
918                 Stateful::loading_state_version = 1000;
919         } else {
920                 if (prop->value().find ('.') != string::npos) {
921                         /* old school version format */
922                         if (prop->value()[0] == '2') {
923                                 Stateful::loading_state_version = 2000;
924                         } else {
925                                 Stateful::loading_state_version = 3000;
926                         }
927                 } else {
928                         Stateful::loading_state_version = atoi (prop->value());
929                 }
930         }
931
932         if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION && _writable) {
933
934                 std::string backup_path(_session_dir->root_path());
935                 std::string backup_filename = string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix);
936                 backup_path = Glib::build_filename (backup_path, backup_filename);
937
938                 // only create a backup for a given statefile version once
939
940                 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
941                         
942                         VersionMismatch (xmlpath, backup_path);
943                         
944                         if (!copy_file (xmlpath, backup_path)) {;
945                                 return -1;
946                         }
947                 }
948         }
949
950         return 0;
951 }
952
953 int
954 Session::load_options (const XMLNode& node)
955 {
956         LocaleGuard lg (X_("C"));
957         config.set_variables (node);
958         return 0;
959 }
960
961 bool
962 Session::save_default_options ()
963 {
964         return config.save_state();
965 }
966
967 XMLNode&
968 Session::get_state()
969 {
970         return state(true);
971 }
972
973 XMLNode&
974 Session::get_template()
975 {
976         /* if we don't disable rec-enable, diskstreams
977            will believe they need to store their capture
978            sources in their state node.
979         */
980
981         disable_record (false);
982
983         return state(false);
984 }
985
986 XMLNode&
987 Session::state (bool full_state)
988 {
989         XMLNode* node = new XMLNode("Session");
990         XMLNode* child;
991
992         char buf[16];
993         snprintf(buf, sizeof(buf), "%d", CURRENT_SESSION_FILE_VERSION);
994         node->add_property("version", buf);
995
996         /* store configuration settings */
997
998         if (full_state) {
999
1000                 node->add_property ("name", _name);
1001                 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
1002                 node->add_property ("sample-rate", buf);
1003
1004                 if (session_dirs.size() > 1) {
1005
1006                         string p;
1007
1008                         vector<space_and_path>::iterator i = session_dirs.begin();
1009                         vector<space_and_path>::iterator next;
1010
1011                         ++i; /* skip the first one */
1012                         next = i;
1013                         ++next;
1014
1015                         while (i != session_dirs.end()) {
1016
1017                                 p += (*i).path;
1018
1019                                 if (next != session_dirs.end()) {
1020                                         p += G_SEARCHPATH_SEPARATOR;
1021                                 } else {
1022                                         break;
1023                                 }
1024
1025                                 ++next;
1026                                 ++i;
1027                         }
1028
1029                         child = node->add_child ("Path");
1030                         child->add_content (p);
1031                 }
1032         }
1033
1034         /* save the ID counter */
1035
1036         snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1037         node->add_property ("id-counter", buf);
1038
1039         /* save the event ID counter */
1040
1041         snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1042         node->add_property ("event-counter", buf);
1043
1044         /* various options */
1045
1046         list<XMLNode*> midi_port_nodes = _midi_ports->get_midi_port_states();
1047         if (!midi_port_nodes.empty()) {
1048                 XMLNode* midi_port_stuff = new XMLNode ("MIDIPorts");
1049                 for (list<XMLNode*>::const_iterator n = midi_port_nodes.begin(); n != midi_port_nodes.end(); ++n) {
1050                         midi_port_stuff->add_child_nocopy (**n);
1051                 }
1052                 node->add_child_nocopy (*midi_port_stuff);
1053         }
1054
1055         node->add_child_nocopy (config.get_variables ());
1056
1057         node->add_child_nocopy (ARDOUR::SessionMetadata::Metadata()->get_state());
1058
1059         child = node->add_child ("Sources");
1060
1061         if (full_state) {
1062                 Glib::Threads::Mutex::Lock sl (source_lock);
1063
1064                 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1065
1066                         /* Don't save information about non-file Sources, or
1067                          * about non-destructive file sources that are empty
1068                          * and unused by any regions.
1069                         */
1070
1071                         boost::shared_ptr<FileSource> fs;
1072
1073                         if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1074
1075                                 if (!fs->destructive()) {
1076                                         if (fs->empty() && !fs->used()) {
1077                                                 continue;
1078                                         }
1079                                 }
1080
1081                                 child->add_child_nocopy (siter->second->get_state());
1082                         }
1083                 }
1084         }
1085
1086         child = node->add_child ("Regions");
1087
1088         if (full_state) {
1089                 Glib::Threads::Mutex::Lock rl (region_lock);
1090                 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1091                 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1092                         boost::shared_ptr<Region> r = i->second;
1093                         /* only store regions not attached to playlists */
1094                         if (r->playlist() == 0) {
1095                                 if (boost::dynamic_pointer_cast<AudioRegion>(r)) {
1096                                         child->add_child_nocopy ((boost::dynamic_pointer_cast<AudioRegion>(r))->get_basic_state ());
1097                                 } else {
1098                                         child->add_child_nocopy (r->get_state ());
1099                                 }
1100                         }
1101                 }
1102
1103                 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1104
1105                 if (!cassocs.empty()) {
1106                         XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1107
1108                         for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1109                                 char buf[64];
1110                                 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1111                                 i->first->id().print (buf, sizeof (buf));
1112                                 can->add_property (X_("copy"), buf);
1113                                 i->second->id().print (buf, sizeof (buf));
1114                                 can->add_property (X_("original"), buf);
1115                                 ca->add_child_nocopy (*can);
1116                         }
1117                 }
1118         }
1119         
1120         
1121
1122         if (full_state) {
1123                 
1124                 if (_locations) {
1125                         node->add_child_nocopy (_locations->get_state());       
1126                 }
1127         } else {
1128                 Locations loc (*this);
1129                 // for a template, just create a new Locations, populate it
1130                 // with the default start and end, and get the state for that.
1131                 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1132                 range->set (max_framepos, 0);
1133                 loc.add (range);
1134                 XMLNode& locations_state = loc.get_state();
1135                 
1136                 if (ARDOUR::Profile->get_trx() && _locations) {
1137                         // For tracks we need stored the Auto Loop Range and all MIDI markers.
1138                         for (Locations::LocationList::const_iterator i = _locations->list ().begin (); i != _locations->list ().end (); ++i) {
1139                                 if ((*i)->is_mark () || (*i)->is_auto_loop ()) {
1140                                         locations_state.add_child_nocopy ((*i)->get_state ());
1141                                 }
1142                         }
1143                 }
1144                 node->add_child_nocopy (locations_state);
1145         }
1146
1147         child = node->add_child ("Bundles");
1148         {
1149                 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1150                 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1151                         boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1152                         if (b) {
1153                                 child->add_child_nocopy (b->get_state());
1154                         }
1155                 }
1156         }
1157
1158         child = node->add_child ("Routes");
1159         {
1160                 boost::shared_ptr<RouteList> r = routes.reader ();
1161
1162                 RoutePublicOrderSorter cmp;
1163                 RouteList public_order (*r);
1164                 public_order.sort (cmp);
1165                 
1166                 /* the sort should have put control outs first */
1167                 
1168                 if (_monitor_out) {
1169                         assert (_monitor_out == public_order.front());
1170                 }
1171
1172                 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1173                         if (!(*i)->is_auditioner()) {
1174                                 if (full_state) {
1175                                         child->add_child_nocopy ((*i)->get_state());
1176                                 } else {
1177                                         child->add_child_nocopy ((*i)->get_template());
1178                                 }
1179                         }
1180                 }
1181         }
1182
1183         playlists->add_state (node, full_state);
1184
1185         child = node->add_child ("RouteGroups");
1186         for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1187                 child->add_child_nocopy ((*i)->get_state());
1188         }
1189
1190         if (_click_io) {
1191                 XMLNode* gain_child = node->add_child ("Click");
1192                 gain_child->add_child_nocopy (_click_io->state (full_state));
1193                 gain_child->add_child_nocopy (_click_gain->state (full_state));
1194         }
1195
1196         if (_ltc_input) {
1197                 XMLNode* ltc_input_child = node->add_child ("LTC-In");
1198                 ltc_input_child->add_child_nocopy (_ltc_input->state (full_state));
1199         }
1200
1201         if (_ltc_input) {
1202                 XMLNode* ltc_output_child = node->add_child ("LTC-Out");
1203                 ltc_output_child->add_child_nocopy (_ltc_output->state (full_state));
1204         }
1205
1206         node->add_child_nocopy (_speakers->get_state());
1207         node->add_child_nocopy (_tempo_map->get_state());
1208         node->add_child_nocopy (get_control_protocol_state());
1209
1210         if (_extra_xml) {
1211                 node->add_child_copy (*_extra_xml);
1212         }
1213
1214         return *node;
1215 }
1216
1217 XMLNode&
1218 Session::get_control_protocol_state ()
1219 {
1220         ControlProtocolManager& cpm (ControlProtocolManager::instance());
1221         return cpm.get_state();
1222 }
1223
1224 int
1225 Session::set_state (const XMLNode& node, int version)
1226 {
1227         XMLNodeList nlist;
1228         XMLNode* child;
1229         const XMLProperty* prop;
1230         int ret = -1;
1231
1232         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1233
1234         if (node.name() != X_("Session")) {
1235                 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1236                 goto out;
1237         }
1238
1239         if ((prop = node.property ("name")) != 0) {
1240                 _name = prop->value ();
1241         }
1242
1243         if ((prop = node.property (X_("sample-rate"))) != 0) {
1244
1245                 _nominal_frame_rate = atoi (prop->value());
1246
1247                 if (_nominal_frame_rate != _current_frame_rate) {
1248                         boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1249                         if (r.get_value_or (0)) {
1250                                 goto out;
1251                         }
1252                 }
1253         }
1254
1255         setup_raid_path(_session_dir->root_path());
1256
1257         if ((prop = node.property (X_("id-counter"))) != 0) {
1258                 uint64_t x;
1259                 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1260                 ID::init_counter (x);
1261         } else {
1262                 /* old sessions used a timebased counter, so fake
1263                    the startup ID counter based on a standard
1264                    timestamp.
1265                 */
1266                 time_t now;
1267                 time (&now);
1268                 ID::init_counter (now);
1269         }
1270
1271         if ((prop = node.property (X_("event-counter"))) != 0) {
1272                 Evoral::init_event_id_counter (atoi (prop->value()));
1273         }
1274
1275
1276         if ((child = find_named_node (node, "MIDIPorts")) != 0) {
1277                 _midi_ports->set_midi_port_states (child->children());
1278         }
1279
1280         IO::disable_connecting ();
1281
1282         Stateful::save_extra_xml (node);
1283
1284         if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1285                 load_options (*child);
1286         } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1287                 load_options (*child);
1288         } else {
1289                 error << _("Session: XML state has no options section") << endmsg;
1290         }
1291
1292         if (version >= 3000) {
1293                 if ((child = find_named_node (node, "Metadata")) == 0) {
1294                         warning << _("Session: XML state has no metadata section") << endmsg;
1295                 } else if ( ARDOUR::SessionMetadata::Metadata()->set_state (*child, version) ) {
1296                         goto out;
1297                 }
1298         }
1299
1300         if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1301                 _speakers->set_state (*child, version);
1302         }
1303
1304         if ((child = find_named_node (node, "Sources")) == 0) {
1305                 error << _("Session: XML state has no sources section") << endmsg;
1306                 goto out;
1307         } else if (load_sources (*child)) {
1308                 goto out;
1309         }
1310
1311         if ((child = find_named_node (node, "TempoMap")) == 0) {
1312                 error << _("Session: XML state has no Tempo Map section") << endmsg;
1313                 goto out;
1314         } else if (_tempo_map->set_state (*child, version)) {
1315                 goto out;
1316         }
1317
1318         if ((child = find_named_node (node, "Locations")) == 0) {
1319                 error << _("Session: XML state has no locations section") << endmsg;
1320                 goto out;
1321         } else if (_locations->set_state (*child, version)) {
1322                 goto out;
1323         }
1324
1325         locations_changed ();
1326
1327         if (_session_range_location) {
1328                 AudioFileSource::set_header_position_offset (_session_range_location->start());
1329         }
1330
1331         if ((child = find_named_node (node, "Regions")) == 0) {
1332                 error << _("Session: XML state has no Regions section") << endmsg;
1333                 goto out;
1334         } else if (load_regions (*child)) {
1335                 goto out;
1336         }
1337
1338         if ((child = find_named_node (node, "Playlists")) == 0) {
1339                 error << _("Session: XML state has no playlists section") << endmsg;
1340                 goto out;
1341         } else if (playlists->load (*this, *child)) {
1342                 goto out;
1343         }
1344
1345         if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1346                 // this is OK
1347         } else if (playlists->load_unused (*this, *child)) {
1348                 goto out;
1349         }
1350
1351         if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1352                 if (load_compounds (*child)) {
1353                         goto out;
1354                 }
1355         }
1356
1357         if (version >= 3000) {
1358                 if ((child = find_named_node (node, "Bundles")) == 0) {
1359                         warning << _("Session: XML state has no bundles section") << endmsg;
1360                         //goto out;
1361                 } else {
1362                         /* We can't load Bundles yet as they need to be able
1363                            to convert from port names to Port objects, which can't happen until
1364                            later */
1365                         _bundle_xml_node = new XMLNode (*child);
1366                 }
1367         }
1368
1369         if (version < 3000) {
1370                 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1371                         error << _("Session: XML state has no diskstreams section") << endmsg;
1372                         goto out;
1373                 } else if (load_diskstreams_2X (*child, version)) {
1374                         goto out;
1375                 }
1376         }
1377
1378         if ((child = find_named_node (node, "Routes")) == 0) {
1379                 error << _("Session: XML state has no routes section") << endmsg;
1380                 goto out;
1381         } else if (load_routes (*child, version)) {
1382                 goto out;
1383         }
1384
1385         /* our diskstreams list is no longer needed as they are now all owned by their Route */
1386         _diskstreams_2X.clear ();
1387
1388         if (version >= 3000) {
1389
1390                 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1391                         error << _("Session: XML state has no route groups section") << endmsg;
1392                         goto out;
1393                 } else if (load_route_groups (*child, version)) {
1394                         goto out;
1395                 }
1396
1397         } else if (version < 3000) {
1398
1399                 if ((child = find_named_node (node, "EditGroups")) == 0) {
1400                         error << _("Session: XML state has no edit groups section") << endmsg;
1401                         goto out;
1402                 } else if (load_route_groups (*child, version)) {
1403                         goto out;
1404                 }
1405
1406                 if ((child = find_named_node (node, "MixGroups")) == 0) {
1407                         error << _("Session: XML state has no mix groups section") << endmsg;
1408                         goto out;
1409                 } else if (load_route_groups (*child, version)) {
1410                         goto out;
1411                 }
1412         }
1413
1414         if ((child = find_named_node (node, "Click")) == 0) {
1415                 warning << _("Session: XML state has no click section") << endmsg;
1416         } else if (_click_io) {
1417                 setup_click_state (&node);
1418         }
1419
1420         if ((child = find_named_node (node, ControlProtocolManager::state_node_name)) != 0) {
1421                 ControlProtocolManager::instance().set_state (*child, version);
1422         }
1423
1424         update_route_record_state ();
1425
1426         /* here beginneth the second phase ... */
1427
1428         StateReady (); /* EMIT SIGNAL */
1429
1430         delete state_tree;
1431         state_tree = 0;
1432         return 0;
1433
1434   out:
1435         delete state_tree;
1436         state_tree = 0;
1437         return ret;
1438 }
1439
1440 int
1441 Session::load_routes (const XMLNode& node, int version)
1442 {
1443         XMLNodeList nlist;
1444         XMLNodeConstIterator niter;
1445         RouteList new_routes;
1446
1447         nlist = node.children();
1448
1449         set_dirty();
1450
1451         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1452
1453                 boost::shared_ptr<Route> route;
1454                 if (version < 3000) {
1455                         route = XMLRouteFactory_2X (**niter, version);
1456                 } else {
1457                         route = XMLRouteFactory (**niter, version);
1458                 }
1459
1460                 if (route == 0) {
1461                         error << _("Session: cannot create Route from XML description.") << endmsg;
1462                         return -1;
1463                 }
1464
1465                 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1466
1467                 new_routes.push_back (route);
1468         }
1469
1470         BootMessage (_("Tracks/busses loaded;  Adding to Session"));
1471
1472         add_routes (new_routes, false, false, false);
1473
1474         BootMessage (_("Finished adding tracks/busses"));
1475
1476         return 0;
1477 }
1478
1479 boost::shared_ptr<Route>
1480 Session::XMLRouteFactory (const XMLNode& node, int version)
1481 {
1482         boost::shared_ptr<Route> ret;
1483
1484         if (node.name() != "Route") {
1485                 return ret;
1486         }
1487
1488         XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1489
1490         DataType type = DataType::AUDIO;
1491         const XMLProperty* prop = node.property("default-type");
1492
1493         if (prop) {
1494                 type = DataType (prop->value());
1495         }
1496
1497         assert (type != DataType::NIL);
1498
1499         if (ds_child) {
1500
1501                 boost::shared_ptr<Track> track;
1502
1503                 if (type == DataType::AUDIO) {
1504                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1505                 } else {
1506                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1507                 }
1508
1509                 if (track->init()) {
1510                         return ret;
1511                 }
1512
1513                 if (track->set_state (node, version)) {
1514                         return ret;
1515                 }
1516
1517 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1518                 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1519 #endif
1520                 ret = track;
1521
1522         } else {
1523                 enum Route::Flag flags = Route::Flag(0);
1524                 const XMLProperty* prop = node.property("flags");
1525                 if (prop) {
1526                         flags = Route::Flag (string_2_enum (prop->value(), flags));
1527                 }
1528
1529                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML"), flags));
1530
1531                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1532 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1533                         // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1534 #endif
1535                         ret = r;
1536                 }
1537         }
1538
1539         return ret;
1540 }
1541
1542 boost::shared_ptr<Route>
1543 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1544 {
1545         boost::shared_ptr<Route> ret;
1546
1547         if (node.name() != "Route") {
1548                 return ret;
1549         }
1550
1551         XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1552         if (!ds_prop) {
1553                 ds_prop = node.property (X_("diskstream"));
1554         }
1555
1556         DataType type = DataType::AUDIO;
1557         const XMLProperty* prop = node.property("default-type");
1558
1559         if (prop) {
1560                 type = DataType (prop->value());
1561         }
1562
1563         assert (type != DataType::NIL);
1564
1565         if (ds_prop) {
1566
1567                 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1568                 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1569                         ++i;
1570                 }
1571
1572                 if (i == _diskstreams_2X.end()) {
1573                         error << _("Could not find diskstream for route") << endmsg;
1574                         return boost::shared_ptr<Route> ();
1575                 }
1576
1577                 boost::shared_ptr<Track> track;
1578
1579                 if (type == DataType::AUDIO) {
1580                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1581                 } else {
1582                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1583                 }
1584
1585                 if (track->init()) {
1586                         return ret;
1587                 }
1588
1589                 if (track->set_state (node, version)) {
1590                         return ret;
1591                 }
1592
1593                 track->set_diskstream (*i);
1594
1595 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1596                 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1597 #endif
1598                 ret = track;
1599
1600         } else {
1601                 enum Route::Flag flags = Route::Flag(0);
1602                 const XMLProperty* prop = node.property("flags");
1603                 if (prop) {
1604                         flags = Route::Flag (string_2_enum (prop->value(), flags));
1605                 }
1606
1607                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML"), flags));
1608
1609                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1610 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1611                         // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1612 #endif
1613                         ret = r;
1614                 }
1615         }
1616
1617         return ret;
1618 }
1619
1620 int
1621 Session::load_regions (const XMLNode& node)
1622 {
1623         XMLNodeList nlist;
1624         XMLNodeConstIterator niter;
1625         boost::shared_ptr<Region> region;
1626
1627         nlist = node.children();
1628
1629         set_dirty();
1630
1631         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1632                 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1633                         error << _("Session: cannot create Region from XML description.");
1634                         const XMLProperty *name = (**niter).property("name");
1635
1636                         if (name) {
1637                                 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1638                         }
1639
1640                         error << endmsg;
1641                 }
1642         }
1643
1644         return 0;
1645 }
1646
1647 int
1648 Session::load_compounds (const XMLNode& node)
1649 {
1650         XMLNodeList calist = node.children();
1651         XMLNodeConstIterator caiter;
1652         XMLProperty *caprop;
1653
1654         for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1655                 XMLNode* ca = *caiter;
1656                 ID orig_id;
1657                 ID copy_id;
1658
1659                 if ((caprop = ca->property (X_("original"))) == 0) {
1660                         continue;
1661                 }
1662                 orig_id = caprop->value();
1663
1664                 if ((caprop = ca->property (X_("copy"))) == 0) {
1665                         continue;
1666                 }
1667                 copy_id = caprop->value();
1668
1669                 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1670                 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1671
1672                 if (!orig || !copy) {
1673                         warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1674                                                    orig_id, copy_id)
1675                                 << endmsg;
1676                         continue;
1677                 }
1678
1679                 RegionFactory::add_compound_association (orig, copy);
1680         }
1681
1682         return 0;
1683 }
1684
1685 void
1686 Session::load_nested_sources (const XMLNode& node)
1687 {
1688         XMLNodeList nlist;
1689         XMLNodeConstIterator niter;
1690
1691         nlist = node.children();
1692
1693         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1694                 if ((*niter)->name() == "Source") {
1695
1696                         /* it may already exist, so don't recreate it unnecessarily 
1697                          */
1698
1699                         XMLProperty* prop = (*niter)->property (X_("id"));
1700                         if (!prop) {
1701                                 error << _("Nested source has no ID info in session file! (ignored)") << endmsg;
1702                                 continue;
1703                         }
1704
1705                         ID source_id (prop->value());
1706
1707                         if (!source_by_id (source_id)) {
1708
1709                                 try {
1710                                         SourceFactory::create (*this, **niter, true);
1711                                 }
1712                                 catch (failed_constructor& err) {
1713                                         error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1714                                 }
1715                         }
1716                 }
1717         }
1718 }
1719
1720 boost::shared_ptr<Region>
1721 Session::XMLRegionFactory (const XMLNode& node, bool full)
1722 {
1723         const XMLProperty* type = node.property("type");
1724
1725         try {
1726
1727                 const XMLNodeList& nlist = node.children();
1728
1729                 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1730                         XMLNode *child = (*niter);
1731                         if (child->name() == "NestedSource") {
1732                                 load_nested_sources (*child);
1733                         }
1734                 }
1735
1736                 if (!type || type->value() == "audio") {
1737                         return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1738                 } else if (type->value() == "midi") {
1739                         return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1740                 }
1741
1742         } catch (failed_constructor& err) {
1743                 return boost::shared_ptr<Region> ();
1744         }
1745
1746         return boost::shared_ptr<Region> ();
1747 }
1748
1749 boost::shared_ptr<AudioRegion>
1750 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1751 {
1752         const XMLProperty* prop;
1753         boost::shared_ptr<Source> source;
1754         boost::shared_ptr<AudioSource> as;
1755         SourceList sources;
1756         SourceList master_sources;
1757         uint32_t nchans = 1;
1758         char buf[128];
1759
1760         if (node.name() != X_("Region")) {
1761                 return boost::shared_ptr<AudioRegion>();
1762         }
1763
1764         if ((prop = node.property (X_("channels"))) != 0) {
1765                 nchans = atoi (prop->value().c_str());
1766         }
1767
1768         if ((prop = node.property ("name")) == 0) {
1769                 cerr << "no name for this region\n";
1770                 abort ();
1771         }
1772
1773         if ((prop = node.property (X_("source-0"))) == 0) {
1774                 if ((prop = node.property ("source")) == 0) {
1775                         error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1776                         return boost::shared_ptr<AudioRegion>();
1777                 }
1778         }
1779
1780         PBD::ID s_id (prop->value());
1781
1782         if ((source = source_by_id (s_id)) == 0) {
1783                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1784                 return boost::shared_ptr<AudioRegion>();
1785         }
1786
1787         as = boost::dynamic_pointer_cast<AudioSource>(source);
1788         if (!as) {
1789                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1790                 return boost::shared_ptr<AudioRegion>();
1791         }
1792
1793         sources.push_back (as);
1794
1795         /* pickup other channels */
1796
1797         for (uint32_t n=1; n < nchans; ++n) {
1798                 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1799                 if ((prop = node.property (buf)) != 0) {
1800
1801                         PBD::ID id2 (prop->value());
1802
1803                         if ((source = source_by_id (id2)) == 0) {
1804                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1805                                 return boost::shared_ptr<AudioRegion>();
1806                         }
1807
1808                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1809                         if (!as) {
1810                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1811                                 return boost::shared_ptr<AudioRegion>();
1812                         }
1813                         sources.push_back (as);
1814                 }
1815         }
1816
1817         for (uint32_t n = 0; n < nchans; ++n) {
1818                 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1819                 if ((prop = node.property (buf)) != 0) {
1820
1821                         PBD::ID id2 (prop->value());
1822
1823                         if ((source = source_by_id (id2)) == 0) {
1824                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1825                                 return boost::shared_ptr<AudioRegion>();
1826                         }
1827
1828                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1829                         if (!as) {
1830                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1831                                 return boost::shared_ptr<AudioRegion>();
1832                         }
1833                         master_sources.push_back (as);
1834                 }
1835         }
1836
1837         try {
1838                 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1839
1840                 /* a final detail: this is the one and only place that we know how long missing files are */
1841
1842                 if (region->whole_file()) {
1843                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1844                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1845                                 if (sfp) {
1846                                         sfp->set_length (region->length());
1847                                 }
1848                         }
1849                 }
1850
1851                 if (!master_sources.empty()) {
1852                         if (master_sources.size() != nchans) {
1853                                 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1854                         } else {
1855                                 region->set_master_sources (master_sources);
1856                         }
1857                 }
1858
1859                 return region;
1860
1861         }
1862
1863         catch (failed_constructor& err) {
1864                 return boost::shared_ptr<AudioRegion>();
1865         }
1866 }
1867
1868 boost::shared_ptr<MidiRegion>
1869 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1870 {
1871         const XMLProperty* prop;
1872         boost::shared_ptr<Source> source;
1873         boost::shared_ptr<MidiSource> ms;
1874         SourceList sources;
1875
1876         if (node.name() != X_("Region")) {
1877                 return boost::shared_ptr<MidiRegion>();
1878         }
1879
1880         if ((prop = node.property ("name")) == 0) {
1881                 cerr << "no name for this region\n";
1882                 abort ();
1883         }
1884
1885         if ((prop = node.property (X_("source-0"))) == 0) {
1886                 if ((prop = node.property ("source")) == 0) {
1887                         error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1888                         return boost::shared_ptr<MidiRegion>();
1889                 }
1890         }
1891
1892         PBD::ID s_id (prop->value());
1893
1894         if ((source = source_by_id (s_id)) == 0) {
1895                 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1896                 return boost::shared_ptr<MidiRegion>();
1897         }
1898
1899         ms = boost::dynamic_pointer_cast<MidiSource>(source);
1900         if (!ms) {
1901                 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1902                 return boost::shared_ptr<MidiRegion>();
1903         }
1904
1905         sources.push_back (ms);
1906
1907         try {
1908                 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1909                 /* a final detail: this is the one and only place that we know how long missing files are */
1910
1911                 if (region->whole_file()) {
1912                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1913                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1914                                 if (sfp) {
1915                                         sfp->set_length (region->length());
1916                                 }
1917                         }
1918                 }
1919
1920                 return region;
1921         }
1922
1923         catch (failed_constructor& err) {
1924                 return boost::shared_ptr<MidiRegion>();
1925         }
1926 }
1927
1928 XMLNode&
1929 Session::get_sources_as_xml ()
1930
1931 {
1932         XMLNode* node = new XMLNode (X_("Sources"));
1933         Glib::Threads::Mutex::Lock lm (source_lock);
1934
1935         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1936                 node->add_child_nocopy (i->second->get_state());
1937         }
1938
1939         return *node;
1940 }
1941
1942 void
1943 Session::reset_write_sources (bool mark_write_complete, bool force)
1944 {
1945         boost::shared_ptr<RouteList> rl = routes.reader();
1946         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1947                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1948                 if (tr) {
1949                         _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
1950                         tr->reset_write_sources(mark_write_complete, force);
1951                         _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
1952                 }
1953         }
1954 }
1955
1956 int
1957 Session::load_sources (const XMLNode& node)
1958 {
1959         XMLNodeList nlist;
1960         XMLNodeConstIterator niter;
1961         boost::shared_ptr<Source> source; /* don't need this but it stops some
1962                                            * versions of gcc complaining about
1963                                            * discarded return values.
1964                                            */
1965
1966         nlist = node.children();
1967
1968         set_dirty();
1969
1970         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1971           retry:
1972                 try {
1973                         if ((source = XMLSourceFactory (**niter)) == 0) {
1974                                 error << _("Session: cannot create Source from XML description.") << endmsg;
1975                         }
1976
1977                 } catch (MissingSource& err) {
1978
1979                         int user_choice;
1980
1981                         if (err.type == DataType::MIDI && Glib::path_is_absolute (err.path)) {
1982                                 error << string_compose (_("A external MIDI file is missing. %1 cannot currently recover from missing external MIDI files"),
1983                                                          PROGRAM_NAME) << endmsg;
1984                                 return -1;
1985                         }
1986
1987                         if (!no_questions_about_missing_files) {
1988                                 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1989                         } else {
1990                                 user_choice = -2;
1991                         }
1992
1993                         switch (user_choice) {
1994                         case 0:
1995                                 /* user added a new search location, so try again */
1996                                 goto retry;
1997
1998
1999                         case 1:
2000                                 /* user asked to quit the entire session load
2001                                  */
2002                                 return -1;
2003
2004                         case 2:
2005                                 no_questions_about_missing_files = true;
2006                                 goto retry;
2007
2008                         case 3:
2009                                 no_questions_about_missing_files = true;
2010                                 /* fallthru */
2011
2012                         case -1:
2013                         default:
2014                                 switch (err.type) {
2015
2016                                 case DataType::AUDIO:
2017                                         source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
2018                                         break;
2019
2020                                 case DataType::MIDI:
2021                                         /* The MIDI file is actually missing so
2022                                          * just create a new one in the same
2023                                          * location. Do not announce its
2024                                          */
2025                                         string fullpath;
2026
2027                                         if (!Glib::path_is_absolute (err.path)) {
2028                                                 fullpath = Glib::build_filename (source_search_path (DataType::MIDI).front(), err.path);
2029                                         } else {
2030                                                 /* this should be an unrecoverable error: we would be creating a MIDI file outside
2031                                                    the session tree.
2032                                                 */
2033                                                 return -1;
2034                                         }
2035                                         /* Note that we do not announce the source just yet - we need to reset its ID before we do that */
2036                                         source = SourceFactory::createWritable (DataType::MIDI, *this, fullpath, false, _current_frame_rate, false, false);
2037                                         /* reset ID to match the missing one */
2038                                         source->set_id (**niter);
2039                                         /* Now we can announce it */
2040                                         SourceFactory::SourceCreated (source);
2041                                         break;
2042                                 }
2043                                 break;
2044                         }
2045                 }
2046         }
2047
2048         return 0;
2049 }
2050
2051 boost::shared_ptr<Source>
2052 Session::XMLSourceFactory (const XMLNode& node)
2053 {
2054         if (node.name() != "Source") {
2055                 return boost::shared_ptr<Source>();
2056         }
2057
2058         try {
2059                 /* note: do peak building in another thread when loading session state */
2060                 return SourceFactory::create (*this, node, true);
2061         }
2062
2063         catch (failed_constructor& err) {
2064                 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the programmers."), PROGRAM_NAME) << endmsg;
2065                 return boost::shared_ptr<Source>();
2066         }
2067 }
2068
2069 int
2070 Session::save_template (string template_name)
2071 {
2072         if ((_state_of_the_state & CannotSave) || template_name.empty ()) {
2073                 return -1;
2074         }
2075
2076         bool absolute_path = Glib::path_is_absolute (template_name);
2077
2078         /* directory to put the template in */
2079         std::string template_dir_path;
2080
2081         if (!absolute_path) {
2082                 std::string user_template_dir(user_template_directory());
2083
2084                 if (g_mkdir_with_parents (user_template_dir.c_str(), 0755) != 0) {
2085                         error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2086                                         user_template_dir, g_strerror (errno)) << endmsg;
2087                         return -1;
2088                 }
2089
2090                 template_dir_path = Glib::build_filename (user_template_dir, template_name);
2091         } else {
2092                 template_dir_path = template_name;
2093         }
2094
2095         if (!ARDOUR::Profile->get_trx()) {
2096                 if (Glib::file_test (template_dir_path, Glib::FILE_TEST_EXISTS)) {
2097                         warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2098                                                                           template_dir_path) << endmsg;
2099                         return -1;
2100                 }
2101                 
2102                 if (g_mkdir_with_parents (template_dir_path.c_str(), 0755) != 0) {
2103                         error << string_compose(_("Could not create directory for Session template\"%1\" (%2)"),
2104                                                                         template_dir_path, g_strerror (errno)) << endmsg;
2105                         return -1;
2106                 }
2107         }
2108
2109         /* file to write */
2110         std::string template_file_path;
2111         
2112         if (ARDOUR::Profile->get_trx()) {
2113                 template_file_path = template_name;
2114         } else {
2115                 if (absolute_path) {
2116                         template_file_path = Glib::build_filename (template_dir_path, Glib::path_get_basename (template_dir_path) + template_suffix);
2117                 } else {
2118                         template_file_path = Glib::build_filename (template_dir_path, template_name + template_suffix);
2119                 }
2120         }
2121
2122         SessionSaveUnderway (); /* EMIT SIGNAL */
2123         
2124         XMLTree tree;
2125
2126         tree.set_root (&get_template());
2127         if (!tree.write (template_file_path)) {
2128                 error << _("template not saved") << endmsg;
2129                 return -1;
2130         }
2131
2132         if (!ARDOUR::Profile->get_trx()) {
2133                 /* copy plugin state directory */
2134
2135                 std::string template_plugin_state_path (Glib::build_filename (template_dir_path, X_("plugins")));
2136
2137                 if (g_mkdir_with_parents (template_plugin_state_path.c_str(), 0755) != 0) {
2138                         error << string_compose(_("Could not create directory for Session template plugin state\"%1\" (%2)"),
2139                                                                         template_plugin_state_path, g_strerror (errno)) << endmsg;
2140                         return -1;
2141                 }
2142                 copy_files (plugins_dir(), template_plugin_state_path);
2143         }
2144
2145         store_recent_templates (template_file_path);
2146
2147         return 0;
2148 }
2149
2150 void
2151 Session::refresh_disk_space ()
2152 {
2153 #if __APPLE__ || (HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H)
2154         
2155         Glib::Threads::Mutex::Lock lm (space_lock);
2156
2157         /* get freespace on every FS that is part of the session path */
2158
2159         _total_free_4k_blocks = 0;
2160         _total_free_4k_blocks_uncertain = false;
2161
2162         for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2163
2164                 struct statfs statfsbuf;
2165                 statfs (i->path.c_str(), &statfsbuf);
2166
2167                 double const scale = statfsbuf.f_bsize / 4096.0;
2168
2169                 /* See if this filesystem is read-only */
2170                 struct statvfs statvfsbuf;
2171                 statvfs (i->path.c_str(), &statvfsbuf);
2172
2173                 /* f_bavail can be 0 if it is undefined for whatever
2174                    filesystem we are looking at; Samba shares mounted
2175                    via GVFS are an example of this.
2176                 */
2177                 if (statfsbuf.f_bavail == 0) {
2178                         /* block count unknown */
2179                         i->blocks = 0;
2180                         i->blocks_unknown = true;
2181                 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2182                         /* read-only filesystem */
2183                         i->blocks = 0;
2184                         i->blocks_unknown = false;
2185                 } else {
2186                         /* read/write filesystem with known space */
2187                         i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2188                         i->blocks_unknown = false;
2189                 }
2190
2191                 _total_free_4k_blocks += i->blocks;
2192                 if (i->blocks_unknown) {
2193                         _total_free_4k_blocks_uncertain = true;
2194                 }
2195         }
2196 #elif defined PLATFORM_WINDOWS
2197         vector<string> scanned_volumes;
2198         vector<string>::iterator j;
2199         vector<space_and_path>::iterator i;
2200     DWORD nSectorsPerCluster, nBytesPerSector,
2201           nFreeClusters, nTotalClusters;
2202     char disk_drive[4];
2203         bool volume_found;
2204
2205         _total_free_4k_blocks = 0;
2206
2207         for (i = session_dirs.begin(); i != session_dirs.end(); i++) {
2208                 strncpy (disk_drive, (*i).path.c_str(), 3);
2209                 disk_drive[3] = 0;
2210                 strupr(disk_drive);
2211
2212                 volume_found = false;
2213                 if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters)))
2214                 {
2215                         int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster;
2216                         int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters;
2217                         i->blocks = (uint32_t)(nFreeBytes / 4096);
2218
2219                         for (j = scanned_volumes.begin(); j != scanned_volumes.end(); j++) {
2220                                 if (0 == j->compare(disk_drive)) {
2221                                         volume_found = true;
2222                                         break;
2223                                 }
2224                         }
2225
2226                         if (!volume_found) {
2227                                 scanned_volumes.push_back(disk_drive);
2228                                 _total_free_4k_blocks += i->blocks;
2229                         }
2230                 }
2231         }
2232
2233         if (0 == _total_free_4k_blocks) {
2234                 strncpy (disk_drive, path().c_str(), 3);
2235                 disk_drive[3] = 0;
2236
2237                 if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters)))
2238                 {
2239                         int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster;
2240                         int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters;
2241                         _total_free_4k_blocks = (uint32_t)(nFreeBytes / 4096);
2242                 }
2243         }
2244 #endif
2245 }
2246
2247 string
2248 Session::get_best_session_directory_for_new_audio ()
2249 {
2250         vector<space_and_path>::iterator i;
2251         string result = _session_dir->root_path();
2252
2253         /* handle common case without system calls */
2254
2255         if (session_dirs.size() == 1) {
2256                 return result;
2257         }
2258
2259         /* OK, here's the algorithm we're following here:
2260
2261         We want to select which directory to use for
2262         the next file source to be created. Ideally,
2263         we'd like to use a round-robin process so as to
2264         get maximum performance benefits from splitting
2265         the files across multiple disks.
2266
2267         However, in situations without much diskspace, an
2268         RR approach may end up filling up a filesystem
2269         with new files while others still have space.
2270         Its therefore important to pay some attention to
2271         the freespace in the filesystem holding each
2272         directory as well. However, if we did that by
2273         itself, we'd keep creating new files in the file
2274         system with the most space until it was as full
2275         as all others, thus negating any performance
2276         benefits of this RAID-1 like approach.
2277
2278         So, we use a user-configurable space threshold. If
2279         there are at least 2 filesystems with more than this
2280         much space available, we use RR selection between them.
2281         If not, then we pick the filesystem with the most space.
2282
2283         This gets a good balance between the two
2284         approaches.
2285         */
2286
2287         refresh_disk_space ();
2288
2289         int free_enough = 0;
2290
2291         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2292                 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2293                         free_enough++;
2294                 }
2295         }
2296
2297         if (free_enough >= 2) {
2298                 /* use RR selection process, ensuring that the one
2299                    picked works OK.
2300                 */
2301
2302                 i = last_rr_session_dir;
2303
2304                 do {
2305                         if (++i == session_dirs.end()) {
2306                                 i = session_dirs.begin();
2307                         }
2308
2309                         if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2310                                 SessionDirectory sdir(i->path);
2311                                 if (sdir.create ()) {
2312                                         result = (*i).path;
2313                                         last_rr_session_dir = i;
2314                                         return result;
2315                                 }
2316                         }
2317
2318                 } while (i != last_rr_session_dir);
2319
2320         } else {
2321
2322                 /* pick FS with the most freespace (and that
2323                    seems to actually work ...)
2324                 */
2325
2326                 vector<space_and_path> sorted;
2327                 space_and_path_ascending_cmp cmp;
2328
2329                 sorted = session_dirs;
2330                 sort (sorted.begin(), sorted.end(), cmp);
2331
2332                 for (i = sorted.begin(); i != sorted.end(); ++i) {
2333                         SessionDirectory sdir(i->path);
2334                         if (sdir.create ()) {
2335                                 result = (*i).path;
2336                                 last_rr_session_dir = i;
2337                                 return result;
2338                         }
2339                 }
2340         }
2341
2342         return result;
2343 }
2344
2345 string
2346 Session::automation_dir () const
2347 {
2348         return Glib::build_filename (_path, automation_dir_name);
2349 }
2350
2351 string
2352 Session::analysis_dir () const
2353 {
2354         return Glib::build_filename (_path, analysis_dir_name);
2355 }
2356
2357 string
2358 Session::plugins_dir () const
2359 {
2360         return Glib::build_filename (_path, plugins_dir_name);
2361 }
2362
2363 string
2364 Session::externals_dir () const
2365 {
2366         return Glib::build_filename (_path, externals_dir_name);
2367 }
2368
2369 int
2370 Session::load_bundles (XMLNode const & node)
2371 {
2372         XMLNodeList nlist = node.children();
2373         XMLNodeConstIterator niter;
2374
2375         set_dirty();
2376
2377         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2378                 if ((*niter)->name() == "InputBundle") {
2379                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2380                 } else if ((*niter)->name() == "OutputBundle") {
2381                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2382                 } else {
2383                         error << string_compose(_("Unknown node \"%1\" found in Bundles list from session file"), (*niter)->name()) << endmsg;
2384                         return -1;
2385                 }
2386         }
2387
2388         return 0;
2389 }
2390
2391 int
2392 Session::load_route_groups (const XMLNode& node, int version)
2393 {
2394         XMLNodeList nlist = node.children();
2395         XMLNodeConstIterator niter;
2396
2397         set_dirty ();
2398
2399         if (version >= 3000) {
2400
2401                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2402                         if ((*niter)->name() == "RouteGroup") {
2403                                 RouteGroup* rg = new RouteGroup (*this, "");
2404                                 add_route_group (rg);
2405                                 rg->set_state (**niter, version);
2406                         }
2407                 }
2408
2409         } else if (version < 3000) {
2410
2411                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2412                         if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2413                                 RouteGroup* rg = new RouteGroup (*this, "");
2414                                 add_route_group (rg);
2415                                 rg->set_state (**niter, version);
2416                         }
2417                 }
2418         }
2419
2420         return 0;
2421 }
2422
2423 static bool
2424 state_file_filter (const string &str, void* /*arg*/)
2425 {
2426         return (str.length() > strlen(statefile_suffix) &&
2427                 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2428 }
2429
2430 static string
2431 remove_end(string state)
2432 {
2433         string statename(state);
2434
2435         string::size_type start,end;
2436         if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2437                 statename = statename.substr (start+1);
2438         }
2439
2440         if ((end = statename.rfind(statefile_suffix)) == string::npos) {
2441                 end = statename.length();
2442         }
2443
2444         return string(statename.substr (0, end));
2445 }
2446
2447 vector<string>
2448 Session::possible_states (string path)
2449 {
2450         vector<string> states;
2451         find_files_matching_filter (states, path, state_file_filter, 0, false, false);
2452
2453         transform(states.begin(), states.end(), states.begin(), remove_end);
2454
2455         sort (states.begin(), states.end());
2456
2457         return states;
2458 }
2459
2460 vector<string>
2461 Session::possible_states () const
2462 {
2463         return possible_states(_path);
2464 }
2465
2466 void
2467 Session::add_route_group (RouteGroup* g)
2468 {
2469         _route_groups.push_back (g);
2470         route_group_added (g); /* EMIT SIGNAL */
2471
2472         g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2473         g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2474         g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2475
2476         set_dirty ();
2477 }
2478
2479 void
2480 Session::remove_route_group (RouteGroup& rg)
2481 {
2482         list<RouteGroup*>::iterator i;
2483
2484         if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2485                 _route_groups.erase (i);
2486                 delete &rg;
2487
2488                 route_group_removed (); /* EMIT SIGNAL */
2489         }
2490 }
2491
2492 /** Set a new order for our route groups, without adding or removing any.
2493  *  @param groups Route group list in the new order.
2494  */
2495 void
2496 Session::reorder_route_groups (list<RouteGroup*> groups)
2497 {
2498         _route_groups = groups;
2499
2500         route_groups_reordered (); /* EMIT SIGNAL */
2501         set_dirty ();
2502 }
2503
2504
2505 RouteGroup *
2506 Session::route_group_by_name (string name)
2507 {
2508         list<RouteGroup *>::iterator i;
2509
2510         for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2511                 if ((*i)->name() == name) {
2512                         return* i;
2513                 }
2514         }
2515         return 0;
2516 }
2517
2518 RouteGroup&
2519 Session::all_route_group() const
2520 {
2521         return *_all_route_group;
2522 }
2523
2524 void
2525 Session::add_commands (vector<Command*> const & cmds)
2526 {
2527         for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2528                 add_command (*i);
2529         }
2530 }
2531
2532 void
2533 Session::add_command (Command* const cmd)
2534 {
2535         assert (_current_trans);
2536         DEBUG_UNDO_HISTORY (
2537             string_compose ("Current Undo Transaction %1, adding command: %2",
2538                             _current_trans->name (),
2539                             cmd->name ()));
2540         _current_trans->add_command (cmd);
2541 }
2542 void
2543 Session::begin_reversible_command (const string& name)
2544 {
2545         begin_reversible_command (g_quark_from_string (name.c_str ()));
2546 }
2547
2548 /** Begin a reversible command using a GQuark to identify it.
2549  *  begin_reversible_command() and commit_reversible_command() calls may be nested,
2550  *  but there must be as many begin...()s as there are commit...()s.
2551  */
2552 void
2553 Session::begin_reversible_command (GQuark q)
2554 {
2555         /* If nested begin/commit pairs are used, we create just one UndoTransaction
2556            to hold all the commands that are committed.  This keeps the order of
2557            commands correct in the history.
2558         */
2559
2560         if (_current_trans == 0) {
2561                 DEBUG_UNDO_HISTORY (string_compose (
2562                     "Begin Reversible Command, new transaction: %1", g_quark_to_string (q)));
2563
2564                 /* start a new transaction */
2565                 assert (_current_trans_quarks.empty ());
2566                 _current_trans = new UndoTransaction();
2567                 _current_trans->set_name (g_quark_to_string (q));
2568         } else {
2569                 DEBUG_UNDO_HISTORY (
2570                     string_compose ("Begin Reversible Command, current transaction: %1",
2571                                     _current_trans->name ()));
2572         }
2573
2574         _current_trans_quarks.push_front (q);
2575 }
2576
2577 void
2578 Session::abort_reversible_command ()
2579 {
2580         if (_current_trans != 0) {
2581                 DEBUG_UNDO_HISTORY (
2582                     string_compose ("Abort Reversible Command: %1", _current_trans->name ()));
2583                 _current_trans->clear();
2584                 delete _current_trans;
2585                 _current_trans = 0;
2586                 _current_trans_quarks.clear();
2587         }
2588 }
2589
2590 void
2591 Session::commit_reversible_command (Command *cmd)
2592 {
2593         assert (_current_trans);
2594         assert (!_current_trans_quarks.empty ());
2595
2596         struct timeval now;
2597
2598         if (cmd) {
2599                 DEBUG_UNDO_HISTORY (
2600                     string_compose ("Current Undo Transaction %1, adding command: %2",
2601                                     _current_trans->name (),
2602                                     cmd->name ()));
2603                 _current_trans->add_command (cmd);
2604         }
2605
2606         DEBUG_UNDO_HISTORY (
2607             string_compose ("Commit Reversible Command, current transaction: %1",
2608                             _current_trans->name ()));
2609
2610         _current_trans_quarks.pop_front ();
2611
2612         if (!_current_trans_quarks.empty ()) {
2613                 DEBUG_UNDO_HISTORY (
2614                     string_compose ("Commit Reversible Command, transaction is not "
2615                                     "top-level, current transaction: %1",
2616                                     _current_trans->name ()));
2617                 /* the transaction we're committing is not the top-level one */
2618                 return;
2619         }
2620
2621         if (_current_trans->empty()) {
2622                 /* no commands were added to the transaction, so just get rid of it */
2623                 DEBUG_UNDO_HISTORY (
2624                     string_compose ("Commit Reversible Command, No commands were "
2625                                     "added to current transaction: %1",
2626                                     _current_trans->name ()));
2627                 delete _current_trans;
2628                 _current_trans = 0;
2629                 return;
2630         }
2631
2632         gettimeofday (&now, 0);
2633         _current_trans->set_timestamp (now);
2634
2635         _history.add (_current_trans);
2636         _current_trans = 0;
2637 }
2638
2639 static bool
2640 accept_all_audio_files (const string& path, void* /*arg*/)
2641 {
2642         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2643                 return false;
2644         }
2645
2646         if (!AudioFileSource::safe_audio_file_extension (path)) {
2647                 return false;
2648         }
2649
2650         return true;
2651 }
2652
2653 static bool
2654 accept_all_midi_files (const string& path, void* /*arg*/)
2655 {
2656         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2657                 return false;
2658         }
2659
2660         return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2661                 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2662                 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2663 }
2664
2665 static bool
2666 accept_all_state_files (const string& path, void* /*arg*/)
2667 {
2668         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2669                 return false;
2670         }
2671
2672         std::string const statefile_ext (statefile_suffix);
2673         if (path.length() >= statefile_ext.length()) {
2674                 return (0 == path.compare (path.length() - statefile_ext.length(), statefile_ext.length(), statefile_ext));
2675         } else {
2676                 return false;
2677         }
2678 }
2679
2680 int
2681 Session::find_all_sources (string path, set<string>& result)
2682 {
2683         XMLTree tree;
2684         XMLNode* node;
2685
2686         if (!tree.read (path)) {
2687                 return -1;
2688         }
2689
2690         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2691                 return -2;
2692         }
2693
2694         XMLNodeList nlist;
2695         XMLNodeConstIterator niter;
2696
2697         nlist = node->children();
2698
2699         set_dirty();
2700
2701         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2702
2703                 XMLProperty* prop;
2704
2705                 if ((prop = (*niter)->property (X_("type"))) == 0) {
2706                         continue;
2707                 }
2708
2709                 DataType type (prop->value());
2710
2711                 if ((prop = (*niter)->property (X_("name"))) == 0) {
2712                         continue;
2713                 }
2714
2715                 if (Glib::path_is_absolute (prop->value())) {
2716                         /* external file, ignore */
2717                         continue;
2718                 }
2719
2720                 string found_path;
2721                 bool is_new;
2722                 uint16_t chan;
2723
2724                 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2725                         result.insert (found_path);
2726                 }
2727         }
2728
2729         return 0;
2730 }
2731
2732 int
2733 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2734 {
2735         vector<string> state_files;
2736         string ripped;
2737         string this_snapshot_path;
2738
2739         result.clear ();
2740
2741         ripped = _path;
2742
2743         if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2744                 ripped = ripped.substr (0, ripped.length() - 1);
2745         }
2746
2747         find_files_matching_filter (state_files, ripped, accept_all_state_files, (void *) 0, true, true);
2748
2749         if (state_files.empty()) {
2750                 /* impossible! */
2751                 return 0;
2752         }
2753
2754         this_snapshot_path = _path;
2755         this_snapshot_path += legalize_for_path (_current_snapshot_name);
2756         this_snapshot_path += statefile_suffix;
2757
2758         for (vector<string>::iterator i = state_files.begin(); i != state_files.end(); ++i) {
2759
2760                 if (exclude_this_snapshot && *i == this_snapshot_path) {
2761                         continue;
2762                 }
2763
2764                 if (find_all_sources (*i, result) < 0) {
2765                         return -1;
2766                 }
2767         }
2768
2769         return 0;
2770 }
2771
2772 struct RegionCounter {
2773     typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2774     AudioSourceList::iterator iter;
2775     boost::shared_ptr<Region> region;
2776     uint32_t count;
2777
2778     RegionCounter() : count (0) {}
2779 };
2780
2781 int
2782 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2783 {
2784         boost::optional<int> r = AskAboutPlaylistDeletion (p);
2785         return r.get_value_or (1);
2786 }
2787
2788 void
2789 Session::cleanup_regions ()
2790 {
2791         bool removed = false;
2792         const RegionFactory::RegionMap& regions (RegionFactory::regions());
2793
2794         for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2795
2796                 uint32_t used = playlists->region_use_count (i->second);
2797
2798                 if (used == 0 && !i->second->automatic ()) {
2799                         removed = true;
2800                         RegionFactory::map_remove (i->second);
2801                 }
2802         }
2803
2804         if (removed) {
2805                 // re-check to remove parent references of compound regions
2806                 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2807                         if (!(i->second->whole_file() && i->second->max_source_level() > 0)) {
2808                                 continue;
2809                         }
2810                         assert(boost::dynamic_pointer_cast<PlaylistSource>(i->second->source (0)) != 0);
2811                         if (0 == playlists->region_use_count (i->second)) {
2812                                 RegionFactory::map_remove (i->second);
2813                         }
2814                 }
2815         }
2816
2817         /* dump the history list */
2818         _history.clear ();
2819
2820         save_state ("");
2821 }
2822
2823 int
2824 Session::cleanup_sources (CleanupReport& rep)
2825 {
2826         // FIXME: needs adaptation to midi
2827
2828         vector<boost::shared_ptr<Source> > dead_sources;
2829         string audio_path;
2830         string midi_path;
2831         vector<string> candidates;
2832         vector<string> unused;
2833         set<string> all_sources;
2834         bool used;
2835         string spath;
2836         int ret = -1;
2837         string tmppath1;
2838         string tmppath2;
2839         Searchpath asp;
2840         Searchpath msp;
2841
2842         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2843
2844         /* consider deleting all unused playlists */
2845
2846         if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2847                 ret = 0;
2848                 goto out;
2849         }
2850
2851         /* sync the "all regions" property of each playlist with its current state
2852          */
2853
2854         playlists->sync_all_regions_with_regions ();
2855
2856         /* find all un-used sources */
2857
2858         rep.paths.clear ();
2859         rep.space = 0;
2860
2861         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2862
2863                 SourceMap::iterator tmp;
2864
2865                 tmp = i;
2866                 ++tmp;
2867
2868                 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2869                    capture files.
2870                 */
2871
2872                 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2873                         dead_sources.push_back (i->second);
2874                         i->second->drop_references ();
2875                 }
2876
2877                 i = tmp;
2878         }
2879
2880         /* build a list of all the possible audio directories for the session */
2881
2882         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2883                 SessionDirectory sdir ((*i).path);
2884                 asp += sdir.sound_path();
2885         }
2886         audio_path += asp.to_string();
2887
2888
2889         /* build a list of all the possible midi directories for the session */
2890
2891         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2892                 SessionDirectory sdir ((*i).path);
2893                 msp += sdir.midi_path();
2894         }
2895         midi_path += msp.to_string();
2896
2897         find_files_matching_filter (candidates, audio_path, accept_all_audio_files, (void *) 0, true, true);
2898         find_files_matching_filter (candidates, midi_path, accept_all_midi_files, (void *) 0, true, true);
2899
2900         /* find all sources, but don't use this snapshot because the
2901            state file on disk still references sources we may have already
2902            dropped.
2903         */
2904
2905         find_all_sources_across_snapshots (all_sources, true);
2906
2907         /*  add our current source list
2908          */
2909
2910         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2911                 boost::shared_ptr<FileSource> fs;
2912                 SourceMap::iterator tmp = i;
2913                 ++tmp;
2914
2915                 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2916
2917                         if (!fs->is_stub()) {
2918
2919                                 if (playlists->source_use_count (fs) != 0) {
2920                                         all_sources.insert (fs->path());
2921                                 } else {
2922                                         
2923                                         /* we might not remove this source from disk, because it may be used
2924                                            by other snapshots, but its not being used in this version
2925                                            so lets get rid of it now, along with any representative regions
2926                                            in the region list.
2927                                         */
2928                                         
2929                                         RegionFactory::remove_regions_using_source (i->second);
2930                                         
2931                                         // also remove source from all_sources
2932                                         
2933                                         for (set<string>::iterator j = all_sources.begin(); j != all_sources.end(); ++j) {
2934                                                 spath = Glib::path_get_basename (*j);
2935                                                 if (spath == i->second->name()) {
2936                                                         all_sources.erase (j);
2937                                                         break;
2938                                                 }
2939                                         }
2940
2941                                         sources.erase (i);
2942                                 }
2943                         }
2944                 }
2945
2946                 i = tmp;
2947         }
2948
2949         for (vector<string>::iterator x = candidates.begin(); x != candidates.end(); ++x) {
2950
2951                 used = false;
2952                 spath = *x;
2953
2954                 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2955
2956                         tmppath1 = canonical_path (spath);
2957                         tmppath2 = canonical_path ((*i));
2958
2959                         if (tmppath1 == tmppath2) {
2960                                 used = true;
2961                                 break;
2962                         }
2963                 }
2964
2965                 if (!used) {
2966                         unused.push_back (spath);
2967                 }
2968         }
2969
2970         /* now try to move all unused files into the "dead" directory(ies) */
2971
2972         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2973                 struct stat statbuf;
2974
2975                 string newpath;
2976
2977                 /* don't move the file across filesystems, just
2978                    stick it in the `dead_dir_name' directory
2979                    on whichever filesystem it was already on.
2980                 */
2981
2982                 if ((*x).find ("/sounds/") != string::npos) {
2983
2984                         /* old school, go up 1 level */
2985
2986                         newpath = Glib::path_get_dirname (*x);      // "sounds"
2987                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2988
2989                 } else {
2990
2991                         /* new school, go up 4 levels */
2992
2993                         newpath = Glib::path_get_dirname (*x);      // "audiofiles" or "midifiles"
2994                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2995                         newpath = Glib::path_get_dirname (newpath); // "interchange"
2996                         newpath = Glib::path_get_dirname (newpath); // "session-dir"
2997                 }
2998
2999                 newpath = Glib::build_filename (newpath, dead_dir_name);
3000
3001                 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
3002                         error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
3003                         return -1;
3004                 }
3005
3006                 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
3007
3008                 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
3009
3010                         /* the new path already exists, try versioning */
3011
3012                         char buf[PATH_MAX+1];
3013                         int version = 1;
3014                         string newpath_v;
3015
3016                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
3017                         newpath_v = buf;
3018
3019                         while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
3020                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
3021                                 newpath_v = buf;
3022                         }
3023
3024                         if (version == 999) {
3025                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
3026                                                   newpath)
3027                                       << endmsg;
3028                         } else {
3029                                 newpath = newpath_v;
3030                         }
3031
3032                 } else {
3033
3034                         /* it doesn't exist, or we can't read it or something */
3035
3036                 }
3037
3038                 stat ((*x).c_str(), &statbuf);
3039
3040                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
3041                         error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
3042                                           (*x), newpath, strerror (errno))
3043                               << endmsg;
3044                         goto out;
3045                 }
3046
3047                 /* see if there an easy to find peakfile for this file, and remove it.
3048                  */
3049
3050                 string base = basename_nosuffix (*x);
3051                 base += "%A"; /* this is what we add for the channel suffix of all native files,
3052                                  or for the first channel of embedded files. it will miss
3053                                  some peakfiles for other channels
3054                               */
3055                 string peakpath = construct_peak_filepath (base);
3056
3057                 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
3058                         if (::g_unlink (peakpath.c_str()) != 0) {
3059                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
3060                                                          peakpath, _path, strerror (errno))
3061                                       << endmsg;
3062                                 /* try to back out */
3063                                 ::rename (newpath.c_str(), _path.c_str());
3064                                 goto out;
3065                         }
3066                 }
3067
3068                 rep.paths.push_back (*x);
3069                 rep.space += statbuf.st_size;
3070         }
3071
3072         /* dump the history list */
3073
3074         _history.clear ();
3075
3076         /* save state so we don't end up a session file
3077            referring to non-existent sources.
3078         */
3079
3080         save_state ("");
3081         ret = 0;
3082
3083   out:
3084         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
3085
3086         return ret;
3087 }
3088
3089 int
3090 Session::cleanup_trash_sources (CleanupReport& rep)
3091 {
3092         // FIXME: needs adaptation for MIDI
3093
3094         vector<space_and_path>::iterator i;
3095         string dead_dir;
3096
3097         rep.paths.clear ();
3098         rep.space = 0;
3099
3100         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3101
3102                 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
3103
3104                 clear_directory (dead_dir, &rep.space, &rep.paths);
3105         }
3106
3107         return 0;
3108 }
3109
3110 void
3111 Session::set_dirty ()
3112 {
3113         /* never mark session dirty during loading */
3114
3115         if (_state_of_the_state & Loading) {
3116                 return;
3117         }
3118
3119         bool was_dirty = dirty();
3120
3121         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3122
3123
3124         if (!was_dirty) {
3125                 DirtyChanged(); /* EMIT SIGNAL */
3126         }
3127 }
3128
3129
3130 void
3131 Session::set_clean ()
3132 {
3133         bool was_dirty = dirty();
3134
3135         _state_of_the_state = Clean;
3136
3137
3138         if (was_dirty) {
3139                 DirtyChanged(); /* EMIT SIGNAL */
3140         }
3141 }
3142
3143 void
3144 Session::set_deletion_in_progress ()
3145 {
3146         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3147 }
3148
3149 void
3150 Session::clear_deletion_in_progress ()
3151 {
3152         _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3153 }
3154
3155 void
3156 Session::add_controllable (boost::shared_ptr<Controllable> c)
3157 {
3158         /* this adds a controllable to the list managed by the Session.
3159            this is a subset of those managed by the Controllable class
3160            itself, and represents the only ones whose state will be saved
3161            as part of the session.
3162         */
3163
3164         Glib::Threads::Mutex::Lock lm (controllables_lock);
3165         controllables.insert (c);
3166 }
3167
3168 struct null_deleter { void operator()(void const *) const {} };
3169
3170 void
3171 Session::remove_controllable (Controllable* c)
3172 {
3173         if (_state_of_the_state & Deletion) {
3174                 return;
3175         }
3176
3177         Glib::Threads::Mutex::Lock lm (controllables_lock);
3178
3179         Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3180
3181         if (x != controllables.end()) {
3182                 controllables.erase (x);
3183         }
3184 }
3185
3186 boost::shared_ptr<Controllable>
3187 Session::controllable_by_id (const PBD::ID& id)
3188 {
3189         Glib::Threads::Mutex::Lock lm (controllables_lock);
3190
3191         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3192                 if ((*i)->id() == id) {
3193                         return *i;
3194                 }
3195         }
3196
3197         return boost::shared_ptr<Controllable>();
3198 }
3199
3200 boost::shared_ptr<Controllable>
3201 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3202 {
3203         boost::shared_ptr<Controllable> c;
3204         boost::shared_ptr<Route> r;
3205
3206         switch (desc.top_level_type()) {
3207         case ControllableDescriptor::NamedRoute:
3208         {
3209                 std::string str = desc.top_level_name();
3210                 if (str == "Master" || str == "master") {
3211                         r = _master_out;
3212                 } else if (str == "control" || str == "listen") {
3213                         r = _monitor_out;
3214                 } else {
3215                         r = route_by_name (desc.top_level_name());
3216                 }
3217                 break;
3218         }
3219
3220         case ControllableDescriptor::RemoteControlID:
3221                 r = route_by_remote_id (desc.rid());
3222                 break;
3223         }
3224
3225         if (!r) {
3226                 return c;
3227         }
3228
3229         switch (desc.subtype()) {
3230         case ControllableDescriptor::Gain:
3231                 c = r->gain_control ();
3232                 break;
3233
3234         case ControllableDescriptor::Trim:
3235                 c = r->trim()->gain_control ();
3236                 break;
3237
3238         case ControllableDescriptor::Solo:
3239                 c = r->solo_control();
3240                 break;
3241
3242         case ControllableDescriptor::Mute:
3243                 c = r->mute_control();
3244                 break;
3245
3246         case ControllableDescriptor::Recenable:
3247         {
3248                 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3249
3250                 if (t) {
3251                         c = t->rec_enable_control ();
3252                 }
3253                 break;
3254         }
3255
3256         case ControllableDescriptor::PanDirection:
3257         {
3258                 c = r->pannable()->pan_azimuth_control;
3259                 break;
3260         }
3261
3262         case ControllableDescriptor::PanWidth:
3263         {
3264                 c = r->pannable()->pan_width_control;
3265                 break;
3266         }
3267
3268         case ControllableDescriptor::PanElevation:
3269         {
3270                 c = r->pannable()->pan_elevation_control;
3271                 break;
3272         }
3273
3274         case ControllableDescriptor::Balance:
3275                 /* XXX simple pan control */
3276                 break;
3277
3278         case ControllableDescriptor::PluginParameter:
3279         {
3280                 uint32_t plugin = desc.target (0);
3281                 uint32_t parameter_index = desc.target (1);
3282
3283                 /* revert to zero based counting */
3284
3285                 if (plugin > 0) {
3286                         --plugin;
3287                 }
3288
3289                 if (parameter_index > 0) {
3290                         --parameter_index;
3291                 }
3292
3293                 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3294
3295                 if (p) {
3296                         c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3297                                 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3298                 }
3299                 break;
3300         }
3301
3302         case ControllableDescriptor::SendGain:
3303         {
3304                 uint32_t send = desc.target (0);
3305
3306                 /* revert to zero-based counting */
3307
3308                 if (send > 0) {
3309                         --send;
3310                 }
3311
3312                 boost::shared_ptr<Processor> p = r->nth_send (send);
3313
3314                 if (p) {
3315                         boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3316                         boost::shared_ptr<Amp> a = s->amp();
3317                         
3318                         if (a) {
3319                                 c = s->amp()->gain_control();
3320                         }
3321                 }
3322                 break;
3323         }
3324
3325         default:
3326                 /* relax and return a null pointer */
3327                 break;
3328         }
3329
3330         return c;
3331 }
3332
3333 void
3334 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3335 {
3336         if (_writable) {
3337                 Stateful::add_instant_xml (node, _path);
3338         }
3339
3340         if (write_to_config) {
3341                 Config->add_instant_xml (node);
3342         }
3343 }
3344
3345 XMLNode*
3346 Session::instant_xml (const string& node_name)
3347 {
3348         return Stateful::instant_xml (node_name, _path);
3349 }
3350
3351 int
3352 Session::save_history (string snapshot_name)
3353 {
3354         XMLTree tree;
3355
3356         if (!_writable) {
3357                 return 0;
3358         }
3359
3360         if (!Config->get_save_history() || Config->get_saved_history_depth() < 0 || 
3361             (_history.undo_depth() == 0 && _history.redo_depth() == 0)) {
3362                 return 0;
3363         }
3364
3365         if (snapshot_name.empty()) {
3366                 snapshot_name = _current_snapshot_name;
3367         }
3368
3369         const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3370         const string backup_filename = history_filename + backup_suffix;
3371         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3372         const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3373
3374         if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3375                 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3376                         error << _("could not backup old history file, current history not saved") << endmsg;
3377                         return -1;
3378                 }
3379         }
3380
3381         tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3382
3383         if (!tree.write (xml_path))
3384         {
3385                 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3386
3387                 if (g_remove (xml_path.c_str()) != 0) {
3388                         error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3389                                         xml_path, g_strerror (errno)) << endmsg;
3390                 }
3391                 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3392                         error << string_compose (_("could not restore history file from backup %1 (%2)"),
3393                                         backup_path, g_strerror (errno)) << endmsg;
3394                 }
3395
3396                 return -1;
3397         }
3398
3399         return 0;
3400 }
3401
3402 int
3403 Session::restore_history (string snapshot_name)
3404 {
3405         XMLTree tree;
3406
3407         if (snapshot_name.empty()) {
3408                 snapshot_name = _current_snapshot_name;
3409         }
3410
3411         const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3412         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3413
3414         info << "Loading history from " << xml_path << endmsg;
3415
3416         if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3417                 info << string_compose (_("%1: no history file \"%2\" for this session."),
3418                                 _name, xml_path) << endmsg;
3419                 return 1;
3420         }
3421
3422         if (!tree.read (xml_path)) {
3423                 error << string_compose (_("Could not understand session history file \"%1\""),
3424                                 xml_path) << endmsg;
3425                 return -1;
3426         }
3427
3428         // replace history
3429         _history.clear();
3430
3431         for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3432
3433                 XMLNode *t = *it;
3434                 UndoTransaction* ut = new UndoTransaction ();
3435                 struct timeval tv;
3436
3437                 ut->set_name(t->property("name")->value());
3438                 stringstream ss(t->property("tv-sec")->value());
3439                 ss >> tv.tv_sec;
3440                 ss.str(t->property("tv-usec")->value());
3441                 ss >> tv.tv_usec;
3442                 ut->set_timestamp(tv);
3443
3444                 for (XMLNodeConstIterator child_it  = t->children().begin();
3445                                 child_it != t->children().end(); child_it++)
3446                 {
3447                         XMLNode *n = *child_it;
3448                         Command *c;
3449
3450                         if (n->name() == "MementoCommand" ||
3451                                         n->name() == "MementoUndoCommand" ||
3452                                         n->name() == "MementoRedoCommand") {
3453
3454                                 if ((c = memento_command_factory(n))) {
3455                                         ut->add_command(c);
3456                                 }
3457
3458                         } else if (n->name() == "NoteDiffCommand") {
3459                                 PBD::ID id (n->property("midi-source")->value());
3460                                 boost::shared_ptr<MidiSource> midi_source =
3461                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3462                                 if (midi_source) {
3463                                         ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3464                                 } else {
3465                                         error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3466                                 }
3467
3468                         } else if (n->name() == "SysExDiffCommand") {
3469
3470                                 PBD::ID id (n->property("midi-source")->value());
3471                                 boost::shared_ptr<MidiSource> midi_source =
3472                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3473                                 if (midi_source) {
3474                                         ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3475                                 } else {
3476                                         error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3477                                 }
3478
3479                         } else if (n->name() == "PatchChangeDiffCommand") {
3480
3481                                 PBD::ID id (n->property("midi-source")->value());
3482                                 boost::shared_ptr<MidiSource> midi_source =
3483                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3484                                 if (midi_source) {
3485                                         ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3486                                 } else {
3487                                         error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3488                                 }
3489
3490                         } else if (n->name() == "StatefulDiffCommand") {
3491                                 if ((c = stateful_diff_command_factory (n))) {
3492                                         ut->add_command (c);
3493                                 }
3494                         } else {
3495                                 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3496                         }
3497                 }
3498
3499                 _history.add (ut);
3500         }
3501
3502         return 0;
3503 }
3504
3505 void
3506 Session::config_changed (std::string p, bool ours)
3507 {
3508         if (ours) {
3509                 set_dirty ();
3510         }
3511
3512         if (p == "seamless-loop") {
3513
3514         } else if (p == "rf-speed") {
3515
3516         } else if (p == "auto-loop") {
3517
3518         } else if (p == "auto-input") {
3519
3520                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3521                         /* auto-input only makes a difference if we're rolling */
3522                         set_track_monitor_input_status (!config.get_auto_input());
3523                 }
3524
3525         } else if (p == "punch-in") {
3526
3527                 Location* location;
3528
3529                 if ((location = _locations->auto_punch_location()) != 0) {
3530
3531                         if (config.get_punch_in ()) {
3532                                 replace_event (SessionEvent::PunchIn, location->start());
3533                         } else {
3534                                 remove_event (location->start(), SessionEvent::PunchIn);
3535                         }
3536                 }
3537
3538         } else if (p == "punch-out") {
3539
3540                 Location* location;
3541
3542                 if ((location = _locations->auto_punch_location()) != 0) {
3543
3544                         if (config.get_punch_out()) {
3545                                 replace_event (SessionEvent::PunchOut, location->end());
3546                         } else {
3547                                 clear_events (SessionEvent::PunchOut);
3548                         }
3549                 }
3550
3551         } else if (p == "edit-mode") {
3552
3553                 Glib::Threads::Mutex::Lock lm (playlists->lock);
3554
3555                 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3556                         (*i)->set_edit_mode (Config->get_edit_mode ());
3557                 }
3558
3559         } else if (p == "use-video-sync") {
3560
3561                 waiting_for_sync_offset = config.get_use_video_sync();
3562
3563         } else if (p == "mmc-control") {
3564
3565                 //poke_midi_thread ();
3566
3567         } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3568
3569                 _mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3570
3571         } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3572
3573                 _mmc->set_send_device_id (Config->get_mmc_send_device_id());
3574
3575         } else if (p == "midi-control") {
3576
3577                 //poke_midi_thread ();
3578
3579         } else if (p == "raid-path") {
3580
3581                 setup_raid_path (config.get_raid_path());
3582
3583         } else if (p == "timecode-format") {
3584
3585                 sync_time_vars ();
3586
3587         } else if (p == "video-pullup") {
3588
3589                 sync_time_vars ();
3590
3591         } else if (p == "seamless-loop") {
3592
3593                 if (play_loop && transport_rolling()) {
3594                         // to reset diskstreams etc
3595                         request_play_loop (true);
3596                 }
3597
3598         } else if (p == "rf-speed") {
3599
3600                 cumulative_rf_motion = 0;
3601                 reset_rf_scale (0);
3602
3603         } else if (p == "click-sound") {
3604
3605                 setup_click_sounds (1);
3606
3607         } else if (p == "click-emphasis-sound") {
3608
3609                 setup_click_sounds (-1);
3610
3611         } else if (p == "clicking") {
3612
3613                 if (Config->get_clicking()) {
3614                         if (_click_io && click_data) { // don't require emphasis data
3615                                 _clicking = true;
3616                         }
3617                 } else {
3618                         _clicking = false;
3619                 }
3620
3621         } else if (p == "click-gain") {
3622                 
3623                 if (_click_gain) {
3624                         _click_gain->set_gain (Config->get_click_gain(), this);
3625                 }
3626
3627         } else if (p == "send-mtc") {
3628
3629                 if (Config->get_send_mtc ()) {
3630                         /* mark us ready to send */
3631                         next_quarter_frame_to_send = 0;
3632                 }
3633
3634         } else if (p == "send-mmc") {
3635
3636                 _mmc->enable_send (Config->get_send_mmc ());
3637
3638         } else if (p == "midi-feedback") {
3639
3640                 session_midi_feedback = Config->get_midi_feedback();
3641
3642         } else if (p == "jack-time-master") {
3643
3644                 engine().reset_timebase ();
3645
3646         } else if (p == "native-file-header-format") {
3647
3648                 if (!first_file_header_format_reset) {
3649                         reset_native_file_format ();
3650                 }
3651
3652                 first_file_header_format_reset = false;
3653
3654         } else if (p == "native-file-data-format") {
3655
3656                 if (!first_file_data_format_reset) {
3657                         reset_native_file_format ();
3658                 }
3659
3660                 first_file_data_format_reset = false;
3661
3662         } else if (p == "external-sync") {
3663                 if (!config.get_external_sync()) {
3664                         drop_sync_source ();
3665                 } else {
3666                         switch_to_sync_source (Config->get_sync_source());
3667                 }
3668         }  else if (p == "denormal-model") {
3669                 setup_fpu ();
3670         } else if (p == "history-depth") {
3671                 set_history_depth (Config->get_history_depth());
3672         } else if (p == "remote-model") {
3673                 /* XXX DO SOMETHING HERE TO TELL THE GUI THAT WE NEED
3674                    TO SET REMOTE ID'S
3675                 */
3676         } else if (p == "initial-program-change") {
3677
3678                 if (_mmc->output_port() && Config->get_initial_program_change() >= 0) {
3679                         MIDI::byte buf[2];
3680
3681                         buf[0] = MIDI::program; // channel zero by default
3682                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3683
3684                         _mmc->output_port()->midimsg (buf, sizeof (buf), 0);
3685                 }
3686         } else if (p == "solo-mute-override") {
3687                 // catch_up_on_solo_mute_override ();
3688         } else if (p == "listen-position" || p == "pfl-position") {
3689                 listen_position_changed ();
3690         } else if (p == "solo-control-is-listen-control") {
3691                 solo_control_mode_changed ();
3692         } else if (p == "solo-mute-gain") {
3693                 _solo_cut_control->Changed();
3694         } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3695                 last_timecode_valid = false;
3696         } else if (p == "playback-buffer-seconds") {
3697                 AudioSource::allocate_working_buffers (frame_rate());
3698         } else if (p == "ltc-source-port") {
3699                 reconnect_ltc_input ();
3700         } else if (p == "ltc-sink-port") {
3701                 reconnect_ltc_output ();
3702         } else if (p == "timecode-generator-offset") {
3703                 ltc_tx_parse_offset();
3704         } else if (p == "auto-return-target-list") {
3705                 follow_playhead_priority ();
3706         }
3707
3708         set_dirty ();
3709 }
3710
3711 void
3712 Session::set_history_depth (uint32_t d)
3713 {
3714         _history.set_depth (d);
3715 }
3716
3717 int
3718 Session::load_diskstreams_2X (XMLNode const & node, int)
3719 {
3720         XMLNodeList          clist;
3721         XMLNodeConstIterator citer;
3722
3723         clist = node.children();
3724
3725         for (citer = clist.begin(); citer != clist.end(); ++citer) {
3726
3727                 try {
3728                         /* diskstreams added automatically by DiskstreamCreated handler */
3729                         if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3730                                 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3731                                 _diskstreams_2X.push_back (dsp);
3732                         } else {
3733                                 error << _("Session: unknown diskstream type in XML") << endmsg;
3734                         }
3735                 }
3736
3737                 catch (failed_constructor& err) {
3738                         error << _("Session: could not load diskstream via XML state") << endmsg;
3739                         return -1;
3740                 }
3741         }
3742
3743         return 0;
3744 }
3745
3746 /** Connect things to the MMC object */
3747 void
3748 Session::setup_midi_machine_control ()
3749 {
3750         _mmc = new MIDI::MachineControl;
3751         _mmc->set_ports (_midi_ports->mmc_input_port(), _midi_ports->mmc_output_port());
3752
3753         _mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3754         _mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3755         _mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3756         _mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3757         _mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3758         _mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3759         _mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3760         _mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3761         _mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3762         _mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3763         _mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3764         _mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3765         _mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3766
3767         /* also handle MIDI SPP because its so common */
3768
3769         _mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3770         _mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3771         _mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3772 }
3773
3774 boost::shared_ptr<Controllable>
3775 Session::solo_cut_control() const
3776 {
3777         /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3778            controls in Ardour that currently get presented to the user in the GUI that require
3779            access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3780
3781            its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3782            it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3783            parameter.
3784         */
3785
3786         return _solo_cut_control;
3787 }
3788
3789 int
3790 Session::rename (const std::string& new_name)
3791 {
3792         string legal_name = legalize_for_path (new_name);
3793         string new_path;
3794         string oldstr;
3795         string newstr;
3796         bool first = true;
3797
3798         string const old_sources_root = _session_dir->sources_root();
3799
3800         if (!_writable || (_state_of_the_state & CannotSave)) {
3801                 error << _("Cannot rename read-only session.") << endmsg;
3802                 return 0; // don't show "messed up" warning
3803         }
3804         if (record_status() == Recording) {
3805                 error << _("Cannot rename session while recording") << endmsg;
3806                 return 0; // don't show "messed up" warning
3807         }
3808
3809         StateProtector stp (this);
3810
3811         /* Rename:
3812
3813          * session directory
3814          * interchange subdirectory
3815          * session file
3816          * session history
3817          
3818          * Backup files are left unchanged and not renamed.
3819          */
3820
3821         /* Windows requires that we close all files before attempting the
3822          * rename. This works on other platforms, but isn't necessary there.
3823          * Leave it in place for all platforms though, since it may help
3824          * catch issues that could arise if the way Source files work ever
3825          * change (since most developers are not using Windows).
3826          */
3827
3828         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
3829                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3830                 if (fs) {
3831                         fs->close ();
3832                 }
3833         }
3834         
3835         /* pass one: not 100% safe check that the new directory names don't
3836          * already exist ...
3837          */
3838
3839         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3840                 
3841                 oldstr = (*i).path;
3842                 
3843                 /* this is a stupid hack because Glib::path_get_dirname() is
3844                  * lexical-only, and so passing it /a/b/c/ gives a different
3845                  * result than passing it /a/b/c ...
3846                  */
3847                 
3848                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3849                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3850                 }
3851                 
3852                 string base = Glib::path_get_dirname (oldstr);
3853                 
3854                 newstr = Glib::build_filename (base, legal_name);
3855                 
3856                 cerr << "Looking for " << newstr << endl;
3857                 
3858                 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3859                         cerr << " exists\n";
3860                         return -1;
3861                 }
3862         }
3863
3864         /* Session dirs */
3865
3866         first = true;
3867         
3868         for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3869
3870                 vector<string> v;
3871
3872                 oldstr = (*i).path;
3873                 
3874                 /* this is a stupid hack because Glib::path_get_dirname() is
3875                  * lexical-only, and so passing it /a/b/c/ gives a different
3876                  * result than passing it /a/b/c ...
3877                  */
3878                 
3879                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3880                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3881                 }
3882
3883                 string base = Glib::path_get_dirname (oldstr);
3884                 newstr = Glib::build_filename (base, legal_name);
3885
3886                 cerr << "for " << oldstr << " new dir = " << newstr << endl;
3887                 
3888                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3889                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3890                         cerr << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
3891                         error << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3892                         return 1;
3893                 }
3894
3895                 /* Reset path in "session dirs" */
3896                 
3897                 (*i).path = newstr;
3898                 (*i).blocks = 0;
3899                 
3900                 /* reset primary SessionDirectory object */
3901                 
3902                 if (first) {
3903                         (*_session_dir) = newstr;
3904                         new_path = newstr;
3905                         first = false;
3906                 }
3907
3908                 /* now rename directory below session_dir/interchange */
3909
3910                 string old_interchange_dir;
3911                 string new_interchange_dir;
3912
3913                 /* use newstr here because we renamed the path
3914                  * (folder/directory) that used to be oldstr to newstr above 
3915                  */     
3916                 
3917                 v.push_back (newstr); 
3918                 v.push_back (interchange_dir_name);
3919                 v.push_back (Glib::path_get_basename (oldstr));
3920
3921                 old_interchange_dir = Glib::build_filename (v);
3922
3923                 v.clear ();
3924                 v.push_back (newstr);
3925                 v.push_back (interchange_dir_name);
3926                 v.push_back (legal_name);
3927                 
3928                 new_interchange_dir = Glib::build_filename (v);
3929                 
3930                 cerr << "Rename " << old_interchange_dir << " => " << new_interchange_dir << endl;
3931                 
3932                 if (::g_rename (old_interchange_dir.c_str(), new_interchange_dir.c_str()) != 0) {
3933                         cerr << string_compose (_("renaming %s as %2 failed (%3)"),
3934                                                  old_interchange_dir, new_interchange_dir,
3935                                                  g_strerror (errno))
3936                               << endl;
3937                         error << string_compose (_("renaming %s as %2 failed (%3)"),
3938                                                  old_interchange_dir, new_interchange_dir,
3939                                                  g_strerror (errno))
3940                               << endmsg;
3941                         return 1;
3942                 }
3943         }
3944
3945         /* state file */
3946         
3947         oldstr = Glib::build_filename (new_path, _current_snapshot_name + statefile_suffix);
3948         newstr= Glib::build_filename (new_path, legal_name + statefile_suffix);
3949         
3950         cerr << "Rename " << oldstr << " => " << newstr << endl;                
3951
3952         if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3953                 cerr << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
3954                 error << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3955                 return 1;
3956         }
3957
3958         /* history file */
3959         
3960         oldstr = Glib::build_filename (new_path, _current_snapshot_name) + history_suffix;
3961
3962         if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS))  {
3963                 newstr = Glib::build_filename (new_path, legal_name) + history_suffix;
3964                 
3965                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3966                 
3967                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3968                         cerr << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
3969                         error << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3970                         return 1;
3971                 }
3972         }
3973
3974         /* remove old name from recent sessions */
3975         remove_recent_sessions (_path);
3976         _path = new_path;
3977         
3978         /* update file source paths */
3979         
3980         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3981                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3982                 if (fs) {
3983                         string p = fs->path ();
3984                         boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3985                         fs->set_path (p);
3986                         SourceFactory::setup_peakfile(i->second, true);
3987                 }
3988         }
3989
3990         _current_snapshot_name = new_name;
3991         _name = new_name;
3992         
3993         set_dirty ();
3994
3995         /* save state again to get everything just right */
3996
3997         save_state (_current_snapshot_name);
3998
3999         /* add to recent sessions */
4000
4001         store_recent_sessions (new_name, _path);
4002
4003         return 0;
4004 }
4005
4006 int
4007 Session::get_session_info_from_path (XMLTree& tree, const string& xmlpath)
4008 {
4009         if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
4010                 return -1;
4011         }
4012
4013         if (!tree.read (xmlpath)) {
4014                 return -1;
4015         }
4016
4017         return 0;
4018 }
4019
4020 int
4021 Session::get_info_from_path (const string& xmlpath, float& sample_rate, SampleFormat& data_format)
4022 {
4023         XMLTree tree;
4024         bool found_sr = false;
4025         bool found_data_format = false;
4026
4027         if (get_session_info_from_path (tree, xmlpath)) {
4028                 return -1;
4029         }
4030
4031         /* sample rate */
4032
4033         const XMLProperty* prop;
4034         if ((prop = tree.root()->property (X_("sample-rate"))) != 0) {          
4035                 sample_rate = atoi (prop->value());
4036                 found_sr = true;
4037         }
4038
4039         const XMLNodeList& children (tree.root()->children());
4040         for (XMLNodeList::const_iterator c = children.begin(); c != children.end(); ++c) {
4041                 const XMLNode* child = *c;
4042                 if (child->name() == "Config") {
4043                         const XMLNodeList& options (child->children());
4044                         for (XMLNodeList::const_iterator oc = options.begin(); oc != options.end(); ++oc) {
4045                                 const XMLNode* option = *oc;
4046                                 const XMLProperty* name = option->property("name");
4047
4048                                 if (!name) {
4049                                         continue;
4050                                 }
4051
4052                                 if (name->value() == "native-file-data-format") {
4053                                         const XMLProperty* value = option->property ("value");
4054                                         if (value) {
4055                                                 SampleFormat fmt = (SampleFormat) string_2_enum (option->property ("value")->value(), fmt);
4056                                                 data_format = fmt;
4057                                                 found_data_format = true;
4058                                                 break;
4059                                         }
4060                                 }
4061                         }
4062                 }
4063                 if (found_data_format) {
4064                         break;
4065                 }
4066         }
4067
4068         return !(found_sr && found_data_format); // zero if they are both found
4069 }
4070
4071 typedef std::vector<boost::shared_ptr<FileSource> > SeveralFileSources;
4072 typedef std::map<std::string,SeveralFileSources> SourcePathMap;
4073
4074 int
4075 Session::bring_all_sources_into_session (boost::function<void(uint32_t,uint32_t,string)> callback)
4076 {
4077         uint32_t total = 0;
4078         uint32_t n = 0;
4079         SourcePathMap source_path_map;
4080         string new_path;
4081         boost::shared_ptr<AudioFileSource> afs;
4082         int ret = 0;
4083
4084         {
4085
4086                 Glib::Threads::Mutex::Lock lm (source_lock);
4087                 
4088                 cerr << " total sources = " << sources.size();
4089                 
4090                 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
4091                         boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
4092                         
4093                         if (!fs) {
4094                                 continue;
4095                         }
4096                         
4097                         if (fs->within_session()) {
4098                                 continue;
4099                         }
4100                         
4101                         if (source_path_map.find (fs->path()) != source_path_map.end()) {
4102                                 source_path_map[fs->path()].push_back (fs);
4103                         } else {
4104                                 SeveralFileSources v;
4105                                 v.push_back (fs);
4106                                 source_path_map.insert (make_pair (fs->path(), v));
4107                         }
4108                         
4109                         total++;
4110                 }
4111                 
4112                 cerr << " fsources = " << total << endl;
4113                 
4114                 for (SourcePathMap::iterator i = source_path_map.begin(); i != source_path_map.end(); ++i) {
4115                         
4116                         /* tell caller where we are */
4117                         
4118                         string old_path = i->first;
4119                         
4120                         callback (n, total, old_path);
4121                         
4122                         cerr << old_path << endl;
4123                         
4124                         new_path.clear ();
4125                         
4126                         switch (i->second.front()->type()) {
4127                         case DataType::AUDIO:
4128                                 new_path = new_audio_source_path_for_embedded (old_path);
4129                                 break;
4130                                 
4131                         case DataType::MIDI:
4132                                 /* XXX not implemented yet */
4133                                 break;
4134                         }
4135                         
4136                         if (new_path.empty()) {
4137                                 continue;
4138                         }
4139                         
4140                         cerr << "Move " << old_path << " => " << new_path << endl;
4141                         
4142                         if (!copy_file (old_path, new_path)) {
4143                                 cerr << "failed !\n";
4144                                 ret = -1;
4145                         }
4146                         
4147                         /* make sure we stop looking in the external
4148                            dir/folder. Remember, this is an all-or-nothing
4149                            operations, it doesn't merge just some files.
4150                         */
4151                         remove_dir_from_search_path (Glib::path_get_dirname (old_path), i->second.front()->type());
4152
4153                         for (SeveralFileSources::iterator f = i->second.begin(); f != i->second.end(); ++f) {
4154                                 (*f)->set_path (new_path);
4155                         }
4156                 }
4157         }
4158
4159         save_state ("", false, false);
4160
4161         return ret;
4162 }
4163
4164 static
4165 bool accept_all_files (string const &, void *)
4166 {
4167         return true;
4168 }
4169
4170 void
4171 Session::save_as_bring_callback (uint32_t,uint32_t,string)
4172 {
4173         /* It would be good if this did something useful vis-a-vis save-as, but the arguments doesn't provide the correct information right now to do this.
4174         */
4175 }
4176
4177 static string
4178 make_new_media_path (string old_path, string new_session_folder, string new_session_path)
4179 {
4180         /* typedir is the "midifiles" or "audiofiles" etc. part of the path. */
4181
4182         string typedir = Glib::path_get_basename (Glib::path_get_dirname (old_path));
4183         vector<string> v;
4184         v.push_back (new_session_folder); /* full path */
4185         v.push_back (interchange_dir_name);
4186         v.push_back (new_session_path);   /* just one directory/folder */
4187         v.push_back (typedir);
4188         v.push_back (Glib::path_get_basename (old_path));
4189         
4190         return Glib::build_filename (v);
4191 }
4192
4193 int
4194 Session::save_as (SaveAs& saveas)
4195 {
4196         vector<string> files;
4197         string current_folder = Glib::path_get_dirname (_path);
4198         string new_folder = legalize_for_path (saveas.new_name);
4199         string to_dir = Glib::build_filename (saveas.new_parent_folder, new_folder);
4200         int64_t total_bytes = 0;
4201         int64_t copied = 0;
4202         int64_t cnt = 0;
4203         int64_t all = 0;
4204         int32_t internal_file_cnt = 0;
4205
4206         vector<string> do_not_copy_extensions;
4207         do_not_copy_extensions.push_back (statefile_suffix);
4208         do_not_copy_extensions.push_back (pending_suffix);
4209         do_not_copy_extensions.push_back (backup_suffix);
4210         do_not_copy_extensions.push_back (temp_suffix);
4211         do_not_copy_extensions.push_back (history_suffix);
4212
4213         /* get total size */
4214
4215         for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
4216                 
4217                 /* need to clear this because
4218                  * find_files_matching_filter() is cumulative
4219                  */
4220                 
4221                 files.clear ();
4222                 
4223                 find_files_matching_filter (files, (*sd).path, accept_all_files, 0, false, true, true);
4224                 
4225                 all += files.size();
4226
4227                 for (vector<string>::iterator i = files.begin(); i != files.end(); ++i) {
4228                         GStatBuf gsb;
4229                         g_stat ((*i).c_str(), &gsb);
4230                         total_bytes += gsb.st_size;
4231                 }
4232         }
4233
4234         /* save old values so we can switch back if we are not switching to the new session */
4235         
4236         string old_path = _path;
4237         string old_name = _name;
4238         string old_snapshot = _current_snapshot_name;
4239         string old_sd = _session_dir->root_path();
4240         vector<string> old_search_path[DataType::num_types];
4241         string old_config_search_path[DataType::num_types];
4242
4243         old_search_path[DataType::AUDIO] = source_search_path (DataType::AUDIO);
4244         old_search_path[DataType::MIDI] = source_search_path (DataType::MIDI);
4245         old_config_search_path[DataType::AUDIO]  = config.get_audio_search_path ();     
4246         old_config_search_path[DataType::MIDI]  = config.get_midi_search_path ();       
4247
4248         /* switch session directory */
4249         
4250         (*_session_dir) = to_dir;
4251
4252         /* create new tree */
4253         
4254         if (!_session_dir->create()) {
4255                 saveas.failure_message = string_compose (_("Cannot create new session folder %1"), to_dir);
4256                 return -1;
4257         }
4258
4259         try {
4260                 /* copy all relevant files. Find each location in session_dirs,
4261                  * and copy files from there to target.
4262                  */
4263                 
4264                 for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
4265                         
4266                         /* need to clear this because
4267                          * find_files_matching_filter() is cumulative
4268                          */
4269                         
4270                         files.clear ();
4271                         
4272                         const size_t prefix_len = (*sd).path.size();
4273                         
4274                         /* Work just on the files within this session dir */
4275                         
4276                         find_files_matching_filter (files, (*sd).path, accept_all_files, 0, false, true, true);
4277                         
4278                         /* add dir separator to protect against collisions with
4279                          * track names (e.g. track named "audiofiles" or
4280                          * "analysis".
4281                          */
4282
4283                         static const std::string audiofile_dir_string = string (sound_dir_name) + G_DIR_SEPARATOR;
4284                         static const std::string midifile_dir_string = string (midi_dir_name) + G_DIR_SEPARATOR;
4285                         static const std::string analysis_dir_string = analysis_dir() + G_DIR_SEPARATOR;
4286
4287                         /* copy all the files. Handling is different for media files
4288                            than others because of the *silly* subtree we have below the interchange
4289                            folder. That really was a bad idea, but I'm not fixing it as part of
4290                            implementing ::save_as().
4291                         */
4292                         
4293                         for (vector<string>::iterator i = files.begin(); i != files.end(); ++i) {
4294
4295                                 std::string from = *i;
4296
4297 #ifdef __APPLE__
4298                                 string filename = Glib::path_get_basename (from);
4299                                 std::transform (filename.begin(), filename.end(), filename.begin(), ::toupper);
4300                                 if (filename == ".DS_STORE") {
4301                                         continue;
4302                                 }
4303 #endif
4304                                 
4305                                 if (from.find (audiofile_dir_string) != string::npos) {
4306                                         
4307                                         /* audio file: only copy if asked */
4308
4309                                         if (saveas.include_media && saveas.copy_media) {
4310                                                 
4311                                                 string to = make_new_media_path (*i, to_dir, new_folder);
4312
4313                                                 info << "media file copying from " << from << " to " << to << endmsg;
4314                                                 
4315                                                 if (!copy_file (from, to)) {
4316                                                         throw Glib::FileError (Glib::FileError::IO_ERROR,
4317                                                                                                    string_compose(_("\ncopying \"%1\" failed !"), from));
4318                                                 }
4319                                         }
4320                                         
4321                                         /* we found media files inside the session folder */
4322                                         
4323                                         internal_file_cnt++;
4324
4325                                 } else if (from.find (midifile_dir_string) != string::npos) {
4326
4327                                         /* midi file: always copy unless
4328                                          * creating an empty new session
4329                                          */
4330
4331                                         if (saveas.include_media) {
4332                                         
4333                                                 string to = make_new_media_path (*i, to_dir, new_folder);
4334                                                 
4335                                                 info << "media file copying from " << from << " to " << to << endmsg;
4336                                                 
4337                                                 if (!copy_file (from, to)) {
4338                                                         throw Glib::FileError (Glib::FileError::IO_ERROR, "copy failed");
4339                                                 }
4340                                         }
4341
4342                                         /* we found media files inside the session folder */
4343                                                 
4344                                         internal_file_cnt++;
4345                                         
4346                                 } else if (from.find (analysis_dir_string) != string::npos) {
4347
4348                                         /*  make sure analysis dir exists in
4349                                          *  new session folder, but we're not
4350                                          *  copying analysis files here, see
4351                                          *  below 
4352                                          */
4353                                         
4354                                         (void) g_mkdir_with_parents (analysis_dir().c_str(), 775);
4355                                         continue;
4356                                         
4357                                 } else {
4358                                         
4359                                         /* normal non-media file. Don't copy state, history, etc.
4360                                          */
4361                                         
4362                                         bool do_copy = true;
4363                                         
4364                                         for (vector<string>::iterator v = do_not_copy_extensions.begin(); v != do_not_copy_extensions.end(); ++v) {
4365                                                 if ((from.length() > (*v).length()) && (from.find (*v) == from.length() - (*v).length())) {
4366                                                         /* end of filename matches extension, do not copy file */
4367                                                         do_copy = false;
4368                                                         break;
4369                                                 } 
4370                                         }
4371
4372                                         if (!saveas.copy_media && from.find (peakfile_suffix) != string::npos) {
4373                                                 /* don't copy peakfiles if
4374                                                  * we're not copying media
4375                                                  */
4376                                                 do_copy = false;
4377                                         }
4378                                         
4379                                         if (do_copy) {
4380                                                 string to = Glib::build_filename (to_dir, from.substr (prefix_len));
4381                                                 
4382                                                 info << "attempting to make directory/folder " << to << endmsg;
4383
4384                                                 if (g_mkdir_with_parents (Glib::path_get_dirname (to).c_str(), 0755)) {
4385                                                         throw Glib::FileError (Glib::FileError::IO_ERROR, "cannot create required directory");
4386                                                 }
4387
4388                                                 info << "attempting to copy " << from << " to " << to << endmsg;
4389                                                 
4390                                                 if (!copy_file (from, to)) {
4391                                                         throw Glib::FileError (Glib::FileError::IO_ERROR,
4392                                                                                                    string_compose(_("\ncopying \"%1\" failed !"), from));
4393                                                 }
4394                                         }
4395                                 }
4396                                 
4397                                 /* measure file size even if we're not going to copy so that our Progress
4398                                    signals are correct, since we included these do-not-copy files
4399                                    in the computation of the total size and file count.
4400                                 */
4401                                 
4402                                 GStatBuf gsb;
4403                                 g_stat (from.c_str(), &gsb);
4404                                 copied += gsb.st_size;
4405                                 cnt++;
4406                                 
4407                                 double fraction = (double) copied / total_bytes;
4408                                 
4409                                 bool keep_going = true;
4410
4411                                 if (saveas.copy_media) {
4412
4413                                         /* no need or expectation of this if
4414                                          * media is not being copied, because
4415                                          * it will be fast(ish).
4416                                          */
4417                                         
4418                                         /* tell someone "X percent, file M of N"; M is one-based */
4419                                         
4420                                         boost::optional<bool> res = saveas.Progress (fraction, cnt, all);
4421                                         
4422                                         if (res) {
4423                                                 keep_going = *res;
4424                                         }
4425                                 }
4426
4427                                 if (!keep_going) {
4428                                         throw Glib::FileError (Glib::FileError::FAILED, "copy cancelled");
4429                                 }
4430                         }
4431
4432                 }
4433
4434                 /* copy optional folders, if any */
4435
4436                 string old = plugins_dir ();
4437                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4438                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4439                         copy_files (old, newdir);
4440                 }
4441
4442                 old = externals_dir ();
4443                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4444                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4445                         copy_files (old, newdir);
4446                 }
4447
4448                 old = automation_dir ();
4449                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4450                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4451                         copy_files (old, newdir);
4452                 }
4453
4454                 if (saveas.include_media) {
4455                 
4456                         if (saveas.copy_media) {
4457 #ifndef PLATFORM_WINDOWS
4458                                 /* There are problems with analysis files on
4459                                  * Windows, because they used a colon in their
4460                                  * names as late as 4.0. Colons are not legal
4461                                  * under Windows even if NTFS allows them.
4462                                  *
4463                                  * This is a tricky problem to solve so for
4464                                  * just don't copy these files. They will be
4465                                  * regenerated as-needed anyway, subject to the 
4466                                  * existing issue that the filenames will be
4467                                  * rejected by Windows, which is a separate
4468                                  * problem (though related).
4469                                  */
4470
4471                                 /* only needed if we are copying media, since the
4472                                  * analysis data refers to media data
4473                                  */
4474                                 
4475                                 old = analysis_dir ();
4476                                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4477                                         string newdir = Glib::build_filename (to_dir, "analysis");
4478                                         copy_files (old, newdir);
4479                                 }
4480 #endif /* PLATFORM_WINDOWS */                           
4481                         }
4482                 }
4483                         
4484                 
4485                 _path = to_dir;
4486                 _current_snapshot_name = saveas.new_name;
4487                 _name = saveas.new_name;
4488
4489                 if (saveas.include_media && !saveas.copy_media) {
4490
4491                         /* reset search paths of the new session (which we're pretending to be right now) to
4492                            include the original session search path, so we can still find all audio.
4493                         */
4494
4495                         if (internal_file_cnt) {
4496                                 for (vector<string>::iterator s = old_search_path[DataType::AUDIO].begin(); s != old_search_path[DataType::AUDIO].end(); ++s) {
4497                                         ensure_search_path_includes (*s, DataType::AUDIO);
4498                                         cerr << "be sure to include " << *s << "  for audio" << endl;
4499                                 }
4500
4501                                 /* we do not do this for MIDI because we copy
4502                                    all MIDI files if saveas.include_media is
4503                                    true
4504                                 */
4505                         }
4506                 }
4507                 
4508                 bool was_dirty = dirty ();
4509
4510                 save_state ("", false, false, !saveas.include_media);
4511                 save_default_options ();
4512                 
4513                 if (saveas.copy_media && saveas.copy_external) {
4514                         if (bring_all_sources_into_session (boost::bind (&Session::save_as_bring_callback, this, _1, _2, _3))) {
4515                                 throw Glib::FileError (Glib::FileError::NO_SPACE_LEFT, "consolidate failed");
4516                         }
4517                 }
4518
4519                 saveas.final_session_folder_name = _path;
4520
4521                 store_recent_sessions (_name, _path);
4522                 
4523                 if (!saveas.switch_to) {
4524
4525                         /* switch back to the way things were */
4526
4527                         _path = old_path;
4528                         _name = old_name;
4529                         _current_snapshot_name = old_snapshot;
4530
4531                         (*_session_dir) = old_sd;
4532
4533                         if (was_dirty) {
4534                                 set_dirty ();
4535                         }
4536
4537                         if (internal_file_cnt) {
4538                                 /* reset these to their original values */
4539                                 config.set_audio_search_path (old_config_search_path[DataType::AUDIO]);
4540                                 config.set_midi_search_path (old_config_search_path[DataType::MIDI]);
4541                         }
4542                         
4543                 } else {
4544
4545                         /* prune session dirs, and update disk space statistics
4546                          */
4547
4548                         space_and_path sp;
4549                         sp.path = _path;
4550                         session_dirs.clear ();
4551                         session_dirs.push_back (sp);
4552                         refresh_disk_space ();
4553
4554                         /* ensure that all existing tracks reset their current capture source paths 
4555                          */
4556                         reset_write_sources (true, true);
4557
4558                         /* the copying above was based on actually discovering files, not just iterating over the sources list.
4559                            But if we're going to switch to the new (copied) session, we need to change the paths in the sources also.
4560                         */
4561
4562                         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
4563                                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
4564
4565                                 if (!fs) {
4566                                         continue;
4567                                 }
4568
4569                                 if (fs->within_session()) {
4570                                         string newpath = make_new_media_path (fs->path(), to_dir, new_folder);
4571                                         fs->set_path (newpath);
4572                                 }
4573                         }
4574                 }
4575
4576         } catch (Glib::FileError& e) {
4577
4578                 saveas.failure_message = e.what();
4579                 
4580                 /* recursively remove all the directories */
4581                 
4582                 remove_directory (to_dir);
4583                 
4584                 /* return error */
4585                 
4586                 return -1;
4587
4588         } catch (...) {
4589
4590                 saveas.failure_message = _("unknown reason");
4591                 
4592                 /* recursively remove all the directories */
4593                 
4594                 remove_directory (to_dir);
4595                 
4596                 /* return error */
4597                 
4598                 return -1;
4599         }
4600         
4601         return 0;
4602 }