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