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