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