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