push seek-after-state-loaded into butler thread, to avoid multiple threads doing...
[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                                         sources.erase (i);
2893                                         
2894                                         // also remove source from all_sources
2895                                         
2896                                         for (set<string>::iterator j = all_sources.begin(); j != all_sources.end(); ++j) {
2897                                                 spath = Glib::path_get_basename (*j);
2898                                                 if ( spath == i->second->name () ) {
2899                                                         all_sources.erase (j);
2900                                                         break;
2901                                                 }
2902                                         }
2903                                 }
2904                         }
2905                 }
2906
2907                 i = tmp;
2908         }
2909
2910         for (vector<string>::iterator x = candidates.begin(); x != candidates.end(); ++x) {
2911
2912                 used = false;
2913                 spath = *x;
2914
2915                 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2916
2917                         tmppath1 = canonical_path (spath);
2918                         tmppath2 = canonical_path ((*i));
2919
2920                         if (tmppath1 == tmppath2) {
2921                                 used = true;
2922                                 break;
2923                         }
2924                 }
2925
2926                 if (!used) {
2927                         unused.push_back (spath);
2928                 }
2929         }
2930
2931         /* now try to move all unused files into the "dead" directory(ies) */
2932
2933         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2934                 struct stat statbuf;
2935
2936                 string newpath;
2937
2938                 /* don't move the file across filesystems, just
2939                    stick it in the `dead_dir_name' directory
2940                    on whichever filesystem it was already on.
2941                 */
2942
2943                 if ((*x).find ("/sounds/") != string::npos) {
2944
2945                         /* old school, go up 1 level */
2946
2947                         newpath = Glib::path_get_dirname (*x);      // "sounds"
2948                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2949
2950                 } else {
2951
2952                         /* new school, go up 4 levels */
2953
2954                         newpath = Glib::path_get_dirname (*x);      // "audiofiles" or "midifiles"
2955                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2956                         newpath = Glib::path_get_dirname (newpath); // "interchange"
2957                         newpath = Glib::path_get_dirname (newpath); // "session-dir"
2958                 }
2959
2960                 newpath = Glib::build_filename (newpath, dead_dir_name);
2961
2962                 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2963                         error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2964                         return -1;
2965                 }
2966
2967                 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2968
2969                 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2970
2971                         /* the new path already exists, try versioning */
2972
2973                         char buf[PATH_MAX+1];
2974                         int version = 1;
2975                         string newpath_v;
2976
2977                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2978                         newpath_v = buf;
2979
2980                         while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2981                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2982                                 newpath_v = buf;
2983                         }
2984
2985                         if (version == 999) {
2986                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2987                                                   newpath)
2988                                       << endmsg;
2989                         } else {
2990                                 newpath = newpath_v;
2991                         }
2992
2993                 } else {
2994
2995                         /* it doesn't exist, or we can't read it or something */
2996
2997                 }
2998
2999                 stat ((*x).c_str(), &statbuf);
3000
3001                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
3002                         error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
3003                                           (*x), newpath, strerror (errno))
3004                               << endmsg;
3005                         goto out;
3006                 }
3007
3008                 /* see if there an easy to find peakfile for this file, and remove it.
3009                  */
3010
3011                 string base = basename_nosuffix (*x);
3012                 base += "%A"; /* this is what we add for the channel suffix of all native files,
3013                                  or for the first channel of embedded files. it will miss
3014                                  some peakfiles for other channels
3015                               */
3016                 string peakpath = peak_path (base);
3017
3018                 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
3019                         if (::g_unlink (peakpath.c_str()) != 0) {
3020                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
3021                                                          peakpath, _path, strerror (errno))
3022                                       << endmsg;
3023                                 /* try to back out */
3024                                 ::rename (newpath.c_str(), _path.c_str());
3025                                 goto out;
3026                         }
3027                 }
3028
3029                 rep.paths.push_back (*x);
3030                 rep.space += statbuf.st_size;
3031         }
3032
3033         /* dump the history list */
3034
3035         _history.clear ();
3036
3037         /* save state so we don't end up a session file
3038            referring to non-existent sources.
3039         */
3040
3041         save_state ("");
3042         ret = 0;
3043
3044   out:
3045         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
3046
3047         return ret;
3048 }
3049
3050 int
3051 Session::cleanup_trash_sources (CleanupReport& rep)
3052 {
3053         // FIXME: needs adaptation for MIDI
3054
3055         vector<space_and_path>::iterator i;
3056         string dead_dir;
3057
3058         rep.paths.clear ();
3059         rep.space = 0;
3060
3061         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3062
3063                 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
3064
3065                 clear_directory (dead_dir, &rep.space, &rep.paths);
3066         }
3067
3068         return 0;
3069 }
3070
3071 void
3072 Session::set_dirty ()
3073 {
3074         /* never mark session dirty during loading */
3075
3076         if (_state_of_the_state & Loading) {
3077                 return;
3078         }
3079
3080         bool was_dirty = dirty();
3081
3082         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3083
3084
3085         if (!was_dirty) {
3086                 DirtyChanged(); /* EMIT SIGNAL */
3087         }
3088 }
3089
3090
3091 void
3092 Session::set_clean ()
3093 {
3094         bool was_dirty = dirty();
3095
3096         _state_of_the_state = Clean;
3097
3098
3099         if (was_dirty) {
3100                 DirtyChanged(); /* EMIT SIGNAL */
3101         }
3102 }
3103
3104 void
3105 Session::set_deletion_in_progress ()
3106 {
3107         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3108 }
3109
3110 void
3111 Session::clear_deletion_in_progress ()
3112 {
3113         _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3114 }
3115
3116 void
3117 Session::add_controllable (boost::shared_ptr<Controllable> c)
3118 {
3119         /* this adds a controllable to the list managed by the Session.
3120            this is a subset of those managed by the Controllable class
3121            itself, and represents the only ones whose state will be saved
3122            as part of the session.
3123         */
3124
3125         Glib::Threads::Mutex::Lock lm (controllables_lock);
3126         controllables.insert (c);
3127 }
3128
3129 struct null_deleter { void operator()(void const *) const {} };
3130
3131 void
3132 Session::remove_controllable (Controllable* c)
3133 {
3134         if (_state_of_the_state & Deletion) {
3135                 return;
3136         }
3137
3138         Glib::Threads::Mutex::Lock lm (controllables_lock);
3139
3140         Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3141
3142         if (x != controllables.end()) {
3143                 controllables.erase (x);
3144         }
3145 }
3146
3147 boost::shared_ptr<Controllable>
3148 Session::controllable_by_id (const PBD::ID& id)
3149 {
3150         Glib::Threads::Mutex::Lock lm (controllables_lock);
3151
3152         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3153                 if ((*i)->id() == id) {
3154                         return *i;
3155                 }
3156         }
3157
3158         return boost::shared_ptr<Controllable>();
3159 }
3160
3161 boost::shared_ptr<Controllable>
3162 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3163 {
3164         boost::shared_ptr<Controllable> c;
3165         boost::shared_ptr<Route> r;
3166
3167         switch (desc.top_level_type()) {
3168         case ControllableDescriptor::NamedRoute:
3169         {
3170                 std::string str = desc.top_level_name();
3171                 if (str == "Master" || str == "master") {
3172                         r = _master_out;
3173                 } else if (str == "control" || str == "listen") {
3174                         r = _monitor_out;
3175                 } else {
3176                         r = route_by_name (desc.top_level_name());
3177                 }
3178                 break;
3179         }
3180
3181         case ControllableDescriptor::RemoteControlID:
3182                 r = route_by_remote_id (desc.rid());
3183                 break;
3184         }
3185
3186         if (!r) {
3187                 return c;
3188         }
3189
3190         switch (desc.subtype()) {
3191         case ControllableDescriptor::Gain:
3192                 c = r->gain_control ();
3193                 break;
3194
3195         case ControllableDescriptor::Trim:
3196                 c = r->trim()->gain_control ();
3197                 break;
3198
3199         case ControllableDescriptor::Solo:
3200                 c = r->solo_control();
3201                 break;
3202
3203         case ControllableDescriptor::Mute:
3204                 c = r->mute_control();
3205                 break;
3206
3207         case ControllableDescriptor::Recenable:
3208         {
3209                 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3210
3211                 if (t) {
3212                         c = t->rec_enable_control ();
3213                 }
3214                 break;
3215         }
3216
3217         case ControllableDescriptor::PanDirection:
3218         {
3219                 c = r->pannable()->pan_azimuth_control;
3220                 break;
3221         }
3222
3223         case ControllableDescriptor::PanWidth:
3224         {
3225                 c = r->pannable()->pan_width_control;
3226                 break;
3227         }
3228
3229         case ControllableDescriptor::PanElevation:
3230         {
3231                 c = r->pannable()->pan_elevation_control;
3232                 break;
3233         }
3234
3235         case ControllableDescriptor::Balance:
3236                 /* XXX simple pan control */
3237                 break;
3238
3239         case ControllableDescriptor::PluginParameter:
3240         {
3241                 uint32_t plugin = desc.target (0);
3242                 uint32_t parameter_index = desc.target (1);
3243
3244                 /* revert to zero based counting */
3245
3246                 if (plugin > 0) {
3247                         --plugin;
3248                 }
3249
3250                 if (parameter_index > 0) {
3251                         --parameter_index;
3252                 }
3253
3254                 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3255
3256                 if (p) {
3257                         c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3258                                 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3259                 }
3260                 break;
3261         }
3262
3263         case ControllableDescriptor::SendGain:
3264         {
3265                 uint32_t send = desc.target (0);
3266
3267                 /* revert to zero-based counting */
3268
3269                 if (send > 0) {
3270                         --send;
3271                 }
3272
3273                 boost::shared_ptr<Processor> p = r->nth_send (send);
3274
3275                 if (p) {
3276                         boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3277                         boost::shared_ptr<Amp> a = s->amp();
3278                         
3279                         if (a) {
3280                                 c = s->amp()->gain_control();
3281                         }
3282                 }
3283                 break;
3284         }
3285
3286         default:
3287                 /* relax and return a null pointer */
3288                 break;
3289         }
3290
3291         return c;
3292 }
3293
3294 void
3295 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3296 {
3297         if (_writable) {
3298                 Stateful::add_instant_xml (node, _path);
3299         }
3300
3301         if (write_to_config) {
3302                 Config->add_instant_xml (node);
3303         }
3304 }
3305
3306 XMLNode*
3307 Session::instant_xml (const string& node_name)
3308 {
3309         return Stateful::instant_xml (node_name, _path);
3310 }
3311
3312 int
3313 Session::save_history (string snapshot_name)
3314 {
3315         XMLTree tree;
3316
3317         if (!_writable) {
3318                 return 0;
3319         }
3320
3321         if (!Config->get_save_history() || Config->get_saved_history_depth() < 0 || 
3322             (_history.undo_depth() == 0 && _history.redo_depth() == 0)) {
3323                 return 0;
3324         }
3325
3326         if (snapshot_name.empty()) {
3327                 snapshot_name = _current_snapshot_name;
3328         }
3329
3330         const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3331         const string backup_filename = history_filename + backup_suffix;
3332         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3333         const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3334
3335         if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3336                 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3337                         error << _("could not backup old history file, current history not saved") << endmsg;
3338                         return -1;
3339                 }
3340         }
3341
3342         tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3343
3344         if (!tree.write (xml_path))
3345         {
3346                 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3347
3348                 if (g_remove (xml_path.c_str()) != 0) {
3349                         error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3350                                         xml_path, g_strerror (errno)) << endmsg;
3351                 }
3352                 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3353                         error << string_compose (_("could not restore history file from backup %1 (%2)"),
3354                                         backup_path, g_strerror (errno)) << endmsg;
3355                 }
3356
3357                 return -1;
3358         }
3359
3360         return 0;
3361 }
3362
3363 int
3364 Session::restore_history (string snapshot_name)
3365 {
3366         XMLTree tree;
3367
3368         if (snapshot_name.empty()) {
3369                 snapshot_name = _current_snapshot_name;
3370         }
3371
3372         const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3373         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3374
3375         info << "Loading history from " << xml_path << endmsg;
3376
3377         if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3378                 info << string_compose (_("%1: no history file \"%2\" for this session."),
3379                                 _name, xml_path) << endmsg;
3380                 return 1;
3381         }
3382
3383         if (!tree.read (xml_path)) {
3384                 error << string_compose (_("Could not understand session history file \"%1\""),
3385                                 xml_path) << endmsg;
3386                 return -1;
3387         }
3388
3389         // replace history
3390         _history.clear();
3391
3392         for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3393
3394                 XMLNode *t = *it;
3395                 UndoTransaction* ut = new UndoTransaction ();
3396                 struct timeval tv;
3397
3398                 ut->set_name(t->property("name")->value());
3399                 stringstream ss(t->property("tv-sec")->value());
3400                 ss >> tv.tv_sec;
3401                 ss.str(t->property("tv-usec")->value());
3402                 ss >> tv.tv_usec;
3403                 ut->set_timestamp(tv);
3404
3405                 for (XMLNodeConstIterator child_it  = t->children().begin();
3406                                 child_it != t->children().end(); child_it++)
3407                 {
3408                         XMLNode *n = *child_it;
3409                         Command *c;
3410
3411                         if (n->name() == "MementoCommand" ||
3412                                         n->name() == "MementoUndoCommand" ||
3413                                         n->name() == "MementoRedoCommand") {
3414
3415                                 if ((c = memento_command_factory(n))) {
3416                                         ut->add_command(c);
3417                                 }
3418
3419                         } else if (n->name() == "NoteDiffCommand") {
3420                                 PBD::ID id (n->property("midi-source")->value());
3421                                 boost::shared_ptr<MidiSource> midi_source =
3422                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3423                                 if (midi_source) {
3424                                         ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3425                                 } else {
3426                                         error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3427                                 }
3428
3429                         } else if (n->name() == "SysExDiffCommand") {
3430
3431                                 PBD::ID id (n->property("midi-source")->value());
3432                                 boost::shared_ptr<MidiSource> midi_source =
3433                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3434                                 if (midi_source) {
3435                                         ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3436                                 } else {
3437                                         error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3438                                 }
3439
3440                         } else if (n->name() == "PatchChangeDiffCommand") {
3441
3442                                 PBD::ID id (n->property("midi-source")->value());
3443                                 boost::shared_ptr<MidiSource> midi_source =
3444                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3445                                 if (midi_source) {
3446                                         ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3447                                 } else {
3448                                         error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3449                                 }
3450
3451                         } else if (n->name() == "StatefulDiffCommand") {
3452                                 if ((c = stateful_diff_command_factory (n))) {
3453                                         ut->add_command (c);
3454                                 }
3455                         } else {
3456                                 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3457                         }
3458                 }
3459
3460                 _history.add (ut);
3461         }
3462
3463         return 0;
3464 }
3465
3466 void
3467 Session::config_changed (std::string p, bool ours)
3468 {
3469         if (ours) {
3470                 set_dirty ();
3471         }
3472
3473         if (p == "seamless-loop") {
3474
3475         } else if (p == "rf-speed") {
3476
3477         } else if (p == "auto-loop") {
3478
3479         } else if (p == "auto-input") {
3480
3481                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3482                         /* auto-input only makes a difference if we're rolling */
3483                         set_track_monitor_input_status (!config.get_auto_input());
3484                 }
3485
3486         } else if (p == "punch-in") {
3487
3488                 Location* location;
3489
3490                 if ((location = _locations->auto_punch_location()) != 0) {
3491
3492                         if (config.get_punch_in ()) {
3493                                 replace_event (SessionEvent::PunchIn, location->start());
3494                         } else {
3495                                 remove_event (location->start(), SessionEvent::PunchIn);
3496                         }
3497                 }
3498
3499         } else if (p == "punch-out") {
3500
3501                 Location* location;
3502
3503                 if ((location = _locations->auto_punch_location()) != 0) {
3504
3505                         if (config.get_punch_out()) {
3506                                 replace_event (SessionEvent::PunchOut, location->end());
3507                         } else {
3508                                 clear_events (SessionEvent::PunchOut);
3509                         }
3510                 }
3511
3512         } else if (p == "edit-mode") {
3513
3514                 Glib::Threads::Mutex::Lock lm (playlists->lock);
3515
3516                 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3517                         (*i)->set_edit_mode (Config->get_edit_mode ());
3518                 }
3519
3520         } else if (p == "use-video-sync") {
3521
3522                 waiting_for_sync_offset = config.get_use_video_sync();
3523
3524         } else if (p == "mmc-control") {
3525
3526                 //poke_midi_thread ();
3527
3528         } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3529
3530                 _mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3531
3532         } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3533
3534                 _mmc->set_send_device_id (Config->get_mmc_send_device_id());
3535
3536         } else if (p == "midi-control") {
3537
3538                 //poke_midi_thread ();
3539
3540         } else if (p == "raid-path") {
3541
3542                 setup_raid_path (config.get_raid_path());
3543
3544         } else if (p == "timecode-format") {
3545
3546                 sync_time_vars ();
3547
3548         } else if (p == "video-pullup") {
3549
3550                 sync_time_vars ();
3551
3552         } else if (p == "seamless-loop") {
3553
3554                 if (play_loop && transport_rolling()) {
3555                         // to reset diskstreams etc
3556                         request_play_loop (true);
3557                 }
3558
3559         } else if (p == "rf-speed") {
3560
3561                 cumulative_rf_motion = 0;
3562                 reset_rf_scale (0);
3563
3564         } else if (p == "click-sound") {
3565
3566                 setup_click_sounds (1);
3567
3568         } else if (p == "click-emphasis-sound") {
3569
3570                 setup_click_sounds (-1);
3571
3572         } else if (p == "clicking") {
3573
3574                 if (Config->get_clicking()) {
3575                         if (_click_io && click_data) { // don't require emphasis data
3576                                 _clicking = true;
3577                         }
3578                 } else {
3579                         _clicking = false;
3580                 }
3581
3582         } else if (p == "click-gain") {
3583                 
3584                 if (_click_gain) {
3585                         _click_gain->set_gain (Config->get_click_gain(), this);
3586                 }
3587
3588         } else if (p == "send-mtc") {
3589
3590                 if (Config->get_send_mtc ()) {
3591                         /* mark us ready to send */
3592                         next_quarter_frame_to_send = 0;
3593                 }
3594
3595         } else if (p == "send-mmc") {
3596
3597                 _mmc->enable_send (Config->get_send_mmc ());
3598
3599         } else if (p == "midi-feedback") {
3600
3601                 session_midi_feedback = Config->get_midi_feedback();
3602
3603         } else if (p == "jack-time-master") {
3604
3605                 engine().reset_timebase ();
3606
3607         } else if (p == "native-file-header-format") {
3608
3609                 if (!first_file_header_format_reset) {
3610                         reset_native_file_format ();
3611                 }
3612
3613                 first_file_header_format_reset = false;
3614
3615         } else if (p == "native-file-data-format") {
3616
3617                 if (!first_file_data_format_reset) {
3618                         reset_native_file_format ();
3619                 }
3620
3621                 first_file_data_format_reset = false;
3622
3623         } else if (p == "external-sync") {
3624                 if (!config.get_external_sync()) {
3625                         drop_sync_source ();
3626                 } else {
3627                         switch_to_sync_source (Config->get_sync_source());
3628                 }
3629         }  else if (p == "denormal-model") {
3630                 setup_fpu ();
3631         } else if (p == "history-depth") {
3632                 set_history_depth (Config->get_history_depth());
3633         } else if (p == "remote-model") {
3634                 /* XXX DO SOMETHING HERE TO TELL THE GUI THAT WE NEED
3635                    TO SET REMOTE ID'S
3636                 */
3637         } else if (p == "initial-program-change") {
3638
3639                 if (_mmc->output_port() && Config->get_initial_program_change() >= 0) {
3640                         MIDI::byte buf[2];
3641
3642                         buf[0] = MIDI::program; // channel zero by default
3643                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3644
3645                         _mmc->output_port()->midimsg (buf, sizeof (buf), 0);
3646                 }
3647         } else if (p == "solo-mute-override") {
3648                 // catch_up_on_solo_mute_override ();
3649         } else if (p == "listen-position" || p == "pfl-position") {
3650                 listen_position_changed ();
3651         } else if (p == "solo-control-is-listen-control") {
3652                 solo_control_mode_changed ();
3653         } else if (p == "solo-mute-gain") {
3654                 _solo_cut_control->Changed();
3655         } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3656                 last_timecode_valid = false;
3657         } else if (p == "playback-buffer-seconds") {
3658                 AudioSource::allocate_working_buffers (frame_rate());
3659         } else if (p == "ltc-source-port") {
3660                 reconnect_ltc_input ();
3661         } else if (p == "ltc-sink-port") {
3662                 reconnect_ltc_output ();
3663         } else if (p == "timecode-generator-offset") {
3664                 ltc_tx_parse_offset();
3665         } else if (p == "auto-return-target-list") {
3666                 follow_playhead_priority ();
3667         }
3668
3669         set_dirty ();
3670 }
3671
3672 void
3673 Session::set_history_depth (uint32_t d)
3674 {
3675         _history.set_depth (d);
3676 }
3677
3678 int
3679 Session::load_diskstreams_2X (XMLNode const & node, int)
3680 {
3681         XMLNodeList          clist;
3682         XMLNodeConstIterator citer;
3683
3684         clist = node.children();
3685
3686         for (citer = clist.begin(); citer != clist.end(); ++citer) {
3687
3688                 try {
3689                         /* diskstreams added automatically by DiskstreamCreated handler */
3690                         if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3691                                 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3692                                 _diskstreams_2X.push_back (dsp);
3693                         } else {
3694                                 error << _("Session: unknown diskstream type in XML") << endmsg;
3695                         }
3696                 }
3697
3698                 catch (failed_constructor& err) {
3699                         error << _("Session: could not load diskstream via XML state") << endmsg;
3700                         return -1;
3701                 }
3702         }
3703
3704         return 0;
3705 }
3706
3707 /** Connect things to the MMC object */
3708 void
3709 Session::setup_midi_machine_control ()
3710 {
3711         _mmc = new MIDI::MachineControl;
3712         _mmc->set_ports (_midi_ports->mmc_input_port(), _midi_ports->mmc_output_port());
3713
3714         _mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3715         _mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3716         _mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3717         _mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3718         _mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3719         _mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3720         _mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3721         _mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3722         _mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3723         _mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3724         _mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3725         _mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3726         _mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3727
3728         /* also handle MIDI SPP because its so common */
3729
3730         _mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3731         _mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3732         _mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3733 }
3734
3735 boost::shared_ptr<Controllable>
3736 Session::solo_cut_control() const
3737 {
3738         /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3739            controls in Ardour that currently get presented to the user in the GUI that require
3740            access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3741
3742            its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3743            it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3744            parameter.
3745         */
3746
3747         return _solo_cut_control;
3748 }
3749
3750 int
3751 Session::rename (const std::string& new_name)
3752 {
3753         string legal_name = legalize_for_path (new_name);
3754         string new_path;
3755         string oldstr;
3756         string newstr;
3757         bool first = true;
3758
3759         string const old_sources_root = _session_dir->sources_root();
3760
3761         if (!_writable || (_state_of_the_state & CannotSave)) {
3762                 error << _("Cannot rename read-only session.") << endmsg;
3763                 return 0; // don't show "messed up" warning
3764         }
3765         if (record_status() == Recording) {
3766                 error << _("Cannot rename session while recording") << endmsg;
3767                 return 0; // don't show "messed up" warning
3768         }
3769
3770         StateProtector stp (this);
3771
3772         /* Rename:
3773
3774          * session directory
3775          * interchange subdirectory
3776          * session file
3777          * session history
3778          
3779          * Backup files are left unchanged and not renamed.
3780          */
3781
3782         /* Windows requires that we close all files before attempting the
3783          * rename. This works on other platforms, but isn't necessary there.
3784          * Leave it in place for all platforms though, since it may help
3785          * catch issues that could arise if the way Source files work ever
3786          * change (since most developers are not using Windows).
3787          */
3788
3789         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
3790                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3791                 if (fs) {
3792                         fs->close ();
3793                 }
3794         }
3795         
3796         /* pass one: not 100% safe check that the new directory names don't
3797          * already exist ...
3798          */
3799
3800         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3801                 
3802                 oldstr = (*i).path;
3803                 
3804                 /* this is a stupid hack because Glib::path_get_dirname() is
3805                  * lexical-only, and so passing it /a/b/c/ gives a different
3806                  * result than passing it /a/b/c ...
3807                  */
3808                 
3809                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3810                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3811                 }
3812                 
3813                 string base = Glib::path_get_dirname (oldstr);
3814                 
3815                 newstr = Glib::build_filename (base, legal_name);
3816                 
3817                 cerr << "Looking for " << newstr << endl;
3818                 
3819                 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3820                         cerr << " exists\n";
3821                         return -1;
3822                 }
3823         }
3824
3825         /* Session dirs */
3826
3827         first = true;
3828         
3829         for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3830
3831                 vector<string> v;
3832
3833                 oldstr = (*i).path;
3834                 
3835                 /* this is a stupid hack because Glib::path_get_dirname() is
3836                  * lexical-only, and so passing it /a/b/c/ gives a different
3837                  * result than passing it /a/b/c ...
3838                  */
3839                 
3840                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3841                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3842                 }
3843
3844                 string base = Glib::path_get_dirname (oldstr);
3845                 newstr = Glib::build_filename (base, legal_name);
3846
3847                 cerr << "for " << oldstr << " new dir = " << newstr << endl;
3848                 
3849                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3850                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3851                         cerr << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
3852                         error << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3853                         return 1;
3854                 }
3855
3856                 /* Reset path in "session dirs" */
3857                 
3858                 (*i).path = newstr;
3859                 (*i).blocks = 0;
3860                 
3861                 /* reset primary SessionDirectory object */
3862                 
3863                 if (first) {
3864                         (*_session_dir) = newstr;
3865                         new_path = newstr;
3866                         first = false;
3867                 }
3868
3869                 /* now rename directory below session_dir/interchange */
3870
3871                 string old_interchange_dir;
3872                 string new_interchange_dir;
3873
3874                 /* use newstr here because we renamed the path
3875                  * (folder/directory) that used to be oldstr to newstr above 
3876                  */     
3877                 
3878                 v.push_back (newstr); 
3879                 v.push_back (interchange_dir_name);
3880                 v.push_back (Glib::path_get_basename (oldstr));
3881
3882                 old_interchange_dir = Glib::build_filename (v);
3883
3884                 v.clear ();
3885                 v.push_back (newstr);
3886                 v.push_back (interchange_dir_name);
3887                 v.push_back (legal_name);
3888                 
3889                 new_interchange_dir = Glib::build_filename (v);
3890                 
3891                 cerr << "Rename " << old_interchange_dir << " => " << new_interchange_dir << endl;
3892                 
3893                 if (::g_rename (old_interchange_dir.c_str(), new_interchange_dir.c_str()) != 0) {
3894                         cerr << string_compose (_("renaming %s as %2 failed (%3)"),
3895                                                  old_interchange_dir, new_interchange_dir,
3896                                                  g_strerror (errno))
3897                               << endl;
3898                         error << string_compose (_("renaming %s as %2 failed (%3)"),
3899                                                  old_interchange_dir, new_interchange_dir,
3900                                                  g_strerror (errno))
3901                               << endmsg;
3902                         return 1;
3903                 }
3904         }
3905
3906         /* state file */
3907         
3908         oldstr = Glib::build_filename (new_path, _current_snapshot_name + statefile_suffix);
3909         newstr= Glib::build_filename (new_path, legal_name + statefile_suffix);
3910         
3911         cerr << "Rename " << oldstr << " => " << newstr << endl;                
3912
3913         if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3914                 cerr << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
3915                 error << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3916                 return 1;
3917         }
3918
3919         /* history file */
3920         
3921         oldstr = Glib::build_filename (new_path, _current_snapshot_name) + history_suffix;
3922
3923         if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS))  {
3924                 newstr = Glib::build_filename (new_path, legal_name) + history_suffix;
3925                 
3926                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3927                 
3928                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3929                         cerr << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
3930                         error << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3931                         return 1;
3932                 }
3933         }
3934
3935         /* remove old name from recent sessions */
3936         remove_recent_sessions (_path);
3937         _path = new_path;
3938         
3939         /* update file source paths */
3940         
3941         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3942                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3943                 if (fs) {
3944                         string p = fs->path ();
3945                         boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3946                         fs->set_path (p);
3947                         SourceFactory::setup_peakfile(i->second, true);
3948                 }
3949         }
3950
3951         _current_snapshot_name = new_name;
3952         _name = new_name;
3953         
3954         set_dirty ();
3955
3956         /* save state again to get everything just right */
3957
3958         save_state (_current_snapshot_name);
3959
3960         /* add to recent sessions */
3961
3962         store_recent_sessions (new_name, _path);
3963
3964         return 0;
3965 }
3966
3967 int
3968 Session::get_session_info_from_path (XMLTree& tree, const string& xmlpath)
3969 {
3970         if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
3971                 return -1;
3972         }
3973
3974         if (!tree.read (xmlpath)) {
3975                 return -1;
3976         }
3977
3978         return 0;
3979 }
3980
3981 int
3982 Session::get_info_from_path (const string& xmlpath, float& sample_rate, SampleFormat& data_format)
3983 {
3984         XMLTree tree;
3985         bool found_sr = false;
3986         bool found_data_format = false;
3987
3988         if (get_session_info_from_path (tree, xmlpath)) {
3989                 return -1;
3990         }
3991
3992         /* sample rate */
3993
3994         const XMLProperty* prop;
3995         if ((prop = tree.root()->property (X_("sample-rate"))) != 0) {          
3996                 sample_rate = atoi (prop->value());
3997                 found_sr = true;
3998         }
3999
4000         const XMLNodeList& children (tree.root()->children());
4001         for (XMLNodeList::const_iterator c = children.begin(); c != children.end(); ++c) {
4002                 const XMLNode* child = *c;
4003                 if (child->name() == "Config") {
4004                         const XMLNodeList& options (child->children());
4005                         for (XMLNodeList::const_iterator oc = options.begin(); oc != options.end(); ++oc) {
4006                                 const XMLNode* option = *oc;
4007                                 const XMLProperty* name = option->property("name");
4008
4009                                 if (!name) {
4010                                         continue;
4011                                 }
4012
4013                                 if (name->value() == "native-file-data-format") {
4014                                         const XMLProperty* value = option->property ("value");
4015                                         if (value) {
4016                                                 SampleFormat fmt = (SampleFormat) string_2_enum (option->property ("value")->value(), fmt);
4017                                                 data_format = fmt;
4018                                                 found_data_format = true;
4019                                                 break;
4020                                         }
4021                                 }
4022                         }
4023                 }
4024                 if (found_data_format) {
4025                         break;
4026                 }
4027         }
4028
4029         return !(found_sr && found_data_format); // zero if they are both found
4030 }
4031
4032 typedef std::vector<boost::shared_ptr<FileSource> > SeveralFileSources;
4033 typedef std::map<std::string,SeveralFileSources> SourcePathMap;
4034
4035 int
4036 Session::bring_all_sources_into_session (boost::function<void(uint32_t,uint32_t,string)> callback)
4037 {
4038         uint32_t total = 0;
4039         uint32_t n = 0;
4040         SourcePathMap source_path_map;
4041         string new_path;
4042         boost::shared_ptr<AudioFileSource> afs;
4043         int ret = 0;
4044
4045         {
4046
4047                 Glib::Threads::Mutex::Lock lm (source_lock);
4048                 
4049                 cerr << " total sources = " << sources.size();
4050                 
4051                 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
4052                         boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
4053                         
4054                         if (!fs) {
4055                                 continue;
4056                         }
4057                         
4058                         if (fs->within_session()) {
4059                                 continue;
4060                         }
4061                         
4062                         if (source_path_map.find (fs->path()) != source_path_map.end()) {
4063                                 source_path_map[fs->path()].push_back (fs);
4064                         } else {
4065                                 SeveralFileSources v;
4066                                 v.push_back (fs);
4067                                 source_path_map.insert (make_pair (fs->path(), v));
4068                         }
4069                         
4070                         total++;
4071                 }
4072                 
4073                 cerr << " fsources = " << total << endl;
4074                 
4075                 for (SourcePathMap::iterator i = source_path_map.begin(); i != source_path_map.end(); ++i) {
4076                         
4077                         /* tell caller where we are */
4078                         
4079                         string old_path = i->first;
4080                         
4081                         callback (n, total, old_path);
4082                         
4083                         cerr << old_path << endl;
4084                         
4085                         new_path.clear ();
4086                         
4087                         switch (i->second.front()->type()) {
4088                         case DataType::AUDIO:
4089                                 new_path = new_audio_source_path_for_embedded (old_path);
4090                                 break;
4091                                 
4092                         case DataType::MIDI:
4093                                 /* XXX not implemented yet */
4094                                 break;
4095                         }
4096                         
4097                         if (new_path.empty()) {
4098                                 continue;
4099                         }
4100                         
4101                         cerr << "Move " << old_path << " => " << new_path << endl;
4102                         
4103                         if (!copy_file (old_path, new_path)) {
4104                                 cerr << "failed !\n";
4105                                 ret = -1;
4106                         }
4107                         
4108                         /* make sure we stop looking in the external
4109                            dir/folder. Remember, this is an all-or-nothing
4110                            operations, it doesn't merge just some files.
4111                         */
4112                         remove_dir_from_search_path (Glib::path_get_dirname (old_path), i->second.front()->type());
4113
4114                         for (SeveralFileSources::iterator f = i->second.begin(); f != i->second.end(); ++f) {
4115                                 (*f)->set_path (new_path);
4116                         }
4117                 }
4118         }
4119
4120         save_state ("", false, false);
4121
4122         return ret;
4123 }
4124
4125 static
4126 bool accept_all_files (string const &, void *)
4127 {
4128         return true;
4129 }
4130
4131 void
4132 Session::save_as_bring_callback (uint32_t,uint32_t,string)
4133 {
4134         /* 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.
4135         */
4136 }
4137
4138 static string
4139 make_new_media_path (string old_path, string new_session_folder, string new_session_path)
4140 {
4141         /* typedir is the "midifiles" or "audiofiles" etc. part of the path. */
4142
4143         string typedir = Glib::path_get_basename (Glib::path_get_dirname (old_path));
4144         vector<string> v;
4145         v.push_back (new_session_folder); /* full path */
4146         v.push_back (interchange_dir_name);
4147         v.push_back (new_session_path);   /* just one directory/folder */
4148         v.push_back (typedir);
4149         v.push_back (Glib::path_get_basename (old_path));
4150         
4151         return Glib::build_filename (v);
4152 }
4153
4154 int
4155 Session::save_as (SaveAs& saveas)
4156 {
4157         vector<string> files;
4158         string current_folder = Glib::path_get_dirname (_path);
4159         string new_folder = legalize_for_path (saveas.new_name);
4160         string to_dir = Glib::build_filename (saveas.new_parent_folder, new_folder);
4161         int64_t total_bytes = 0;
4162         int64_t copied = 0;
4163         int64_t cnt = 0;
4164         int64_t all = 0;
4165         int32_t internal_file_cnt = 0;
4166
4167         vector<string> do_not_copy_extensions;
4168         do_not_copy_extensions.push_back (statefile_suffix);
4169         do_not_copy_extensions.push_back (pending_suffix);
4170         do_not_copy_extensions.push_back (backup_suffix);
4171         do_not_copy_extensions.push_back (temp_suffix);
4172         do_not_copy_extensions.push_back (history_suffix);
4173
4174         /* get total size */
4175
4176         for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
4177                 
4178                 /* need to clear this because
4179                  * find_files_matching_filter() is cumulative
4180                  */
4181                 
4182                 files.clear ();
4183                 
4184                 find_files_matching_filter (files, (*sd).path, accept_all_files, 0, false, true, true);
4185                 
4186                 all += files.size();
4187
4188                 for (vector<string>::iterator i = files.begin(); i != files.end(); ++i) {
4189                         GStatBuf gsb;
4190                         g_stat ((*i).c_str(), &gsb);
4191                         total_bytes += gsb.st_size;
4192                 }
4193         }
4194
4195         /* save old values so we can switch back if we are not switching to the new session */
4196         
4197         string old_path = _path;
4198         string old_name = _name;
4199         string old_snapshot = _current_snapshot_name;
4200         string old_sd = _session_dir->root_path();
4201         vector<string> old_search_path[DataType::num_types];
4202         string old_config_search_path[DataType::num_types];
4203
4204         old_search_path[DataType::AUDIO] = source_search_path (DataType::AUDIO);
4205         old_search_path[DataType::MIDI] = source_search_path (DataType::MIDI);
4206         old_config_search_path[DataType::AUDIO]  = config.get_audio_search_path ();     
4207         old_config_search_path[DataType::MIDI]  = config.get_midi_search_path ();       
4208
4209         /* switch session directory */
4210         
4211         (*_session_dir) = to_dir;
4212
4213         /* create new tree */
4214         
4215         if (!_session_dir->create()) {
4216                 saveas.failure_message = string_compose (_("Cannot create new session folder %1"), to_dir);
4217                 return -1;
4218         }
4219
4220         try {
4221                 /* copy all relevant files. Find each location in session_dirs,
4222                  * and copy files from there to target.
4223                  */
4224                 
4225                 for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
4226                         
4227                         /* need to clear this because
4228                          * find_files_matching_filter() is cumulative
4229                          */
4230                         
4231                         files.clear ();
4232                         
4233                         const size_t prefix_len = (*sd).path.size();
4234                         
4235                         /* Work just on the files within this session dir */
4236                         
4237                         find_files_matching_filter (files, (*sd).path, accept_all_files, 0, false, true, true);
4238                         
4239                         /* add dir separator to protect against collisions with
4240                          * track names (e.g. track named "audiofiles" or
4241                          * "analysis".
4242                          */
4243
4244                         static const std::string audiofile_dir_string = string (sound_dir_name) + G_DIR_SEPARATOR;
4245                         static const std::string midifile_dir_string = string (midi_dir_name) + G_DIR_SEPARATOR;
4246                         static const std::string analysis_dir_string = analysis_dir() + G_DIR_SEPARATOR;
4247
4248                         /* copy all the files. Handling is different for media files
4249                            than others because of the *silly* subtree we have below the interchange
4250                            folder. That really was a bad idea, but I'm not fixing it as part of
4251                            implementing ::save_as().
4252                         */
4253                         
4254                         for (vector<string>::iterator i = files.begin(); i != files.end(); ++i) {
4255
4256                                 std::string from = *i;
4257
4258 #ifdef __APPLE__
4259                                 string filename = Glib::path_get_basename (from);
4260                                 std::transform (filename.begin(), filename.end(), filename.begin(), ::toupper);
4261                                 if (filename == ".DS_STORE") {
4262                                         continue;
4263                                 }
4264 #endif
4265                                 
4266                                 if (from.find (audiofile_dir_string) != string::npos) {
4267                                         
4268                                         /* audio file: only copy if asked */
4269
4270                                         if (saveas.include_media && saveas.copy_media) {
4271                                                 
4272                                                 string to = make_new_media_path (*i, to_dir, new_folder);
4273
4274                                                 info << "media file copying from " << from << " to " << to << endmsg;
4275                                                 
4276                                                 if (!copy_file (from, to)) {
4277                                                         throw Glib::FileError (Glib::FileError::IO_ERROR,
4278                                                                                                    string_compose(_("\ncopying \"%1\" failed !"), from));
4279                                                 }
4280                                         }
4281                                         
4282                                         /* we found media files inside the session folder */
4283                                         
4284                                         internal_file_cnt++;
4285
4286                                 } else if (from.find (midifile_dir_string) != string::npos) {
4287
4288                                         /* midi file: always copy unless
4289                                          * creating an empty new session
4290                                          */
4291
4292                                         if (saveas.include_media) {
4293                                         
4294                                                 string to = make_new_media_path (*i, to_dir, new_folder);
4295                                                 
4296                                                 info << "media file copying from " << from << " to " << to << endmsg;
4297                                                 
4298                                                 if (!copy_file (from, to)) {
4299                                                         throw Glib::FileError (Glib::FileError::IO_ERROR, "copy failed");
4300                                                 }
4301                                         }
4302
4303                                         /* we found media files inside the session folder */
4304                                                 
4305                                         internal_file_cnt++;
4306                                         
4307                                 } else if (from.find (analysis_dir_string) != string::npos) {
4308
4309                                         /*  make sure analysis dir exists in
4310                                          *  new session folder, but we're not
4311                                          *  copying analysis files here, see
4312                                          *  below 
4313                                          */
4314                                         
4315                                         (void) g_mkdir_with_parents (analysis_dir().c_str(), 775);
4316                                         continue;
4317                                         
4318                                 } else {
4319                                         
4320                                         /* normal non-media file. Don't copy state, history, etc.
4321                                          */
4322                                         
4323                                         bool do_copy = true;
4324                                         
4325                                         for (vector<string>::iterator v = do_not_copy_extensions.begin(); v != do_not_copy_extensions.end(); ++v) {
4326                                                 if ((from.length() > (*v).length()) && (from.find (*v) == from.length() - (*v).length())) {
4327                                                         /* end of filename matches extension, do not copy file */
4328                                                         do_copy = false;
4329                                                         break;
4330                                                 } 
4331                                         }
4332
4333                                         if (!saveas.copy_media && from.find (peakfile_suffix) != string::npos) {
4334                                                 /* don't copy peakfiles if
4335                                                  * we're not copying media
4336                                                  */
4337                                                 do_copy = false;
4338                                         }
4339                                         
4340                                         if (do_copy) {
4341                                                 string to = Glib::build_filename (to_dir, from.substr (prefix_len));
4342                                                 
4343                                                 info << "attempting to make directory/folder " << to << endmsg;
4344
4345                                                 if (g_mkdir_with_parents (Glib::path_get_dirname (to).c_str(), 0755)) {
4346                                                         throw Glib::FileError (Glib::FileError::IO_ERROR, "cannot create required directory");
4347                                                 }
4348
4349                                                 info << "attempting to copy " << from << " to " << to << endmsg;
4350                                                 
4351                                                 if (!copy_file (from, to)) {
4352                                                         throw Glib::FileError (Glib::FileError::IO_ERROR,
4353                                                                                                    string_compose(_("\ncopying \"%1\" failed !"), from));
4354                                                 }
4355                                         }
4356                                 }
4357                                 
4358                                 /* measure file size even if we're not going to copy so that our Progress
4359                                    signals are correct, since we included these do-not-copy files
4360                                    in the computation of the total size and file count.
4361                                 */
4362                                 
4363                                 GStatBuf gsb;
4364                                 g_stat (from.c_str(), &gsb);
4365                                 copied += gsb.st_size;
4366                                 cnt++;
4367                                 
4368                                 double fraction = (double) copied / total_bytes;
4369                                 
4370                                 bool keep_going = true;
4371
4372                                 if (saveas.copy_media) {
4373
4374                                         /* no need or expectation of this if
4375                                          * media is not being copied, because
4376                                          * it will be fast(ish).
4377                                          */
4378                                         
4379                                         /* tell someone "X percent, file M of N"; M is one-based */
4380                                         
4381                                         boost::optional<bool> res = saveas.Progress (fraction, cnt, all);
4382                                         
4383                                         if (res) {
4384                                                 keep_going = *res;
4385                                         }
4386                                 }
4387
4388                                 if (!keep_going) {
4389                                         throw Glib::FileError (Glib::FileError::FAILED, "copy cancelled");
4390                                 }
4391                         }
4392
4393                 }
4394
4395                 /* copy optional folders, if any */
4396
4397                 string old = plugins_dir ();
4398                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4399                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4400                         copy_files (old, newdir);
4401                 }
4402
4403                 old = externals_dir ();
4404                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4405                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4406                         copy_files (old, newdir);
4407                 }
4408
4409                 old = automation_dir ();
4410                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4411                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4412                         copy_files (old, newdir);
4413                 }
4414
4415                 if (saveas.include_media) {
4416                 
4417                         if (saveas.copy_media) {
4418 #ifndef PLATFORM_WINDOWS
4419                                 /* There are problems with analysis files on
4420                                  * Windows, because they used a colon in their
4421                                  * names as late as 4.0. Colons are not legal
4422                                  * under Windows even if NTFS allows them.
4423                                  *
4424                                  * This is a tricky problem to solve so for
4425                                  * just don't copy these files. They will be
4426                                  * regenerated as-needed anyway, subject to the 
4427                                  * existing issue that the filenames will be
4428                                  * rejected by Windows, which is a separate
4429                                  * problem (though related).
4430                                  */
4431
4432                                 /* only needed if we are copying media, since the
4433                                  * analysis data refers to media data
4434                                  */
4435                                 
4436                                 old = analysis_dir ();
4437                                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4438                                         string newdir = Glib::build_filename (to_dir, "analysis");
4439                                         copy_files (old, newdir);
4440                                 }
4441 #endif /* PLATFORM_WINDOWS */                           
4442                         }
4443                 }
4444                         
4445                 
4446                 _path = to_dir;
4447                 _current_snapshot_name = saveas.new_name;
4448                 _name = saveas.new_name;
4449
4450                 if (saveas.include_media && !saveas.copy_media) {
4451
4452                         /* reset search paths of the new session (which we're pretending to be right now) to
4453                            include the original session search path, so we can still find all audio.
4454                         */
4455
4456                         if (internal_file_cnt) {
4457                                 for (vector<string>::iterator s = old_search_path[DataType::AUDIO].begin(); s != old_search_path[DataType::AUDIO].end(); ++s) {
4458                                         ensure_search_path_includes (*s, DataType::AUDIO);
4459                                         cerr << "be sure to include " << *s << "  for audio" << endl;
4460                                 }
4461
4462                                 /* we do not do this for MIDI because we copy
4463                                    all MIDI files if saveas.include_media is
4464                                    true
4465                                 */
4466                         }
4467                 }
4468                 
4469                 bool was_dirty = dirty ();
4470
4471                 save_state ("", false, false, !saveas.include_media);
4472                 save_default_options ();
4473                 
4474                 if (saveas.copy_media && saveas.copy_external) {
4475                         if (bring_all_sources_into_session (boost::bind (&Session::save_as_bring_callback, this, _1, _2, _3))) {
4476                                 throw Glib::FileError (Glib::FileError::NO_SPACE_LEFT, "consolidate failed");
4477                         }
4478                 }
4479
4480                 saveas.final_session_folder_name = _path;
4481
4482                 store_recent_sessions (_name, _path);
4483                 
4484                 if (!saveas.switch_to) {
4485
4486                         /* switch back to the way things were */
4487
4488                         _path = old_path;
4489                         _name = old_name;
4490                         _current_snapshot_name = old_snapshot;
4491
4492                         (*_session_dir) = old_sd;
4493
4494                         if (was_dirty) {
4495                                 set_dirty ();
4496                         }
4497
4498                         if (internal_file_cnt) {
4499                                 /* reset these to their original values */
4500                                 config.set_audio_search_path (old_config_search_path[DataType::AUDIO]);
4501                                 config.set_midi_search_path (old_config_search_path[DataType::MIDI]);
4502                         }
4503                         
4504                 } else {
4505
4506                         /* prune session dirs, and update disk space statistics
4507                          */
4508
4509                         space_and_path sp;
4510                         sp.path = _path;
4511                         session_dirs.clear ();
4512                         session_dirs.push_back (sp);
4513                         refresh_disk_space ();
4514
4515                         /* ensure that all existing tracks reset their current capture source paths 
4516                          */
4517                         reset_write_sources (true, true);
4518
4519                         /* the copying above was based on actually discovering files, not just iterating over the sources list.
4520                            But if we're going to switch to the new (copied) session, we need to change the paths in the sources also.
4521                         */
4522
4523                         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
4524                                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
4525
4526                                 if (!fs) {
4527                                         continue;
4528                                 }
4529
4530                                 if (fs->within_session()) {
4531                                         string newpath = make_new_media_path (fs->path(), to_dir, new_folder);
4532                                         fs->set_path (newpath);
4533                                 }
4534                         }
4535                 }
4536
4537         } catch (Glib::FileError& e) {
4538
4539                 saveas.failure_message = e.what();
4540                 
4541                 /* recursively remove all the directories */
4542                 
4543                 remove_directory (to_dir);
4544                 
4545                 /* return error */
4546                 
4547                 return -1;
4548
4549         } catch (...) {
4550
4551                 saveas.failure_message = _("unknown reason");
4552                 
4553                 /* recursively remove all the directories */
4554                 
4555                 remove_directory (to_dir);
4556                 
4557                 /* return error */
4558                 
4559                 return -1;
4560         }
4561         
4562         return 0;
4563 }