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