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