5e07a9204ed2c524d0eefbbdbe94755248d01fa1
[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         }
3649
3650         set_dirty ();
3651 }
3652
3653 void
3654 Session::set_history_depth (uint32_t d)
3655 {
3656         _history.set_depth (d);
3657 }
3658
3659 int
3660 Session::load_diskstreams_2X (XMLNode const & node, int)
3661 {
3662         XMLNodeList          clist;
3663         XMLNodeConstIterator citer;
3664
3665         clist = node.children();
3666
3667         for (citer = clist.begin(); citer != clist.end(); ++citer) {
3668
3669                 try {
3670                         /* diskstreams added automatically by DiskstreamCreated handler */
3671                         if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3672                                 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3673                                 _diskstreams_2X.push_back (dsp);
3674                         } else {
3675                                 error << _("Session: unknown diskstream type in XML") << endmsg;
3676                         }
3677                 }
3678
3679                 catch (failed_constructor& err) {
3680                         error << _("Session: could not load diskstream via XML state") << endmsg;
3681                         return -1;
3682                 }
3683         }
3684
3685         return 0;
3686 }
3687
3688 /** Connect things to the MMC object */
3689 void
3690 Session::setup_midi_machine_control ()
3691 {
3692         _mmc = new MIDI::MachineControl;
3693         _mmc->set_ports (_midi_ports->mmc_input_port(), _midi_ports->mmc_output_port());
3694
3695         _mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3696         _mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3697         _mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3698         _mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3699         _mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3700         _mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3701         _mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3702         _mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3703         _mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3704         _mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3705         _mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3706         _mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3707         _mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3708
3709         /* also handle MIDI SPP because its so common */
3710
3711         _mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3712         _mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3713         _mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3714 }
3715
3716 boost::shared_ptr<Controllable>
3717 Session::solo_cut_control() const
3718 {
3719         /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3720            controls in Ardour that currently get presented to the user in the GUI that require
3721            access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3722
3723            its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3724            it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3725            parameter.
3726         */
3727
3728         return _solo_cut_control;
3729 }
3730
3731 int
3732 Session::rename (const std::string& new_name)
3733 {
3734         string legal_name = legalize_for_path (new_name);
3735         string new_path;
3736         string oldstr;
3737         string newstr;
3738         bool first = true;
3739
3740         string const old_sources_root = _session_dir->sources_root();
3741
3742         if (!_writable || (_state_of_the_state & CannotSave)) {
3743                 error << _("Cannot rename read-only session.") << endmsg;
3744                 return 0; // don't show "messed up" warning
3745         }
3746         if (record_status() == Recording) {
3747                 error << _("Cannot rename session while recording") << endmsg;
3748                 return 0; // don't show "messed up" warning
3749         }
3750
3751         StateProtector stp (this);
3752
3753         /* Rename:
3754
3755          * session directory
3756          * interchange subdirectory
3757          * session file
3758          * session history
3759          
3760          * Backup files are left unchanged and not renamed.
3761          */
3762
3763         /* Windows requires that we close all files before attempting the
3764          * rename. This works on other platforms, but isn't necessary there.
3765          * Leave it in place for all platforms though, since it may help
3766          * catch issues that could arise if the way Source files work ever
3767          * change (since most developers are not using Windows).
3768          */
3769
3770         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
3771                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3772                 if (fs) {
3773                         fs->close ();
3774                 }
3775         }
3776         
3777         /* pass one: not 100% safe check that the new directory names don't
3778          * already exist ...
3779          */
3780
3781         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3782                 
3783                 oldstr = (*i).path;
3784                 
3785                 /* this is a stupid hack because Glib::path_get_dirname() is
3786                  * lexical-only, and so passing it /a/b/c/ gives a different
3787                  * result than passing it /a/b/c ...
3788                  */
3789                 
3790                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3791                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3792                 }
3793                 
3794                 string base = Glib::path_get_dirname (oldstr);
3795                 
3796                 newstr = Glib::build_filename (base, legal_name);
3797                 
3798                 cerr << "Looking for " << newstr << endl;
3799                 
3800                 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3801                         cerr << " exists\n";
3802                         return -1;
3803                 }
3804         }
3805
3806         /* Session dirs */
3807
3808         first = true;
3809         
3810         for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3811
3812                 vector<string> v;
3813
3814                 oldstr = (*i).path;
3815                 
3816                 /* this is a stupid hack because Glib::path_get_dirname() is
3817                  * lexical-only, and so passing it /a/b/c/ gives a different
3818                  * result than passing it /a/b/c ...
3819                  */
3820                 
3821                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3822                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3823                 }
3824
3825                 string base = Glib::path_get_dirname (oldstr);
3826                 newstr = Glib::build_filename (base, legal_name);
3827
3828                 cerr << "for " << oldstr << " new dir = " << newstr << endl;
3829                 
3830                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3831                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3832                         cerr << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
3833                         error << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3834                         return 1;
3835                 }
3836
3837                 /* Reset path in "session dirs" */
3838                 
3839                 (*i).path = newstr;
3840                 (*i).blocks = 0;
3841                 
3842                 /* reset primary SessionDirectory object */
3843                 
3844                 if (first) {
3845                         (*_session_dir) = newstr;
3846                         new_path = newstr;
3847                         first = false;
3848                 }
3849
3850                 /* now rename directory below session_dir/interchange */
3851
3852                 string old_interchange_dir;
3853                 string new_interchange_dir;
3854
3855                 /* use newstr here because we renamed the path
3856                  * (folder/directory) that used to be oldstr to newstr above 
3857                  */     
3858                 
3859                 v.push_back (newstr); 
3860                 v.push_back (interchange_dir_name);
3861                 v.push_back (Glib::path_get_basename (oldstr));
3862
3863                 old_interchange_dir = Glib::build_filename (v);
3864
3865                 v.clear ();
3866                 v.push_back (newstr);
3867                 v.push_back (interchange_dir_name);
3868                 v.push_back (legal_name);
3869                 
3870                 new_interchange_dir = Glib::build_filename (v);
3871                 
3872                 cerr << "Rename " << old_interchange_dir << " => " << new_interchange_dir << endl;
3873                 
3874                 if (::g_rename (old_interchange_dir.c_str(), new_interchange_dir.c_str()) != 0) {
3875                         cerr << string_compose (_("renaming %s as %2 failed (%3)"),
3876                                                  old_interchange_dir, new_interchange_dir,
3877                                                  g_strerror (errno))
3878                               << endl;
3879                         error << string_compose (_("renaming %s as %2 failed (%3)"),
3880                                                  old_interchange_dir, new_interchange_dir,
3881                                                  g_strerror (errno))
3882                               << endmsg;
3883                         return 1;
3884                 }
3885         }
3886
3887         /* state file */
3888         
3889         oldstr = Glib::build_filename (new_path, _current_snapshot_name + statefile_suffix);
3890         newstr= Glib::build_filename (new_path, legal_name + statefile_suffix);
3891         
3892         cerr << "Rename " << oldstr << " => " << newstr << endl;                
3893
3894         if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3895                 cerr << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
3896                 error << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3897                 return 1;
3898         }
3899
3900         /* history file */
3901         
3902         oldstr = Glib::build_filename (new_path, _current_snapshot_name) + history_suffix;
3903
3904         if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS))  {
3905                 newstr = Glib::build_filename (new_path, legal_name) + history_suffix;
3906                 
3907                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3908                 
3909                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3910                         cerr << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
3911                         error << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3912                         return 1;
3913                 }
3914         }
3915
3916         /* remove old name from recent sessions */
3917         remove_recent_sessions (_path);
3918         _path = new_path;
3919         
3920         /* update file source paths */
3921         
3922         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3923                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3924                 if (fs) {
3925                         string p = fs->path ();
3926                         boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3927                         fs->set_path (p);
3928                         SourceFactory::setup_peakfile(i->second, true);
3929                 }
3930         }
3931
3932         _current_snapshot_name = new_name;
3933         _name = new_name;
3934         
3935         set_dirty ();
3936
3937         /* save state again to get everything just right */
3938
3939         save_state (_current_snapshot_name);
3940
3941         /* add to recent sessions */
3942
3943         store_recent_sessions (new_name, _path);
3944
3945         return 0;
3946 }
3947
3948 int
3949 Session::get_session_info_from_path (XMLTree& tree, const string& xmlpath)
3950 {
3951         if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
3952                 return -1;
3953         }
3954
3955         if (!tree.read (xmlpath)) {
3956                 return -1;
3957         }
3958
3959         return 0;
3960 }
3961
3962 int
3963 Session::get_info_from_path (const string& xmlpath, float& sample_rate, SampleFormat& data_format)
3964 {
3965         XMLTree tree;
3966         bool found_sr = false;
3967         bool found_data_format = false;
3968
3969         if (get_session_info_from_path (tree, xmlpath)) {
3970                 return -1;
3971         }
3972
3973         /* sample rate */
3974
3975         const XMLProperty* prop;
3976         if ((prop = tree.root()->property (X_("sample-rate"))) != 0) {          
3977                 sample_rate = atoi (prop->value());
3978                 found_sr = true;
3979         }
3980
3981         const XMLNodeList& children (tree.root()->children());
3982         for (XMLNodeList::const_iterator c = children.begin(); c != children.end(); ++c) {
3983                 const XMLNode* child = *c;
3984                 if (child->name() == "Config") {
3985                         const XMLNodeList& options (child->children());
3986                         for (XMLNodeList::const_iterator oc = options.begin(); oc != options.end(); ++oc) {
3987                                 const XMLNode* option = *oc;
3988                                 const XMLProperty* name = option->property("name");
3989
3990                                 if (!name) {
3991                                         continue;
3992                                 }
3993
3994                                 if (name->value() == "native-file-data-format") {
3995                                         const XMLProperty* value = option->property ("value");
3996                                         if (value) {
3997                                                 SampleFormat fmt = (SampleFormat) string_2_enum (option->property ("value")->value(), fmt);
3998                                                 data_format = fmt;
3999                                                 found_data_format = true;
4000                                                 break;
4001                                         }
4002                                 }
4003                         }
4004                 }
4005                 if (found_data_format) {
4006                         break;
4007                 }
4008         }
4009
4010         return !(found_sr && found_data_format); // zero if they are both found
4011 }
4012
4013 typedef std::vector<boost::shared_ptr<FileSource> > SeveralFileSources;
4014 typedef std::map<std::string,SeveralFileSources> SourcePathMap;
4015
4016 int
4017 Session::bring_all_sources_into_session (boost::function<void(uint32_t,uint32_t,string)> callback)
4018 {
4019         uint32_t total = 0;
4020         uint32_t n = 0;
4021         SourcePathMap source_path_map;
4022         string new_path;
4023         boost::shared_ptr<AudioFileSource> afs;
4024         int ret = 0;
4025
4026         {
4027
4028                 Glib::Threads::Mutex::Lock lm (source_lock);
4029                 
4030                 cerr << " total sources = " << sources.size();
4031                 
4032                 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
4033                         boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
4034                         
4035                         if (!fs) {
4036                                 continue;
4037                         }
4038                         
4039                         if (fs->within_session()) {
4040                                 continue;
4041                         }
4042                         
4043                         if (source_path_map.find (fs->path()) != source_path_map.end()) {
4044                                 source_path_map[fs->path()].push_back (fs);
4045                         } else {
4046                                 SeveralFileSources v;
4047                                 v.push_back (fs);
4048                                 source_path_map.insert (make_pair (fs->path(), v));
4049                         }
4050                         
4051                         total++;
4052                 }
4053                 
4054                 cerr << " fsources = " << total << endl;
4055                 
4056                 for (SourcePathMap::iterator i = source_path_map.begin(); i != source_path_map.end(); ++i) {
4057                         
4058                         /* tell caller where we are */
4059                         
4060                         string old_path = i->first;
4061                         
4062                         callback (n, total, old_path);
4063                         
4064                         cerr << old_path << endl;
4065                         
4066                         new_path.clear ();
4067                         
4068                         switch (i->second.front()->type()) {
4069                         case DataType::AUDIO:
4070                                 new_path = new_audio_source_path_for_embedded (old_path);
4071                                 break;
4072                                 
4073                         case DataType::MIDI:
4074                                 /* XXX not implemented yet */
4075                                 break;
4076                         }
4077                         
4078                         if (new_path.empty()) {
4079                                 continue;
4080                         }
4081                         
4082                         cerr << "Move " << old_path << " => " << new_path << endl;
4083                         
4084                         if (!copy_file (old_path, new_path)) {
4085                                 cerr << "failed !\n";
4086                                 ret = -1;
4087                         }
4088                         
4089                         /* make sure we stop looking in the external
4090                            dir/folder. Remember, this is an all-or-nothing
4091                            operations, it doesn't merge just some files.
4092                         */
4093                         remove_dir_from_search_path (Glib::path_get_dirname (old_path), i->second.front()->type());
4094
4095                         for (SeveralFileSources::iterator f = i->second.begin(); f != i->second.end(); ++f) {
4096                                 (*f)->set_path (new_path);
4097                         }
4098                 }
4099         }
4100
4101         save_state ("", false, false);
4102
4103         return ret;
4104 }
4105
4106 static
4107 bool accept_all_files (string const &, void *)
4108 {
4109         return true;
4110 }
4111
4112 void
4113 Session::save_as_bring_callback (uint32_t,uint32_t,string)
4114 {
4115         /* 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.
4116         */
4117 }
4118
4119 static string
4120 make_new_media_path (string old_path, string new_session_folder, string new_session_path)
4121 {
4122         /* typedir is the "midifiles" or "audiofiles" etc. part of the path. */
4123
4124         string typedir = Glib::path_get_basename (Glib::path_get_dirname (old_path));
4125         vector<string> v;
4126         v.push_back (new_session_folder); /* full path */
4127         v.push_back (interchange_dir_name);
4128         v.push_back (new_session_path);   /* just one directory/folder */
4129         v.push_back (typedir);
4130         v.push_back (Glib::path_get_basename (old_path));
4131         
4132         return Glib::build_filename (v);
4133 }
4134
4135 int
4136 Session::save_as (SaveAs& saveas)
4137 {
4138         vector<string> files;
4139         string current_folder = Glib::path_get_dirname (_path);
4140         string new_folder = legalize_for_path (saveas.new_name);
4141         string to_dir = Glib::build_filename (saveas.new_parent_folder, new_folder);
4142         int64_t total_bytes = 0;
4143         int64_t copied = 0;
4144         int64_t cnt = 0;
4145         int64_t all = 0;
4146         int32_t internal_file_cnt = 0;
4147
4148         vector<string> do_not_copy_extensions;
4149         do_not_copy_extensions.push_back (statefile_suffix);
4150         do_not_copy_extensions.push_back (pending_suffix);
4151         do_not_copy_extensions.push_back (backup_suffix);
4152         do_not_copy_extensions.push_back (temp_suffix);
4153         do_not_copy_extensions.push_back (history_suffix);
4154
4155         /* get total size */
4156
4157         for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
4158                 
4159                 /* need to clear this because
4160                  * find_files_matching_filter() is cumulative
4161                  */
4162                 
4163                 files.clear ();
4164                 
4165                 find_files_matching_filter (files, (*sd).path, accept_all_files, 0, false, true, true);
4166                 
4167                 all += files.size();
4168
4169                 for (vector<string>::iterator i = files.begin(); i != files.end(); ++i) {
4170                         GStatBuf gsb;
4171                         g_stat ((*i).c_str(), &gsb);
4172                         total_bytes += gsb.st_size;
4173                 }
4174         }
4175
4176         /* save old values so we can switch back if we are not switching to the new session */
4177         
4178         string old_path = _path;
4179         string old_name = _name;
4180         string old_snapshot = _current_snapshot_name;
4181         string old_sd = _session_dir->root_path();
4182         vector<string> old_search_path[DataType::num_types];
4183         string old_config_search_path[DataType::num_types];
4184
4185         old_search_path[DataType::AUDIO] = source_search_path (DataType::AUDIO);
4186         old_search_path[DataType::MIDI] = source_search_path (DataType::MIDI);
4187         old_config_search_path[DataType::AUDIO]  = config.get_audio_search_path ();     
4188         old_config_search_path[DataType::MIDI]  = config.get_midi_search_path ();       
4189
4190         /* switch session directory */
4191         
4192         (*_session_dir) = to_dir;
4193
4194         /* create new tree */
4195         
4196         if (!_session_dir->create()) {
4197                 saveas.failure_message = string_compose (_("Cannot create new session folder %1"), to_dir);
4198                 return -1;
4199         }
4200
4201         try {
4202                 /* copy all relevant files. Find each location in session_dirs,
4203                  * and copy files from there to target.
4204                  */
4205                 
4206                 for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
4207                         
4208                         /* need to clear this because
4209                          * find_files_matching_filter() is cumulative
4210                          */
4211                         
4212                         files.clear ();
4213                         
4214                         const size_t prefix_len = (*sd).path.size();
4215                         
4216                         /* Work just on the files within this session dir */
4217                         
4218                         find_files_matching_filter (files, (*sd).path, accept_all_files, 0, false, true, true);
4219                         
4220                         /* add dir separator to protect against collisions with
4221                          * track names (e.g. track named "audiofiles" or
4222                          * "analysis".
4223                          */
4224
4225                         static const std::string audiofile_dir_string = string (sound_dir_name) + G_DIR_SEPARATOR;
4226                         static const std::string midifile_dir_string = string (midi_dir_name) + G_DIR_SEPARATOR;
4227                         static const std::string analysis_dir_string = analysis_dir() + G_DIR_SEPARATOR;
4228
4229                         /* copy all the files. Handling is different for media files
4230                            than others because of the *silly* subtree we have below the interchange
4231                            folder. That really was a bad idea, but I'm not fixing it as part of
4232                            implementing ::save_as().
4233                         */
4234                         
4235                         for (vector<string>::iterator i = files.begin(); i != files.end(); ++i) {
4236
4237                                 std::string from = *i;
4238
4239 #ifdef __APPLE__
4240                                 string filename = Glib::path_get_basename (from);
4241                                 std::transform (filename.begin(), filename.end(), filename.begin(), ::toupper);
4242                                 if (filename == ".DS_STORE") {
4243                                         continue;
4244                                 }
4245 #endif
4246                                 
4247                                 if (from.find (audiofile_dir_string) != string::npos) {
4248                                         
4249                                         /* audio file: only copy if asked */
4250
4251                                         if (saveas.include_media && saveas.copy_media) {
4252                                                 
4253                                                 string to = make_new_media_path (*i, to_dir, new_folder);
4254
4255                                                 info << "media file copying from " << from << " to " << to << endmsg;
4256                                                 
4257                                                 if (!copy_file (from, to)) {
4258                                                         throw Glib::FileError (Glib::FileError::IO_ERROR,
4259                                                                                                    string_compose(_("\ncopying \"%1\" failed !"), from));
4260                                                 }
4261                                         }
4262                                         
4263                                         /* we found media files inside the session folder */
4264                                         
4265                                         internal_file_cnt++;
4266
4267                                 } else if (from.find (midifile_dir_string) != string::npos) {
4268
4269                                         /* midi file: always copy unless
4270                                          * creating an empty new session
4271                                          */
4272
4273                                         if (saveas.include_media) {
4274                                         
4275                                                 string to = make_new_media_path (*i, to_dir, new_folder);
4276                                                 
4277                                                 info << "media file copying from " << from << " to " << to << endmsg;
4278                                                 
4279                                                 if (!copy_file (from, to)) {
4280                                                         throw Glib::FileError (Glib::FileError::IO_ERROR, "copy failed");
4281                                                 }
4282                                         }
4283
4284                                         /* we found media files inside the session folder */
4285                                                 
4286                                         internal_file_cnt++;
4287                                         
4288                                 } else if (from.find (analysis_dir_string) != string::npos) {
4289
4290                                         /*  make sure analysis dir exists in
4291                                          *  new session folder, but we're not
4292                                          *  copying analysis files here, see
4293                                          *  below 
4294                                          */
4295                                         
4296                                         (void) g_mkdir_with_parents (analysis_dir().c_str(), 775);
4297                                         continue;
4298                                         
4299                                 } else {
4300                                         
4301                                         /* normal non-media file. Don't copy state, history, etc.
4302                                          */
4303                                         
4304                                         bool do_copy = true;
4305                                         
4306                                         for (vector<string>::iterator v = do_not_copy_extensions.begin(); v != do_not_copy_extensions.end(); ++v) {
4307                                                 if ((from.length() > (*v).length()) && (from.find (*v) == from.length() - (*v).length())) {
4308                                                         /* end of filename matches extension, do not copy file */
4309                                                         do_copy = false;
4310                                                         break;
4311                                                 } 
4312                                         }
4313
4314                                         if (!saveas.copy_media && from.find (peakfile_suffix) != string::npos) {
4315                                                 /* don't copy peakfiles if
4316                                                  * we're not copying media
4317                                                  */
4318                                                 do_copy = false;
4319                                         }
4320                                         
4321                                         if (do_copy) {
4322                                                 string to = Glib::build_filename (to_dir, from.substr (prefix_len));
4323                                                 
4324                                                 info << "attempting to make directory/folder " << to << endmsg;
4325
4326                                                 if (g_mkdir_with_parents (Glib::path_get_dirname (to).c_str(), 0755)) {
4327                                                         throw Glib::FileError (Glib::FileError::IO_ERROR, "cannot create required directory");
4328                                                 }
4329
4330                                                 info << "attempting to copy " << from << " to " << to << endmsg;
4331                                                 
4332                                                 if (!copy_file (from, to)) {
4333                                                         throw Glib::FileError (Glib::FileError::IO_ERROR,
4334                                                                                                    string_compose(_("\ncopying \"%1\" failed !"), from));
4335                                                 }
4336                                         }
4337                                 }
4338                                 
4339                                 /* measure file size even if we're not going to copy so that our Progress
4340                                    signals are correct, since we included these do-not-copy files
4341                                    in the computation of the total size and file count.
4342                                 */
4343                                 
4344                                 GStatBuf gsb;
4345                                 g_stat (from.c_str(), &gsb);
4346                                 copied += gsb.st_size;
4347                                 cnt++;
4348                                 
4349                                 double fraction = (double) copied / total_bytes;
4350                                 
4351                                 bool keep_going = true;
4352
4353                                 if (saveas.copy_media) {
4354
4355                                         /* no need or expectation of this if
4356                                          * media is not being copied, because
4357                                          * it will be fast(ish).
4358                                          */
4359                                         
4360                                         /* tell someone "X percent, file M of N"; M is one-based */
4361                                         
4362                                         boost::optional<bool> res = saveas.Progress (fraction, cnt, all);
4363                                         
4364                                         if (res) {
4365                                                 keep_going = *res;
4366                                         }
4367                                 }
4368
4369                                 if (!keep_going) {
4370                                         throw Glib::FileError (Glib::FileError::FAILED, "copy cancelled");
4371                                 }
4372                         }
4373
4374                 }
4375
4376                 /* copy optional folders, if any */
4377
4378                 string old = plugins_dir ();
4379                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4380                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4381                         copy_files (old, newdir);
4382                 }
4383
4384                 old = externals_dir ();
4385                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4386                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4387                         copy_files (old, newdir);
4388                 }
4389
4390                 old = automation_dir ();
4391                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4392                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4393                         copy_files (old, newdir);
4394                 }
4395
4396                 if (saveas.include_media) {
4397                 
4398                         if (saveas.copy_media) {
4399 #ifndef PLATFORM_WINDOWS
4400                                 /* There are problems with analysis files on
4401                                  * Windows, because they used a colon in their
4402                                  * names as late as 4.0. Colons are not legal
4403                                  * under Windows even if NTFS allows them.
4404                                  *
4405                                  * This is a tricky problem to solve so for
4406                                  * just don't copy these files. They will be
4407                                  * regenerated as-needed anyway, subject to the 
4408                                  * existing issue that the filenames will be
4409                                  * rejected by Windows, which is a separate
4410                                  * problem (though related).
4411                                  */
4412
4413                                 /* only needed if we are copying media, since the
4414                                  * analysis data refers to media data
4415                                  */
4416                                 
4417                                 old = analysis_dir ();
4418                                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4419                                         string newdir = Glib::build_filename (to_dir, "analysis");
4420                                         copy_files (old, newdir);
4421                                 }
4422 #endif /* PLATFORM_WINDOWS */                           
4423                         }
4424                 }
4425                         
4426                 
4427                 _path = to_dir;
4428                 _current_snapshot_name = saveas.new_name;
4429                 _name = saveas.new_name;
4430
4431                 if (saveas.include_media && !saveas.copy_media) {
4432
4433                         /* reset search paths of the new session (which we're pretending to be right now) to
4434                            include the original session search path, so we can still find all audio.
4435                         */
4436
4437                         if (internal_file_cnt) {
4438                                 for (vector<string>::iterator s = old_search_path[DataType::AUDIO].begin(); s != old_search_path[DataType::AUDIO].end(); ++s) {
4439                                         ensure_search_path_includes (*s, DataType::AUDIO);
4440                                 }
4441
4442                                 /* we do not do this for MIDI because we copy
4443                                    all MIDI files if saveas.include_media is
4444                                    true
4445                                 */
4446                         }
4447                 }
4448                 
4449                 bool was_dirty = dirty ();
4450
4451                 save_state ("", false, false, !saveas.include_media);
4452                 save_default_options ();
4453                 
4454                 if (saveas.copy_media && saveas.copy_external) {
4455                         if (bring_all_sources_into_session (boost::bind (&Session::save_as_bring_callback, this, _1, _2, _3))) {
4456                                 throw Glib::FileError (Glib::FileError::NO_SPACE_LEFT, "consolidate failed");
4457                         }
4458                 }
4459
4460                 saveas.final_session_folder_name = _path;
4461
4462                 store_recent_sessions (_name, _path);
4463                 
4464                 if (!saveas.switch_to) {
4465
4466                         /* switch back to the way things were */
4467
4468                         _path = old_path;
4469                         _name = old_name;
4470                         _current_snapshot_name = old_snapshot;
4471
4472                         (*_session_dir) = old_sd;
4473
4474                         if (was_dirty) {
4475                                 set_dirty ();
4476                         }
4477
4478                         if (internal_file_cnt) {
4479                                 /* reset these to their original values */
4480                                 config.set_audio_search_path (old_config_search_path[DataType::AUDIO]);
4481                                 config.set_midi_search_path (old_config_search_path[DataType::MIDI]);
4482                         }
4483                         
4484                 } else {
4485
4486                         /* prune session dirs, and update disk space statistics
4487                          */
4488
4489                         space_and_path sp;
4490                         sp.path = _path;
4491                         session_dirs.clear ();
4492                         session_dirs.push_back (sp);
4493                         refresh_disk_space ();
4494
4495                         /* ensure that all existing tracks reset their current capture source paths 
4496                          */
4497                         reset_write_sources (true, true);
4498
4499                         /* the copying above was based on actually discovering files, not just iterating over the sources list.
4500                            But if we're going to switch to the new (copied) session, we need to change the paths in the sources also.
4501                         */
4502
4503                         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
4504                                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
4505
4506                                 if (!fs) {
4507                                         continue;
4508                                 }
4509
4510                                 if (fs->within_session()) {
4511                                         string newpath = make_new_media_path (fs->path(), to_dir, new_folder);
4512                                         fs->set_path (newpath);
4513                                 }
4514                         }
4515                 }
4516
4517         } catch (Glib::FileError& e) {
4518
4519                 saveas.failure_message = e.what();
4520                 
4521                 /* recursively remove all the directories */
4522                 
4523                 remove_directory (to_dir);
4524                 
4525                 /* return error */
4526                 
4527                 return -1;
4528
4529         } catch (...) {
4530
4531                 saveas.failure_message = _("unknown reason");
4532                 
4533                 /* recursively remove all the directories */
4534                 
4535                 remove_directory (to_dir);
4536                 
4537                 /* return error */
4538                 
4539                 return -1;
4540         }
4541         
4542         return 0;
4543 }