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