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