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