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