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