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