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