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