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