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