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