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