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