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