Disallow empty names for Groups, automatically enumerate them
[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 string
1854 Session::path_from_region_name (DataType type, string name, string identifier)
1855 {
1856         char buf[PATH_MAX+1];
1857         uint32_t n;
1858         SessionDirectory sdir(get_best_session_directory_for_new_source());
1859         std::string source_dir = ((type == DataType::AUDIO)
1860                 ? sdir.sound_path() : sdir.midi_path());
1861
1862         string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1863
1864         for (n = 0; n < 999999; ++n) {
1865                 if (identifier.length()) {
1866                         snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1867                                   identifier.c_str(), n, ext.c_str());
1868                 } else {
1869                         snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1870                                         n, ext.c_str());
1871                 }
1872
1873                 std::string source_path = Glib::build_filename (source_dir, buf);
1874
1875                 if (!Glib::file_test (source_path, Glib::FILE_TEST_EXISTS)) {
1876                         return source_path;
1877                 }
1878         }
1879
1880         error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1881                                  name, identifier)
1882               << endmsg;
1883
1884         return "";
1885 }
1886
1887
1888 int
1889 Session::load_sources (const XMLNode& node)
1890 {
1891         XMLNodeList nlist;
1892         XMLNodeConstIterator niter;
1893         boost::shared_ptr<Source> source;
1894
1895         nlist = node.children();
1896
1897         set_dirty();
1898
1899         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1900           retry:
1901                 try {
1902                         if ((source = XMLSourceFactory (**niter)) == 0) {
1903                                 error << _("Session: cannot create Source from XML description.") << endmsg;
1904                         }
1905
1906                 } catch (MissingSource& err) {
1907
1908                         int user_choice;
1909
1910                         if (!no_questions_about_missing_files) {
1911                                 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1912                         } else {
1913                                 user_choice = -2;
1914                         }
1915
1916                         switch (user_choice) {
1917                         case 0:
1918                                 /* user added a new search location, so try again */
1919                                 goto retry;
1920
1921
1922                         case 1:
1923                                 /* user asked to quit the entire session load
1924                                  */
1925                                 return -1;
1926
1927                         case 2:
1928                                 no_questions_about_missing_files = true;
1929                                 goto retry;
1930
1931                         case 3:
1932                                 no_questions_about_missing_files = true;
1933                                 /* fallthru */
1934
1935                         case -1:
1936                         default:
1937                                 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1938                                 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
1939                                 break;
1940                         }
1941                 }
1942         }
1943
1944         return 0;
1945 }
1946
1947 boost::shared_ptr<Source>
1948 Session::XMLSourceFactory (const XMLNode& node)
1949 {
1950         if (node.name() != "Source") {
1951                 return boost::shared_ptr<Source>();
1952         }
1953
1954         try {
1955                 /* note: do peak building in another thread when loading session state */
1956                 return SourceFactory::create (*this, node, true);
1957         }
1958
1959         catch (failed_constructor& err) {
1960                 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1961                 return boost::shared_ptr<Source>();
1962         }
1963 }
1964
1965 int
1966 Session::save_template (string template_name)
1967 {
1968         XMLTree tree;
1969
1970         if (_state_of_the_state & CannotSave) {
1971                 return -1;
1972         }
1973
1974         std::string user_template_dir(user_template_directory());
1975
1976         if (g_mkdir_with_parents (user_template_dir.c_str(), 0755) != 0) {
1977                 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
1978                                 user_template_dir, g_strerror (errno)) << endmsg;
1979                 return -1;
1980         }
1981
1982         tree.set_root (&get_template());
1983
1984         std::string template_dir_path(user_template_dir);
1985         
1986         /* directory to put the template in */
1987         template_dir_path = Glib::build_filename (template_dir_path, template_name);
1988
1989         if (Glib::file_test (template_dir_path, Glib::FILE_TEST_EXISTS)) {
1990                 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1991                                 template_dir_path) << endmsg;
1992                 return -1;
1993         }
1994         
1995         if (g_mkdir_with_parents (template_dir_path.c_str(), 0755) != 0) {
1996                 error << string_compose(_("Could not create directory for Session template\"%1\" (%2)"),
1997                                 template_dir_path, g_strerror (errno)) << endmsg;
1998                 return -1;
1999         }
2000
2001         /* file to write */
2002         std::string template_file_path(template_dir_path);
2003         template_file_path = Glib::build_filename (template_file_path, template_name + template_suffix);
2004
2005         if (!tree.write (template_file_path)) {
2006                 error << _("template not saved") << endmsg;
2007                 return -1;
2008         }
2009
2010         /* copy plugin state directory */
2011
2012         std::string template_plugin_state_path(template_dir_path);
2013         template_plugin_state_path = Glib::build_filename (template_plugin_state_path, X_("plugins"));
2014
2015         if (g_mkdir_with_parents (template_plugin_state_path.c_str(), 0755) != 0) {
2016                 error << string_compose(_("Could not create directory for Session template plugin state\"%1\" (%2)"),
2017                                 template_plugin_state_path, g_strerror (errno)) << endmsg;
2018                 return -1;
2019         }
2020
2021         copy_files (plugins_dir(), template_plugin_state_path);
2022
2023         return 0;
2024 }
2025
2026 void
2027 Session::refresh_disk_space ()
2028 {
2029 #if __APPLE__ || (HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H)
2030         
2031         Glib::Threads::Mutex::Lock lm (space_lock);
2032
2033         /* get freespace on every FS that is part of the session path */
2034
2035         _total_free_4k_blocks = 0;
2036         _total_free_4k_blocks_uncertain = false;
2037
2038         for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2039
2040                 struct statfs statfsbuf;
2041                 statfs (i->path.c_str(), &statfsbuf);
2042
2043                 double const scale = statfsbuf.f_bsize / 4096.0;
2044
2045                 /* See if this filesystem is read-only */
2046                 struct statvfs statvfsbuf;
2047                 statvfs (i->path.c_str(), &statvfsbuf);
2048
2049                 /* f_bavail can be 0 if it is undefined for whatever
2050                    filesystem we are looking at; Samba shares mounted
2051                    via GVFS are an example of this.
2052                 */
2053                 if (statfsbuf.f_bavail == 0) {
2054                         /* block count unknown */
2055                         i->blocks = 0;
2056                         i->blocks_unknown = true;
2057                 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2058                         /* read-only filesystem */
2059                         i->blocks = 0;
2060                         i->blocks_unknown = false;
2061                 } else {
2062                         /* read/write filesystem with known space */
2063                         i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2064                         i->blocks_unknown = false;
2065                 }
2066
2067                 _total_free_4k_blocks += i->blocks;
2068                 if (i->blocks_unknown) {
2069                         _total_free_4k_blocks_uncertain = true;
2070                 }
2071         }
2072 #elif defined (COMPILER_MSVC)
2073         vector<string> scanned_volumes;
2074         vector<string>::iterator j;
2075         vector<space_and_path>::iterator i;
2076     DWORD nSectorsPerCluster, nBytesPerSector,
2077           nFreeClusters, nTotalClusters;
2078     char disk_drive[4];
2079         bool volume_found;
2080
2081         _total_free_4k_blocks = 0;
2082
2083         for (i = session_dirs.begin(); i != session_dirs.end(); i++) {
2084                 strncpy (disk_drive, (*i).path.c_str(), 3);
2085                 disk_drive[3] = 0;
2086                 strupr(disk_drive);
2087
2088                 volume_found = false;
2089                 if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters)))
2090                 {
2091                         int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster;
2092                         int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters;
2093                         i->blocks = (uint32_t)(nFreeBytes / 4096);
2094
2095                         for (j = scanned_volumes.begin(); j != scanned_volumes.end(); j++) {
2096                                 if (0 == j->compare(disk_drive)) {
2097                                         volume_found = true;
2098                                         break;
2099                                 }
2100                         }
2101
2102                         if (!volume_found) {
2103                                 scanned_volumes.push_back(disk_drive);
2104                                 _total_free_4k_blocks += i->blocks;
2105                         }
2106                 }
2107         }
2108
2109         if (0 == _total_free_4k_blocks) {
2110                 strncpy (disk_drive, path().c_str(), 3);
2111                 disk_drive[3] = 0;
2112
2113                 if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters)))
2114                 {
2115                         int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster;
2116                         int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters;
2117                         _total_free_4k_blocks = (uint32_t)(nFreeBytes / 4096);
2118                 }
2119         }
2120 #endif
2121 }
2122
2123 string
2124 Session::get_best_session_directory_for_new_source ()
2125 {
2126         vector<space_and_path>::iterator i;
2127         string result = _session_dir->root_path();
2128
2129         /* handle common case without system calls */
2130
2131         if (session_dirs.size() == 1) {
2132                 return result;
2133         }
2134
2135         /* OK, here's the algorithm we're following here:
2136
2137         We want to select which directory to use for
2138         the next file source to be created. Ideally,
2139         we'd like to use a round-robin process so as to
2140         get maximum performance benefits from splitting
2141         the files across multiple disks.
2142
2143         However, in situations without much diskspace, an
2144         RR approach may end up filling up a filesystem
2145         with new files while others still have space.
2146         Its therefore important to pay some attention to
2147         the freespace in the filesystem holding each
2148         directory as well. However, if we did that by
2149         itself, we'd keep creating new files in the file
2150         system with the most space until it was as full
2151         as all others, thus negating any performance
2152         benefits of this RAID-1 like approach.
2153
2154         So, we use a user-configurable space threshold. If
2155         there are at least 2 filesystems with more than this
2156         much space available, we use RR selection between them.
2157         If not, then we pick the filesystem with the most space.
2158
2159         This gets a good balance between the two
2160         approaches.
2161         */
2162
2163         refresh_disk_space ();
2164
2165         int free_enough = 0;
2166
2167         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2168                 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2169                         free_enough++;
2170                 }
2171         }
2172
2173         if (free_enough >= 2) {
2174                 /* use RR selection process, ensuring that the one
2175                    picked works OK.
2176                 */
2177
2178                 i = last_rr_session_dir;
2179
2180                 do {
2181                         if (++i == session_dirs.end()) {
2182                                 i = session_dirs.begin();
2183                         }
2184
2185                         if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2186                                 SessionDirectory sdir(i->path);
2187                                 if (sdir.create ()) {
2188                                         result = (*i).path;
2189                                         last_rr_session_dir = i;
2190                                         return result;
2191                                 }
2192                         }
2193
2194                 } while (i != last_rr_session_dir);
2195
2196         } else {
2197
2198                 /* pick FS with the most freespace (and that
2199                    seems to actually work ...)
2200                 */
2201
2202                 vector<space_and_path> sorted;
2203                 space_and_path_ascending_cmp cmp;
2204
2205                 sorted = session_dirs;
2206                 sort (sorted.begin(), sorted.end(), cmp);
2207
2208                 for (i = sorted.begin(); i != sorted.end(); ++i) {
2209                         SessionDirectory sdir(i->path);
2210                         if (sdir.create ()) {
2211                                 result = (*i).path;
2212                                 last_rr_session_dir = i;
2213                                 return result;
2214                         }
2215                 }
2216         }
2217
2218         return result;
2219 }
2220
2221 string
2222 Session::automation_dir () const
2223 {
2224         return Glib::build_filename (_path, "automation");
2225 }
2226
2227 string
2228 Session::analysis_dir () const
2229 {
2230         return Glib::build_filename (_path, "analysis");
2231 }
2232
2233 string
2234 Session::plugins_dir () const
2235 {
2236         return Glib::build_filename (_path, "plugins");
2237 }
2238
2239 string
2240 Session::externals_dir () const
2241 {
2242         return Glib::build_filename (_path, "externals");
2243 }
2244
2245 int
2246 Session::load_bundles (XMLNode const & node)
2247 {
2248         XMLNodeList nlist = node.children();
2249         XMLNodeConstIterator niter;
2250
2251         set_dirty();
2252
2253         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2254                 if ((*niter)->name() == "InputBundle") {
2255                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2256                 } else if ((*niter)->name() == "OutputBundle") {
2257                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2258                 } else {
2259                         error << string_compose(_("Unknown node \"%1\" found in Bundles list from session file"), (*niter)->name()) << endmsg;
2260                         return -1;
2261                 }
2262         }
2263
2264         return 0;
2265 }
2266
2267 int
2268 Session::load_route_groups (const XMLNode& node, int version)
2269 {
2270         XMLNodeList nlist = node.children();
2271         XMLNodeConstIterator niter;
2272
2273         set_dirty ();
2274
2275         if (version >= 3000) {
2276
2277                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2278                         if ((*niter)->name() == "RouteGroup") {
2279                                 RouteGroup* rg = new RouteGroup (*this, "");
2280                                 add_route_group (rg);
2281                                 rg->set_state (**niter, version);
2282                         }
2283                 }
2284
2285         } else if (version < 3000) {
2286
2287                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2288                         if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2289                                 RouteGroup* rg = new RouteGroup (*this, "");
2290                                 add_route_group (rg);
2291                                 rg->set_state (**niter, version);
2292                         }
2293                 }
2294         }
2295
2296         return 0;
2297 }
2298
2299 void
2300 Session::auto_save()
2301 {
2302         save_state (_current_snapshot_name);
2303 }
2304
2305 static bool
2306 state_file_filter (const string &str, void* /*arg*/)
2307 {
2308         return (str.length() > strlen(statefile_suffix) &&
2309                 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2310 }
2311
2312 static string
2313 remove_end(string state)
2314 {
2315         string statename(state);
2316
2317         string::size_type start,end;
2318         if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2319                 statename = statename.substr (start+1);
2320         }
2321
2322         if ((end = statename.rfind(".ardour")) == string::npos) {
2323                 end = statename.length();
2324         }
2325
2326         return string(statename.substr (0, end));
2327 }
2328
2329 vector<string>
2330 Session::possible_states (string path)
2331 {
2332         vector<string> states;
2333         find_files_matching_filter (states, path, state_file_filter, 0, false, false);
2334
2335         transform(states.begin(), states.end(), states.begin(), remove_end);
2336
2337         sort (states.begin(), states.end());
2338
2339         return states;
2340 }
2341
2342 vector<string>
2343 Session::possible_states () const
2344 {
2345         return possible_states(_path);
2346 }
2347
2348 void
2349 Session::add_route_group (RouteGroup* g)
2350 {
2351         _route_groups.push_back (g);
2352         route_group_added (g); /* EMIT SIGNAL */
2353
2354         g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2355         g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2356         g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2357
2358         set_dirty ();
2359 }
2360
2361 void
2362 Session::remove_route_group (RouteGroup& rg)
2363 {
2364         list<RouteGroup*>::iterator i;
2365
2366         if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2367                 _route_groups.erase (i);
2368                 delete &rg;
2369
2370                 route_group_removed (); /* EMIT SIGNAL */
2371         }
2372 }
2373
2374 /** Set a new order for our route groups, without adding or removing any.
2375  *  @param groups Route group list in the new order.
2376  */
2377 void
2378 Session::reorder_route_groups (list<RouteGroup*> groups)
2379 {
2380         _route_groups = groups;
2381
2382         route_groups_reordered (); /* EMIT SIGNAL */
2383         set_dirty ();
2384 }
2385
2386
2387 RouteGroup *
2388 Session::route_group_by_name (string name)
2389 {
2390         list<RouteGroup *>::iterator i;
2391
2392         for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2393                 if ((*i)->name() == name) {
2394                         return* i;
2395                 }
2396         }
2397         return 0;
2398 }
2399
2400 RouteGroup&
2401 Session::all_route_group() const
2402 {
2403         return *_all_route_group;
2404 }
2405
2406 void
2407 Session::add_commands (vector<Command*> const & cmds)
2408 {
2409         for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2410                 add_command (*i);
2411         }
2412 }
2413
2414 void
2415 Session::begin_reversible_command (const string& name)
2416 {
2417         begin_reversible_command (g_quark_from_string (name.c_str ()));
2418 }
2419
2420 /** Begin a reversible command using a GQuark to identify it.
2421  *  begin_reversible_command() and commit_reversible_command() calls may be nested,
2422  *  but there must be as many begin...()s as there are commit...()s.
2423  */
2424 void
2425 Session::begin_reversible_command (GQuark q)
2426 {
2427         /* If nested begin/commit pairs are used, we create just one UndoTransaction
2428            to hold all the commands that are committed.  This keeps the order of
2429            commands correct in the history.
2430         */
2431
2432         if (_current_trans == 0) {
2433                 /* start a new transaction */
2434                 assert (_current_trans_quarks.empty ());
2435                 _current_trans = new UndoTransaction();
2436                 _current_trans->set_name (g_quark_to_string (q));
2437         }
2438
2439         _current_trans_quarks.push_front (q);
2440 }
2441
2442 void
2443 Session::commit_reversible_command (Command *cmd)
2444 {
2445         assert (_current_trans);
2446         assert (!_current_trans_quarks.empty ());
2447
2448         struct timeval now;
2449
2450         if (cmd) {
2451                 _current_trans->add_command (cmd);
2452         }
2453
2454         _current_trans_quarks.pop_front ();
2455
2456         if (!_current_trans_quarks.empty ()) {
2457                 /* the transaction we're committing is not the top-level one */
2458                 return;
2459         }
2460
2461         if (_current_trans->empty()) {
2462                 /* no commands were added to the transaction, so just get rid of it */
2463                 delete _current_trans;
2464                 _current_trans = 0;
2465                 return;
2466         }
2467
2468         gettimeofday (&now, 0);
2469         _current_trans->set_timestamp (now);
2470
2471         _history.add (_current_trans);
2472         _current_trans = 0;
2473 }
2474
2475 static bool
2476 accept_all_audio_files (const string& path, void* /*arg*/)
2477 {
2478         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2479                 return false;
2480         }
2481
2482         if (!AudioFileSource::safe_audio_file_extension (path)) {
2483                 return false;
2484         }
2485
2486         return true;
2487 }
2488
2489 static bool
2490 accept_all_midi_files (const string& path, void* /*arg*/)
2491 {
2492         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2493                 return false;
2494         }
2495
2496         return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2497                 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2498                 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2499 }
2500
2501 static bool
2502 accept_all_state_files (const string& path, void* /*arg*/)
2503 {
2504         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2505                 return false;
2506         }
2507
2508         return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2509 }
2510
2511 int
2512 Session::find_all_sources (string path, set<string>& result)
2513 {
2514         XMLTree tree;
2515         XMLNode* node;
2516
2517         if (!tree.read (path)) {
2518                 return -1;
2519         }
2520
2521         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2522                 return -2;
2523         }
2524
2525         XMLNodeList nlist;
2526         XMLNodeConstIterator niter;
2527
2528         nlist = node->children();
2529
2530         set_dirty();
2531
2532         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2533
2534                 XMLProperty* prop;
2535
2536                 if ((prop = (*niter)->property (X_("type"))) == 0) {
2537                         continue;
2538                 }
2539
2540                 DataType type (prop->value());
2541
2542                 if ((prop = (*niter)->property (X_("name"))) == 0) {
2543                         continue;
2544                 }
2545
2546                 if (Glib::path_is_absolute (prop->value())) {
2547                         /* external file, ignore */
2548                         continue;
2549                 }
2550
2551                 string found_path;
2552                 bool is_new;
2553                 uint16_t chan;
2554
2555                 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2556                         result.insert (found_path);
2557                 }
2558         }
2559
2560         return 0;
2561 }
2562
2563 int
2564 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2565 {
2566         vector<string> state_files;
2567         string ripped;
2568         string this_snapshot_path;
2569
2570         result.clear ();
2571
2572         ripped = _path;
2573
2574         if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2575                 ripped = ripped.substr (0, ripped.length() - 1);
2576         }
2577
2578         find_files_matching_filter (state_files, ripped, accept_all_state_files, (void *) 0, true, true);
2579
2580         if (state_files.empty()) {
2581                 /* impossible! */
2582                 return 0;
2583         }
2584
2585         this_snapshot_path = _path;
2586         this_snapshot_path += legalize_for_path (_current_snapshot_name);
2587         this_snapshot_path += statefile_suffix;
2588
2589         for (vector<string>::iterator i = state_files.begin(); i != state_files.end(); ++i) {
2590
2591                 if (exclude_this_snapshot && *i == this_snapshot_path) {
2592                         continue;
2593                 }
2594
2595                 if (find_all_sources (*i, result) < 0) {
2596                         return -1;
2597                 }
2598         }
2599
2600         return 0;
2601 }
2602
2603 struct RegionCounter {
2604     typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2605     AudioSourceList::iterator iter;
2606     boost::shared_ptr<Region> region;
2607     uint32_t count;
2608
2609     RegionCounter() : count (0) {}
2610 };
2611
2612 int
2613 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2614 {
2615         boost::optional<int> r = AskAboutPlaylistDeletion (p);
2616         return r.get_value_or (1);
2617 }
2618
2619 void
2620 Session::cleanup_regions ()
2621 {
2622         const RegionFactory::RegionMap& regions (RegionFactory::regions());
2623
2624         for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2625
2626                 uint32_t used = playlists->region_use_count (i->second);
2627
2628                 if (used == 0 && !i->second->automatic ()) {
2629                         RegionFactory::map_remove (i->second);
2630                 }
2631         }
2632
2633         /* dump the history list */
2634         _history.clear ();
2635
2636         save_state ("");
2637 }
2638
2639 int
2640 Session::cleanup_sources (CleanupReport& rep)
2641 {
2642         // FIXME: needs adaptation to midi
2643
2644         vector<boost::shared_ptr<Source> > dead_sources;
2645         string audio_path;
2646         string midi_path;
2647         vector<string> candidates;
2648         vector<string> unused;
2649         set<string> all_sources;
2650         bool used;
2651         string spath;
2652         int ret = -1;
2653         string tmppath1;
2654         string tmppath2;
2655         Searchpath asp;
2656         Searchpath msp;
2657
2658         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2659
2660         /* consider deleting all unused playlists */
2661
2662         if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2663                 ret = 0;
2664                 goto out;
2665         }
2666
2667         /* sync the "all regions" property of each playlist with its current state
2668          */
2669
2670         playlists->sync_all_regions_with_regions ();
2671
2672         /* find all un-used sources */
2673
2674         rep.paths.clear ();
2675         rep.space = 0;
2676
2677         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2678
2679                 SourceMap::iterator tmp;
2680
2681                 tmp = i;
2682                 ++tmp;
2683
2684                 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2685                    capture files.
2686                 */
2687
2688                 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2689                         dead_sources.push_back (i->second);
2690                         i->second->drop_references ();
2691                 }
2692
2693                 i = tmp;
2694         }
2695
2696         /* build a list of all the possible audio directories for the session */
2697
2698         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2699                 SessionDirectory sdir ((*i).path);
2700                 asp += sdir.sound_path();
2701         }
2702         audio_path += asp.to_string();
2703
2704
2705         /* build a list of all the possible midi directories for the session */
2706
2707         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2708                 SessionDirectory sdir ((*i).path);
2709                 msp += sdir.midi_path();
2710         }
2711         midi_path += msp.to_string();
2712
2713         find_files_matching_filter (candidates, audio_path, accept_all_audio_files, (void *) 0, true, true);
2714         find_files_matching_filter (candidates, midi_path, accept_all_midi_files, (void *) 0, true, true);
2715
2716         /* find all sources, but don't use this snapshot because the
2717            state file on disk still references sources we may have already
2718            dropped.
2719         */
2720
2721         find_all_sources_across_snapshots (all_sources, true);
2722
2723         /*  add our current source list
2724          */
2725
2726         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2727                 boost::shared_ptr<FileSource> fs;
2728                 SourceMap::iterator tmp = i;
2729                 ++tmp;
2730
2731                 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2732
2733                         if (!fs->is_stub()) {
2734
2735                                 if (playlists->source_use_count (fs) != 0) {
2736                                         all_sources.insert (fs->path());
2737                                 } else {
2738                                         
2739                                         /* we might not remove this source from disk, because it may be used
2740                                            by other snapshots, but its not being used in this version
2741                                            so lets get rid of it now, along with any representative regions
2742                                            in the region list.
2743                                         */
2744                                         
2745                                         RegionFactory::remove_regions_using_source (i->second);
2746                                         sources.erase (i);
2747                                 }
2748                         }
2749                 }
2750
2751                 i = tmp;
2752         }
2753
2754         for (vector<string>::iterator x = candidates.begin(); x != candidates.end(); ++x) {
2755
2756                 used = false;
2757                 spath = *x;
2758
2759                 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2760
2761                         tmppath1 = canonical_path (spath);
2762                         tmppath2 = canonical_path ((*i));
2763
2764                         if (tmppath1 == tmppath2) {
2765                                 used = true;
2766                                 break;
2767                         }
2768                 }
2769
2770                 if (!used) {
2771                         unused.push_back (spath);
2772                 }
2773         }
2774
2775         /* now try to move all unused files into the "dead" directory(ies) */
2776
2777         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2778                 struct stat statbuf;
2779
2780                 string newpath;
2781
2782                 /* don't move the file across filesystems, just
2783                    stick it in the `dead_dir_name' directory
2784                    on whichever filesystem it was already on.
2785                 */
2786
2787                 if ((*x).find ("/sounds/") != string::npos) {
2788
2789                         /* old school, go up 1 level */
2790
2791                         newpath = Glib::path_get_dirname (*x);      // "sounds"
2792                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2793
2794                 } else {
2795
2796                         /* new school, go up 4 levels */
2797
2798                         newpath = Glib::path_get_dirname (*x);      // "audiofiles" or "midifiles"
2799                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2800                         newpath = Glib::path_get_dirname (newpath); // "interchange"
2801                         newpath = Glib::path_get_dirname (newpath); // "session-dir"
2802                 }
2803
2804                 newpath = Glib::build_filename (newpath, dead_dir_name);
2805
2806                 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2807                         error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2808                         return -1;
2809                 }
2810
2811                 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2812
2813                 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2814
2815                         /* the new path already exists, try versioning */
2816
2817                         char buf[PATH_MAX+1];
2818                         int version = 1;
2819                         string newpath_v;
2820
2821                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2822                         newpath_v = buf;
2823
2824                         while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2825                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2826                                 newpath_v = buf;
2827                         }
2828
2829                         if (version == 999) {
2830                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2831                                                   newpath)
2832                                       << endmsg;
2833                         } else {
2834                                 newpath = newpath_v;
2835                         }
2836
2837                 } else {
2838
2839                         /* it doesn't exist, or we can't read it or something */
2840
2841                 }
2842
2843                 stat ((*x).c_str(), &statbuf);
2844
2845                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2846                         error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2847                                           (*x), newpath, strerror (errno))
2848                               << endmsg;
2849                         goto out;
2850                 }
2851
2852                 /* see if there an easy to find peakfile for this file, and remove it.
2853                  */
2854
2855                 string base = basename_nosuffix (*x);
2856                 base += "%A"; /* this is what we add for the channel suffix of all native files,
2857                                  or for the first channel of embedded files. it will miss
2858                                  some peakfiles for other channels
2859                               */
2860                 string peakpath = peak_path (base);
2861
2862                 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2863                         if (::g_unlink (peakpath.c_str()) != 0) {
2864                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2865                                                          peakpath, _path, strerror (errno))
2866                                       << endmsg;
2867                                 /* try to back out */
2868                                 ::rename (newpath.c_str(), _path.c_str());
2869                                 goto out;
2870                         }
2871                 }
2872
2873                 rep.paths.push_back (*x);
2874                 rep.space += statbuf.st_size;
2875         }
2876
2877         /* dump the history list */
2878
2879         _history.clear ();
2880
2881         /* save state so we don't end up a session file
2882            referring to non-existent sources.
2883         */
2884
2885         save_state ("");
2886         ret = 0;
2887
2888   out:
2889         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2890
2891         return ret;
2892 }
2893
2894 int
2895 Session::cleanup_trash_sources (CleanupReport& rep)
2896 {
2897         // FIXME: needs adaptation for MIDI
2898
2899         vector<space_and_path>::iterator i;
2900         string dead_dir;
2901
2902         rep.paths.clear ();
2903         rep.space = 0;
2904
2905         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2906
2907                 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2908
2909                 clear_directory (dead_dir, &rep.space, &rep.paths);
2910         }
2911
2912         return 0;
2913 }
2914
2915 void
2916 Session::set_dirty ()
2917 {
2918         bool was_dirty = dirty();
2919
2920         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2921
2922
2923         if (!was_dirty) {
2924                 DirtyChanged(); /* EMIT SIGNAL */
2925         }
2926 }
2927
2928
2929 void
2930 Session::set_clean ()
2931 {
2932         bool was_dirty = dirty();
2933
2934         _state_of_the_state = Clean;
2935
2936
2937         if (was_dirty) {
2938                 DirtyChanged(); /* EMIT SIGNAL */
2939         }
2940 }
2941
2942 void
2943 Session::set_deletion_in_progress ()
2944 {
2945         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2946 }
2947
2948 void
2949 Session::clear_deletion_in_progress ()
2950 {
2951         _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2952 }
2953
2954 void
2955 Session::add_controllable (boost::shared_ptr<Controllable> c)
2956 {
2957         /* this adds a controllable to the list managed by the Session.
2958            this is a subset of those managed by the Controllable class
2959            itself, and represents the only ones whose state will be saved
2960            as part of the session.
2961         */
2962
2963         Glib::Threads::Mutex::Lock lm (controllables_lock);
2964         controllables.insert (c);
2965 }
2966
2967 struct null_deleter { void operator()(void const *) const {} };
2968
2969 void
2970 Session::remove_controllable (Controllable* c)
2971 {
2972         if (_state_of_the_state & Deletion) {
2973                 return;
2974         }
2975
2976         Glib::Threads::Mutex::Lock lm (controllables_lock);
2977
2978         Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2979
2980         if (x != controllables.end()) {
2981                 controllables.erase (x);
2982         }
2983 }
2984
2985 boost::shared_ptr<Controllable>
2986 Session::controllable_by_id (const PBD::ID& id)
2987 {
2988         Glib::Threads::Mutex::Lock lm (controllables_lock);
2989
2990         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2991                 if ((*i)->id() == id) {
2992                         return *i;
2993                 }
2994         }
2995
2996         return boost::shared_ptr<Controllable>();
2997 }
2998
2999 boost::shared_ptr<Controllable>
3000 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3001 {
3002         boost::shared_ptr<Controllable> c;
3003         boost::shared_ptr<Route> r;
3004
3005         switch (desc.top_level_type()) {
3006         case ControllableDescriptor::NamedRoute:
3007         {
3008                 std::string str = desc.top_level_name();
3009                 if (str == "master") {
3010                         r = _master_out;
3011                 } else if (str == "control" || str == "listen") {
3012                         r = _monitor_out;
3013                 } else {
3014                         r = route_by_name (desc.top_level_name());
3015                 }
3016                 break;
3017         }
3018
3019         case ControllableDescriptor::RemoteControlID:
3020                 r = route_by_remote_id (desc.rid());
3021                 break;
3022         }
3023
3024         if (!r) {
3025                 return c;
3026         }
3027
3028         switch (desc.subtype()) {
3029         case ControllableDescriptor::Gain:
3030                 c = r->gain_control ();
3031                 break;
3032
3033         case ControllableDescriptor::Solo:
3034                 c = r->solo_control();
3035                 break;
3036
3037         case ControllableDescriptor::Mute:
3038                 c = r->mute_control();
3039                 break;
3040
3041         case ControllableDescriptor::Recenable:
3042         {
3043                 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3044
3045                 if (t) {
3046                         c = t->rec_enable_control ();
3047                 }
3048                 break;
3049         }
3050
3051         case ControllableDescriptor::PanDirection:
3052         {
3053                 c = r->pannable()->pan_azimuth_control;
3054                 break;
3055         }
3056
3057         case ControllableDescriptor::PanWidth:
3058         {
3059                 c = r->pannable()->pan_width_control;
3060                 break;
3061         }
3062
3063         case ControllableDescriptor::PanElevation:
3064         {
3065                 c = r->pannable()->pan_elevation_control;
3066                 break;
3067         }
3068
3069         case ControllableDescriptor::Balance:
3070                 /* XXX simple pan control */
3071                 break;
3072
3073         case ControllableDescriptor::PluginParameter:
3074         {
3075                 uint32_t plugin = desc.target (0);
3076                 uint32_t parameter_index = desc.target (1);
3077
3078                 /* revert to zero based counting */
3079
3080                 if (plugin > 0) {
3081                         --plugin;
3082                 }
3083
3084                 if (parameter_index > 0) {
3085                         --parameter_index;
3086                 }
3087
3088                 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3089
3090                 if (p) {
3091                         c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3092                                 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3093                 }
3094                 break;
3095         }
3096
3097         case ControllableDescriptor::SendGain:
3098         {
3099                 uint32_t send = desc.target (0);
3100
3101                 /* revert to zero-based counting */
3102
3103                 if (send > 0) {
3104                         --send;
3105                 }
3106
3107                 boost::shared_ptr<Processor> p = r->nth_send (send);
3108
3109                 if (p) {
3110                         boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3111                         boost::shared_ptr<Amp> a = s->amp();
3112                         
3113                         if (a) {
3114                                 c = s->amp()->gain_control();
3115                         }
3116                 }
3117                 break;
3118         }
3119
3120         default:
3121                 /* relax and return a null pointer */
3122                 break;
3123         }
3124
3125         return c;
3126 }
3127
3128 void
3129 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3130 {
3131         if (_writable) {
3132                 Stateful::add_instant_xml (node, _path);
3133         }
3134
3135         if (write_to_config) {
3136                 Config->add_instant_xml (node);
3137         }
3138 }
3139
3140 XMLNode*
3141 Session::instant_xml (const string& node_name)
3142 {
3143         return Stateful::instant_xml (node_name, _path);
3144 }
3145
3146 int
3147 Session::save_history (string snapshot_name)
3148 {
3149         XMLTree tree;
3150
3151         if (!_writable) {
3152                 return 0;
3153         }
3154
3155         if (snapshot_name.empty()) {
3156                 snapshot_name = _current_snapshot_name;
3157         }
3158
3159         const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3160         const string backup_filename = history_filename + backup_suffix;
3161         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3162         const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3163
3164         if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3165                 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3166                         error << _("could not backup old history file, current history not saved") << endmsg;
3167                         return -1;
3168                 }
3169         }
3170
3171         if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3172                 return 0;
3173         }
3174
3175         tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3176
3177         if (!tree.write (xml_path))
3178         {
3179                 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3180
3181                 if (g_remove (xml_path.c_str()) != 0) {
3182                         error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3183                                         xml_path, g_strerror (errno)) << endmsg;
3184                 }
3185                 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3186                         error << string_compose (_("could not restore history file from backup %1 (%2)"),
3187                                         backup_path, g_strerror (errno)) << endmsg;
3188                 }
3189
3190                 return -1;
3191         }
3192
3193         return 0;
3194 }
3195
3196 int
3197 Session::restore_history (string snapshot_name)
3198 {
3199         XMLTree tree;
3200
3201         if (snapshot_name.empty()) {
3202                 snapshot_name = _current_snapshot_name;
3203         }
3204
3205         const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3206         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3207
3208         info << "Loading history from " << xml_path << endmsg;
3209
3210         if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3211                 info << string_compose (_("%1: no history file \"%2\" for this session."),
3212                                 _name, xml_path) << endmsg;
3213                 return 1;
3214         }
3215
3216         if (!tree.read (xml_path)) {
3217                 error << string_compose (_("Could not understand session history file \"%1\""),
3218                                 xml_path) << endmsg;
3219                 return -1;
3220         }
3221
3222         // replace history
3223         _history.clear();
3224
3225         for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3226
3227                 XMLNode *t = *it;
3228                 UndoTransaction* ut = new UndoTransaction ();
3229                 struct timeval tv;
3230
3231                 ut->set_name(t->property("name")->value());
3232                 stringstream ss(t->property("tv-sec")->value());
3233                 ss >> tv.tv_sec;
3234                 ss.str(t->property("tv-usec")->value());
3235                 ss >> tv.tv_usec;
3236                 ut->set_timestamp(tv);
3237
3238                 for (XMLNodeConstIterator child_it  = t->children().begin();
3239                                 child_it != t->children().end(); child_it++)
3240                 {
3241                         XMLNode *n = *child_it;
3242                         Command *c;
3243
3244                         if (n->name() == "MementoCommand" ||
3245                                         n->name() == "MementoUndoCommand" ||
3246                                         n->name() == "MementoRedoCommand") {
3247
3248                                 if ((c = memento_command_factory(n))) {
3249                                         ut->add_command(c);
3250                                 }
3251
3252                         } else if (n->name() == "NoteDiffCommand") {
3253                                 PBD::ID id (n->property("midi-source")->value());
3254                                 boost::shared_ptr<MidiSource> midi_source =
3255                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3256                                 if (midi_source) {
3257                                         ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3258                                 } else {
3259                                         error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3260                                 }
3261
3262                         } else if (n->name() == "SysExDiffCommand") {
3263
3264                                 PBD::ID id (n->property("midi-source")->value());
3265                                 boost::shared_ptr<MidiSource> midi_source =
3266                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3267                                 if (midi_source) {
3268                                         ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3269                                 } else {
3270                                         error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3271                                 }
3272
3273                         } else if (n->name() == "PatchChangeDiffCommand") {
3274
3275                                 PBD::ID id (n->property("midi-source")->value());
3276                                 boost::shared_ptr<MidiSource> midi_source =
3277                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3278                                 if (midi_source) {
3279                                         ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3280                                 } else {
3281                                         error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3282                                 }
3283
3284                         } else if (n->name() == "StatefulDiffCommand") {
3285                                 if ((c = stateful_diff_command_factory (n))) {
3286                                         ut->add_command (c);
3287                                 }
3288                         } else {
3289                                 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3290                         }
3291                 }
3292
3293                 _history.add (ut);
3294         }
3295
3296         return 0;
3297 }
3298
3299 void
3300 Session::config_changed (std::string p, bool ours)
3301 {
3302         if (ours) {
3303                 set_dirty ();
3304         }
3305
3306         if (p == "seamless-loop") {
3307
3308         } else if (p == "rf-speed") {
3309
3310         } else if (p == "auto-loop") {
3311
3312         } else if (p == "auto-input") {
3313
3314                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3315                         /* auto-input only makes a difference if we're rolling */
3316                         set_track_monitor_input_status (!config.get_auto_input());
3317                 }
3318
3319         } else if (p == "punch-in") {
3320
3321                 Location* location;
3322
3323                 if ((location = _locations->auto_punch_location()) != 0) {
3324
3325                         if (config.get_punch_in ()) {
3326                                 replace_event (SessionEvent::PunchIn, location->start());
3327                         } else {
3328                                 remove_event (location->start(), SessionEvent::PunchIn);
3329                         }
3330                 }
3331
3332         } else if (p == "punch-out") {
3333
3334                 Location* location;
3335
3336                 if ((location = _locations->auto_punch_location()) != 0) {
3337
3338                         if (config.get_punch_out()) {
3339                                 replace_event (SessionEvent::PunchOut, location->end());
3340                         } else {
3341                                 clear_events (SessionEvent::PunchOut);
3342                         }
3343                 }
3344
3345         } else if (p == "edit-mode") {
3346
3347                 Glib::Threads::Mutex::Lock lm (playlists->lock);
3348
3349                 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3350                         (*i)->set_edit_mode (Config->get_edit_mode ());
3351                 }
3352
3353         } else if (p == "use-video-sync") {
3354
3355                 waiting_for_sync_offset = config.get_use_video_sync();
3356
3357         } else if (p == "mmc-control") {
3358
3359                 //poke_midi_thread ();
3360
3361         } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3362
3363                 _mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3364
3365         } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3366
3367                 _mmc->set_send_device_id (Config->get_mmc_send_device_id());
3368
3369         } else if (p == "midi-control") {
3370
3371                 //poke_midi_thread ();
3372
3373         } else if (p == "raid-path") {
3374
3375                 setup_raid_path (config.get_raid_path());
3376
3377         } else if (p == "timecode-format") {
3378
3379                 sync_time_vars ();
3380
3381         } else if (p == "video-pullup") {
3382
3383                 sync_time_vars ();
3384
3385         } else if (p == "seamless-loop") {
3386
3387                 if (play_loop && transport_rolling()) {
3388                         // to reset diskstreams etc
3389                         request_play_loop (true);
3390                 }
3391
3392         } else if (p == "rf-speed") {
3393
3394                 cumulative_rf_motion = 0;
3395                 reset_rf_scale (0);
3396
3397         } else if (p == "click-sound") {
3398
3399                 setup_click_sounds (1);
3400
3401         } else if (p == "click-emphasis-sound") {
3402
3403                 setup_click_sounds (-1);
3404
3405         } else if (p == "clicking") {
3406
3407                 if (Config->get_clicking()) {
3408                         if (_click_io && click_data) { // don't require emphasis data
3409                                 _clicking = true;
3410                         }
3411                 } else {
3412                         _clicking = false;
3413                 }
3414
3415         } else if (p == "click-gain") {
3416                 
3417                 if (_click_gain) {
3418                         _click_gain->set_gain (Config->get_click_gain(), this);
3419                 }
3420
3421         } else if (p == "send-mtc") {
3422
3423                 if (Config->get_send_mtc ()) {
3424                         /* mark us ready to send */
3425                         next_quarter_frame_to_send = 0;
3426                 }
3427
3428         } else if (p == "send-mmc") {
3429
3430                 _mmc->enable_send (Config->get_send_mmc ());
3431
3432         } else if (p == "midi-feedback") {
3433
3434                 session_midi_feedback = Config->get_midi_feedback();
3435
3436         } else if (p == "jack-time-master") {
3437
3438                 engine().reset_timebase ();
3439
3440         } else if (p == "native-file-header-format") {
3441
3442                 if (!first_file_header_format_reset) {
3443                         reset_native_file_format ();
3444                 }
3445
3446                 first_file_header_format_reset = false;
3447
3448         } else if (p == "native-file-data-format") {
3449
3450                 if (!first_file_data_format_reset) {
3451                         reset_native_file_format ();
3452                 }
3453
3454                 first_file_data_format_reset = false;
3455
3456         } else if (p == "external-sync") {
3457                 if (!config.get_external_sync()) {
3458                         drop_sync_source ();
3459                 } else {
3460                         switch_to_sync_source (Config->get_sync_source());
3461                 }
3462         }  else if (p == "denormal-model") {
3463                 setup_fpu ();
3464         } else if (p == "history-depth") {
3465                 set_history_depth (Config->get_history_depth());
3466         } else if (p == "remote-model") {
3467                 /* XXX DO SOMETHING HERE TO TELL THE GUI THAT WE NEED
3468                    TO SET REMOTE ID'S
3469                 */
3470         } else if (p == "initial-program-change") {
3471
3472                 if (_mmc->output_port() && Config->get_initial_program_change() >= 0) {
3473                         MIDI::byte buf[2];
3474
3475                         buf[0] = MIDI::program; // channel zero by default
3476                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3477
3478                         _mmc->output_port()->midimsg (buf, sizeof (buf), 0);
3479                 }
3480         } else if (p == "solo-mute-override") {
3481                 // catch_up_on_solo_mute_override ();
3482         } else if (p == "listen-position" || p == "pfl-position") {
3483                 listen_position_changed ();
3484         } else if (p == "solo-control-is-listen-control") {
3485                 solo_control_mode_changed ();
3486         } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3487                 last_timecode_valid = false;
3488         } else if (p == "playback-buffer-seconds") {
3489                 AudioSource::allocate_working_buffers (frame_rate());
3490         } else if (p == "automation-thinning-factor") {
3491                 Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
3492         } else if (p == "ltc-source-port") {
3493                 reconnect_ltc_input ();
3494         } else if (p == "ltc-sink-port") {
3495                 reconnect_ltc_output ();
3496         } else if (p == "timecode-generator-offset") {
3497                 ltc_tx_parse_offset();
3498         }
3499
3500         set_dirty ();
3501 }
3502
3503 void
3504 Session::set_history_depth (uint32_t d)
3505 {
3506         _history.set_depth (d);
3507 }
3508
3509 int
3510 Session::load_diskstreams_2X (XMLNode const & node, int)
3511 {
3512         XMLNodeList          clist;
3513         XMLNodeConstIterator citer;
3514
3515         clist = node.children();
3516
3517         for (citer = clist.begin(); citer != clist.end(); ++citer) {
3518
3519                 try {
3520                         /* diskstreams added automatically by DiskstreamCreated handler */
3521                         if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3522                                 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3523                                 _diskstreams_2X.push_back (dsp);
3524                         } else {
3525                                 error << _("Session: unknown diskstream type in XML") << endmsg;
3526                         }
3527                 }
3528
3529                 catch (failed_constructor& err) {
3530                         error << _("Session: could not load diskstream via XML state") << endmsg;
3531                         return -1;
3532                 }
3533         }
3534
3535         return 0;
3536 }
3537
3538 /** Connect things to the MMC object */
3539 void
3540 Session::setup_midi_machine_control ()
3541 {
3542         _mmc = new MIDI::MachineControl;
3543         _mmc->set_ports (_midi_ports->mmc_input_port(), _midi_ports->mmc_output_port());
3544
3545         _mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3546         _mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3547         _mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3548         _mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3549         _mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3550         _mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3551         _mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3552         _mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3553         _mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3554         _mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3555         _mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3556         _mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3557         _mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3558
3559         /* also handle MIDI SPP because its so common */
3560
3561         _mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3562         _mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3563         _mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3564 }
3565
3566 boost::shared_ptr<Controllable>
3567 Session::solo_cut_control() const
3568 {
3569         /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3570            controls in Ardour that currently get presented to the user in the GUI that require
3571            access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3572
3573            its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3574            it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3575            parameter.
3576         */
3577
3578         return _solo_cut_control;
3579 }
3580
3581 int
3582 Session::rename (const std::string& new_name)
3583 {
3584         string legal_name = legalize_for_path (new_name);
3585         string newpath;
3586         string oldstr;
3587         string newstr;
3588         bool first = true;
3589
3590         string const old_sources_root = _session_dir->sources_root();
3591
3592         /* Rename:
3593
3594          * session directory
3595          * interchange subdirectory
3596          * session file
3597          * session history
3598          
3599          * Backup files are left unchanged and not renamed.
3600          */
3601
3602         /* pass one: not 100% safe check that the new directory names don't
3603          * already exist ...
3604          */
3605
3606         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3607                 vector<string> v;
3608
3609                 oldstr = (*i).path;
3610
3611                 /* this is a stupid hack because Glib::path_get_dirname() is
3612                  * lexical-only, and so passing it /a/b/c/ gives a different
3613                  * result than passing it /a/b/c ...
3614                  */
3615
3616                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3617                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3618                 }
3619
3620                 string base = Glib::path_get_dirname (oldstr);
3621                 string p = Glib::path_get_basename (oldstr);
3622
3623                 newstr = Glib::build_filename (base, legal_name);
3624                 
3625                 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3626                         return -1;
3627                 }
3628         }
3629
3630         /* Session dirs */
3631         
3632         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3633                 vector<string> v;
3634
3635                 oldstr = (*i).path;
3636
3637                 /* this is a stupid hack because Glib::path_get_dirname() is
3638                  * lexical-only, and so passing it /a/b/c/ gives a different
3639                  * result than passing it /a/b/c ...
3640                  */
3641
3642                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3643                         oldstr = oldstr.substr (0, oldstr.length() - 1);
3644                 }
3645
3646                 string base = Glib::path_get_dirname (oldstr);
3647                 string p = Glib::path_get_basename (oldstr);
3648
3649                 newstr = Glib::build_filename (base, legal_name);
3650
3651                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3652
3653                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3654                         error << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3655                         return 1;
3656                 }
3657
3658                 if (first) {
3659                         (*_session_dir) = newstr;
3660                         newpath = newstr;
3661                         first = 1;
3662                 }
3663
3664                 /* directory below interchange */
3665
3666                 v.push_back (newstr);
3667                 v.push_back (interchange_dir_name);
3668                 v.push_back (p);
3669
3670                 oldstr = Glib::build_filename (v);
3671
3672                 v.clear ();
3673                 v.push_back (newstr);
3674                 v.push_back (interchange_dir_name);
3675                 v.push_back (legal_name);
3676
3677                 newstr = Glib::build_filename (v);
3678                 
3679                 cerr << "Rename " << oldstr << " => " << newstr << endl;
3680                 
3681                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3682                         error << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3683                         return 1;
3684                 }
3685         }
3686
3687         /* state file */
3688         
3689         oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3690         newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3691         
3692         cerr << "Rename " << oldstr << " => " << newstr << endl;                
3693
3694         if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3695                 error << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3696                 return 1;
3697         }
3698
3699         /* history file */
3700
3701         
3702         oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3703
3704         if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS))  {
3705                 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3706                 
3707                 cerr << "Rename " << oldstr << " => " << newstr << endl;                
3708                 
3709                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3710                         error << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
3711                         return 1;
3712                 }
3713         }
3714
3715         /* update file source paths */
3716         
3717         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3718                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3719                 if (fs) {
3720                         string p = fs->path ();
3721                         boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3722                         fs->set_path (p);
3723                 }
3724         }
3725
3726         /* remove old name from recent sessions */
3727
3728         remove_recent_sessions (_path);
3729
3730         _path = newpath;
3731         _current_snapshot_name = new_name;
3732         _name = new_name;
3733
3734         /* re-add directory separator - reverse hack to oldstr above */
3735         if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
3736                 _path += G_DIR_SEPARATOR;
3737         }
3738
3739         set_dirty ();
3740
3741         /* save state again to get everything just right */
3742
3743         save_state (_current_snapshot_name);
3744
3745
3746         /* add to recent sessions */
3747
3748         store_recent_sessions (new_name, _path);
3749
3750         return 0;
3751 }
3752
3753 int
3754 Session::get_session_info_from_path (XMLTree& tree, const string& xmlpath)
3755 {
3756         if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
3757                 return -1;
3758         }
3759
3760         if (!tree.read (xmlpath)) {
3761                 return -1;
3762         }
3763
3764         return 0;
3765 }
3766
3767 int
3768 Session::get_info_from_path (const string& xmlpath, float& sample_rate, SampleFormat& data_format)
3769 {
3770         XMLTree tree;
3771         bool found_sr = false;
3772         bool found_data_format = false;
3773
3774         if (get_session_info_from_path (tree, xmlpath)) {
3775                 return -1;
3776         }
3777
3778         /* sample rate */
3779
3780         const XMLProperty* prop;
3781         if ((prop = tree.root()->property (X_("sample-rate"))) != 0) {          
3782                 sample_rate = atoi (prop->value());
3783                 found_sr = true;
3784         }
3785
3786         const XMLNodeList& children (tree.root()->children());
3787         for (XMLNodeList::const_iterator c = children.begin(); c != children.end(); ++c) {
3788                 const XMLNode* child = *c;
3789                 if (child->name() == "Config") {
3790                         const XMLNodeList& options (child->children());
3791                         for (XMLNodeList::const_iterator oc = options.begin(); oc != options.end(); ++oc) {
3792                                 const XMLNode* option = *oc;
3793                                 const XMLProperty* name = option->property("name");
3794
3795                                 if (!name) {
3796                                         continue;
3797                                 }
3798
3799                                 if (name->value() == "native-file-data-format") {
3800                                         const XMLProperty* value = option->property ("value");
3801                                         if (value) {
3802                                                 SampleFormat fmt = (SampleFormat) string_2_enum (option->property ("value")->value(), fmt);
3803                                                 data_format = fmt;
3804                                                 found_data_format = true;
3805                                                 break;
3806                                         }
3807                                 }
3808                         }
3809                 }
3810                 if (found_data_format) {
3811                         break;
3812                 }
3813         }
3814
3815         return !(found_sr && found_data_format); // zero if they are both found
3816 }