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