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