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