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