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