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