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