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