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