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