initial pass at session-renaming functionality
[ardour.git] / libs / ardour / session_state.cc
1 /*
2   Copyright (C) 1999-2002 Paul Davis
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU General Public License as published by
6   the Free Software Foundation; either version 2 of the License, or
7   (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.
13
14   You should have received a copy of the GNU General Public License
15   along with this program; if not, write to the Free Software
16   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20
21 #ifdef WAF_BUILD
22 #include "libardour-config.h"
23 #endif
24
25 #include <stdint.h>
26
27 #include <algorithm>
28 #include <fstream>
29 #include <string>
30 #include <cerrno>
31
32
33 #include <cstdio> /* snprintf(3) ... grrr */
34 #include <cmath>
35 #include <unistd.h>
36 #include <sys/stat.h>
37 #include <climits>
38 #include <fcntl.h>
39 #include <poll.h>
40 #include <signal.h>
41 #include <sys/mman.h>
42 #include <sys/time.h>
43
44 #ifdef HAVE_SYS_VFS_H
45 #include <sys/vfs.h>
46 #else
47 #include <sys/param.h>
48 #include <sys/mount.h>
49 #endif
50
51 #include <glib.h>
52
53 #include <glibmm.h>
54 #include <glibmm/thread.h>
55
56 #include "midi++/mmc.h"
57 #include "midi++/port.h"
58 #include "midi++/manager.h"
59
60 #include "pbd/boost_debug.h"
61 #include "pbd/basename.h"
62 #include "pbd/controllable_descriptor.h"
63 #include "pbd/enumwriter.h"
64 #include "pbd/error.h"
65 #include "pbd/pathscanner.h"
66 #include "pbd/pthread_utils.h"
67 #include "pbd/search_path.h"
68 #include "pbd/stacktrace.h"
69 #include "pbd/convert.h"
70 #include "pbd/clear_dir.h"
71
72 #include "ardour/amp.h"
73 #include "ardour/audio_diskstream.h"
74 #include "ardour/audio_playlist_source.h"
75 #include "ardour/audio_track.h"
76 #include "ardour/audioengine.h"
77 #include "ardour/audiofilesource.h"
78 #include "ardour/audioplaylist.h"
79 #include "ardour/audioregion.h"
80 #include "ardour/auditioner.h"
81 #include "ardour/automation_control.h"
82 #include "ardour/buffer.h"
83 #include "ardour/butler.h"
84 #include "ardour/configuration.h"
85 #include "ardour/control_protocol_manager.h"
86 #include "ardour/crossfade.h"
87 #include "ardour/cycle_timer.h"
88 #include "ardour/directory_names.h"
89 #include "ardour/filename_extensions.h"
90 #include "ardour/io_processor.h"
91 #include "ardour/location.h"
92 #include "ardour/midi_diskstream.h"
93 #include "ardour/midi_patch_manager.h"
94 #include "ardour/midi_playlist.h"
95 #include "ardour/midi_region.h"
96 #include "ardour/midi_source.h"
97 #include "ardour/midi_track.h"
98 #include "ardour/named_selection.h"
99 #include "ardour/pannable.h"
100 #include "ardour/processor.h"
101 #include "ardour/port.h"
102 #include "ardour/proxy_controllable.h"
103 #include "ardour/region_factory.h"
104 #include "ardour/route_group.h"
105 #include "ardour/send.h"
106 #include "ardour/session.h"
107 #include "ardour/session_directory.h"
108 #include "ardour/session_metadata.h"
109 #include "ardour/session_state_utils.h"
110 #include "ardour/session_playlists.h"
111 #include "ardour/session_utils.h"
112 #include "ardour/silentfilesource.h"
113 #include "ardour/slave.h"
114 #include "ardour/smf_source.h"
115 #include "ardour/sndfile_helpers.h"
116 #include "ardour/sndfilesource.h"
117 #include "ardour/source_factory.h"
118 #include "ardour/template_utils.h"
119 #include "ardour/tempo.h"
120 #include "ardour/ticker.h"
121 #include "ardour/user_bundle.h"
122 #include "ardour/utils.h"
123 #include "ardour/utils.h"
124 #include "ardour/version.h"
125 #include "ardour/playlist_factory.h"
126
127 #include "control_protocol/control_protocol.h"
128
129 #include "i18n.h"
130 #include <locale.h>
131
132 using namespace std;
133 using namespace ARDOUR;
134 using namespace PBD;
135
136
137 void
138 Session::first_stage_init (string fullpath, string snapshot_name)
139 {
140         if (fullpath.length() == 0) {
141                 destroy ();
142                 throw failed_constructor();
143         }
144
145         char buf[PATH_MAX+1];
146         if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
147                 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
148                 destroy ();
149                 throw failed_constructor();
150         }
151
152         _path = string(buf);
153
154         if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
155                 _path += G_DIR_SEPARATOR;
156         }
157
158         /* these two are just provisional settings. set_state()
159            will likely override them.
160         */
161
162         _name = _current_snapshot_name = snapshot_name;
163
164         set_history_depth (Config->get_history_depth());
165
166         _current_frame_rate = _engine.frame_rate ();
167         _nominal_frame_rate = _current_frame_rate;
168         _base_frame_rate = _current_frame_rate;
169
170         _tempo_map = new TempoMap (_current_frame_rate);
171         _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
172
173
174         _non_soloed_outs_muted = false;
175         _listen_cnt = 0;
176         _solo_isolated_cnt = 0;
177         g_atomic_int_set (&processing_prohibited, 0);
178         _transport_speed = 0;
179         _last_transport_speed = 0;
180         _target_transport_speed = 0;
181         auto_play_legal = false;
182         transport_sub_state = 0;
183         _transport_frame = 0;
184         _requested_return_frame = -1;
185         _session_range_location = 0;
186         g_atomic_int_set (&_record_status, Disabled);
187         loop_changing = false;
188         play_loop = false;
189         have_looped = false;
190         _last_roll_location = 0;
191         _last_roll_or_reversal_location = 0;
192         _last_record_location = 0;
193         pending_locate_frame = 0;
194         pending_locate_roll = false;
195         pending_locate_flush = false;
196         state_was_pending = false;
197         set_next_event ();
198         outbound_mtc_timecode_frame = 0;
199         next_quarter_frame_to_send = -1;
200         current_block_size = 0;
201         solo_update_disabled = false;
202         _have_captured = false;
203         _worst_output_latency = 0;
204         _worst_input_latency = 0;
205         _worst_track_latency = 0;
206         _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
207         _was_seamless = Config->get_seamless_loop ();
208         _slave = 0;
209         _send_qf_mtc = false;
210         _pframes_since_last_mtc = 0;
211         g_atomic_int_set (&_playback_load, 100);
212         g_atomic_int_set (&_capture_load, 100);
213         _play_range = false;
214         _exporting = false;
215         pending_abort = false;
216         destructive_index = 0;
217         first_file_data_format_reset = true;
218         first_file_header_format_reset = true;
219         post_export_sync = false;
220         midi_control_ui = 0;
221         _step_editors = 0;
222         no_questions_about_missing_files = false;
223         _speakers.reset (new Speakers);
224
225         AudioDiskstream::allocate_working_buffers();
226
227         /* default short fade = 15ms */
228
229         Crossfade::set_short_xfade_length ((framecnt_t) floor (config.get_short_xfade_seconds() * frame_rate()));
230         SndFileSource::setup_standard_crossfades (*this, frame_rate());
231
232         last_mmc_step.tv_sec = 0;
233         last_mmc_step.tv_usec = 0;
234         step_speed = 0.0;
235
236         /* click sounds are unset by default, which causes us to internal
237            waveforms for clicks.
238         */
239
240         click_length = 0;
241         click_emphasis_length = 0;
242         _clicking = false;
243
244         process_function = &Session::process_with_events;
245
246         if (config.get_use_video_sync()) {
247                 waiting_for_sync_offset = true;
248         } else {
249                 waiting_for_sync_offset = false;
250         }
251
252         last_timecode_when = 0;
253         last_timecode_valid = false;
254
255         sync_time_vars ();
256
257         last_rr_session_dir = session_dirs.begin();
258         refresh_disk_space ();
259
260         /* default: assume simple stereo speaker configuration */
261
262         _speakers->setup_default_speakers (2);
263
264         /* slave stuff */
265
266         average_slave_delta = 1800; // !!! why 1800 ????
267         have_first_delta_accumulator = false;
268         delta_accumulator_cnt = 0;
269         _slave_state = Stopped;
270
271         _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
272                                                         boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
273                                                         boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
274         add_controllable (_solo_cut_control);
275
276         _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
277
278         /* These are all static "per-class" signals */
279
280         SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
281         PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
282         AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
283         Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
284         IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
285
286         /* stop IO objects from doing stuff until we're ready for them */
287
288         Delivery::disable_panners ();
289         IO::disable_connecting ();
290 }
291
292 int
293 Session::second_stage_init ()
294 {
295         AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
296
297         if (!_is_new) {
298                 if (load_state (_current_snapshot_name)) {
299                         return -1;
300                 }
301         }
302
303         if (_butler->start_thread()) {
304                 return -1;
305         }
306
307         if (start_midi_thread ()) {
308                 return -1;
309         }
310
311         setup_midi_machine_control ();
312
313         // set_state() will call setup_raid_path(), but if it's a new session we need
314         // to call setup_raid_path() here.
315
316         if (state_tree) {
317                 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
318                         return -1;
319                 }
320         } else {
321                 setup_raid_path(_path);
322         }
323
324         /* we can't save till after ::when_engine_running() is called,
325            because otherwise we save state with no connections made.
326            therefore, we reset _state_of_the_state because ::set_state()
327            will have cleared it.
328
329            we also have to include Loading so that any events that get
330            generated between here and the end of ::when_engine_running()
331            will be processed directly rather than queued.
332         */
333
334         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
335
336         _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
337         _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
338         setup_click_sounds (0);
339         setup_midi_control ();
340
341         /* Pay attention ... */
342
343         _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
344         _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
345
346         try {
347                 when_engine_running ();
348         }
349
350         /* handle this one in a different way than all others, so that its clear what happened */
351
352         catch (AudioEngine::PortRegistrationFailure& err) {
353                 error << err.what() << endmsg;
354                 return -1;
355         }
356
357         catch (...) {
358                 return -1;
359         }
360
361         BootMessage (_("Reset Remote Controls"));
362
363         send_full_time_code (0);
364         _engine.transport_locate (0);
365
366         MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
367         MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
368
369         MidiClockTicker::instance().set_session (this);
370         MIDI::Name::MidiPatchManager::instance().set_session (this);
371
372         /* initial program change will be delivered later; see ::config_changed() */
373
374         _state_of_the_state = Clean;
375
376         Port::set_connecting_blocked (false);
377
378         DirtyChanged (); /* EMIT SIGNAL */
379
380         if (state_was_pending) {
381                 save_state (_current_snapshot_name);
382                 remove_pending_capture_state ();
383                 state_was_pending = false;
384         }
385
386         BootMessage (_("Session loading complete"));
387
388         return 0;
389 }
390
391 string
392 Session::raid_path () const
393 {
394         SearchPath raid_search_path;
395
396         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
397                 raid_search_path += sys::path((*i).path);
398         }
399
400         return raid_search_path.to_string ();
401 }
402
403 void
404 Session::setup_raid_path (string path)
405 {
406         if (path.empty()) {
407                 return;
408         }
409
410         space_and_path sp;
411         string fspath;
412
413         session_dirs.clear ();
414
415         SearchPath search_path(path);
416         SearchPath sound_search_path;
417         SearchPath midi_search_path;
418
419         for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
420                 sp.path = (*i).to_string ();
421                 sp.blocks = 0; // not needed
422                 session_dirs.push_back (sp);
423
424                 SessionDirectory sdir(sp.path);
425
426                 sound_search_path += sdir.sound_path ();
427                 midi_search_path += sdir.midi_path ();
428         }
429
430         // reset the round-robin soundfile path thingie
431         last_rr_session_dir = session_dirs.begin();
432 }
433
434 bool
435 Session::path_is_within_session (const std::string& path)
436 {
437         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
438                 if (path.find ((*i).path) == 0) {
439                         return true;
440                 }
441         }
442         return false;
443 }
444
445 int
446 Session::ensure_subdirs ()
447 {
448         string dir;
449
450         dir = session_directory().peak_path().to_string();
451
452         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
453                 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
454                 return -1;
455         }
456
457         dir = session_directory().sound_path().to_string();
458
459         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
460                 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
461                 return -1;
462         }
463
464         dir = session_directory().midi_path().to_string();
465
466         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
467                 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
468                 return -1;
469         }
470
471         dir = session_directory().dead_path().to_string();
472
473         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
474                 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
475                 return -1;
476         }
477
478         dir = session_directory().export_path().to_string();
479
480         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
481                 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
482                 return -1;
483         }
484
485         dir = analysis_dir ();
486
487         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
488                 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
489                 return -1;
490         }
491
492         dir = plugins_dir ();
493
494         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
495                 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
496                 return -1;
497         }
498
499         return 0;
500 }
501
502 /** Caller must not hold process lock */
503 int
504 Session::create (const string& mix_template, BusProfile* bus_profile)
505 {
506         if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
507                 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
508                 return -1;
509         }
510
511         if (ensure_subdirs ()) {
512                 return -1;
513         }
514
515         _writable = exists_and_writable (sys::path (_path));
516
517         if (!mix_template.empty()) {
518                 std::string in_path = mix_template;
519
520                 ifstream in(in_path.c_str());
521
522                 if (in) {
523                         string out_path = _path;
524                         out_path += _name;
525                         out_path += statefile_suffix;
526
527                         ofstream out(out_path.c_str());
528
529                         if (out) {
530                                 out << in.rdbuf();
531                                 _is_new = false;
532                                 return 0;
533
534                         } else {
535                                 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
536                                         << endmsg;
537                                 return -1;
538                         }
539
540                 } else {
541                         error << string_compose (_("Could not open mix template %1 for reading"), in_path)
542                                 << endmsg;
543                         return -1;
544                 }
545
546         }
547
548         /* Instantiate metadata */
549
550         _metadata = new SessionMetadata ();
551
552         /* set initial start + end point */
553
554         _state_of_the_state = Clean;
555
556         /* set up Master Out and Control Out if necessary */
557
558         if (bus_profile) {
559
560                 RouteList rl;
561                 int control_id = 1;
562                 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
563
564                 if (bus_profile->master_out_channels) {
565                         boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
566                         if (r->init ()) {
567                                 return -1;
568                         }
569 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
570                         boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
571 #endif
572                         {
573                                 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
574                                 r->input()->ensure_io (count, false, this);
575                                 r->output()->ensure_io (count, false, this);
576                         }
577                         r->set_remote_control_id (control_id++);
578
579                         rl.push_back (r);
580
581                         if (Config->get_use_monitor_bus()) {
582                                 boost::shared_ptr<Route> r (new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO));
583                                 if (r->init ()) {
584                                         return -1;
585                                 }
586 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
587                                 boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
588 #endif
589                                 {
590                                         Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
591                                         r->input()->ensure_io (count, false, this);
592                                         r->output()->ensure_io (count, false, this);
593                                 }
594                                 r->set_remote_control_id (control_id);
595
596                                 rl.push_back (r);
597                         }
598
599                 } else {
600                         /* prohibit auto-connect to master, because there isn't one */
601                         bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
602                 }
603
604                 if (!rl.empty()) {
605                         add_routes (rl, false, false);
606                 }
607
608                 /* this allows the user to override settings with an environment variable.
609                  */
610
611                 if (no_auto_connect()) {
612                         bus_profile->input_ac = AutoConnectOption (0);
613                         bus_profile->output_ac = AutoConnectOption (0);
614                 }
615
616                 Config->set_input_auto_connect (bus_profile->input_ac);
617                 Config->set_output_auto_connect (bus_profile->output_ac);
618         }
619
620         save_state ("");
621
622         return 0;
623 }
624
625 void
626 Session::maybe_write_autosave()
627 {
628         if (dirty() && record_status() != Recording) {
629                 save_state("", true);
630         }
631 }
632
633 void
634 Session::remove_pending_capture_state ()
635 {
636         sys::path pending_state_file_path(_session_dir->root_path());
637
638         pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
639
640         try
641         {
642                 sys::remove (pending_state_file_path);
643         }
644         catch(sys::filesystem_error& ex)
645         {
646                 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
647                                 pending_state_file_path.to_string(), ex.what()) << endmsg;
648         }
649 }
650
651 /** Rename a state file.
652  *  @param old_name Old snapshot name.
653  *  @param new_name New snapshot name.
654  */
655 void
656 Session::rename_state (string old_name, string new_name)
657 {
658         if (old_name == _current_snapshot_name || old_name == _name) {
659                 /* refuse to rename the current snapshot or the "main" one */
660                 return;
661         }
662
663         const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
664         const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
665
666         const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
667         const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
668
669         try
670         {
671                 sys::rename (old_xml_path, new_xml_path);
672         }
673         catch (const sys::filesystem_error& err)
674         {
675                 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
676                                 old_name, new_name, err.what()) << endmsg;
677         }
678 }
679
680 /** Remove a state file.
681  *  @param snapshot_name Snapshot name.
682  */
683 void
684 Session::remove_state (string snapshot_name)
685 {
686         if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
687                 // refuse to remove the current snapshot or the "main" one
688                 return;
689         }
690
691         sys::path xml_path(_session_dir->root_path());
692
693         xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
694
695         if (!create_backup_file (xml_path)) {
696                 // don't remove it if a backup can't be made
697                 // create_backup_file will log the error.
698                 return;
699         }
700
701         // and delete it
702         sys::remove (xml_path);
703 }
704
705 #ifdef HAVE_JACK_SESSION
706 void
707 Session::jack_session_event (jack_session_event_t * event)
708 {
709         char timebuf[128];
710         time_t n;
711         struct tm local_time;
712
713         time (&n);
714         localtime_r (&n, &local_time);
715         strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
716
717         if (event->type == JackSessionSaveTemplate)
718         {
719                 if (save_template( timebuf )) {
720                         event->flags = JackSessionSaveError;
721                 } else {
722                         string cmd ("ardour3 -P -U ");
723                         cmd += event->client_uuid;
724                         cmd += " -T ";
725                         cmd += timebuf;
726
727                         event->command_line = strdup (cmd.c_str());
728                 }
729         }
730         else
731         {
732                 if (save_state (timebuf)) {
733                         event->flags = JackSessionSaveError;
734                 } else {
735                         sys::path xml_path (_session_dir->root_path());
736                         xml_path /= legalize_for_path (timebuf) + statefile_suffix;
737
738                         string cmd ("ardour3 -P -U ");
739                         cmd += event->client_uuid;
740                         cmd += " \"";
741                         cmd += xml_path.to_string();
742                         cmd += '\"';
743
744                         event->command_line = strdup (cmd.c_str());
745                 }
746         }
747
748         jack_session_reply (_engine.jack(), event);
749
750         if (event->type == JackSessionSaveAndQuit) {
751                 Quit (); /* EMIT SIGNAL */
752         }
753
754         jack_session_event_free( event );
755 }
756 #endif
757
758 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
759 int
760 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
761 {
762         XMLTree tree;
763         sys::path xml_path(_session_dir->root_path());
764
765         if (!_writable || (_state_of_the_state & CannotSave)) {
766                 return 1;
767         }
768
769         if (!_engine.connected ()) {
770                 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
771                                          PROGRAM_NAME)
772                       << endmsg;
773                 return 1;
774         }
775
776         /* tell sources we're saving first, in case they write out to a new file
777          * which should be saved with the state rather than the old one */
778         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
779                 i->second->session_saved();
780         }
781
782         tree.set_root (&get_state());
783
784         if (snapshot_name.empty()) {
785                 snapshot_name = _current_snapshot_name;
786         } else if (switch_to_snapshot) {
787                 _current_snapshot_name = snapshot_name;
788         }
789
790         if (!pending) {
791
792                 /* proper save: use statefile_suffix (.ardour in English) */
793
794                 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
795
796                 /* make a backup copy of the old file */
797
798                 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
799                         // create_backup_file will log the error
800                         return -1;
801                 }
802
803         } else {
804
805                 /* pending save: use pending_suffix (.pending in English) */
806                 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
807         }
808
809         sys::path tmp_path(_session_dir->root_path());
810
811         tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
812
813         // cerr << "actually writing state to " << xml_path.to_string() << endl;
814
815         if (!tree.write (tmp_path.to_string())) {
816                 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
817                 sys::remove (tmp_path);
818                 return -1;
819
820         } else {
821
822                 if (::rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
823                         error << string_compose (_("could not rename temporary session file %1 to %2"),
824                                         tmp_path.to_string(), xml_path.to_string()) << endmsg;
825                         sys::remove (tmp_path);
826                         return -1;
827                 }
828         }
829
830         if (!pending) {
831
832                 save_history (snapshot_name);
833
834                 bool was_dirty = dirty();
835
836                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
837
838                 if (was_dirty) {
839                         DirtyChanged (); /* EMIT SIGNAL */
840                 }
841
842                 StateSaved (snapshot_name); /* EMIT SIGNAL */
843         }
844
845         return 0;
846 }
847
848 int
849 Session::restore_state (string snapshot_name)
850 {
851         if (load_state (snapshot_name) == 0) {
852                 set_state (*state_tree->root(), Stateful::loading_state_version);
853         }
854
855         return 0;
856 }
857
858 int
859 Session::load_state (string snapshot_name)
860 {
861         delete state_tree;
862         state_tree = 0;
863
864         state_was_pending = false;
865
866         /* check for leftover pending state from a crashed capture attempt */
867
868         sys::path xmlpath(_session_dir->root_path());
869         xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
870
871         if (sys::exists (xmlpath)) {
872
873                 /* there is pending state from a crashed capture attempt */
874
875                 boost::optional<int> r = AskAboutPendingState();
876                 if (r.get_value_or (1)) {
877                         state_was_pending = true;
878                 }
879         }
880
881         if (!state_was_pending) {
882                 xmlpath = _session_dir->root_path();
883                 xmlpath /= snapshot_name;
884         }
885
886         if (!sys::exists (xmlpath)) {
887                 xmlpath = _session_dir->root_path();
888                 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
889                 if (!sys::exists (xmlpath)) {
890                         error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
891                         return 1;
892                 }
893         }
894
895         state_tree = new XMLTree;
896
897         set_dirty();
898
899         _writable = exists_and_writable (xmlpath);
900
901         if (!state_tree->read (xmlpath.to_string())) {
902                 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
903                 delete state_tree;
904                 state_tree = 0;
905                 return -1;
906         }
907
908         XMLNode& root (*state_tree->root());
909
910         if (root.name() != X_("Session")) {
911                 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
912                 delete state_tree;
913                 state_tree = 0;
914                 return -1;
915         }
916
917         const XMLProperty* prop;
918
919         if ((prop = root.property ("version")) == 0) {
920                 /* no version implies very old version of Ardour */
921                 Stateful::loading_state_version = 1000;
922         } else {
923                 int major;
924                 int minor;
925                 int micro;
926
927                 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, &micro);
928                 Stateful::loading_state_version = (major * 1000) + minor;
929         }
930
931         if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
932
933                 sys::path backup_path(_session_dir->root_path());
934
935                 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
936
937                 // only create a backup once
938                 if (sys::exists (backup_path)) {
939                         return 0;
940                 }
941
942                 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
943                                         xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
944                      << endmsg;
945
946                 try
947                 {
948                         sys::copy_file (xmlpath, backup_path);
949                 }
950                 catch(sys::filesystem_error& ex)
951                 {
952                         error << string_compose (_("Unable to make backup of state file %1 (%2)"),
953                                         xmlpath.to_string(), ex.what())
954                                 << endmsg;
955                         return -1;
956                 }
957         }
958
959         return 0;
960 }
961
962 int
963 Session::load_options (const XMLNode& node)
964 {
965         LocaleGuard lg (X_("POSIX"));
966         config.set_variables (node);
967         return 0;
968 }
969
970 XMLNode&
971 Session::get_state()
972 {
973         return state(true);
974 }
975
976 XMLNode&
977 Session::get_template()
978 {
979         /* if we don't disable rec-enable, diskstreams
980            will believe they need to store their capture
981            sources in their state node.
982         */
983
984         disable_record (false);
985
986         return state(false);
987 }
988
989 XMLNode&
990 Session::state(bool full_state)
991 {
992         XMLNode* node = new XMLNode("Session");
993         XMLNode* child;
994
995         // store libardour version, just in case
996         char buf[16];
997         snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
998         node->add_property("version", string(buf));
999
1000         /* store configuration settings */
1001
1002         if (full_state) {
1003
1004                 node->add_property ("name", _name);
1005                 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
1006                 node->add_property ("sample-rate", buf);
1007
1008                 if (session_dirs.size() > 1) {
1009
1010                         string p;
1011
1012                         vector<space_and_path>::iterator i = session_dirs.begin();
1013                         vector<space_and_path>::iterator next;
1014
1015                         ++i; /* skip the first one */
1016                         next = i;
1017                         ++next;
1018
1019                         while (i != session_dirs.end()) {
1020
1021                                 p += (*i).path;
1022
1023                                 if (next != session_dirs.end()) {
1024                                         p += ':';
1025                                 } else {
1026                                         break;
1027                                 }
1028
1029                                 ++next;
1030                                 ++i;
1031                         }
1032
1033                         child = node->add_child ("Path");
1034                         child->add_content (p);
1035                 }
1036         }
1037
1038         /* save the ID counter */
1039
1040         snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1041         node->add_property ("id-counter", buf);
1042
1043         /* save the event ID counter */
1044
1045         snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1046         node->add_property ("event-counter", buf);
1047
1048         /* various options */
1049
1050         node->add_child_nocopy (config.get_variables ());
1051
1052         node->add_child_nocopy (_metadata->get_state());
1053
1054         child = node->add_child ("Sources");
1055
1056         if (full_state) {
1057                 Glib::Mutex::Lock sl (source_lock);
1058
1059                 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1060
1061                         /* Don't save information about non-file Sources, or
1062                          * about non-destructive file sources that are empty
1063                          * and unused by any regions.
1064                         */
1065
1066                         boost::shared_ptr<FileSource> fs;
1067
1068                         if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1069
1070                                 if (!fs->destructive()) {
1071                                         if (fs->empty() && !fs->used()) {
1072                                                 continue;
1073                                         }
1074                                 }
1075
1076                                 child->add_child_nocopy (siter->second->get_state());
1077                         }
1078                 }
1079         }
1080
1081         child = node->add_child ("Regions");
1082
1083         if (full_state) {
1084                 Glib::Mutex::Lock rl (region_lock);
1085                 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1086                 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1087                         boost::shared_ptr<Region> r = i->second;
1088                         /* only store regions not attached to playlists */
1089                         if (r->playlist() == 0) {
1090                                 child->add_child_nocopy (r->state ());
1091                         }
1092                 }
1093
1094                 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1095
1096                 if (!cassocs.empty()) {
1097                         XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1098
1099                         for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1100                                 char buf[64];
1101                                 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1102                                 i->first->id().print (buf, sizeof (buf));
1103                                 can->add_property (X_("copy"), buf);
1104                                 i->second->id().print (buf, sizeof (buf));
1105                                 can->add_property (X_("original"), buf);
1106                                 ca->add_child_nocopy (*can);
1107                         }
1108                 }
1109         }
1110
1111         if (full_state) {
1112                 node->add_child_nocopy (_locations->get_state());
1113         } else {
1114                 // for a template, just create a new Locations, populate it
1115                 // with the default start and end, and get the state for that.
1116                 Locations loc (*this);
1117                 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1118                 range->set (max_framepos, 0);
1119                 loc.add (range);
1120                 node->add_child_nocopy (loc.get_state());
1121         }
1122
1123         child = node->add_child ("Bundles");
1124         {
1125                 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1126                 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1127                         boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1128                         if (b) {
1129                                 child->add_child_nocopy (b->get_state());
1130                         }
1131                 }
1132         }
1133
1134         child = node->add_child ("Routes");
1135         {
1136                 boost::shared_ptr<RouteList> r = routes.reader ();
1137
1138                 RoutePublicOrderSorter cmp;
1139                 RouteList public_order (*r);
1140                 public_order.sort (cmp);
1141
1142                 /* the sort should have put control outs first */
1143
1144                 if (_monitor_out) {
1145                         assert (_monitor_out == public_order.front());
1146                 }
1147
1148                 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1149                         if (!(*i)->is_hidden()) {
1150                                 if (full_state) {
1151                                         child->add_child_nocopy ((*i)->get_state());
1152                                 } else {
1153                                         child->add_child_nocopy ((*i)->get_template());
1154                                 }
1155                         }
1156                 }
1157         }
1158
1159         playlists->add_state (node, full_state);
1160
1161         child = node->add_child ("RouteGroups");
1162         for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1163                 child->add_child_nocopy ((*i)->get_state());
1164         }
1165
1166         if (_click_io) {
1167                 child = node->add_child ("Click");
1168                 child->add_child_nocopy (_click_io->state (full_state));
1169         }
1170
1171         if (full_state) {
1172                 child = node->add_child ("NamedSelections");
1173                 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1174                         if (full_state) {
1175                                 child->add_child_nocopy ((*i)->get_state());
1176                         }
1177                 }
1178         }
1179
1180         node->add_child_nocopy (_speakers->get_state());
1181         node->add_child_nocopy (_tempo_map->get_state());
1182         node->add_child_nocopy (get_control_protocol_state());
1183
1184         if (_extra_xml) {
1185                 node->add_child_copy (*_extra_xml);
1186         }
1187
1188         return *node;
1189 }
1190
1191 XMLNode&
1192 Session::get_control_protocol_state ()
1193 {
1194         ControlProtocolManager& cpm (ControlProtocolManager::instance());
1195         return cpm.get_state();
1196 }
1197
1198 int
1199 Session::set_state (const XMLNode& node, int version)
1200 {
1201         XMLNodeList nlist;
1202         XMLNode* child;
1203         const XMLProperty* prop;
1204         int ret = -1;
1205
1206         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1207
1208         if (node.name() != X_("Session")) {
1209                 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1210                 return -1;
1211         }
1212
1213         if ((prop = node.property ("version")) != 0) {
1214                 version = atoi (prop->value ()) * 1000;
1215         }
1216
1217         if ((prop = node.property ("name")) != 0) {
1218                 _name = prop->value ();
1219         }
1220
1221         if ((prop = node.property (X_("sample-rate"))) != 0) {
1222
1223                 _nominal_frame_rate = atoi (prop->value());
1224
1225                 if (_nominal_frame_rate != _current_frame_rate) {
1226                         boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1227                         if (r.get_value_or (0)) {
1228                                 return -1;
1229                         }
1230                 }
1231         }
1232
1233         setup_raid_path(_session_dir->root_path().to_string());
1234
1235         if ((prop = node.property (X_("id-counter"))) != 0) {
1236                 uint64_t x;
1237                 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1238                 ID::init_counter (x);
1239         } else {
1240                 /* old sessions used a timebased counter, so fake
1241                    the startup ID counter based on a standard
1242                    timestamp.
1243                 */
1244                 time_t now;
1245                 time (&now);
1246                 ID::init_counter (now);
1247         }
1248
1249         if ((prop = node.property (X_("event-counter"))) != 0) {
1250                 Evoral::init_event_id_counter (atoi (prop->value()));
1251         }
1252
1253         IO::disable_connecting ();
1254
1255         Stateful::save_extra_xml (node);
1256
1257         if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1258                 load_options (*child);
1259         } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1260                 load_options (*child);
1261         } else {
1262                 error << _("Session: XML state has no options section") << endmsg;
1263         }
1264
1265         if (version >= 3000) {
1266                 if ((child = find_named_node (node, "Metadata")) == 0) {
1267                         warning << _("Session: XML state has no metadata section") << endmsg;
1268                 } else if (_metadata->set_state (*child, version)) {
1269                         goto out;
1270                 }
1271         }
1272
1273         if ((child = find_named_node (node, "Locations")) == 0) {
1274                 error << _("Session: XML state has no locations section") << endmsg;
1275                 goto out;
1276         } else if (_locations->set_state (*child, version)) {
1277                 goto out;
1278         }
1279
1280         if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1281                 _speakers->set_state (*child, version);
1282         }
1283
1284         Location* location;
1285
1286         if ((location = _locations->auto_loop_location()) != 0) {
1287                 set_auto_loop_location (location);
1288         }
1289
1290         if ((location = _locations->auto_punch_location()) != 0) {
1291                 set_auto_punch_location (location);
1292         }
1293
1294         if ((location = _locations->session_range_location()) != 0) {
1295                 delete _session_range_location;
1296                 _session_range_location = location;
1297         }
1298
1299         if (_session_range_location) {
1300                 AudioFileSource::set_header_position_offset (_session_range_location->start());
1301         }
1302
1303         if ((child = find_named_node (node, "Sources")) == 0) {
1304                 error << _("Session: XML state has no sources section") << endmsg;
1305                 goto out;
1306         } else if (load_sources (*child)) {
1307                 goto out;
1308         }
1309
1310         if ((child = find_named_node (node, "TempoMap")) == 0) {
1311                 error << _("Session: XML state has no Tempo Map section") << endmsg;
1312                 goto out;
1313         } else if (_tempo_map->set_state (*child, version)) {
1314                 goto out;
1315         }
1316
1317         if ((child = find_named_node (node, "Regions")) == 0) {
1318                 error << _("Session: XML state has no Regions section") << endmsg;
1319                 goto out;
1320         } else if (load_regions (*child)) {
1321                 goto out;
1322         }
1323
1324         if ((child = find_named_node (node, "Playlists")) == 0) {
1325                 error << _("Session: XML state has no playlists section") << endmsg;
1326                 goto out;
1327         } else if (playlists->load (*this, *child)) {
1328                 goto out;
1329         }
1330
1331         if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1332                 // this is OK
1333         } else if (playlists->load_unused (*this, *child)) {
1334                 goto out;
1335         }
1336
1337         if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1338                 if (load_compounds (*child)) {
1339                         goto out;
1340                 }
1341         }
1342
1343         if ((child = find_named_node (node, "NamedSelections")) != 0) {
1344                 if (load_named_selections (*child)) {
1345                         goto out;
1346                 }
1347         }
1348
1349         if (version >= 3000) {
1350                 if ((child = find_named_node (node, "Bundles")) == 0) {
1351                         warning << _("Session: XML state has no bundles section") << endmsg;
1352                         //goto out;
1353                 } else {
1354                         /* We can't load Bundles yet as they need to be able
1355                            to convert from port names to Port objects, which can't happen until
1356                            later */
1357                         _bundle_xml_node = new XMLNode (*child);
1358                 }
1359         }
1360
1361         if (version < 3000) {
1362                 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1363                         error << _("Session: XML state has no diskstreams section") << endmsg;
1364                         goto out;
1365                 } else if (load_diskstreams_2X (*child, version)) {
1366                         goto out;
1367                 }
1368         }
1369
1370         if ((child = find_named_node (node, "Routes")) == 0) {
1371                 error << _("Session: XML state has no routes section") << endmsg;
1372                 goto out;
1373         } else if (load_routes (*child, version)) {
1374                 goto out;
1375         }
1376
1377         /* our diskstreams list is no longer needed as they are now all owned by their Route */
1378         _diskstreams_2X.clear ();
1379
1380         if (version >= 3000) {
1381
1382                 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1383                         error << _("Session: XML state has no route groups section") << endmsg;
1384                         goto out;
1385                 } else if (load_route_groups (*child, version)) {
1386                         goto out;
1387                 }
1388
1389         } else if (version < 3000) {
1390
1391                 if ((child = find_named_node (node, "EditGroups")) == 0) {
1392                         error << _("Session: XML state has no edit groups section") << endmsg;
1393                         goto out;
1394                 } else if (load_route_groups (*child, version)) {
1395                         goto out;
1396                 }
1397
1398                 if ((child = find_named_node (node, "MixGroups")) == 0) {
1399                         error << _("Session: XML state has no mix groups section") << endmsg;
1400                         goto out;
1401                 } else if (load_route_groups (*child, version)) {
1402                         goto out;
1403                 }
1404         }
1405
1406         if ((child = find_named_node (node, "Click")) == 0) {
1407                 warning << _("Session: XML state has no click section") << endmsg;
1408         } else if (_click_io) {
1409                 _click_io->set_state (*child, version);
1410         }
1411
1412         if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1413                 ControlProtocolManager::instance().set_protocol_states (*child);
1414         }
1415
1416         /* here beginneth the second phase ... */
1417
1418         StateReady (); /* EMIT SIGNAL */
1419
1420         return 0;
1421
1422   out:
1423         return ret;
1424 }
1425
1426 int
1427 Session::load_routes (const XMLNode& node, int version)
1428 {
1429         XMLNodeList nlist;
1430         XMLNodeConstIterator niter;
1431         RouteList new_routes;
1432
1433         nlist = node.children();
1434
1435         set_dirty();
1436
1437         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1438
1439                 boost::shared_ptr<Route> route;
1440                 if (version < 3000) {
1441                         route = XMLRouteFactory_2X (**niter, version);
1442                 } else {
1443                         route = XMLRouteFactory (**niter, version);
1444                 }
1445
1446                 if (route == 0) {
1447                         error << _("Session: cannot create Route from XML description.") << endmsg;
1448                         return -1;
1449                 }
1450
1451                 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1452
1453                 new_routes.push_back (route);
1454         }
1455
1456         add_routes (new_routes, false, false);
1457
1458         return 0;
1459 }
1460
1461 boost::shared_ptr<Route>
1462 Session::XMLRouteFactory (const XMLNode& node, int version)
1463 {
1464         boost::shared_ptr<Route> ret;
1465
1466         if (node.name() != "Route") {
1467                 return ret;
1468         }
1469
1470         XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1471
1472         DataType type = DataType::AUDIO;
1473         const XMLProperty* prop = node.property("default-type");
1474
1475         if (prop) {
1476                 type = DataType (prop->value());
1477         }
1478
1479         assert (type != DataType::NIL);
1480
1481         if (ds_child) {
1482
1483                 boost::shared_ptr<Track> track;
1484
1485                 if (type == DataType::AUDIO) {
1486                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1487                 } else {
1488                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1489                 }
1490
1491                 if (track->init()) {
1492                         return ret;
1493                 }
1494
1495                 if (track->set_state (node, version)) {
1496                         return ret;
1497                 }
1498
1499 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1500                 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1501 #endif
1502                 ret = track;
1503
1504         } else {
1505                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1506
1507                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1508 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1509                         boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1510 #endif
1511                         ret = r;
1512                 }
1513         }
1514
1515         return ret;
1516 }
1517
1518 boost::shared_ptr<Route>
1519 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1520 {
1521         boost::shared_ptr<Route> ret;
1522
1523         if (node.name() != "Route") {
1524                 return ret;
1525         }
1526
1527         XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1528         if (!ds_prop) {
1529                 ds_prop = node.property (X_("diskstream"));
1530         }
1531
1532         DataType type = DataType::AUDIO;
1533         const XMLProperty* prop = node.property("default-type");
1534
1535         if (prop) {
1536                 type = DataType (prop->value());
1537         }
1538
1539         assert (type != DataType::NIL);
1540
1541         if (ds_prop) {
1542
1543                 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1544                 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1545                         ++i;
1546                 }
1547
1548                 if (i == _diskstreams_2X.end()) {
1549                         error << _("Could not find diskstream for route") << endmsg;
1550                         return boost::shared_ptr<Route> ();
1551                 }
1552
1553                 boost::shared_ptr<Track> track;
1554
1555                 if (type == DataType::AUDIO) {
1556                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1557                 } else {
1558                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1559                 }
1560
1561                 if (track->init()) {
1562                         return ret;
1563                 }
1564
1565                 if (track->set_state (node, version)) {
1566                         return ret;
1567                 }
1568
1569                 track->set_diskstream (*i);
1570
1571 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1572                 boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1573 #endif
1574                 ret = track;
1575
1576         } else {
1577                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1578
1579                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1580 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1581                         boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1582 #endif
1583                         ret = r;
1584                 }
1585         }
1586
1587         return ret;
1588 }
1589
1590 int
1591 Session::load_regions (const XMLNode& node)
1592 {
1593         XMLNodeList nlist;
1594         XMLNodeConstIterator niter;
1595         boost::shared_ptr<Region> region;
1596
1597         nlist = node.children();
1598
1599         set_dirty();
1600
1601         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1602                 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1603                         error << _("Session: cannot create Region from XML description.");
1604                         const XMLProperty *name = (**niter).property("name");
1605
1606                         if (name) {
1607                                 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1608                         }
1609
1610                         error << endmsg;
1611                 }
1612         }
1613
1614         return 0;
1615 }
1616
1617 int
1618 Session::load_compounds (const XMLNode& node)
1619 {
1620         XMLNodeList calist = node.children();
1621         XMLNodeConstIterator caiter;
1622         XMLProperty *caprop;
1623
1624         for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1625                 XMLNode* ca = *caiter;
1626                 ID orig_id;
1627                 ID copy_id;
1628
1629                 if ((caprop = ca->property (X_("original"))) == 0) {
1630                         continue;
1631                 }
1632                 orig_id = caprop->value();
1633
1634                 if ((caprop = ca->property (X_("copy"))) == 0) {
1635                         continue;
1636                 }
1637                 copy_id = caprop->value();
1638
1639                 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1640                 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1641
1642                 if (!orig || !copy) {
1643                         warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1644                                                    orig_id, copy_id)
1645                                 << endmsg;
1646                         continue;
1647                 }
1648
1649                 RegionFactory::add_compound_association (orig, copy);
1650         }
1651
1652         return 0;
1653 }
1654
1655 void
1656 Session::load_nested_sources (const XMLNode& node)
1657 {
1658         XMLNodeList nlist;
1659         XMLNodeConstIterator niter;
1660
1661         nlist = node.children();
1662
1663         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1664                 if ((*niter)->name() == "Source") {
1665
1666                         /* it may already exist, so don't recreate it unnecessarily 
1667                          */
1668
1669                         XMLProperty* prop = (*niter)->property (X_("id"));
1670                         if (!prop) {
1671                                 error << _("Nested source has no ID info in session state file! (ignored)") << endmsg;
1672                                 continue;
1673                         }
1674
1675                         ID source_id (prop->value());
1676
1677                         if (!source_by_id (source_id)) {
1678
1679                                 try {
1680                                         SourceFactory::create (*this, **niter, true);
1681                                 }
1682                                 catch (failed_constructor& err) {
1683                                         error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1684                                 }
1685                         }
1686                 }
1687         }
1688 }
1689
1690 boost::shared_ptr<Region>
1691 Session::XMLRegionFactory (const XMLNode& node, bool full)
1692 {
1693         const XMLProperty* type = node.property("type");
1694
1695         try {
1696
1697                 const XMLNodeList& nlist = node.children();
1698
1699                 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1700                         XMLNode *child = (*niter);
1701                         if (child->name() == "NestedSource") {
1702                                 load_nested_sources (*child);
1703                         }
1704                 }
1705
1706                 if (!type || type->value() == "audio") {
1707                         return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1708                 } else if (type->value() == "midi") {
1709                         return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1710                 }
1711
1712         } catch (failed_constructor& err) {
1713                 return boost::shared_ptr<Region> ();
1714         }
1715
1716         return boost::shared_ptr<Region> ();
1717 }
1718
1719 boost::shared_ptr<AudioRegion>
1720 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1721 {
1722         const XMLProperty* prop;
1723         boost::shared_ptr<Source> source;
1724         boost::shared_ptr<AudioSource> as;
1725         SourceList sources;
1726         SourceList master_sources;
1727         uint32_t nchans = 1;
1728         char buf[128];
1729
1730         if (node.name() != X_("Region")) {
1731                 return boost::shared_ptr<AudioRegion>();
1732         }
1733
1734         if ((prop = node.property (X_("channels"))) != 0) {
1735                 nchans = atoi (prop->value().c_str());
1736         }
1737
1738         if ((prop = node.property ("name")) == 0) {
1739                 cerr << "no name for this region\n";
1740                 abort ();
1741         }
1742
1743         if ((prop = node.property (X_("source-0"))) == 0) {
1744                 if ((prop = node.property ("source")) == 0) {
1745                         error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1746                         return boost::shared_ptr<AudioRegion>();
1747                 }
1748         }
1749
1750         PBD::ID s_id (prop->value());
1751
1752         if ((source = source_by_id (s_id)) == 0) {
1753                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1754                 return boost::shared_ptr<AudioRegion>();
1755         }
1756
1757         as = boost::dynamic_pointer_cast<AudioSource>(source);
1758         if (!as) {
1759                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1760                 return boost::shared_ptr<AudioRegion>();
1761         }
1762
1763         sources.push_back (as);
1764
1765         /* pickup other channels */
1766
1767         for (uint32_t n=1; n < nchans; ++n) {
1768                 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1769                 if ((prop = node.property (buf)) != 0) {
1770
1771                         PBD::ID id2 (prop->value());
1772
1773                         if ((source = source_by_id (id2)) == 0) {
1774                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1775                                 return boost::shared_ptr<AudioRegion>();
1776                         }
1777
1778                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1779                         if (!as) {
1780                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1781                                 return boost::shared_ptr<AudioRegion>();
1782                         }
1783                         sources.push_back (as);
1784                 }
1785         }
1786
1787         for (uint32_t n = 0; n < nchans; ++n) {
1788                 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1789                 if ((prop = node.property (buf)) != 0) {
1790
1791                         PBD::ID id2 (prop->value());
1792
1793                         if ((source = source_by_id (id2)) == 0) {
1794                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1795                                 return boost::shared_ptr<AudioRegion>();
1796                         }
1797
1798                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1799                         if (!as) {
1800                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1801                                 return boost::shared_ptr<AudioRegion>();
1802                         }
1803                         master_sources.push_back (as);
1804                 }
1805         }
1806
1807         try {
1808                 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1809
1810                 /* a final detail: this is the one and only place that we know how long missing files are */
1811
1812                 if (region->whole_file()) {
1813                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1814                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1815                                 if (sfp) {
1816                                         sfp->set_length (region->length());
1817                                 }
1818                         }
1819                 }
1820
1821                 if (!master_sources.empty()) {
1822                         if (master_sources.size() != nchans) {
1823                                 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1824                         } else {
1825                                 region->set_master_sources (master_sources);
1826                         }
1827                 }
1828
1829                 return region;
1830
1831         }
1832
1833         catch (failed_constructor& err) {
1834                 return boost::shared_ptr<AudioRegion>();
1835         }
1836 }
1837
1838 boost::shared_ptr<MidiRegion>
1839 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1840 {
1841         const XMLProperty* prop;
1842         boost::shared_ptr<Source> source;
1843         boost::shared_ptr<MidiSource> ms;
1844         SourceList sources;
1845
1846         if (node.name() != X_("Region")) {
1847                 return boost::shared_ptr<MidiRegion>();
1848         }
1849
1850         if ((prop = node.property ("name")) == 0) {
1851                 cerr << "no name for this region\n";
1852                 abort ();
1853         }
1854
1855         if ((prop = node.property (X_("source-0"))) == 0) {
1856                 if ((prop = node.property ("source")) == 0) {
1857                         error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1858                         return boost::shared_ptr<MidiRegion>();
1859                 }
1860         }
1861
1862         PBD::ID s_id (prop->value());
1863
1864         if ((source = source_by_id (s_id)) == 0) {
1865                 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1866                 return boost::shared_ptr<MidiRegion>();
1867         }
1868
1869         ms = boost::dynamic_pointer_cast<MidiSource>(source);
1870         if (!ms) {
1871                 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1872                 return boost::shared_ptr<MidiRegion>();
1873         }
1874
1875         sources.push_back (ms);
1876
1877         try {
1878                 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1879                 /* a final detail: this is the one and only place that we know how long missing files are */
1880
1881                 if (region->whole_file()) {
1882                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1883                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1884                                 if (sfp) {
1885                                         sfp->set_length (region->length());
1886                                 }
1887                         }
1888                 }
1889
1890                 return region;
1891         }
1892
1893         catch (failed_constructor& err) {
1894                 return boost::shared_ptr<MidiRegion>();
1895         }
1896 }
1897
1898 XMLNode&
1899 Session::get_sources_as_xml ()
1900
1901 {
1902         XMLNode* node = new XMLNode (X_("Sources"));
1903         Glib::Mutex::Lock lm (source_lock);
1904
1905         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1906                 node->add_child_nocopy (i->second->get_state());
1907         }
1908
1909         return *node;
1910 }
1911
1912 string
1913 Session::path_from_region_name (DataType type, string name, string identifier)
1914 {
1915         char buf[PATH_MAX+1];
1916         uint32_t n;
1917         SessionDirectory sdir(get_best_session_directory_for_new_source());
1918         sys::path source_dir = ((type == DataType::AUDIO)
1919                 ? sdir.sound_path() : sdir.midi_path());
1920
1921         string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1922
1923         for (n = 0; n < 999999; ++n) {
1924                 if (identifier.length()) {
1925                         snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1926                                   identifier.c_str(), n, ext.c_str());
1927                 } else {
1928                         snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1929                                         n, ext.c_str());
1930                 }
1931
1932                 sys::path source_path = source_dir / buf;
1933
1934                 if (!sys::exists (source_path)) {
1935                         return source_path.to_string();
1936                 }
1937         }
1938
1939         error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1940                                  name, identifier)
1941               << endmsg;
1942
1943         return "";
1944 }
1945
1946
1947 int
1948 Session::load_sources (const XMLNode& node)
1949 {
1950         XMLNodeList nlist;
1951         XMLNodeConstIterator niter;
1952         boost::shared_ptr<Source> source;
1953
1954         nlist = node.children();
1955
1956         set_dirty();
1957
1958         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1959           retry:
1960                 try {
1961                         if ((source = XMLSourceFactory (**niter)) == 0) {
1962                                 error << _("Session: cannot create Source from XML description.") << endmsg;
1963                         }
1964
1965                 } catch (MissingSource& err) {
1966
1967                         int user_choice;
1968
1969                         if (!no_questions_about_missing_files) {
1970                                 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1971                         } else {
1972                                 user_choice = -2;
1973                         }
1974
1975                         switch (user_choice) {
1976                         case 0:
1977                                 /* user added a new search location, so try again */
1978                                 goto retry;
1979
1980
1981                         case 1:
1982                                 /* user asked to quit the entire session load
1983                                  */
1984                                 return -1;
1985
1986                         case 2:
1987                                 no_questions_about_missing_files = true;
1988                                 goto retry;
1989
1990                         case 3:
1991                                 no_questions_about_missing_files = true;
1992                                 /* fallthru */
1993
1994                         case -1:
1995                         default:
1996                                 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1997                                 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
1998                                 break;
1999                         }
2000                 }
2001         }
2002
2003         return 0;
2004 }
2005
2006 boost::shared_ptr<Source>
2007 Session::XMLSourceFactory (const XMLNode& node)
2008 {
2009         if (node.name() != "Source") {
2010                 return boost::shared_ptr<Source>();
2011         }
2012
2013         try {
2014                 /* note: do peak building in another thread when loading session state */
2015                 return SourceFactory::create (*this, node, true);
2016         }
2017
2018         catch (failed_constructor& err) {
2019                 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2020                 return boost::shared_ptr<Source>();
2021         }
2022 }
2023
2024 int
2025 Session::save_template (string template_name)
2026 {
2027         XMLTree tree;
2028
2029         if (_state_of_the_state & CannotSave) {
2030                 return -1;
2031         }
2032
2033         sys::path user_template_dir(user_template_directory());
2034
2035         try
2036         {
2037                 sys::create_directories (user_template_dir);
2038         }
2039         catch(sys::filesystem_error& ex)
2040         {
2041                 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
2042                                 user_template_dir.to_string(), ex.what()) << endmsg;
2043                 return -1;
2044         }
2045
2046         tree.set_root (&get_template());
2047
2048         sys::path template_file_path(user_template_dir);
2049         template_file_path /= template_name + template_suffix;
2050
2051         if (sys::exists (template_file_path))
2052         {
2053                 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2054                                 template_file_path.to_string()) << endmsg;
2055                 return -1;
2056         }
2057
2058         if (!tree.write (template_file_path.to_string())) {
2059                 error << _("template not saved") << endmsg;
2060                 return -1;
2061         }
2062
2063         return 0;
2064 }
2065
2066 int
2067 Session::rename_template (string old_name, string new_name)
2068 {
2069         sys::path old_path (user_template_directory());
2070         old_path /= old_name + template_suffix;
2071
2072         sys::path new_path(user_template_directory());
2073         new_path /= new_name + template_suffix;
2074
2075         if (sys::exists (new_path)) {
2076                 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
2077                                           new_path.to_string()) << endmsg;
2078                 return -1;
2079         }
2080
2081         try {
2082                 sys::rename (old_path, new_path);
2083                 return 0;
2084         } catch (...) {
2085                 return -1;
2086         }
2087 }
2088
2089 int
2090 Session::delete_template (string name)
2091 {
2092         sys::path path = user_template_directory();
2093         path /= name + template_suffix;
2094
2095         try {
2096                 sys::remove (path);
2097                 return 0;
2098         } catch (...) {
2099                 return -1;
2100         }
2101 }
2102
2103 void
2104 Session::refresh_disk_space ()
2105 {
2106 #if HAVE_SYS_VFS_H
2107         struct statfs statfsbuf;
2108         vector<space_and_path>::iterator i;
2109         Glib::Mutex::Lock lm (space_lock);
2110         double scale;
2111
2112         /* get freespace on every FS that is part of the session path */
2113
2114         _total_free_4k_blocks = 0;
2115
2116         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2117                 statfs ((*i).path.c_str(), &statfsbuf);
2118
2119                 scale = statfsbuf.f_bsize/4096.0;
2120
2121                 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2122                 _total_free_4k_blocks += (*i).blocks;
2123         }
2124 #endif
2125 }
2126
2127 string
2128 Session::get_best_session_directory_for_new_source ()
2129 {
2130         vector<space_and_path>::iterator i;
2131         string result = _session_dir->root_path().to_string();
2132
2133         /* handle common case without system calls */
2134
2135         if (session_dirs.size() == 1) {
2136                 return result;
2137         }
2138
2139         /* OK, here's the algorithm we're following here:
2140
2141         We want to select which directory to use for
2142         the next file source to be created. Ideally,
2143         we'd like to use a round-robin process so as to
2144         get maximum performance benefits from splitting
2145         the files across multiple disks.
2146
2147         However, in situations without much diskspace, an
2148         RR approach may end up filling up a filesystem
2149         with new files while others still have space.
2150         Its therefore important to pay some attention to
2151         the freespace in the filesystem holding each
2152         directory as well. However, if we did that by
2153         itself, we'd keep creating new files in the file
2154         system with the most space until it was as full
2155         as all others, thus negating any performance
2156         benefits of this RAID-1 like approach.
2157
2158         So, we use a user-configurable space threshold. If
2159         there are at least 2 filesystems with more than this
2160         much space available, we use RR selection between them.
2161         If not, then we pick the filesystem with the most space.
2162
2163         This gets a good balance between the two
2164         approaches.
2165         */
2166
2167         refresh_disk_space ();
2168
2169         int free_enough = 0;
2170
2171         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2172                 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2173                         free_enough++;
2174                 }
2175         }
2176
2177         if (free_enough >= 2) {
2178                 /* use RR selection process, ensuring that the one
2179                    picked works OK.
2180                 */
2181
2182                 i = last_rr_session_dir;
2183
2184                 do {
2185                         if (++i == session_dirs.end()) {
2186                                 i = session_dirs.begin();
2187                         }
2188
2189                         if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2190                                 if (create_session_directory ((*i).path)) {
2191                                         result = (*i).path;
2192                                         last_rr_session_dir = i;
2193                                         return result;
2194                                 }
2195                         }
2196
2197                 } while (i != last_rr_session_dir);
2198
2199         } else {
2200
2201                 /* pick FS with the most freespace (and that
2202                    seems to actually work ...)
2203                 */
2204
2205                 vector<space_and_path> sorted;
2206                 space_and_path_ascending_cmp cmp;
2207
2208                 sorted = session_dirs;
2209                 sort (sorted.begin(), sorted.end(), cmp);
2210
2211                 for (i = sorted.begin(); i != sorted.end(); ++i) {
2212                         if (create_session_directory ((*i).path)) {
2213                                 result = (*i).path;
2214                                 last_rr_session_dir = i;
2215                                 return result;
2216                         }
2217                 }
2218         }
2219
2220         return result;
2221 }
2222
2223 int
2224 Session::load_named_selections (const XMLNode& node)
2225 {
2226         XMLNodeList nlist;
2227         XMLNodeConstIterator niter;
2228         NamedSelection *ns;
2229
2230         nlist = node.children();
2231
2232         set_dirty();
2233
2234         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2235
2236                 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2237                         error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2238                 }
2239         }
2240
2241         return 0;
2242 }
2243
2244 NamedSelection *
2245 Session::XMLNamedSelectionFactory (const XMLNode& node)
2246 {
2247         try {
2248                 return new NamedSelection (*this, node);
2249         }
2250
2251         catch (failed_constructor& err) {
2252                 return 0;
2253         }
2254 }
2255
2256 string
2257 Session::automation_dir () const
2258 {
2259         return Glib::build_filename (_path, "automation");
2260 }
2261
2262 string
2263 Session::analysis_dir () const
2264 {
2265         return Glib::build_filename (_path, "analysis");
2266 }
2267
2268 string
2269 Session::plugins_dir () const
2270 {
2271         return Glib::build_filename (_path, "plugins");
2272 }
2273
2274 int
2275 Session::load_bundles (XMLNode const & node)
2276 {
2277         XMLNodeList nlist = node.children();
2278         XMLNodeConstIterator niter;
2279
2280         set_dirty();
2281
2282         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2283                 if ((*niter)->name() == "InputBundle") {
2284                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2285                 } else if ((*niter)->name() == "OutputBundle") {
2286                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2287                 } else {
2288                         error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2289                         return -1;
2290                 }
2291         }
2292
2293         return 0;
2294 }
2295
2296 int
2297 Session::load_route_groups (const XMLNode& node, int version)
2298 {
2299         XMLNodeList nlist = node.children();
2300         XMLNodeConstIterator niter;
2301
2302         set_dirty ();
2303
2304         if (version >= 3000) {
2305
2306                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2307                         if ((*niter)->name() == "RouteGroup") {
2308                                 RouteGroup* rg = new RouteGroup (*this, "");
2309                                 add_route_group (rg);
2310                                 rg->set_state (**niter, version);
2311                         }
2312                 }
2313
2314         } else if (version < 3000) {
2315
2316                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2317                         if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2318                                 RouteGroup* rg = new RouteGroup (*this, "");
2319                                 add_route_group (rg);
2320                                 rg->set_state (**niter, version);
2321                         }
2322                 }
2323         }
2324
2325         return 0;
2326 }
2327
2328 void
2329 Session::auto_save()
2330 {
2331         save_state (_current_snapshot_name);
2332 }
2333
2334 static bool
2335 state_file_filter (const string &str, void */*arg*/)
2336 {
2337         return (str.length() > strlen(statefile_suffix) &&
2338                 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2339 }
2340
2341 struct string_cmp {
2342         bool operator()(const string* a, const string* b) {
2343                 return *a < *b;
2344         }
2345 };
2346
2347 static string*
2348 remove_end(string* state)
2349 {
2350         string statename(*state);
2351
2352         string::size_type start,end;
2353         if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2354                 statename = statename.substr (start+1);
2355         }
2356
2357         if ((end = statename.rfind(".ardour")) == string::npos) {
2358                 end = statename.length();
2359         }
2360
2361         return new string(statename.substr (0, end));
2362 }
2363
2364 vector<string *> *
2365 Session::possible_states (string path)
2366 {
2367         PathScanner scanner;
2368         vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2369
2370         transform(states->begin(), states->end(), states->begin(), remove_end);
2371
2372         string_cmp cmp;
2373         sort (states->begin(), states->end(), cmp);
2374
2375         return states;
2376 }
2377
2378 vector<string *> *
2379 Session::possible_states () const
2380 {
2381         return possible_states(_path);
2382 }
2383
2384 void
2385 Session::add_route_group (RouteGroup* g)
2386 {
2387         _route_groups.push_back (g);
2388         route_group_added (g); /* EMIT SIGNAL */
2389
2390         g->MembershipChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2391         g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2392
2393         set_dirty ();
2394 }
2395
2396 void
2397 Session::remove_route_group (RouteGroup& rg)
2398 {
2399         list<RouteGroup*>::iterator i;
2400
2401         if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2402                 _route_groups.erase (i);
2403                 delete &rg;
2404
2405                 route_group_removed (); /* EMIT SIGNAL */
2406         }
2407 }
2408
2409 /** Set a new order for our route groups, without adding or removing any.
2410  *  @param groups Route group list in the new order.
2411  */
2412 void
2413 Session::reorder_route_groups (list<RouteGroup*> groups)
2414 {
2415         _route_groups = groups;
2416
2417         route_groups_reordered (); /* EMIT SIGNAL */
2418         set_dirty ();
2419 }
2420
2421
2422 RouteGroup *
2423 Session::route_group_by_name (string name)
2424 {
2425         list<RouteGroup *>::iterator i;
2426
2427         for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2428                 if ((*i)->name() == name) {
2429                         return* i;
2430                 }
2431         }
2432         return 0;
2433 }
2434
2435 RouteGroup&
2436 Session::all_route_group() const
2437 {
2438         return *_all_route_group;
2439 }
2440
2441 void
2442 Session::add_commands (vector<Command*> const & cmds)
2443 {
2444         for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2445                 add_command (*i);
2446         }
2447 }
2448
2449 void
2450 Session::begin_reversible_command (const string& name)
2451 {
2452         begin_reversible_command (g_quark_from_string (name.c_str ()));
2453 }
2454
2455 /** Begin a reversible command using a GQuark to identify it.
2456  *  begin_reversible_command() and commit_reversible_command() calls may be nested,
2457  *  but there must be as many begin...()s as there are commit...()s.
2458  */
2459 void
2460 Session::begin_reversible_command (GQuark q)
2461 {
2462         /* If nested begin/commit pairs are used, we create just one UndoTransaction
2463            to hold all the commands that are committed.  This keeps the order of
2464            commands correct in the history.
2465         */
2466
2467         if (_current_trans == 0) {
2468                 /* start a new transaction */
2469                 assert (_current_trans_quarks.empty ());
2470                 _current_trans = new UndoTransaction();
2471                 _current_trans->set_name (g_quark_to_string (q));
2472         }
2473
2474         _current_trans_quarks.push_front (q);
2475 }
2476
2477 void
2478 Session::commit_reversible_command (Command *cmd)
2479 {
2480         assert (_current_trans);
2481         assert (!_current_trans_quarks.empty ());
2482
2483         struct timeval now;
2484
2485         if (cmd) {
2486                 _current_trans->add_command (cmd);
2487         }
2488
2489         _current_trans_quarks.pop_front ();
2490
2491         if (!_current_trans_quarks.empty ()) {
2492                 /* the transaction we're committing is not the top-level one */
2493                 return;
2494         }
2495
2496         if (_current_trans->empty()) {
2497                 /* no commands were added to the transaction, so just get rid of it */
2498                 delete _current_trans;
2499                 _current_trans = 0;
2500                 return;
2501         }
2502
2503         gettimeofday (&now, 0);
2504         _current_trans->set_timestamp (now);
2505
2506         _history.add (_current_trans);
2507         _current_trans = 0;
2508 }
2509
2510 static bool
2511 accept_all_audio_files (const string& path, void */*arg*/)
2512 {
2513         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2514                 return false;
2515         }
2516
2517         if (!AudioFileSource::safe_audio_file_extension (path)) {
2518                 return false;
2519         }
2520
2521         return true;
2522 }
2523
2524 static bool
2525 accept_all_midi_files (const string& path, void */*arg*/)
2526 {
2527         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2528                 return false;
2529         }
2530
2531         return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2532                 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2533                 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2534 }
2535
2536 static bool
2537 accept_all_state_files (const string& path, void */*arg*/)
2538 {
2539         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2540                 return false;
2541         }
2542
2543         return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2544 }
2545
2546 int
2547 Session::find_all_sources (string path, set<string>& result)
2548 {
2549         XMLTree tree;
2550         XMLNode* node;
2551
2552         if (!tree.read (path)) {
2553                 return -1;
2554         }
2555
2556         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2557                 return -2;
2558         }
2559
2560         XMLNodeList nlist;
2561         XMLNodeConstIterator niter;
2562
2563         nlist = node->children();
2564
2565         set_dirty();
2566
2567         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2568
2569                 XMLProperty* prop;
2570
2571                 if ((prop = (*niter)->property (X_("type"))) == 0) {
2572                         continue;
2573                 }
2574
2575                 DataType type (prop->value());
2576
2577                 if ((prop = (*niter)->property (X_("name"))) == 0) {
2578                         continue;
2579                 }
2580
2581                 if (Glib::path_is_absolute (prop->value())) {
2582                         /* external file, ignore */
2583                         continue;
2584                 }
2585
2586                 string found_path;
2587                 bool is_new;
2588                 uint16_t chan;
2589
2590                 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2591                         result.insert (found_path);
2592                 }
2593         }
2594
2595         return 0;
2596 }
2597
2598 int
2599 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2600 {
2601         PathScanner scanner;
2602         vector<string*>* state_files;
2603         string ripped;
2604         string this_snapshot_path;
2605
2606         result.clear ();
2607
2608         ripped = _path;
2609
2610         if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2611                 ripped = ripped.substr (0, ripped.length() - 1);
2612         }
2613
2614         state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2615
2616         if (state_files == 0) {
2617                 /* impossible! */
2618                 return 0;
2619         }
2620
2621         this_snapshot_path = _path;
2622         this_snapshot_path += legalize_for_path (_current_snapshot_name);
2623         this_snapshot_path += statefile_suffix;
2624
2625         for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2626
2627                 if (exclude_this_snapshot && **i == this_snapshot_path) {
2628                         continue;
2629                 }
2630
2631                 if (find_all_sources (**i, result) < 0) {
2632                         return -1;
2633                 }
2634         }
2635
2636         return 0;
2637 }
2638
2639 struct RegionCounter {
2640     typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2641     AudioSourceList::iterator iter;
2642     boost::shared_ptr<Region> region;
2643     uint32_t count;
2644
2645     RegionCounter() : count (0) {}
2646 };
2647
2648 int
2649 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2650 {
2651         boost::optional<int> r = AskAboutPlaylistDeletion (p);
2652         return r.get_value_or (1);
2653 }
2654
2655 void
2656 Session::cleanup_regions ()
2657 {
2658         const RegionFactory::RegionMap& regions (RegionFactory::regions());
2659
2660         for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2661
2662                 boost::shared_ptr<AudioRegion> audio_region = boost::dynamic_pointer_cast<AudioRegion>( i->second);
2663
2664                 if (!audio_region) {
2665                         continue;
2666                 }
2667
2668                 uint32_t used = playlists->region_use_count (audio_region);
2669
2670                 if (used == 0 && !audio_region->automatic()) {
2671                         RegionFactory::map_remove(i->second);
2672                 }
2673         }
2674
2675         /* dump the history list */
2676         _history.clear ();
2677
2678         save_state ("");
2679 }
2680
2681 int
2682 Session::cleanup_sources (CleanupReport& rep)
2683 {
2684         // FIXME: needs adaptation to midi
2685
2686         vector<boost::shared_ptr<Source> > dead_sources;
2687         PathScanner scanner;
2688         string audio_path;
2689         string midi_path;
2690         vector<space_and_path>::iterator i;
2691         vector<space_and_path>::iterator nexti;
2692         vector<string*>* candidates;
2693         vector<string*>* candidates2;
2694         vector<string> unused;
2695         set<string> all_sources;
2696         bool used;
2697         string spath;
2698         int ret = -1;
2699
2700         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2701
2702         /* consider deleting all unused playlists */
2703
2704         if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2705                 ret = 0;
2706                 goto out;
2707         }
2708
2709         /* sync the "all regions" property of each playlist with its current state
2710          */
2711
2712         playlists->sync_all_regions_with_regions ();
2713
2714         /* find all un-used sources */
2715
2716         rep.paths.clear ();
2717         rep.space = 0;
2718
2719         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2720
2721                 SourceMap::iterator tmp;
2722
2723                 tmp = i;
2724                 ++tmp;
2725
2726                 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2727                    capture files.
2728                 */
2729
2730                 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2731                         dead_sources.push_back (i->second);
2732                         i->second->drop_references ();
2733                 }
2734
2735                 i = tmp;
2736         }
2737
2738         /* build a list of all the possible audio directories for the session */
2739
2740         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2741
2742                 nexti = i;
2743                 ++nexti;
2744
2745                 SessionDirectory sdir ((*i).path);
2746                 audio_path += sdir.sound_path().to_string();
2747
2748                 if (nexti != session_dirs.end()) {
2749                         audio_path += ':';
2750                 }
2751
2752                 i = nexti;
2753         }
2754
2755
2756         /* build a list of all the possible midi directories for the session */
2757
2758         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2759
2760                 nexti = i;
2761                 ++nexti;
2762
2763                 SessionDirectory sdir ((*i).path);
2764                 midi_path += sdir.midi_path().to_string();
2765
2766                 if (nexti != session_dirs.end()) {
2767                         midi_path += ':';
2768                 }
2769
2770                 i = nexti;
2771         }
2772
2773         candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2774         candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2775
2776         /* merge them */
2777
2778         if (candidates) {
2779                 if (candidates2) {
2780                         for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2781                                 candidates->push_back (*i);
2782                         }
2783                         delete candidates2;
2784                 }
2785         } else {
2786                 candidates = candidates2; // might still be null
2787         }
2788
2789         /* find all sources, but don't use this snapshot because the
2790            state file on disk still references sources we may have already
2791            dropped.
2792         */
2793
2794         find_all_sources_across_snapshots (all_sources, true);
2795
2796         /*  add our current source list
2797          */
2798
2799         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2800                 boost::shared_ptr<FileSource> fs;
2801                 SourceMap::iterator tmp = i;
2802                 ++tmp;
2803
2804                 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2805                         if (playlists->source_use_count (fs) != 0) {
2806                                 all_sources.insert (fs->path());
2807                         } else {
2808
2809                                 /* we might not remove this source from disk, because it may be used
2810                                    by other snapshots, but its not being used in this version
2811                                    so lets get rid of it now, along with any representative regions
2812                                    in the region list.
2813                                 */
2814
2815                                 RegionFactory::remove_regions_using_source (i->second);
2816                                 sources.erase (i);
2817                         }
2818                 }
2819
2820                 i = tmp;
2821         }
2822
2823         char tmppath1[PATH_MAX+1];
2824         char tmppath2[PATH_MAX+1];
2825
2826         if (candidates) {
2827                 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2828
2829                         used = false;
2830                         spath = **x;
2831
2832                         for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2833
2834                                 if (realpath(spath.c_str(), tmppath1) == 0) {
2835                                         error << string_compose (_("Cannot expand path %1 (%2)"),
2836                                                                  spath, strerror (errno)) << endmsg;
2837                                         continue;
2838                                 }
2839
2840                                 if (realpath((*i).c_str(),  tmppath2) == 0) {
2841                                         error << string_compose (_("Cannot expand path %1 (%2)"),
2842                                                                  (*i), strerror (errno)) << endmsg;
2843                                         continue;
2844                                 }
2845
2846                                 if (strcmp(tmppath1, tmppath2) == 0) {
2847                                         used = true;
2848                                         break;
2849                                 }
2850                         }
2851
2852                         if (!used) {
2853                                 unused.push_back (spath);
2854                         }
2855
2856                         delete *x;
2857                 }
2858
2859                 delete candidates;
2860         }
2861
2862         /* now try to move all unused files into the "dead" directory(ies) */
2863
2864         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2865                 struct stat statbuf;
2866
2867                 string newpath;
2868
2869                 /* don't move the file across filesystems, just
2870                    stick it in the `dead_dir_name' directory
2871                    on whichever filesystem it was already on.
2872                 */
2873
2874                 if ((*x).find ("/sounds/") != string::npos) {
2875
2876                         /* old school, go up 1 level */
2877
2878                         newpath = Glib::path_get_dirname (*x);      // "sounds"
2879                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2880
2881                 } else {
2882
2883                         /* new school, go up 4 levels */
2884
2885                         newpath = Glib::path_get_dirname (*x);      // "audiofiles" or "midifiles"
2886                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2887                         newpath = Glib::path_get_dirname (newpath); // "interchange"
2888                         newpath = Glib::path_get_dirname (newpath); // "session-dir"
2889                 }
2890
2891                 newpath = Glib::build_filename (newpath, dead_dir_name);
2892
2893                 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2894                         error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2895                         return -1;
2896                 }
2897
2898                 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2899
2900                 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2901
2902                         /* the new path already exists, try versioning */
2903
2904                         char buf[PATH_MAX+1];
2905                         int version = 1;
2906                         string newpath_v;
2907
2908                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2909                         newpath_v = buf;
2910
2911                         while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2912                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2913                                 newpath_v = buf;
2914                         }
2915
2916                         if (version == 999) {
2917                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2918                                                   newpath)
2919                                       << endmsg;
2920                         } else {
2921                                 newpath = newpath_v;
2922                         }
2923
2924                 } else {
2925
2926                         /* it doesn't exist, or we can't read it or something */
2927
2928                 }
2929
2930                 stat ((*x).c_str(), &statbuf);
2931
2932                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2933                         error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2934                                           (*x), newpath, strerror (errno))
2935                               << endmsg;
2936                         goto out;
2937                 }
2938
2939                 /* see if there an easy to find peakfile for this file, and remove it.
2940                  */
2941
2942                 string base = basename_nosuffix (*x);
2943                 base += "%A"; /* this is what we add for the channel suffix of all native files,
2944                                  or for the first channel of embedded files. it will miss
2945                                  some peakfiles for other channels
2946                               */
2947                 string peakpath = peak_path (base);
2948
2949                 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2950                         if (::unlink (peakpath.c_str()) != 0) {
2951                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2952                                                          peakpath, _path, strerror (errno))
2953                                       << endmsg;
2954                                 /* try to back out */
2955                                 ::rename (newpath.c_str(), _path.c_str());
2956                                 goto out;
2957                         }
2958                 }
2959
2960                 rep.paths.push_back (*x);
2961                 rep.space += statbuf.st_size;
2962         }
2963
2964         /* dump the history list */
2965
2966         _history.clear ();
2967
2968         /* save state so we don't end up a session file
2969            referring to non-existent sources.
2970         */
2971
2972         save_state ("");
2973         ret = 0;
2974
2975   out:
2976         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2977
2978         return ret;
2979 }
2980
2981 int
2982 Session::cleanup_trash_sources (CleanupReport& rep)
2983 {
2984         // FIXME: needs adaptation for MIDI
2985
2986         vector<space_and_path>::iterator i;
2987         string dead_dir;
2988
2989         rep.paths.clear ();
2990         rep.space = 0;
2991
2992         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2993
2994                 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2995
2996                 clear_directory (dead_dir, &rep.space, &rep.paths);
2997         }
2998
2999         return 0;
3000 }
3001
3002 void
3003 Session::set_dirty ()
3004 {
3005         bool was_dirty = dirty();
3006
3007         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3008
3009
3010         if (!was_dirty) {
3011                 DirtyChanged(); /* EMIT SIGNAL */
3012         }
3013 }
3014
3015
3016 void
3017 Session::set_clean ()
3018 {
3019         bool was_dirty = dirty();
3020
3021         _state_of_the_state = Clean;
3022
3023
3024         if (was_dirty) {
3025                 DirtyChanged(); /* EMIT SIGNAL */
3026         }
3027 }
3028
3029 void
3030 Session::set_deletion_in_progress ()
3031 {
3032         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3033 }
3034
3035 void
3036 Session::clear_deletion_in_progress ()
3037 {
3038         _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3039 }
3040
3041 void
3042 Session::add_controllable (boost::shared_ptr<Controllable> c)
3043 {
3044         /* this adds a controllable to the list managed by the Session.
3045            this is a subset of those managed by the Controllable class
3046            itself, and represents the only ones whose state will be saved
3047            as part of the session.
3048         */
3049
3050         Glib::Mutex::Lock lm (controllables_lock);
3051         controllables.insert (c);
3052 }
3053
3054 struct null_deleter { void operator()(void const *) const {} };
3055
3056 void
3057 Session::remove_controllable (Controllable* c)
3058 {
3059         if (_state_of_the_state | Deletion) {
3060                 return;
3061         }
3062
3063         Glib::Mutex::Lock lm (controllables_lock);
3064
3065         Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3066
3067         if (x != controllables.end()) {
3068                 controllables.erase (x);
3069         }
3070 }
3071
3072 boost::shared_ptr<Controllable>
3073 Session::controllable_by_id (const PBD::ID& id)
3074 {
3075         Glib::Mutex::Lock lm (controllables_lock);
3076
3077         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3078                 if ((*i)->id() == id) {
3079                         return *i;
3080                 }
3081         }
3082
3083         return boost::shared_ptr<Controllable>();
3084 }
3085
3086 boost::shared_ptr<Controllable>
3087 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3088 {
3089         boost::shared_ptr<Controllable> c;
3090         boost::shared_ptr<Route> r;
3091
3092         switch (desc.top_level_type()) {
3093         case ControllableDescriptor::NamedRoute:
3094         {
3095                 std::string str = desc.top_level_name();
3096                 if (str == "master") {
3097                         r = _master_out;
3098                 } else if (str == "control" || str == "listen") {
3099                         r = _monitor_out;
3100                 } else {
3101                         r = route_by_name (desc.top_level_name());
3102                 }
3103                 break;
3104         }
3105
3106         case ControllableDescriptor::RemoteControlID:
3107                 r = route_by_remote_id (desc.rid());
3108                 break;
3109         }
3110
3111         if (!r) {
3112                 return c;
3113         }
3114
3115         switch (desc.subtype()) {
3116         case ControllableDescriptor::Gain:
3117                 c = r->gain_control ();
3118                 break;
3119
3120         case ControllableDescriptor::Solo:
3121                 c = r->solo_control();
3122                 break;
3123
3124         case ControllableDescriptor::Mute:
3125                 c = r->mute_control();
3126                 break;
3127
3128         case ControllableDescriptor::Recenable:
3129         {
3130                 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3131
3132                 if (t) {
3133                         c = t->rec_enable_control ();
3134                 }
3135                 break;
3136         }
3137
3138         case ControllableDescriptor::PanDirection:
3139         {
3140                 c = r->pannable()->pan_azimuth_control;
3141                 break;
3142         }
3143
3144         case ControllableDescriptor::PanWidth:
3145         {
3146                 c = r->pannable()->pan_width_control;
3147                 break;
3148         }
3149
3150         case ControllableDescriptor::PanElevation:
3151         {
3152                 c = r->pannable()->pan_elevation_control;
3153                 break;
3154         }
3155
3156         case ControllableDescriptor::Balance:
3157                 /* XXX simple pan control */
3158                 break;
3159
3160         case ControllableDescriptor::PluginParameter:
3161         {
3162                 uint32_t plugin = desc.target (0);
3163                 uint32_t parameter_index = desc.target (1);
3164
3165                 /* revert to zero based counting */
3166
3167                 if (plugin > 0) {
3168                         --plugin;
3169                 }
3170
3171                 if (parameter_index > 0) {
3172                         --parameter_index;
3173                 }
3174
3175                 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3176
3177                 if (p) {
3178                         c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3179                                 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3180                 }
3181                 break;
3182         }
3183
3184         case ControllableDescriptor::SendGain:
3185         {
3186                 uint32_t send = desc.target (0);
3187
3188                 /* revert to zero-based counting */
3189
3190                 if (send > 0) {
3191                         --send;
3192                 }
3193
3194                 boost::shared_ptr<Processor> p = r->nth_send (send);
3195
3196                 if (p) {
3197                         boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3198                         boost::shared_ptr<Amp> a = s->amp();
3199
3200                         if (a) {
3201                                 c = s->amp()->gain_control();
3202                         }
3203                 }
3204                 break;
3205         }
3206
3207         default:
3208                 /* relax and return a null pointer */
3209                 break;
3210         }
3211
3212         return c;
3213 }
3214
3215 void
3216 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3217 {
3218         if (_writable) {
3219                 Stateful::add_instant_xml (node, _path);
3220         }
3221
3222         if (write_to_config) {
3223                 Config->add_instant_xml (node);
3224         }
3225 }
3226
3227 XMLNode*
3228 Session::instant_xml (const string& node_name)
3229 {
3230         return Stateful::instant_xml (node_name, _path);
3231 }
3232
3233 int
3234 Session::save_history (string snapshot_name)
3235 {
3236         XMLTree tree;
3237
3238         if (!_writable) {
3239                 return 0;
3240         }
3241
3242         if (snapshot_name.empty()) {
3243                 snapshot_name = _current_snapshot_name;
3244         }
3245
3246         const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3247         const string backup_filename = history_filename + backup_suffix;
3248         const sys::path xml_path = _session_dir->root_path() / history_filename;
3249         const sys::path backup_path = _session_dir->root_path() / backup_filename;
3250
3251         if (sys::exists (xml_path)) {
3252                 try
3253                 {
3254                         sys::rename (xml_path, backup_path);
3255                 }
3256                 catch (const sys::filesystem_error& err)
3257                 {
3258                         error << _("could not backup old history file, current history not saved") << endmsg;
3259                         return -1;
3260                 }
3261         }
3262
3263         if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3264                 return 0;
3265         }
3266
3267         tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3268
3269         if (!tree.write (xml_path.to_string()))
3270         {
3271                 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3272
3273                 try
3274                 {
3275                         sys::remove (xml_path);
3276                         sys::rename (backup_path, xml_path);
3277                 }
3278                 catch (const sys::filesystem_error& err)
3279                 {
3280                         error << string_compose (_("could not restore history file from backup %1 (%2)"),
3281                                         backup_path.to_string(), err.what()) << endmsg;
3282                 }
3283
3284                 return -1;
3285         }
3286
3287         return 0;
3288 }
3289
3290 int
3291 Session::restore_history (string snapshot_name)
3292 {
3293         XMLTree tree;
3294
3295         if (snapshot_name.empty()) {
3296                 snapshot_name = _current_snapshot_name;
3297         }
3298
3299         const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3300         const sys::path xml_path = _session_dir->root_path() / xml_filename;
3301
3302         info << "Loading history from " << xml_path.to_string() << endmsg;
3303
3304         if (!sys::exists (xml_path)) {
3305                 info << string_compose (_("%1: no history file \"%2\" for this session."),
3306                                 _name, xml_path.to_string()) << endmsg;
3307                 return 1;
3308         }
3309
3310         if (!tree.read (xml_path.to_string())) {
3311                 error << string_compose (_("Could not understand session history file \"%1\""),
3312                                 xml_path.to_string()) << endmsg;
3313                 return -1;
3314         }
3315
3316         // replace history
3317         _history.clear();
3318
3319         for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3320
3321                 XMLNode *t = *it;
3322                 UndoTransaction* ut = new UndoTransaction ();
3323                 struct timeval tv;
3324
3325                 ut->set_name(t->property("name")->value());
3326                 stringstream ss(t->property("tv-sec")->value());
3327                 ss >> tv.tv_sec;
3328                 ss.str(t->property("tv-usec")->value());
3329                 ss >> tv.tv_usec;
3330                 ut->set_timestamp(tv);
3331
3332                 for (XMLNodeConstIterator child_it  = t->children().begin();
3333                                 child_it != t->children().end(); child_it++)
3334                 {
3335                         XMLNode *n = *child_it;
3336                         Command *c;
3337
3338                         if (n->name() == "MementoCommand" ||
3339                                         n->name() == "MementoUndoCommand" ||
3340                                         n->name() == "MementoRedoCommand") {
3341
3342                                 if ((c = memento_command_factory(n))) {
3343                                         ut->add_command(c);
3344                                 }
3345
3346                         } else if (n->name() == "NoteDiffCommand") {
3347                                 PBD::ID id (n->property("midi-source")->value());
3348                                 boost::shared_ptr<MidiSource> midi_source =
3349                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3350                                 if (midi_source) {
3351                                         ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3352                                 } else {
3353                                         error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3354                                 }
3355
3356                         } else if (n->name() == "SysExDiffCommand") {
3357
3358                                 PBD::ID id (n->property("midi-source")->value());
3359                                 boost::shared_ptr<MidiSource> midi_source =
3360                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3361                                 if (midi_source) {
3362                                         ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3363                                 } else {
3364                                         error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3365                                 }
3366
3367                         } else if (n->name() == "PatchChangeDiffCommand") {
3368
3369                                 PBD::ID id (n->property("midi-source")->value());
3370                                 boost::shared_ptr<MidiSource> midi_source =
3371                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3372                                 if (midi_source) {
3373                                         ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3374                                 } else {
3375                                         error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3376                                 }
3377
3378                         } else if (n->name() == "StatefulDiffCommand") {
3379                                 if ((c = stateful_diff_command_factory (n))) {
3380                                         ut->add_command (c);
3381                                 }
3382                         } else {
3383                                 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3384                         }
3385                 }
3386
3387                 _history.add (ut);
3388         }
3389
3390         return 0;
3391 }
3392
3393 void
3394 Session::config_changed (std::string p, bool ours)
3395 {
3396         if (ours) {
3397                 set_dirty ();
3398         }
3399
3400         if (p == "seamless-loop") {
3401
3402         } else if (p == "rf-speed") {
3403
3404         } else if (p == "auto-loop") {
3405
3406         } else if (p == "auto-input") {
3407
3408                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3409                         /* auto-input only makes a difference if we're rolling */
3410                         set_track_monitor_input_status (!config.get_auto_input());
3411                 }
3412
3413         } else if (p == "punch-in") {
3414
3415                 Location* location;
3416
3417                 if ((location = _locations->auto_punch_location()) != 0) {
3418
3419                         if (config.get_punch_in ()) {
3420                                 replace_event (SessionEvent::PunchIn, location->start());
3421                         } else {
3422                                 remove_event (location->start(), SessionEvent::PunchIn);
3423                         }
3424                 }
3425
3426         } else if (p == "punch-out") {
3427
3428                 Location* location;
3429
3430                 if ((location = _locations->auto_punch_location()) != 0) {
3431
3432                         if (config.get_punch_out()) {
3433                                 replace_event (SessionEvent::PunchOut, location->end());
3434                         } else {
3435                                 clear_events (SessionEvent::PunchOut);
3436                         }
3437                 }
3438
3439         } else if (p == "edit-mode") {
3440
3441                 Glib::Mutex::Lock lm (playlists->lock);
3442
3443                 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3444                         (*i)->set_edit_mode (Config->get_edit_mode ());
3445                 }
3446
3447         } else if (p == "use-video-sync") {
3448
3449                 waiting_for_sync_offset = config.get_use_video_sync();
3450
3451         } else if (p == "mmc-control") {
3452
3453                 //poke_midi_thread ();
3454
3455         } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3456
3457                 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3458
3459         } else if (p == "mmc-send-id") {
3460
3461                 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3462
3463         } else if (p == "midi-control") {
3464
3465                 //poke_midi_thread ();
3466
3467         } else if (p == "raid-path") {
3468
3469                 setup_raid_path (config.get_raid_path());
3470
3471         } else if (p == "timecode-format") {
3472
3473                 sync_time_vars ();
3474
3475         } else if (p == "video-pullup") {
3476
3477                 sync_time_vars ();
3478
3479         } else if (p == "seamless-loop") {
3480
3481                 if (play_loop && transport_rolling()) {
3482                         // to reset diskstreams etc
3483                         request_play_loop (true);
3484                 }
3485
3486         } else if (p == "rf-speed") {
3487
3488                 cumulative_rf_motion = 0;
3489                 reset_rf_scale (0);
3490
3491         } else if (p == "click-sound") {
3492
3493                 setup_click_sounds (1);
3494
3495         } else if (p == "click-emphasis-sound") {
3496
3497                 setup_click_sounds (-1);
3498
3499         } else if (p == "clicking") {
3500
3501                 if (Config->get_clicking()) {
3502                         if (_click_io && click_data) { // don't require emphasis data
3503                                 _clicking = true;
3504                         }
3505                 } else {
3506                         _clicking = false;
3507                 }
3508
3509         } else if (p == "send-mtc") {
3510
3511                 if (Config->get_send_mtc ()) {
3512                         /* mark us ready to send */
3513                         next_quarter_frame_to_send = 0;
3514                 }
3515
3516         } else if (p == "send-mmc") {
3517
3518                 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3519
3520         } else if (p == "midi-feedback") {
3521
3522                 session_midi_feedback = Config->get_midi_feedback();
3523
3524         } else if (p == "jack-time-master") {
3525
3526                 engine().reset_timebase ();
3527
3528         } else if (p == "native-file-header-format") {
3529
3530                 if (!first_file_header_format_reset) {
3531                         reset_native_file_format ();
3532                 }
3533
3534                 first_file_header_format_reset = false;
3535
3536         } else if (p == "native-file-data-format") {
3537
3538                 if (!first_file_data_format_reset) {
3539                         reset_native_file_format ();
3540                 }
3541
3542                 first_file_data_format_reset = false;
3543
3544         } else if (p == "external-sync") {
3545                 if (!config.get_external_sync()) {
3546                         drop_sync_source ();
3547                 } else {
3548                         switch_to_sync_source (config.get_sync_source());
3549                 }
3550         } else if (p == "remote-model") {
3551                 set_remote_control_ids ();
3552         }  else if (p == "denormal-model") {
3553                 setup_fpu ();
3554         } else if (p == "history-depth") {
3555                 set_history_depth (Config->get_history_depth());
3556         } else if (p == "sync-all-route-ordering") {
3557                 sync_order_keys ("session");
3558         } else if (p == "initial-program-change") {
3559
3560                 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3561                         MIDI::byte buf[2];
3562
3563                         buf[0] = MIDI::program; // channel zero by default
3564                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3565
3566                         MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3567                 }
3568         } else if (p == "solo-mute-override") {
3569                 // catch_up_on_solo_mute_override ();
3570         } else if (p == "listen-position" || p == "pfl-position") {
3571                 listen_position_changed ();
3572         } else if (p == "solo-control-is-listen-control") {
3573                 solo_control_mode_changed ();
3574         } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3575                 last_timecode_valid = false;
3576         } else if (p == "playback-buffer-seconds") {
3577                 AudioSource::allocate_working_buffers (frame_rate());
3578         }
3579
3580         set_dirty ();
3581 }
3582
3583 void
3584 Session::set_history_depth (uint32_t d)
3585 {
3586         _history.set_depth (d);
3587 }
3588
3589 int
3590 Session::load_diskstreams_2X (XMLNode const & node, int)
3591 {
3592         XMLNodeList          clist;
3593         XMLNodeConstIterator citer;
3594
3595         clist = node.children();
3596
3597         for (citer = clist.begin(); citer != clist.end(); ++citer) {
3598
3599                 try {
3600                         /* diskstreams added automatically by DiskstreamCreated handler */
3601                         if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3602                                 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3603                                 _diskstreams_2X.push_back (dsp);
3604                         } else {
3605                                 error << _("Session: unknown diskstream type in XML") << endmsg;
3606                         }
3607                 }
3608
3609                 catch (failed_constructor& err) {
3610                         error << _("Session: could not load diskstream via XML state") << endmsg;
3611                         return -1;
3612                 }
3613         }
3614
3615         return 0;
3616 }
3617
3618 /** Connect things to the MMC object */
3619 void
3620 Session::setup_midi_machine_control ()
3621 {
3622         MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3623
3624         mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3625         mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3626         mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3627         mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3628         mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3629         mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3630         mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3631         mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3632         mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3633         mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3634         mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3635         mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3636         mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3637
3638         /* also handle MIDI SPP because its so common */
3639
3640         mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this, _1, _2));
3641         mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3642         mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));
3643 }
3644
3645 boost::shared_ptr<Controllable>
3646 Session::solo_cut_control() const
3647 {
3648         /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3649            controls in Ardour that currently get presented to the user in the GUI that require
3650            access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3651
3652            its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3653            it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3654            parameter.
3655         */
3656
3657         return _solo_cut_control;
3658 }
3659
3660 int
3661 Session::rename (const std::string& new_name)
3662 {
3663         string legal_name = legalize_for_path (new_name);
3664         string newpath;
3665         string oldstr;
3666         string newstr;
3667         bool first = true;
3668
3669 #define RENAME ::rename
3670
3671         /* Rename:
3672
3673          * session directory
3674          * interchange subdirectory
3675          * session file
3676          * session history
3677          
3678          * Backup files are left unchanged and not renamed.
3679          */
3680
3681         /* pass one: not 100% safe check that the new directory names don't
3682          * already exist ...
3683          */
3684
3685         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3686                 vector<string> v;
3687
3688                 oldstr = (*i).path;
3689
3690                 /* this is a stupid hack because Glib::path_get_dirname() is
3691                  * lexical-only, and so passing it /a/b/c/ gives a different
3692                  * result than passing it /a/b/c ...
3693                  */
3694
3695                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3696                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3697                 }
3698
3699                 string base = Glib::path_get_dirname (oldstr);
3700                 string p = Glib::path_get_basename (oldstr);
3701
3702                 newstr = Glib::build_filename (base, legal_name);
3703                 
3704                 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3705                         return -1;
3706                 }
3707         }
3708
3709         /* Session dirs */
3710         
3711         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3712                 vector<string> v;
3713
3714                 oldstr = (*i).path;
3715
3716                 /* this is a stupid hack because Glib::path_get_dirname() is
3717                  * lexical-only, and so passing it /a/b/c/ gives a different
3718                  * result than passing it /a/b/c ...
3719                  */
3720
3721                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3722                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3723                 }
3724
3725                 string base = Glib::path_get_dirname (oldstr);
3726                 string p = Glib::path_get_basename (oldstr);
3727
3728                 newstr = Glib::build_filename (base, legal_name);
3729
3730                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3731
3732                 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3733                         return 1;
3734                 }
3735
3736                 if (first) {
3737                         (*_session_dir) = newstr;
3738                         newpath = newstr;
3739                         first = 1;
3740                 }
3741
3742                 /* directory below interchange */
3743
3744                 v.push_back (newstr);
3745                 v.push_back (interchange_dir_name);
3746                 v.push_back (p);
3747
3748                 oldstr = Glib::build_filename (v);
3749
3750                 v.clear ();
3751                 v.push_back (newstr);
3752                 v.push_back (interchange_dir_name);
3753                 v.push_back (legal_name);
3754
3755                 newstr = Glib::build_filename (v);
3756                 
3757                 cerr << "Rename " << oldstr << " => " << newstr << endl;
3758                 
3759                 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3760                         return 1;
3761                 }
3762         }
3763
3764         /* state file */
3765         
3766         oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3767         newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3768         
3769         cerr << "Rename " << oldstr << " => " << newstr << endl;                
3770
3771         if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3772                 return 1;
3773         }
3774
3775         /* history file */
3776         
3777         oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3778         newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3779         
3780         cerr << "Rename " << oldstr << " => " << newstr << endl;                
3781
3782         if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3783                 return 1;
3784         }
3785
3786         _path = newpath;
3787         _current_snapshot_name = new_name;
3788         _name = new_name;
3789
3790         set_dirty ();
3791
3792         /* save state again to get everything just right */
3793
3794         save_state (_current_snapshot_name);
3795
3796         return 0;
3797
3798 #undef RENAME
3799 }