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