2 Copyright (C) 1999-2002 Paul Davis
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.
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.
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.
22 #include "libardour-config.h"
33 #include <cstdio> /* snprintf(3) ... grrr */
47 #include <sys/param.h>
48 #include <sys/mount.h>
52 #include <glibmm/thread.h>
54 #include "midi++/mmc.h"
55 #include "midi++/port.h"
56 #include "midi++/manager.h"
58 #include "pbd/boost_debug.h"
59 #include "pbd/controllable_descriptor.h"
60 #include "pbd/enumwriter.h"
61 #include "pbd/error.h"
62 #include "pbd/pathscanner.h"
63 #include "pbd/pthread_utils.h"
64 #include "pbd/search_path.h"
65 #include "pbd/stacktrace.h"
66 #include "pbd/convert.h"
67 #include "pbd/clear_dir.h"
69 #include "ardour/amp.h"
70 #include "ardour/audio_diskstream.h"
71 #include "ardour/audio_track.h"
72 #include "ardour/audioengine.h"
73 #include "ardour/audiofilesource.h"
74 #include "ardour/audioplaylist.h"
75 #include "ardour/audioregion.h"
76 #include "ardour/auditioner.h"
77 #include "ardour/automation_control.h"
78 #include "ardour/buffer.h"
79 #include "ardour/butler.h"
80 #include "ardour/configuration.h"
81 #include "ardour/control_protocol_manager.h"
82 #include "ardour/crossfade.h"
83 #include "ardour/cycle_timer.h"
84 #include "ardour/directory_names.h"
85 #include "ardour/filename_extensions.h"
86 #include "ardour/io_processor.h"
87 #include "ardour/location.h"
88 #include "ardour/midi_diskstream.h"
89 #include "ardour/midi_patch_manager.h"
90 #include "ardour/midi_playlist.h"
91 #include "ardour/midi_region.h"
92 #include "ardour/midi_source.h"
93 #include "ardour/midi_track.h"
94 #include "ardour/named_selection.h"
95 #include "ardour/pannable.h"
96 #include "ardour/processor.h"
97 #include "ardour/port.h"
98 #include "ardour/proxy_controllable.h"
99 #include "ardour/region_factory.h"
100 #include "ardour/route_group.h"
101 #include "ardour/send.h"
102 #include "ardour/session.h"
103 #include "ardour/session_directory.h"
104 #include "ardour/session_metadata.h"
105 #include "ardour/session_state_utils.h"
106 #include "ardour/session_playlists.h"
107 #include "ardour/session_utils.h"
108 #include "ardour/silentfilesource.h"
109 #include "ardour/slave.h"
110 #include "ardour/smf_source.h"
111 #include "ardour/sndfile_helpers.h"
112 #include "ardour/sndfilesource.h"
113 #include "ardour/source_factory.h"
114 #include "ardour/template_utils.h"
115 #include "ardour/tempo.h"
116 #include "ardour/ticker.h"
117 #include "ardour/user_bundle.h"
118 #include "ardour/utils.h"
119 #include "ardour/utils.h"
120 #include "ardour/version.h"
121 #include "ardour/playlist_factory.h"
123 #include "control_protocol/control_protocol.h"
129 using namespace ARDOUR
;
133 Session::first_stage_init (string fullpath
, string snapshot_name
)
135 if (fullpath
.length() == 0) {
137 throw failed_constructor();
140 char buf
[PATH_MAX
+1];
141 if (!realpath (fullpath
.c_str(), buf
) && (errno
!= ENOENT
)) {
142 error
<< string_compose(_("Could not use path %1 (%s)"), buf
, strerror(errno
)) << endmsg
;
144 throw failed_constructor();
149 if (_path
[_path
.length()-1] != '/') {
150 _path
+= G_DIR_SEPARATOR
;
153 if (Glib::file_test (_path
, Glib::FILE_TEST_EXISTS
) && ::access (_path
.c_str(), W_OK
)) {
159 /* these two are just provisional settings. set_state()
160 will likely override them.
163 _name
= _current_snapshot_name
= snapshot_name
;
165 set_history_depth (Config
->get_history_depth());
167 _current_frame_rate
= _engine
.frame_rate ();
168 _nominal_frame_rate
= _current_frame_rate
;
169 _base_frame_rate
= _current_frame_rate
;
171 _tempo_map
= new TempoMap (_current_frame_rate
);
172 _tempo_map
->PropertyChanged
.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed
, this, _1
));
175 _non_soloed_outs_muted
= false;
177 _solo_isolated_cnt
= 0;
178 g_atomic_int_set (&processing_prohibited
, 0);
179 _transport_speed
= 0;
180 _last_transport_speed
= 0;
181 _target_transport_speed
= 0;
182 auto_play_legal
= false;
183 transport_sub_state
= 0;
184 _transport_frame
= 0;
185 _requested_return_frame
= -1;
186 _session_range_location
= 0;
187 g_atomic_int_set (&_record_status
, Disabled
);
188 loop_changing
= false;
191 _last_roll_location
= 0;
192 _last_roll_or_reversal_location
= 0;
193 _last_record_location
= 0;
194 pending_locate_frame
= 0;
195 pending_locate_roll
= false;
196 pending_locate_flush
= false;
197 state_was_pending
= false;
199 outbound_mtc_timecode_frame
= 0;
200 next_quarter_frame_to_send
= -1;
201 current_block_size
= 0;
202 solo_update_disabled
= false;
203 _have_captured
= false;
204 _worst_output_latency
= 0;
205 _worst_input_latency
= 0;
206 _worst_track_latency
= 0;
207 _state_of_the_state
= StateOfTheState(CannotSave
|InitialConnecting
|Loading
);
208 _was_seamless
= Config
->get_seamless_loop ();
210 _send_qf_mtc
= false;
211 _pframes_since_last_mtc
= 0;
212 g_atomic_int_set (&_playback_load
, 100);
213 g_atomic_int_set (&_capture_load
, 100);
216 pending_abort
= false;
217 destructive_index
= 0;
218 first_file_data_format_reset
= true;
219 first_file_header_format_reset
= true;
220 post_export_sync
= false;
223 no_questions_about_missing_files
= false;
224 _speakers
= new Speakers
;
226 AudioDiskstream::allocate_working_buffers();
228 /* default short fade = 15ms */
230 Crossfade::set_short_xfade_length ((framecnt_t
) floor (config
.get_short_xfade_seconds() * frame_rate()));
231 SndFileSource::setup_standard_crossfades (*this, frame_rate());
233 last_mmc_step
.tv_sec
= 0;
234 last_mmc_step
.tv_usec
= 0;
237 /* click sounds are unset by default, which causes us to internal
238 waveforms for clicks.
242 click_emphasis_length
= 0;
245 process_function
= &Session::process_with_events
;
247 if (config
.get_use_video_sync()) {
248 waiting_for_sync_offset
= true;
250 waiting_for_sync_offset
= false;
253 last_timecode_when
= 0;
254 last_timecode_valid
= false;
258 last_rr_session_dir
= session_dirs
.begin();
259 refresh_disk_space ();
261 /* default: assume simple stereo speaker configuration */
263 _speakers
->setup_default_speakers (2);
267 average_slave_delta
= 1800; // !!! why 1800 ????
268 have_first_delta_accumulator
= false;
269 delta_accumulator_cnt
= 0;
270 _slave_state
= Stopped
;
272 _solo_cut_control
.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike
,
273 boost::bind (&RCConfiguration::set_solo_mute_gain
, Config
, _1
),
274 boost::bind (&RCConfiguration::get_solo_mute_gain
, Config
)));
275 add_controllable (_solo_cut_control
);
277 _engine
.GraphReordered
.connect_same_thread (*this, boost::bind (&Session::graph_reordered
, this));
279 /* These are all static "per-class" signals */
281 SourceFactory::SourceCreated
.connect_same_thread (*this, boost::bind (&Session::add_source
, this, _1
));
282 PlaylistFactory::PlaylistCreated
.connect_same_thread (*this, boost::bind (&Session::add_playlist
, this, _1
, _2
));
283 AutomationList::AutomationListCreated
.connect_same_thread (*this, boost::bind (&Session::add_automation_list
, this, _1
));
284 Controllable::Destroyed
.connect_same_thread (*this, boost::bind (&Session::remove_controllable
, this, _1
));
285 IO::PortCountChanged
.connect_same_thread (*this, boost::bind (&Session::ensure_buffers
, this, _1
));
287 /* stop IO objects from doing stuff until we're ready for them */
289 Delivery::disable_panners ();
290 IO::disable_connecting ();
294 Session::second_stage_init ()
296 AudioFileSource::set_peak_dir (_session_dir
->peak_path().to_string());
299 if (load_state (_current_snapshot_name
)) {
302 cleanup_stubfiles ();
305 if (_butler
->start_thread()) {
309 if (start_midi_thread ()) {
313 setup_midi_machine_control ();
315 // set_state() will call setup_raid_path(), but if it's a new session we need
316 // to call setup_raid_path() here.
319 if (set_state (*state_tree
->root(), Stateful::loading_state_version
)) {
323 setup_raid_path(_path
);
326 /* we can't save till after ::when_engine_running() is called,
327 because otherwise we save state with no connections made.
328 therefore, we reset _state_of_the_state because ::set_state()
329 will have cleared it.
331 we also have to include Loading so that any events that get
332 generated between here and the end of ::when_engine_running()
333 will be processed directly rather than queued.
336 _state_of_the_state
= StateOfTheState (_state_of_the_state
|CannotSave
|Loading
);
338 _locations
->changed
.connect_same_thread (*this, boost::bind (&Session::locations_changed
, this));
339 _locations
->added
.connect_same_thread (*this, boost::bind (&Session::locations_added
, this, _1
));
340 setup_click_sounds (0);
341 setup_midi_control ();
343 /* Pay attention ... */
345 _engine
.Halted
.connect_same_thread (*this, boost::bind (&Session::engine_halted
, this));
346 _engine
.Xrun
.connect_same_thread (*this, boost::bind (&Session::xrun_recovery
, this));
349 when_engine_running ();
352 /* handle this one in a different way than all others, so that its clear what happened */
354 catch (AudioEngine::PortRegistrationFailure
& err
) {
355 error
<< err
.what() << endmsg
;
363 BootMessage (_("Reset Remote Controls"));
365 send_full_time_code (0);
366 _engine
.transport_locate (0);
368 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset
));
369 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
371 MidiClockTicker::instance().set_session (this);
372 MIDI::Name::MidiPatchManager::instance().set_session (this);
374 /* initial program change will be delivered later; see ::config_changed() */
376 BootMessage (_("Reset Control Protocols"));
378 ControlProtocolManager::instance().set_session (this);
380 _state_of_the_state
= Clean
;
382 Port::set_connecting_blocked (false);
384 DirtyChanged (); /* EMIT SIGNAL */
386 if (state_was_pending
) {
387 save_state (_current_snapshot_name
);
388 remove_pending_capture_state ();
389 state_was_pending
= false;
392 BootMessage (_("Session loading complete"));
398 Session::raid_path () const
400 SearchPath raid_search_path
;
402 for (vector
<space_and_path
>::const_iterator i
= session_dirs
.begin(); i
!= session_dirs
.end(); ++i
) {
403 raid_search_path
+= sys::path((*i
).path
);
406 return raid_search_path
.to_string ();
410 Session::setup_raid_path (string path
)
419 session_dirs
.clear ();
421 SearchPath
search_path(path
);
422 SearchPath sound_search_path
;
423 SearchPath midi_search_path
;
425 for (SearchPath::const_iterator i
= search_path
.begin(); i
!= search_path
.end(); ++i
) {
426 sp
.path
= (*i
).to_string ();
427 sp
.blocks
= 0; // not needed
428 session_dirs
.push_back (sp
);
430 SessionDirectory
sdir(sp
.path
);
432 sound_search_path
+= sdir
.sound_path ();
433 midi_search_path
+= sdir
.midi_path ();
436 // reset the round-robin soundfile path thingie
437 last_rr_session_dir
= session_dirs
.begin();
441 Session::path_is_within_session (const std::string
& path
)
443 for (vector
<space_and_path
>::const_iterator i
= session_dirs
.begin(); i
!= session_dirs
.end(); ++i
) {
444 if (path
.find ((*i
).path
) == 0) {
452 Session::ensure_subdirs ()
456 dir
= session_directory().peak_path().to_string();
458 if (g_mkdir_with_parents (dir
.c_str(), 0755) < 0) {
459 error
<< string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir
, strerror (errno
)) << endmsg
;
463 dir
= session_directory().sound_path().to_string();
465 if (g_mkdir_with_parents (dir
.c_str(), 0755) < 0) {
466 error
<< string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir
, strerror (errno
)) << endmsg
;
470 dir
= session_directory().sound_stub_path().to_string();
472 if (g_mkdir_with_parents (dir
.c_str(), 0755) < 0) {
473 error
<< string_compose(_("Session: cannot create session stub sounds dir \"%1\" (%2)"), dir
, strerror (errno
)) << endmsg
;
477 dir
= session_directory().midi_path().to_string();
479 if (g_mkdir_with_parents (dir
.c_str(), 0755) < 0) {
480 error
<< string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir
, strerror (errno
)) << endmsg
;
484 dir
= session_directory().midi_stub_path().to_string();
486 if (g_mkdir_with_parents (dir
.c_str(), 0755) < 0) {
487 error
<< string_compose(_("Session: cannot create session stub midi dir \"%1\" (%2)"), dir
, strerror (errno
)) << endmsg
;
491 dir
= session_directory().dead_sound_path().to_string();
493 if (g_mkdir_with_parents (dir
.c_str(), 0755) < 0) {
494 error
<< string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir
, strerror (errno
)) << endmsg
;
498 dir
= session_directory().export_path().to_string();
500 if (g_mkdir_with_parents (dir
.c_str(), 0755) < 0) {
501 error
<< string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir
, strerror (errno
)) << endmsg
;
505 dir
= analysis_dir ();
507 if (g_mkdir_with_parents (dir
.c_str(), 0755) < 0) {
508 error
<< string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir
, strerror (errno
)) << endmsg
;
512 dir
= plugins_dir ();
514 if (g_mkdir_with_parents (dir
.c_str(), 0755) < 0) {
515 error
<< string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir
, strerror (errno
)) << endmsg
;
522 /** Caller must not hold process lock */
524 Session::create (const string
& mix_template
, BusProfile
* bus_profile
)
526 if (g_mkdir_with_parents (_path
.c_str(), 0755) < 0) {
527 error
<< string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path
, strerror (errno
)) << endmsg
;
531 if (ensure_subdirs ()) {
535 if (!mix_template
.empty()) {
536 std::string in_path
= mix_template
;
538 ifstream
in(in_path
.c_str());
541 string out_path
= _path
;
543 out_path
+= statefile_suffix
;
545 ofstream
out(out_path
.c_str());
553 error
<< string_compose (_("Could not open %1 for writing mix template"), out_path
)
559 error
<< string_compose (_("Could not open mix template %1 for reading"), in_path
)
566 /* Instantiate metadata */
568 _metadata
= new SessionMetadata ();
570 /* set initial start + end point */
572 _state_of_the_state
= Clean
;
574 /* set up Master Out and Control Out if necessary */
580 ChanCount
count(DataType::AUDIO
, bus_profile
->master_out_channels
);
582 if (bus_profile
->master_out_channels
) {
583 Route
* rt
= new Route (*this, _("master"), Route::MasterOut
, DataType::AUDIO
);
588 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
589 boost_debug_shared_ptr_mark_interesting (rt
, "Route");
591 boost::shared_ptr
<Route
> r (rt
);
593 Glib::Mutex::Lock
lm (AudioEngine::instance()->process_lock ());
594 r
->input()->ensure_io (count
, false, this);
595 r
->output()->ensure_io (count
, false, this);
597 r
->set_remote_control_id (control_id
++);
601 if (Config
->get_use_monitor_bus()) {
602 Route
* rt
= new Route (*this, _("monitor"), Route::MonitorOut
, DataType::AUDIO
);
607 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
608 boost_debug_shared_ptr_mark_interesting (rt
, "Route");
610 boost::shared_ptr
<Route
> r (rt
);
612 Glib::Mutex::Lock
lm (AudioEngine::instance()->process_lock ());
613 r
->input()->ensure_io (count
, false, this);
614 r
->output()->ensure_io (count
, false, this);
616 r
->set_remote_control_id (control_id
);
622 /* prohibit auto-connect to master, because there isn't one */
623 bus_profile
->output_ac
= AutoConnectOption (bus_profile
->output_ac
& ~AutoConnectMaster
);
627 add_routes (rl
, false);
630 /* this allows the user to override settings with an environment variable.
633 if (no_auto_connect()) {
634 bus_profile
->input_ac
= AutoConnectOption (0);
635 bus_profile
->output_ac
= AutoConnectOption (0);
638 Config
->set_input_auto_connect (bus_profile
->input_ac
);
639 Config
->set_output_auto_connect (bus_profile
->output_ac
);
648 Session::maybe_write_autosave()
650 if (dirty() && record_status() != Recording
) {
651 save_state("", true);
656 Session::remove_pending_capture_state ()
658 sys::path
pending_state_file_path(_session_dir
->root_path());
660 pending_state_file_path
/= legalize_for_path (_current_snapshot_name
) + pending_suffix
;
664 sys::remove (pending_state_file_path
);
666 catch(sys::filesystem_error
& ex
)
668 error
<< string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
669 pending_state_file_path
.to_string(), ex
.what()) << endmsg
;
673 /** Rename a state file.
674 * @param snapshot_name Snapshot name.
677 Session::rename_state (string old_name
, string new_name
)
679 if (old_name
== _current_snapshot_name
|| old_name
== _name
) {
680 /* refuse to rename the current snapshot or the "main" one */
684 const string old_xml_filename
= legalize_for_path (old_name
) + statefile_suffix
;
685 const string new_xml_filename
= legalize_for_path (new_name
) + statefile_suffix
;
687 const sys::path old_xml_path
= _session_dir
->root_path() / old_xml_filename
;
688 const sys::path new_xml_path
= _session_dir
->root_path() / new_xml_filename
;
692 sys::rename (old_xml_path
, new_xml_path
);
694 catch (const sys::filesystem_error
& err
)
696 error
<< string_compose(_("could not rename snapshot %1 to %2 (%3)"),
697 old_name
, new_name
, err
.what()) << endmsg
;
701 /** Remove a state file.
702 * @param snapshot_name Snapshot name.
705 Session::remove_state (string snapshot_name
)
707 if (snapshot_name
== _current_snapshot_name
|| snapshot_name
== _name
) {
708 // refuse to remove the current snapshot or the "main" one
712 sys::path
xml_path(_session_dir
->root_path());
714 xml_path
/= legalize_for_path (snapshot_name
) + statefile_suffix
;
716 if (!create_backup_file (xml_path
)) {
717 // don't remove it if a backup can't be made
718 // create_backup_file will log the error.
723 sys::remove (xml_path
);
726 #ifdef HAVE_JACK_SESSION
728 Session::jack_session_event (jack_session_event_t
* event
)
732 struct tm local_time
;
735 localtime_r (&n
, &local_time
);
736 strftime (timebuf
, sizeof(timebuf
), "JS_%FT%T", &local_time
);
738 if (event
->type
== JackSessionSaveTemplate
)
740 if (save_template( timebuf
)) {
741 event
->flags
= JackSessionSaveError
;
743 string
cmd ("ardour3 -P -U ");
744 cmd
+= event
->client_uuid
;
748 event
->command_line
= strdup (cmd
.c_str());
753 if (save_state (timebuf
)) {
754 event
->flags
= JackSessionSaveError
;
756 sys::path
xml_path (_session_dir
->root_path());
757 xml_path
/= legalize_for_path (timebuf
) + statefile_suffix
;
759 string
cmd ("ardour3 -P -U ");
760 cmd
+= event
->client_uuid
;
762 cmd
+= xml_path
.to_string();
765 event
->command_line
= strdup (cmd
.c_str());
769 jack_session_reply (_engine
.jack(), event
);
771 if (event
->type
== JackSessionSaveAndQuit
) {
772 Quit (); /* EMIT SIGNAL */
775 jack_session_event_free( event
);
780 Session::save_state (string snapshot_name
, bool pending
, bool switch_to_snapshot
)
783 sys::path
xml_path(_session_dir
->root_path());
785 if (!_writable
|| (_state_of_the_state
& CannotSave
)) {
789 if (!_engine
.connected ()) {
790 error
<< string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
796 /* tell sources we're saving first, in case they write out to a new file
797 * which should be saved with the state rather than the old one */
798 for (SourceMap::const_iterator i
= sources
.begin(); i
!= sources
.end(); ++i
) {
799 i
->second
->session_saved();
802 tree
.set_root (&get_state());
804 if (snapshot_name
.empty()) {
805 snapshot_name
= _current_snapshot_name
;
806 } else if (switch_to_snapshot
) {
807 _current_snapshot_name
= snapshot_name
;
812 /* proper save: use statefile_suffix (.ardour in English) */
814 xml_path
/= legalize_for_path (snapshot_name
) + statefile_suffix
;
816 /* make a backup copy of the old file */
818 if (sys::exists(xml_path
) && !create_backup_file (xml_path
)) {
819 // create_backup_file will log the error
825 /* pending save: use pending_suffix (.pending in English) */
826 xml_path
/= legalize_for_path (snapshot_name
) + pending_suffix
;
829 sys::path
tmp_path(_session_dir
->root_path());
831 tmp_path
/= legalize_for_path (snapshot_name
) + temp_suffix
;
833 // cerr << "actually writing state to " << xml_path.to_string() << endl;
835 if (!tree
.write (tmp_path
.to_string())) {
836 error
<< string_compose (_("state could not be saved to %1"), tmp_path
.to_string()) << endmsg
;
837 sys::remove (tmp_path
);
842 if (rename (tmp_path
.to_string().c_str(), xml_path
.to_string().c_str()) != 0) {
843 error
<< string_compose (_("could not rename temporary session file %1 to %2"),
844 tmp_path
.to_string(), xml_path
.to_string()) << endmsg
;
845 sys::remove (tmp_path
);
852 save_history (snapshot_name
);
854 bool was_dirty
= dirty();
856 _state_of_the_state
= StateOfTheState (_state_of_the_state
& ~Dirty
);
859 DirtyChanged (); /* EMIT SIGNAL */
862 StateSaved (snapshot_name
); /* EMIT SIGNAL */
869 Session::restore_state (string snapshot_name
)
871 if (load_state (snapshot_name
) == 0) {
872 set_state (*state_tree
->root(), Stateful::loading_state_version
);
879 Session::load_state (string snapshot_name
)
884 state_was_pending
= false;
886 /* check for leftover pending state from a crashed capture attempt */
888 sys::path
xmlpath(_session_dir
->root_path());
889 xmlpath
/= legalize_for_path (snapshot_name
) + pending_suffix
;
891 if (sys::exists (xmlpath
)) {
893 /* there is pending state from a crashed capture attempt */
895 boost::optional
<int> r
= AskAboutPendingState();
896 if (r
.get_value_or (1)) {
897 state_was_pending
= true;
901 if (!state_was_pending
) {
902 xmlpath
= _session_dir
->root_path();
903 xmlpath
/= snapshot_name
;
906 if (!sys::exists (xmlpath
)) {
907 xmlpath
= _session_dir
->root_path();
908 xmlpath
/= legalize_for_path (snapshot_name
) + statefile_suffix
;
909 if (!sys::exists (xmlpath
)) {
910 error
<< string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name
, xmlpath
.to_string()) << endmsg
;
915 state_tree
= new XMLTree
;
919 /* writable() really reflects the whole folder, but if for any
920 reason the session state file can't be written to, still
924 if (::access (xmlpath
.to_string().c_str(), W_OK
) != 0) {
928 if (!state_tree
->read (xmlpath
.to_string())) {
929 error
<< string_compose(_("Could not understand ardour file %1"), xmlpath
.to_string()) << endmsg
;
935 XMLNode
& root (*state_tree
->root());
937 if (root
.name() != X_("Session")) {
938 error
<< string_compose (_("Session file %1 is not a session"), xmlpath
.to_string()) << endmsg
;
944 const XMLProperty
* prop
;
946 if ((prop
= root
.property ("version")) == 0) {
947 /* no version implies very old version of Ardour */
948 Stateful::loading_state_version
= 1000;
954 sscanf (prop
->value().c_str(), "%d.%d.%d", &major
, &minor
, µ
);
955 Stateful::loading_state_version
= (major
* 1000) + minor
;
958 if (Stateful::loading_state_version
< CURRENT_SESSION_FILE_VERSION
) {
960 sys::path
backup_path(_session_dir
->root_path());
962 backup_path
/= legalize_for_path (snapshot_name
) + "-1" + statefile_suffix
;
964 // only create a backup once
965 if (sys::exists (backup_path
)) {
969 info
<< string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
970 xmlpath
.to_string(), backup_path
.to_string(), PROGRAM_NAME
)
975 sys::copy_file (xmlpath
, backup_path
);
977 catch(sys::filesystem_error
& ex
)
979 error
<< string_compose (_("Unable to make backup of state file %1 (%2)"),
980 xmlpath
.to_string(), ex
.what())
990 Session::load_options (const XMLNode
& node
)
992 LocaleGuard
lg (X_("POSIX"));
993 config
.set_variables (node
);
1004 Session::get_template()
1006 /* if we don't disable rec-enable, diskstreams
1007 will believe they need to store their capture
1008 sources in their state node.
1011 disable_record (false);
1013 return state(false);
1017 Session::state(bool full_state
)
1019 XMLNode
* node
= new XMLNode("Session");
1022 // store libardour version, just in case
1024 snprintf(buf
, sizeof(buf
), "%d.%d.%d", libardour3_major_version
, libardour3_minor_version
, libardour3_micro_version
);
1025 node
->add_property("version", string(buf
));
1027 /* store configuration settings */
1031 node
->add_property ("name", _name
);
1032 snprintf (buf
, sizeof (buf
), "%" PRId64
, _nominal_frame_rate
);
1033 node
->add_property ("sample-rate", buf
);
1035 if (session_dirs
.size() > 1) {
1039 vector
<space_and_path
>::iterator i
= session_dirs
.begin();
1040 vector
<space_and_path
>::iterator next
;
1042 ++i
; /* skip the first one */
1046 while (i
!= session_dirs
.end()) {
1050 if (next
!= session_dirs
.end()) {
1060 child
= node
->add_child ("Path");
1061 child
->add_content (p
);
1065 /* save the ID counter */
1067 snprintf (buf
, sizeof (buf
), "%" PRIu64
, ID::counter());
1068 node
->add_property ("id-counter", buf
);
1070 /* save the event ID counter */
1072 snprintf (buf
, sizeof (buf
), "%d", Evoral::event_id_counter());
1073 node
->add_property ("event-counter", buf
);
1075 /* various options */
1077 node
->add_child_nocopy (config
.get_variables ());
1079 node
->add_child_nocopy (_metadata
->get_state());
1081 child
= node
->add_child ("Sources");
1084 Glib::Mutex::Lock
sl (source_lock
);
1086 for (SourceMap::iterator siter
= sources
.begin(); siter
!= sources
.end(); ++siter
) {
1088 /* Don't save information about non-destructive file sources that are empty
1089 and unused by any regions.
1092 boost::shared_ptr
<FileSource
> fs
;
1093 if ((fs
= boost::dynamic_pointer_cast
<FileSource
> (siter
->second
)) != 0) {
1094 if (!fs
->destructive()) {
1095 if (fs
->empty() && !fs
->used()) {
1101 child
->add_child_nocopy (siter
->second
->get_state());
1105 child
= node
->add_child ("Regions");
1108 Glib::Mutex::Lock
rl (region_lock
);
1109 const RegionFactory::RegionMap
& region_map (RegionFactory::all_regions());
1110 for (RegionFactory::RegionMap::const_iterator i
= region_map
.begin(); i
!= region_map
.end(); ++i
) {
1111 boost::shared_ptr
<Region
> r
= i
->second
;
1112 /* only store regions not attached to playlists */
1113 if (r
->playlist() == 0) {
1114 child
->add_child_nocopy (r
->state ());
1120 node
->add_child_nocopy (_locations
->get_state());
1122 // for a template, just create a new Locations, populate it
1123 // with the default start and end, and get the state for that.
1124 Locations
loc (*this);
1125 Location
* range
= new Location (*this, 0, 0, _("session"), Location::IsSessionRange
);
1126 range
->set (max_framepos
, 0);
1128 node
->add_child_nocopy (loc
.get_state());
1131 child
= node
->add_child ("Bundles");
1133 boost::shared_ptr
<BundleList
> bundles
= _bundles
.reader ();
1134 for (BundleList::iterator i
= bundles
->begin(); i
!= bundles
->end(); ++i
) {
1135 boost::shared_ptr
<UserBundle
> b
= boost::dynamic_pointer_cast
<UserBundle
> (*i
);
1137 child
->add_child_nocopy (b
->get_state());
1142 child
= node
->add_child ("Routes");
1144 boost::shared_ptr
<RouteList
> r
= routes
.reader ();
1146 RoutePublicOrderSorter cmp
;
1147 RouteList
public_order (*r
);
1148 public_order
.sort (cmp
);
1150 /* the sort should have put control outs first */
1153 assert (_monitor_out
== public_order
.front());
1156 for (RouteList::iterator i
= public_order
.begin(); i
!= public_order
.end(); ++i
) {
1157 if (!(*i
)->is_hidden()) {
1159 child
->add_child_nocopy ((*i
)->get_state());
1161 child
->add_child_nocopy ((*i
)->get_template());
1167 playlists
->add_state (node
, full_state
);
1169 child
= node
->add_child ("RouteGroups");
1170 for (list
<RouteGroup
*>::iterator i
= _route_groups
.begin(); i
!= _route_groups
.end(); ++i
) {
1171 child
->add_child_nocopy ((*i
)->get_state());
1175 child
= node
->add_child ("Click");
1176 child
->add_child_nocopy (_click_io
->state (full_state
));
1180 child
= node
->add_child ("NamedSelections");
1181 for (NamedSelectionList::iterator i
= named_selections
.begin(); i
!= named_selections
.end(); ++i
) {
1183 child
->add_child_nocopy ((*i
)->get_state());
1188 node
->add_child_nocopy (_speakers
->get_state());
1190 node
->add_child_nocopy (_tempo_map
->get_state());
1192 node
->add_child_nocopy (get_control_protocol_state());
1195 node
->add_child_copy (*_extra_xml
);
1202 Session::get_control_protocol_state ()
1204 ControlProtocolManager
& cpm (ControlProtocolManager::instance());
1205 return cpm
.get_state();
1209 Session::set_state (const XMLNode
& node
, int version
)
1213 const XMLProperty
* prop
;
1216 _state_of_the_state
= StateOfTheState (_state_of_the_state
|CannotSave
);
1218 if (node
.name() != X_("Session")) {
1219 fatal
<< _("programming error: Session: incorrect XML node sent to set_state()") << endmsg
;
1223 if ((prop
= node
.property ("version")) != 0) {
1224 version
= atoi (prop
->value ()) * 1000;
1227 if ((prop
= node
.property ("name")) != 0) {
1228 _name
= prop
->value ();
1231 if ((prop
= node
.property (X_("sample-rate"))) != 0) {
1233 _nominal_frame_rate
= atoi (prop
->value());
1235 if (_nominal_frame_rate
!= _current_frame_rate
) {
1236 boost::optional
<int> r
= AskAboutSampleRateMismatch (_nominal_frame_rate
, _current_frame_rate
);
1237 if (r
.get_value_or (0)) {
1243 setup_raid_path(_session_dir
->root_path().to_string());
1245 if ((prop
= node
.property (X_("id-counter"))) != 0) {
1247 sscanf (prop
->value().c_str(), "%" PRIu64
, &x
);
1248 ID::init_counter (x
);
1250 /* old sessions used a timebased counter, so fake
1251 the startup ID counter based on a standard
1256 ID::init_counter (now
);
1259 if ((prop
= node
.property (X_("event-counter"))) != 0) {
1260 Evoral::init_event_id_counter (atoi (prop
->value()));
1263 IO::disable_connecting ();
1265 /* Object loading order:
1270 MIDI Control // relies on data from Options/Config
1283 if ((child
= find_named_node (node
, "Extra")) != 0) {
1284 _extra_xml
= new XMLNode (*child
);
1287 if (((child
= find_named_node (node
, "Options")) != 0)) { /* old style */
1288 load_options (*child
);
1289 } else if ((child
= find_named_node (node
, "Config")) != 0) { /* new style */
1290 load_options (*child
);
1292 error
<< _("Session: XML state has no options section") << endmsg
;
1295 if (version
>= 3000) {
1296 if ((child
= find_named_node (node
, "Metadata")) == 0) {
1297 warning
<< _("Session: XML state has no metadata section") << endmsg
;
1298 } else if (_metadata
->set_state (*child
, version
)) {
1303 if ((child
= find_named_node (node
, "Locations")) == 0) {
1304 error
<< _("Session: XML state has no locations section") << endmsg
;
1306 } else if (_locations
->set_state (*child
, version
)) {
1310 if ((child
= find_named_node (node
, X_("Speakers"))) != 0) {
1311 _speakers
->set_state (*child
, version
);
1316 if ((location
= _locations
->auto_loop_location()) != 0) {
1317 set_auto_loop_location (location
);
1320 if ((location
= _locations
->auto_punch_location()) != 0) {
1321 set_auto_punch_location (location
);
1324 if ((location
= _locations
->session_range_location()) != 0) {
1325 delete _session_range_location
;
1326 _session_range_location
= location
;
1329 if (_session_range_location
) {
1330 AudioFileSource::set_header_position_offset (_session_range_location
->start());
1333 if ((child
= find_named_node (node
, "Sources")) == 0) {
1334 error
<< _("Session: XML state has no sources section") << endmsg
;
1336 } else if (load_sources (*child
)) {
1340 if ((child
= find_named_node (node
, "Regions")) == 0) {
1341 error
<< _("Session: XML state has no Regions section") << endmsg
;
1343 } else if (load_regions (*child
)) {
1347 if ((child
= find_named_node (node
, "Playlists")) == 0) {
1348 error
<< _("Session: XML state has no playlists section") << endmsg
;
1350 } else if (playlists
->load (*this, *child
)) {
1354 if ((child
= find_named_node (node
, "UnusedPlaylists")) == 0) {
1356 } else if (playlists
->load_unused (*this, *child
)) {
1360 if ((child
= find_named_node (node
, "NamedSelections")) != 0) {
1361 if (load_named_selections (*child
)) {
1366 if (version
>= 3000) {
1367 if ((child
= find_named_node (node
, "Bundles")) == 0) {
1368 warning
<< _("Session: XML state has no bundles section") << endmsg
;
1371 /* We can't load Bundles yet as they need to be able
1372 to convert from port names to Port objects, which can't happen until
1374 _bundle_xml_node
= new XMLNode (*child
);
1378 if ((child
= find_named_node (node
, "TempoMap")) == 0) {
1379 error
<< _("Session: XML state has no Tempo Map section") << endmsg
;
1381 } else if (_tempo_map
->set_state (*child
, version
)) {
1385 if (version
< 3000) {
1386 if ((child
= find_named_node (node
, X_("DiskStreams"))) == 0) {
1387 error
<< _("Session: XML state has no diskstreams section") << endmsg
;
1389 } else if (load_diskstreams_2X (*child
, version
)) {
1394 if ((child
= find_named_node (node
, "Routes")) == 0) {
1395 error
<< _("Session: XML state has no routes section") << endmsg
;
1397 } else if (load_routes (*child
, version
)) {
1401 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1402 _diskstreams_2X
.clear ();
1404 if (version
>= 3000) {
1406 if ((child
= find_named_node (node
, "RouteGroups")) == 0) {
1407 error
<< _("Session: XML state has no route groups section") << endmsg
;
1409 } else if (load_route_groups (*child
, version
)) {
1413 } else if (version
< 3000) {
1415 if ((child
= find_named_node (node
, "EditGroups")) == 0) {
1416 error
<< _("Session: XML state has no edit groups section") << endmsg
;
1418 } else if (load_route_groups (*child
, version
)) {
1422 if ((child
= find_named_node (node
, "MixGroups")) == 0) {
1423 error
<< _("Session: XML state has no mix groups section") << endmsg
;
1425 } else if (load_route_groups (*child
, version
)) {
1430 if ((child
= find_named_node (node
, "Click")) == 0) {
1431 warning
<< _("Session: XML state has no click section") << endmsg
;
1432 } else if (_click_io
) {
1433 _click_io
->set_state (*child
, version
);
1436 if ((child
= find_named_node (node
, "ControlProtocols")) != 0) {
1437 ControlProtocolManager::instance().set_protocol_states (*child
);
1440 /* here beginneth the second phase ... */
1442 StateReady (); /* EMIT SIGNAL */
1451 Session::load_routes (const XMLNode
& node
, int version
)
1454 XMLNodeConstIterator niter
;
1455 RouteList new_routes
;
1457 nlist
= node
.children();
1461 for (niter
= nlist
.begin(); niter
!= nlist
.end(); ++niter
) {
1463 boost::shared_ptr
<Route
> route
;
1464 if (version
< 3000) {
1465 route
= XMLRouteFactory_2X (**niter
, version
);
1467 route
= XMLRouteFactory (**niter
, version
);
1471 error
<< _("Session: cannot create Route from XML description.") << endmsg
;
1475 BootMessage (string_compose (_("Loaded track/bus %1"), route
->name()));
1477 new_routes
.push_back (route
);
1480 add_routes (new_routes
, false);
1485 boost::shared_ptr
<Route
>
1486 Session::XMLRouteFactory (const XMLNode
& node
, int version
)
1488 boost::shared_ptr
<Route
> ret
;
1490 if (node
.name() != "Route") {
1494 XMLNode
* ds_child
= find_named_node (node
, X_("Diskstream"));
1496 DataType type
= DataType::AUDIO
;
1497 const XMLProperty
* prop
= node
.property("default-type");
1500 type
= DataType (prop
->value());
1503 assert (type
!= DataType::NIL
);
1509 if (type
== DataType::AUDIO
) {
1510 track
= new AudioTrack (*this, X_("toBeResetFroXML"));
1513 track
= new MidiTrack (*this, X_("toBeResetFroXML"));
1516 if (track
->init()) {
1521 if (track
->set_state (node
, version
)) {
1526 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1527 boost_debug_shared_ptr_mark_interesting (track
, "Track");
1532 Route
* rt
= new Route (*this, X_("toBeResetFroXML"));
1534 if (rt
->init () == 0 && rt
->set_state (node
, version
) == 0) {
1535 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1536 boost_debug_shared_ptr_mark_interesting (rt
, "Route");
1547 boost::shared_ptr
<Route
>
1548 Session::XMLRouteFactory_2X (const XMLNode
& node
, int version
)
1550 boost::shared_ptr
<Route
> ret
;
1552 if (node
.name() != "Route") {
1556 XMLProperty
const * ds_prop
= node
.property (X_("diskstream-id"));
1558 ds_prop
= node
.property (X_("diskstream"));
1561 DataType type
= DataType::AUDIO
;
1562 const XMLProperty
* prop
= node
.property("default-type");
1565 type
= DataType (prop
->value());
1568 assert (type
!= DataType::NIL
);
1572 list
<boost::shared_ptr
<Diskstream
> >::iterator i
= _diskstreams_2X
.begin ();
1573 while (i
!= _diskstreams_2X
.end() && (*i
)->id() != ds_prop
->value()) {
1577 if (i
== _diskstreams_2X
.end()) {
1578 error
<< _("Could not find diskstream for route") << endmsg
;
1579 return boost::shared_ptr
<Route
> ();
1584 if (type
== DataType::AUDIO
) {
1585 track
= new AudioTrack (*this, X_("toBeResetFroXML"));
1588 track
= new MidiTrack (*this, X_("toBeResetFroXML"));
1591 if (track
->init()) {
1596 if (track
->set_state (node
, version
)) {
1601 track
->set_diskstream (*i
);
1603 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1604 boost_debug_shared_ptr_mark_interesting (track
, "Track");
1609 Route
* rt
= new Route (*this, X_("toBeResetFroXML"));
1611 if (rt
->init () == 0 && rt
->set_state (node
, version
) == 0) {
1612 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1613 boost_debug_shared_ptr_mark_interesting (rt
, "Route");
1625 Session::load_regions (const XMLNode
& node
)
1628 XMLNodeConstIterator niter
;
1629 boost::shared_ptr
<Region
> region
;
1631 nlist
= node
.children();
1635 for (niter
= nlist
.begin(); niter
!= nlist
.end(); ++niter
) {
1636 if ((region
= XMLRegionFactory (**niter
, false)) == 0) {
1637 error
<< _("Session: cannot create Region from XML description.");
1638 const XMLProperty
*name
= (**niter
).property("name");
1641 error
<< " " << string_compose (_("Can not load state for region '%1'"), name
->value());
1651 boost::shared_ptr
<Region
>
1652 Session::XMLRegionFactory (const XMLNode
& node
, bool full
)
1654 const XMLProperty
* type
= node
.property("type");
1658 if (!type
|| type
->value() == "audio") {
1659 return boost::shared_ptr
<Region
>(XMLAudioRegionFactory (node
, full
));
1660 } else if (type
->value() == "midi") {
1661 return boost::shared_ptr
<Region
>(XMLMidiRegionFactory (node
, full
));
1664 } catch (failed_constructor
& err
) {
1665 return boost::shared_ptr
<Region
> ();
1668 return boost::shared_ptr
<Region
> ();
1671 boost::shared_ptr
<AudioRegion
>
1672 Session::XMLAudioRegionFactory (const XMLNode
& node
, bool /*full*/)
1674 const XMLProperty
* prop
;
1675 boost::shared_ptr
<Source
> source
;
1676 boost::shared_ptr
<AudioSource
> as
;
1678 SourceList master_sources
;
1679 uint32_t nchans
= 1;
1682 if (node
.name() != X_("Region")) {
1683 return boost::shared_ptr
<AudioRegion
>();
1686 if ((prop
= node
.property (X_("channels"))) != 0) {
1687 nchans
= atoi (prop
->value().c_str());
1690 if ((prop
= node
.property ("name")) == 0) {
1691 cerr
<< "no name for this region\n";
1695 if ((prop
= node
.property (X_("source-0"))) == 0) {
1696 if ((prop
= node
.property ("source")) == 0) {
1697 error
<< _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg
;
1698 return boost::shared_ptr
<AudioRegion
>();
1702 PBD::ID
s_id (prop
->value());
1704 if ((source
= source_by_id (s_id
)) == 0) {
1705 error
<< string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id
) << endmsg
;
1706 return boost::shared_ptr
<AudioRegion
>();
1709 as
= boost::dynamic_pointer_cast
<AudioSource
>(source
);
1711 error
<< string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id
) << endmsg
;
1712 return boost::shared_ptr
<AudioRegion
>();
1715 sources
.push_back (as
);
1717 /* pickup other channels */
1719 for (uint32_t n
=1; n
< nchans
; ++n
) {
1720 snprintf (buf
, sizeof(buf
), X_("source-%d"), n
);
1721 if ((prop
= node
.property (buf
)) != 0) {
1723 PBD::ID
id2 (prop
->value());
1725 if ((source
= source_by_id (id2
)) == 0) {
1726 error
<< string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2
) << endmsg
;
1727 return boost::shared_ptr
<AudioRegion
>();
1730 as
= boost::dynamic_pointer_cast
<AudioSource
>(source
);
1732 error
<< string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2
) << endmsg
;
1733 return boost::shared_ptr
<AudioRegion
>();
1735 sources
.push_back (as
);
1739 for (uint32_t n
= 0; n
< nchans
; ++n
) {
1740 snprintf (buf
, sizeof(buf
), X_("master-source-%d"), n
);
1741 if ((prop
= node
.property (buf
)) != 0) {
1743 PBD::ID
id2 (prop
->value());
1745 if ((source
= source_by_id (id2
)) == 0) {
1746 error
<< string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2
) << endmsg
;
1747 return boost::shared_ptr
<AudioRegion
>();
1750 as
= boost::dynamic_pointer_cast
<AudioSource
>(source
);
1752 error
<< string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2
) << endmsg
;
1753 return boost::shared_ptr
<AudioRegion
>();
1755 master_sources
.push_back (as
);
1760 boost::shared_ptr
<AudioRegion
> region (boost::dynamic_pointer_cast
<AudioRegion
> (RegionFactory::create (sources
, node
)));
1762 /* a final detail: this is the one and only place that we know how long missing files are */
1764 if (region
->whole_file()) {
1765 for (SourceList::iterator sx
= sources
.begin(); sx
!= sources
.end(); ++sx
) {
1766 boost::shared_ptr
<SilentFileSource
> sfp
= boost::dynamic_pointer_cast
<SilentFileSource
> (*sx
);
1768 sfp
->set_length (region
->length());
1773 if (!master_sources
.empty()) {
1774 if (master_sources
.size() != nchans
) {
1775 error
<< _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg
;
1777 region
->set_master_sources (master_sources
);
1785 catch (failed_constructor
& err
) {
1786 return boost::shared_ptr
<AudioRegion
>();
1790 boost::shared_ptr
<MidiRegion
>
1791 Session::XMLMidiRegionFactory (const XMLNode
& node
, bool /*full*/)
1793 const XMLProperty
* prop
;
1794 boost::shared_ptr
<Source
> source
;
1795 boost::shared_ptr
<MidiSource
> ms
;
1798 if (node
.name() != X_("Region")) {
1799 return boost::shared_ptr
<MidiRegion
>();
1802 if ((prop
= node
.property ("name")) == 0) {
1803 cerr
<< "no name for this region\n";
1807 if ((prop
= node
.property (X_("source-0"))) == 0) {
1808 if ((prop
= node
.property ("source")) == 0) {
1809 error
<< _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg
;
1810 return boost::shared_ptr
<MidiRegion
>();
1814 PBD::ID
s_id (prop
->value());
1816 if ((source
= source_by_id (s_id
)) == 0) {
1817 error
<< string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id
) << endmsg
;
1818 return boost::shared_ptr
<MidiRegion
>();
1821 ms
= boost::dynamic_pointer_cast
<MidiSource
>(source
);
1823 error
<< string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id
) << endmsg
;
1824 return boost::shared_ptr
<MidiRegion
>();
1827 sources
.push_back (ms
);
1830 boost::shared_ptr
<MidiRegion
> region (boost::dynamic_pointer_cast
<MidiRegion
> (RegionFactory::create (sources
, node
)));
1831 /* a final detail: this is the one and only place that we know how long missing files are */
1833 if (region
->whole_file()) {
1834 for (SourceList::iterator sx
= sources
.begin(); sx
!= sources
.end(); ++sx
) {
1835 boost::shared_ptr
<SilentFileSource
> sfp
= boost::dynamic_pointer_cast
<SilentFileSource
> (*sx
);
1837 sfp
->set_length (region
->length());
1845 catch (failed_constructor
& err
) {
1846 return boost::shared_ptr
<MidiRegion
>();
1851 Session::get_sources_as_xml ()
1854 XMLNode
* node
= new XMLNode (X_("Sources"));
1855 Glib::Mutex::Lock
lm (source_lock
);
1857 for (SourceMap::iterator i
= sources
.begin(); i
!= sources
.end(); ++i
) {
1858 node
->add_child_nocopy (i
->second
->get_state());
1865 Session::path_from_region_name (DataType type
, string name
, string identifier
)
1867 char buf
[PATH_MAX
+1];
1869 SessionDirectory
sdir(get_best_session_directory_for_new_source());
1870 sys::path source_dir
= ((type
== DataType::AUDIO
)
1871 ? sdir
.sound_path() : sdir
.midi_path());
1873 string ext
= native_header_format_extension (config
.get_native_file_header_format(), type
);
1875 for (n
= 0; n
< 999999; ++n
) {
1876 if (identifier
.length()) {
1877 snprintf (buf
, sizeof(buf
), "%s%s%" PRIu32
"%s", name
.c_str(),
1878 identifier
.c_str(), n
, ext
.c_str());
1880 snprintf (buf
, sizeof(buf
), "%s-%" PRIu32
"%s", name
.c_str(),
1884 sys::path source_path
= source_dir
/ buf
;
1886 if (!sys::exists (source_path
)) {
1887 return source_path
.to_string();
1891 error
<< string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1900 Session::load_sources (const XMLNode
& node
)
1903 XMLNodeConstIterator niter
;
1904 boost::shared_ptr
<Source
> source
;
1906 nlist
= node
.children();
1910 for (niter
= nlist
.begin(); niter
!= nlist
.end(); ++niter
) {
1913 if ((source
= XMLSourceFactory (**niter
)) == 0) {
1914 error
<< _("Session: cannot create Source from XML description.") << endmsg
;
1917 } catch (MissingSource
& err
) {
1921 if (!no_questions_about_missing_files
) {
1922 user_choice
= MissingFile (this, err
.path
, err
.type
).get_value_or (-1);
1927 switch (user_choice
) {
1929 /* user added a new search location, so try again */
1934 /* user asked to quit the entire session load
1939 no_questions_about_missing_files
= true;
1943 no_questions_about_missing_files
= true;
1948 warning
<< _("A sound file is missing. It will be replaced by silence.") << endmsg
;
1949 source
= SourceFactory::createSilent (*this, **niter
, max_framecnt
, _current_frame_rate
);
1958 boost::shared_ptr
<Source
>
1959 Session::XMLSourceFactory (const XMLNode
& node
)
1961 if (node
.name() != "Source") {
1962 return boost::shared_ptr
<Source
>();
1966 /* note: do peak building in another thread when loading session state */
1967 return SourceFactory::create (*this, node
, true);
1970 catch (failed_constructor
& err
) {
1971 error
<< string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME
) << endmsg
;
1972 return boost::shared_ptr
<Source
>();
1977 Session::save_template (string template_name
)
1981 if (_state_of_the_state
& CannotSave
) {
1985 sys::path
user_template_dir(user_template_directory());
1989 sys::create_directories (user_template_dir
);
1991 catch(sys::filesystem_error
& ex
)
1993 error
<< string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1994 user_template_dir
.to_string(), ex
.what()) << endmsg
;
1998 tree
.set_root (&get_template());
2000 sys::path
template_file_path(user_template_dir
);
2001 template_file_path
/= template_name
+ template_suffix
;
2003 if (sys::exists (template_file_path
))
2005 warning
<< string_compose(_("Template \"%1\" already exists - new version not created"),
2006 template_file_path
.to_string()) << endmsg
;
2010 if (!tree
.write (template_file_path
.to_string())) {
2011 error
<< _("template not saved") << endmsg
;
2019 Session::rename_template (string old_name
, string new_name
)
2021 sys::path
old_path (user_template_directory());
2022 old_path
/= old_name
+ template_suffix
;
2024 sys::path
new_path(user_template_directory());
2025 new_path
/= new_name
+ template_suffix
;
2027 if (sys::exists (new_path
)) {
2028 warning
<< string_compose(_("Template \"%1\" already exists - template not renamed"),
2029 new_path
.to_string()) << endmsg
;
2034 sys::rename (old_path
, new_path
);
2042 Session::delete_template (string name
)
2044 sys::path path
= user_template_directory();
2045 path
/= name
+ template_suffix
;
2056 Session::refresh_disk_space ()
2059 struct statfs statfsbuf
;
2060 vector
<space_and_path
>::iterator i
;
2061 Glib::Mutex::Lock
lm (space_lock
);
2064 /* get freespace on every FS that is part of the session path */
2066 _total_free_4k_blocks
= 0;
2068 for (i
= session_dirs
.begin(); i
!= session_dirs
.end(); ++i
) {
2069 statfs ((*i
).path
.c_str(), &statfsbuf
);
2071 scale
= statfsbuf
.f_bsize
/4096.0;
2073 (*i
).blocks
= (uint32_t) floor (statfsbuf
.f_bavail
* scale
);
2074 _total_free_4k_blocks
+= (*i
).blocks
;
2080 Session::get_best_session_directory_for_new_source ()
2082 vector
<space_and_path
>::iterator i
;
2083 string result
= _session_dir
->root_path().to_string();
2085 /* handle common case without system calls */
2087 if (session_dirs
.size() == 1) {
2091 /* OK, here's the algorithm we're following here:
2093 We want to select which directory to use for
2094 the next file source to be created. Ideally,
2095 we'd like to use a round-robin process so as to
2096 get maximum performance benefits from splitting
2097 the files across multiple disks.
2099 However, in situations without much diskspace, an
2100 RR approach may end up filling up a filesystem
2101 with new files while others still have space.
2102 Its therefore important to pay some attention to
2103 the freespace in the filesystem holding each
2104 directory as well. However, if we did that by
2105 itself, we'd keep creating new files in the file
2106 system with the most space until it was as full
2107 as all others, thus negating any performance
2108 benefits of this RAID-1 like approach.
2110 So, we use a user-configurable space threshold. If
2111 there are at least 2 filesystems with more than this
2112 much space available, we use RR selection between them.
2113 If not, then we pick the filesystem with the most space.
2115 This gets a good balance between the two
2119 refresh_disk_space ();
2121 int free_enough
= 0;
2123 for (i
= session_dirs
.begin(); i
!= session_dirs
.end(); ++i
) {
2124 if ((*i
).blocks
* 4096 >= Config
->get_disk_choice_space_threshold()) {
2129 if (free_enough
>= 2) {
2130 /* use RR selection process, ensuring that the one
2134 i
= last_rr_session_dir
;
2137 if (++i
== session_dirs
.end()) {
2138 i
= session_dirs
.begin();
2141 if ((*i
).blocks
* 4096 >= Config
->get_disk_choice_space_threshold()) {
2142 if (create_session_directory ((*i
).path
)) {
2144 last_rr_session_dir
= i
;
2149 } while (i
!= last_rr_session_dir
);
2153 /* pick FS with the most freespace (and that
2154 seems to actually work ...)
2157 vector
<space_and_path
> sorted
;
2158 space_and_path_ascending_cmp cmp
;
2160 sorted
= session_dirs
;
2161 sort (sorted
.begin(), sorted
.end(), cmp
);
2163 for (i
= sorted
.begin(); i
!= sorted
.end(); ++i
) {
2164 if (create_session_directory ((*i
).path
)) {
2166 last_rr_session_dir
= i
;
2176 Session::load_named_selections (const XMLNode
& node
)
2179 XMLNodeConstIterator niter
;
2182 nlist
= node
.children();
2186 for (niter
= nlist
.begin(); niter
!= nlist
.end(); ++niter
) {
2188 if ((ns
= XMLNamedSelectionFactory (**niter
)) == 0) {
2189 error
<< _("Session: cannot create Named Selection from XML description.") << endmsg
;
2197 Session::XMLNamedSelectionFactory (const XMLNode
& node
)
2200 return new NamedSelection (*this, node
);
2203 catch (failed_constructor
& err
) {
2209 Session::automation_dir () const
2211 return Glib::build_filename (_path
, "automation");
2215 Session::analysis_dir () const
2217 return Glib::build_filename (_path
, "analysis");
2221 Session::plugins_dir () const
2223 return Glib::build_filename (_path
, "plugins");
2227 Session::load_bundles (XMLNode
const & node
)
2229 XMLNodeList nlist
= node
.children();
2230 XMLNodeConstIterator niter
;
2234 for (niter
= nlist
.begin(); niter
!= nlist
.end(); ++niter
) {
2235 if ((*niter
)->name() == "InputBundle") {
2236 add_bundle (boost::shared_ptr
<UserBundle
> (new UserBundle (**niter
, true)));
2237 } else if ((*niter
)->name() == "OutputBundle") {
2238 add_bundle (boost::shared_ptr
<UserBundle
> (new UserBundle (**niter
, false)));
2240 error
<< string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter
)->name()) << endmsg
;
2249 Session::load_route_groups (const XMLNode
& node
, int version
)
2251 XMLNodeList nlist
= node
.children();
2252 XMLNodeConstIterator niter
;
2256 if (version
>= 3000) {
2258 for (niter
= nlist
.begin(); niter
!= nlist
.end(); ++niter
) {
2259 if ((*niter
)->name() == "RouteGroup") {
2260 RouteGroup
* rg
= new RouteGroup (*this, "");
2261 add_route_group (rg
);
2262 rg
->set_state (**niter
, version
);
2266 } else if (version
< 3000) {
2268 for (niter
= nlist
.begin(); niter
!= nlist
.end(); ++niter
) {
2269 if ((*niter
)->name() == "EditGroup" || (*niter
)->name() == "MixGroup") {
2270 RouteGroup
* rg
= new RouteGroup (*this, "");
2271 add_route_group (rg
);
2272 rg
->set_state (**niter
, version
);
2281 Session::auto_save()
2283 save_state (_current_snapshot_name
);
2287 state_file_filter (const string
&str
, void */
*arg*/
)
2289 return (str
.length() > strlen(statefile_suffix
) &&
2290 str
.find (statefile_suffix
) == (str
.length() - strlen (statefile_suffix
)));
2294 bool operator()(const string
* a
, const string
* b
) {
2300 remove_end(string
* state
)
2302 string
statename(*state
);
2304 string::size_type start
,end
;
2305 if ((start
= statename
.find_last_of (G_DIR_SEPARATOR
)) != string::npos
) {
2306 statename
= statename
.substr (start
+1);
2309 if ((end
= statename
.rfind(".ardour")) == string::npos
) {
2310 end
= statename
.length();
2313 return new string(statename
.substr (0, end
));
2317 Session::possible_states (string path
)
2319 PathScanner scanner
;
2320 vector
<string
*>* states
= scanner (path
, state_file_filter
, 0, false, false);
2322 transform(states
->begin(), states
->end(), states
->begin(), remove_end
);
2325 sort (states
->begin(), states
->end(), cmp
);
2331 Session::possible_states () const
2333 return possible_states(_path
);
2337 Session::add_route_group (RouteGroup
* g
)
2339 _route_groups
.push_back (g
);
2340 route_group_added (g
); /* EMIT SIGNAL */
2342 g
->MembershipChanged
.connect_same_thread (*this, boost::bind (&Session::route_group_changed
, this));
2343 g
->PropertyChanged
.connect_same_thread (*this, boost::bind (&Session::route_group_changed
, this));
2349 Session::remove_route_group (RouteGroup
& rg
)
2351 list
<RouteGroup
*>::iterator i
;
2353 if ((i
= find (_route_groups
.begin(), _route_groups
.end(), &rg
)) != _route_groups
.end()) {
2354 _route_groups
.erase (i
);
2357 route_group_removed (); /* EMIT SIGNAL */
2363 Session::route_group_by_name (string name
)
2365 list
<RouteGroup
*>::iterator i
;
2367 for (i
= _route_groups
.begin(); i
!= _route_groups
.end(); ++i
) {
2368 if ((*i
)->name() == name
) {
2376 Session::all_route_group() const
2378 return *_all_route_group
;
2382 Session::add_commands (vector
<Command
*> const & cmds
)
2384 for (vector
<Command
*>::const_iterator i
= cmds
.begin(); i
!= cmds
.end(); ++i
) {
2390 Session::begin_reversible_command (const string
& name
)
2392 begin_reversible_command (g_quark_from_string (name
.c_str ()));
2395 /** Begin a reversible command using a GQuark to identify it.
2396 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2397 * but there must be as many begin...()s as there are commit...()s.
2400 Session::begin_reversible_command (GQuark q
)
2402 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2403 to hold all the commands that are committed. This keeps the order of
2404 commands correct in the history.
2407 if (_current_trans
== 0) {
2408 /* start a new transaction */
2409 assert (_current_trans_quarks
.empty ());
2410 _current_trans
= new UndoTransaction();
2411 _current_trans
->set_name (g_quark_to_string (q
));
2414 _current_trans_quarks
.push_front (q
);
2418 Session::commit_reversible_command (Command
*cmd
)
2420 assert (_current_trans
);
2421 assert (!_current_trans_quarks
.empty ());
2426 _current_trans
->add_command (cmd
);
2429 _current_trans_quarks
.pop_front ();
2431 if (!_current_trans_quarks
.empty ()) {
2432 /* the transaction we're committing is not the top-level one */
2436 if (_current_trans
->empty()) {
2437 /* no commands were added to the transaction, so just get rid of it */
2438 delete _current_trans
;
2443 gettimeofday (&now
, 0);
2444 _current_trans
->set_timestamp (now
);
2446 _history
.add (_current_trans
);
2451 accept_all_non_peak_files (const string
& path
, void */
*arg*/
)
2453 if (!Glib::file_test (path
, Glib::FILE_TEST_IS_REGULAR
)) {
2457 return (path
.length() > 5 && path
.find (peakfile_suffix
) != (path
.length() - 5));
2461 accept_all_state_files (const string
& path
, void */
*arg*/
)
2463 return (path
.length() > 7 && path
.find (".ardour") == (path
.length() - 7));
2467 Session::find_all_sources (string path
, set
<string
>& result
)
2472 if (!tree
.read (path
)) {
2476 if ((node
= find_named_node (*tree
.root(), "Sources")) == 0) {
2481 XMLNodeConstIterator niter
;
2483 nlist
= node
->children();
2487 for (niter
= nlist
.begin(); niter
!= nlist
.end(); ++niter
) {
2491 if ((prop
= (*niter
)->property (X_("type"))) == 0) {
2495 DataType
type (prop
->value());
2497 if ((prop
= (*niter
)->property (X_("name"))) == 0) {
2501 if (Glib::path_is_absolute (prop
->value())) {
2502 /* external file, ignore */
2510 if (FileSource::find (*this, type
, prop
->value(), true, is_new
, chan
, found_path
)) {
2511 result
.insert (found_path
);
2519 Session::find_all_sources_across_snapshots (set
<string
>& result
, bool exclude_this_snapshot
)
2521 PathScanner scanner
;
2522 vector
<string
*>* state_files
;
2524 string this_snapshot_path
;
2530 if (ripped
[ripped
.length()-1] == G_DIR_SEPARATOR
) {
2531 ripped
= ripped
.substr (0, ripped
.length() - 1);
2534 state_files
= scanner (ripped
, accept_all_state_files
, (void *) 0, false, true);
2536 if (state_files
== 0) {
2541 this_snapshot_path
= _path
;
2542 this_snapshot_path
+= legalize_for_path (_current_snapshot_name
);
2543 this_snapshot_path
+= statefile_suffix
;
2545 for (vector
<string
*>::iterator i
= state_files
->begin(); i
!= state_files
->end(); ++i
) {
2547 if (exclude_this_snapshot
&& **i
== this_snapshot_path
) {
2551 if (find_all_sources (**i
, result
) < 0) {
2559 struct RegionCounter
{
2560 typedef std::map
<PBD::ID
,boost::shared_ptr
<AudioSource
> > AudioSourceList
;
2561 AudioSourceList::iterator iter
;
2562 boost::shared_ptr
<Region
> region
;
2565 RegionCounter() : count (0) {}
2569 Session::ask_about_playlist_deletion (boost::shared_ptr
<Playlist
> p
)
2571 boost::optional
<int> r
= AskAboutPlaylistDeletion (p
);
2572 return r
.get_value_or (1);
2576 Session::cleanup_regions ()
2578 const RegionFactory::RegionMap
& regions (RegionFactory::regions());
2580 for (RegionFactory::RegionMap::const_iterator i
= regions
.begin(); i
!= regions
.end(); ++i
) {
2582 boost::shared_ptr
<AudioRegion
> audio_region
= boost::dynamic_pointer_cast
<AudioRegion
>( i
->second
);
2584 if (!audio_region
) {
2588 uint32_t used
= playlists
->region_use_count (audio_region
);
2590 if (used
== 0 && !audio_region
->automatic()) {
2591 RegionFactory::map_remove(i
->second
);
2595 /* dump the history list */
2602 Session::cleanup_sources (CleanupReport
& rep
)
2604 // FIXME: needs adaptation to midi
2606 vector
<boost::shared_ptr
<Source
> > dead_sources
;
2607 PathScanner scanner
;
2609 vector
<space_and_path
>::iterator i
;
2610 vector
<space_and_path
>::iterator nexti
;
2611 vector
<string
*>* soundfiles
;
2612 vector
<string
> unused
;
2613 set
<string
> all_sources
;
2618 _state_of_the_state
= (StateOfTheState
) (_state_of_the_state
| InCleanup
);
2620 /* step 1: consider deleting all unused playlists */
2622 if (playlists
->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion
, _1
))) {
2627 /* step 2: find all un-used sources */
2632 for (SourceMap::iterator i
= sources
.begin(); i
!= sources
.end(); ) {
2634 SourceMap::iterator tmp
;
2639 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2643 if (!i
->second
->used() && (i
->second
->length(i
->second
->timeline_position() > 0))) {
2644 dead_sources
.push_back (i
->second
);
2645 i
->second
->drop_references ();
2651 /* build a list of all the possible sound directories for the session */
2653 for (i
= session_dirs
.begin(); i
!= session_dirs
.end(); ) {
2658 SessionDirectory
sdir ((*i
).path
);
2659 sound_path
+= sdir
.sound_path().to_string();
2661 if (nexti
!= session_dirs
.end()) {
2668 /* now do the same thing for the files that ended up in the sounds dir(s)
2669 but are not referenced as sources in any snapshot.
2672 soundfiles
= scanner (sound_path
, accept_all_non_peak_files
, (void *) 0, false, true);
2674 if (soundfiles
== 0) {
2678 /* find all sources, but don't use this snapshot because the
2679 state file on disk still references sources we may have already
2683 find_all_sources_across_snapshots (all_sources
, true);
2685 /* add our current source list
2688 for (SourceMap::iterator i
= sources
.begin(); i
!= sources
.end(); ++i
) {
2689 boost::shared_ptr
<FileSource
> fs
;
2691 if ((fs
= boost::dynamic_pointer_cast
<FileSource
> (i
->second
)) != 0) {
2692 all_sources
.insert (fs
->path());
2696 char tmppath1
[PATH_MAX
+1];
2697 char tmppath2
[PATH_MAX
+1];
2699 for (vector
<string
*>::iterator x
= soundfiles
->begin(); x
!= soundfiles
->end(); ++x
) {
2704 for (set
<string
>::iterator i
= all_sources
.begin(); i
!= all_sources
.end(); ++i
) {
2706 if (realpath(spath
.c_str(), tmppath1
) == 0) {
2707 error
<< string_compose (_("Cannot expand path %1 (%2)"),
2708 spath
, strerror (errno
)) << endmsg
;
2712 if (realpath((*i
).c_str(), tmppath2
) == 0) {
2713 error
<< string_compose (_("Cannot expand path %1 (%2)"),
2714 (*i
), strerror (errno
)) << endmsg
;
2718 if (strcmp(tmppath1
, tmppath2
) == 0) {
2725 unused
.push_back (spath
);
2729 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2731 for (vector
<string
>::iterator x
= unused
.begin(); x
!= unused
.end(); ++x
) {
2732 struct stat statbuf
;
2734 rep
.paths
.push_back (*x
);
2735 if (stat ((*x
).c_str(), &statbuf
) == 0) {
2736 rep
.space
+= statbuf
.st_size
;
2741 /* don't move the file across filesystems, just
2742 stick it in the `dead_sound_dir_name' directory
2743 on whichever filesystem it was already on.
2746 if ((*x
).find ("/sounds/") != string::npos
) {
2748 /* old school, go up 1 level */
2750 newpath
= Glib::path_get_dirname (*x
); // "sounds"
2751 newpath
= Glib::path_get_dirname (newpath
); // "session-name"
2755 /* new school, go up 4 levels */
2757 newpath
= Glib::path_get_dirname (*x
); // "audiofiles"
2758 newpath
= Glib::path_get_dirname (newpath
); // "session-name"
2759 newpath
= Glib::path_get_dirname (newpath
); // "interchange"
2760 newpath
= Glib::path_get_dirname (newpath
); // "session-dir"
2763 newpath
= Glib::build_filename (newpath
, dead_sound_dir_name
);
2765 if (g_mkdir_with_parents (newpath
.c_str(), 0755) < 0) {
2766 error
<< string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath
, strerror (errno
)) << endmsg
;
2770 newpath
= Glib::build_filename (newpath
, Glib::path_get_basename ((*x
)));
2772 if (Glib::file_test (newpath
, Glib::FILE_TEST_EXISTS
)) {
2774 /* the new path already exists, try versioning */
2776 char buf
[PATH_MAX
+1];
2780 snprintf (buf
, sizeof (buf
), "%s.%d", newpath
.c_str(), version
);
2783 while (access (newpath_v
.c_str(), F_OK
) == 0 && version
< 999) {
2784 snprintf (buf
, sizeof (buf
), "%s.%d", newpath
.c_str(), ++version
);
2788 if (version
== 999) {
2789 error
<< string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2793 newpath
= newpath_v
;
2798 /* it doesn't exist, or we can't read it or something */
2802 if (::rename ((*x
).c_str(), newpath
.c_str()) != 0) {
2803 error
<< string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2804 (*x
), newpath
, strerror (errno
))
2809 /* see if there an easy to find peakfile for this file, and remove it.
2812 string peakpath
= (*x
).substr (0, (*x
).find_last_of ('.'));
2813 peakpath
+= peakfile_suffix
;
2815 if (access (peakpath
.c_str(), W_OK
) == 0) {
2816 if (::unlink (peakpath
.c_str()) != 0) {
2817 error
<< string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2818 peakpath
, _path
, strerror (errno
))
2820 /* try to back out */
2821 rename (newpath
.c_str(), _path
.c_str());
2829 /* dump the history list */
2833 /* save state so we don't end up a session file
2834 referring to non-existent sources.
2840 _state_of_the_state
= (StateOfTheState
) (_state_of_the_state
& ~InCleanup
);
2846 Session::cleanup_trash_sources (CleanupReport
& rep
)
2848 // FIXME: needs adaptation for MIDI
2850 vector
<space_and_path
>::iterator i
;
2851 string dead_sound_dir
;
2856 for (i
= session_dirs
.begin(); i
!= session_dirs
.end(); ++i
) {
2858 dead_sound_dir
= (*i
).path
;
2859 dead_sound_dir
+= dead_sound_dir_name
;
2861 clear_directory (dead_sound_dir
, &rep
.space
, &rep
.paths
);
2868 Session::cleanup_stubfiles ()
2870 vector
<space_and_path
>::iterator i
;
2872 for (i
= session_dirs
.begin(); i
!= session_dirs
.end(); ++i
) {
2875 string lname
= legalize_for_path (_name
);
2879 /* XXX this is a hack caused by semantic conflicts
2880 between space_and_path and the SessionDirectory concept.
2883 v
.push_back ((*i
).path
);
2884 v
.push_back ("interchange");
2885 v
.push_back (lname
);
2886 v
.push_back ("audiofiles");
2887 v
.push_back (stub_dir_name
);
2889 dir
= Glib::build_filename (v
);
2891 clear_directory (dir
);
2894 v
.push_back ((*i
).path
);
2895 v
.push_back ("interchange");
2896 v
.push_back (lname
);
2897 v
.push_back ("midifiles");
2898 v
.push_back (stub_dir_name
);
2900 dir
= Glib::build_filename (v
);
2902 clear_directory (dir
);
2907 Session::set_dirty ()
2909 bool was_dirty
= dirty();
2911 _state_of_the_state
= StateOfTheState (_state_of_the_state
| Dirty
);
2915 DirtyChanged(); /* EMIT SIGNAL */
2921 Session::set_clean ()
2923 bool was_dirty
= dirty();
2925 _state_of_the_state
= Clean
;
2929 DirtyChanged(); /* EMIT SIGNAL */
2934 Session::set_deletion_in_progress ()
2936 _state_of_the_state
= StateOfTheState (_state_of_the_state
| Deletion
);
2940 Session::clear_deletion_in_progress ()
2942 _state_of_the_state
= StateOfTheState (_state_of_the_state
& (~Deletion
));
2946 Session::add_controllable (boost::shared_ptr
<Controllable
> c
)
2948 /* this adds a controllable to the list managed by the Session.
2949 this is a subset of those managed by the Controllable class
2950 itself, and represents the only ones whose state will be saved
2951 as part of the session.
2954 Glib::Mutex::Lock
lm (controllables_lock
);
2955 controllables
.insert (c
);
2958 struct null_deleter
{ void operator()(void const *) const {} };
2961 Session::remove_controllable (Controllable
* c
)
2963 if (_state_of_the_state
| Deletion
) {
2967 Glib::Mutex::Lock
lm (controllables_lock
);
2969 Controllables::iterator x
= controllables
.find (boost::shared_ptr
<Controllable
>(c
, null_deleter()));
2971 if (x
!= controllables
.end()) {
2972 controllables
.erase (x
);
2976 boost::shared_ptr
<Controllable
>
2977 Session::controllable_by_id (const PBD::ID
& id
)
2979 Glib::Mutex::Lock
lm (controllables_lock
);
2981 for (Controllables::iterator i
= controllables
.begin(); i
!= controllables
.end(); ++i
) {
2982 if ((*i
)->id() == id
) {
2987 return boost::shared_ptr
<Controllable
>();
2990 boost::shared_ptr
<Controllable
>
2991 Session::controllable_by_descriptor (const ControllableDescriptor
& desc
)
2993 boost::shared_ptr
<Controllable
> c
;
2994 boost::shared_ptr
<Route
> r
;
2996 switch (desc
.top_level_type()) {
2997 case ControllableDescriptor::NamedRoute
:
2999 std::string str
= desc
.top_level_name();
3000 if (str
== "master") {
3002 } else if (str
== "control" || str
== "listen") {
3005 r
= route_by_name (desc
.top_level_name());
3010 case ControllableDescriptor::RemoteControlID
:
3011 r
= route_by_remote_id (desc
.rid());
3019 switch (desc
.subtype()) {
3020 case ControllableDescriptor::Gain
:
3021 c
= r
->gain_control ();
3024 case ControllableDescriptor::Solo
:
3025 c
= r
->solo_control();
3028 case ControllableDescriptor::Mute
:
3029 c
= r
->mute_control();
3032 case ControllableDescriptor::Recenable
:
3034 boost::shared_ptr
<Track
> t
= boost::dynamic_pointer_cast
<Track
>(r
);
3037 c
= t
->rec_enable_control ();
3042 case ControllableDescriptor::PanDirection
:
3044 c
= r
->pannable()->pan_azimuth_control
;
3048 case ControllableDescriptor::PanWidth
:
3050 c
= r
->pannable()->pan_width_control
;
3054 case ControllableDescriptor::PanElevation
:
3056 c
= r
->pannable()->pan_elevation_control
;
3060 case ControllableDescriptor::Balance
:
3061 /* XXX simple pan control */
3064 case ControllableDescriptor::PluginParameter
:
3066 uint32_t plugin
= desc
.target (0);
3067 uint32_t parameter_index
= desc
.target (1);
3069 /* revert to zero based counting */
3075 if (parameter_index
> 0) {
3079 boost::shared_ptr
<Processor
> p
= r
->nth_plugin (plugin
);
3082 c
= boost::dynamic_pointer_cast
<ARDOUR::AutomationControl
>(
3083 p
->control(Evoral::Parameter(PluginAutomation
, 0, parameter_index
)));
3088 case ControllableDescriptor::SendGain
:
3090 uint32_t send
= desc
.target (0);
3092 /* revert to zero-based counting */
3098 boost::shared_ptr
<Processor
> p
= r
->nth_send (send
);
3101 boost::shared_ptr
<Send
> s
= boost::dynamic_pointer_cast
<Send
>(p
);
3102 boost::shared_ptr
<Amp
> a
= s
->amp();
3105 c
= s
->amp()->gain_control();
3112 /* relax and return a null pointer */
3120 Session::add_instant_xml (XMLNode
& node
, bool write_to_config
)
3123 Stateful::add_instant_xml (node
, _path
);
3126 if (write_to_config
) {
3127 Config
->add_instant_xml (node
);
3132 Session::instant_xml (const string
& node_name
)
3134 return Stateful::instant_xml (node_name
, _path
);
3138 Session::save_history (string snapshot_name
)
3146 if (snapshot_name
.empty()) {
3147 snapshot_name
= _current_snapshot_name
;
3150 const string history_filename
= legalize_for_path (snapshot_name
) + history_suffix
;
3151 const string backup_filename
= history_filename
+ backup_suffix
;
3152 const sys::path xml_path
= _session_dir
->root_path() / history_filename
;
3153 const sys::path backup_path
= _session_dir
->root_path() / backup_filename
;
3155 if (sys::exists (xml_path
)) {
3158 sys::rename (xml_path
, backup_path
);
3160 catch (const sys::filesystem_error
& err
)
3162 error
<< _("could not backup old history file, current history not saved") << endmsg
;
3167 if (!Config
->get_save_history() || Config
->get_saved_history_depth() < 0) {
3171 tree
.set_root (&_history
.get_state (Config
->get_saved_history_depth()));
3173 if (!tree
.write (xml_path
.to_string()))
3175 error
<< string_compose (_("history could not be saved to %1"), xml_path
.to_string()) << endmsg
;
3179 sys::remove (xml_path
);
3180 sys::rename (backup_path
, xml_path
);
3182 catch (const sys::filesystem_error
& err
)
3184 error
<< string_compose (_("could not restore history file from backup %1 (%2)"),
3185 backup_path
.to_string(), err
.what()) << endmsg
;
3195 Session::restore_history (string snapshot_name
)
3199 if (snapshot_name
.empty()) {
3200 snapshot_name
= _current_snapshot_name
;
3203 const string xml_filename
= legalize_for_path (snapshot_name
) + history_suffix
;
3204 const sys::path xml_path
= _session_dir
->root_path() / xml_filename
;
3206 info
<< "Loading history from " << xml_path
.to_string() << endmsg
;
3208 if (!sys::exists (xml_path
)) {
3209 info
<< string_compose (_("%1: no history file \"%2\" for this session."),
3210 _name
, xml_path
.to_string()) << endmsg
;
3214 if (!tree
.read (xml_path
.to_string())) {
3215 error
<< string_compose (_("Could not understand session history file \"%1\""),
3216 xml_path
.to_string()) << endmsg
;
3223 for (XMLNodeConstIterator it
= tree
.root()->children().begin(); it
!= tree
.root()->children().end(); it
++) {
3226 UndoTransaction
* ut
= new UndoTransaction ();
3229 ut
->set_name(t
->property("name")->value());
3230 stringstream
ss(t
->property("tv-sec")->value());
3232 ss
.str(t
->property("tv-usec")->value());
3234 ut
->set_timestamp(tv
);
3236 for (XMLNodeConstIterator child_it
= t
->children().begin();
3237 child_it
!= t
->children().end(); child_it
++)
3239 XMLNode
*n
= *child_it
;
3242 if (n
->name() == "MementoCommand" ||
3243 n
->name() == "MementoUndoCommand" ||
3244 n
->name() == "MementoRedoCommand") {
3246 if ((c
= memento_command_factory(n
))) {
3250 } else if (n
->name() == "NoteDiffCommand") {
3251 PBD::ID
id (n
->property("midi-source")->value());
3252 boost::shared_ptr
<MidiSource
> midi_source
=
3253 boost::dynamic_pointer_cast
<MidiSource
, Source
>(source_by_id(id
));
3255 ut
->add_command (new MidiModel::NoteDiffCommand(midi_source
->model(), *n
));
3257 error
<< _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg
;
3260 } else if (n
->name() == "SysExDiffCommand") {
3262 PBD::ID
id (n
->property("midi-source")->value());
3263 boost::shared_ptr
<MidiSource
> midi_source
=
3264 boost::dynamic_pointer_cast
<MidiSource
, Source
>(source_by_id(id
));
3266 ut
->add_command (new MidiModel::SysExDiffCommand (midi_source
->model(), *n
));
3268 error
<< _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg
;
3271 } else if (n
->name() == "PatchChangeDiffCommand") {
3273 PBD::ID
id (n
->property("midi-source")->value());
3274 boost::shared_ptr
<MidiSource
> midi_source
=
3275 boost::dynamic_pointer_cast
<MidiSource
, Source
>(source_by_id(id
));
3277 ut
->add_command (new MidiModel::PatchChangeDiffCommand (midi_source
->model(), *n
));
3279 error
<< _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg
;
3282 } else if (n
->name() == "StatefulDiffCommand") {
3283 if ((c
= stateful_diff_command_factory (n
))) {
3284 ut
->add_command (c
);
3287 error
<< string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n
->name()) << endmsg
;
3298 Session::config_changed (std::string p
, bool ours
)
3304 if (p
== "seamless-loop") {
3306 } else if (p
== "rf-speed") {
3308 } else if (p
== "auto-loop") {
3310 } else if (p
== "auto-input") {
3312 if (Config
->get_monitoring_model() == HardwareMonitoring
&& transport_rolling()) {
3313 /* auto-input only makes a difference if we're rolling */
3315 boost::shared_ptr
<RouteList
> rl
= routes
.reader ();
3316 for (RouteList::iterator i
= rl
->begin(); i
!= rl
->end(); ++i
) {
3317 boost::shared_ptr
<Track
> tr
= boost::dynamic_pointer_cast
<Track
> (*i
);
3318 if (tr
&& tr
->record_enabled ()) {
3319 tr
->monitor_input (!config
.get_auto_input());
3324 } else if (p
== "punch-in") {
3328 if ((location
= _locations
->auto_punch_location()) != 0) {
3330 if (config
.get_punch_in ()) {
3331 replace_event (SessionEvent::PunchIn
, location
->start());
3333 remove_event (location
->start(), SessionEvent::PunchIn
);
3337 } else if (p
== "punch-out") {
3341 if ((location
= _locations
->auto_punch_location()) != 0) {
3343 if (config
.get_punch_out()) {
3344 replace_event (SessionEvent::PunchOut
, location
->end());
3346 clear_events (SessionEvent::PunchOut
);
3350 } else if (p
== "edit-mode") {
3352 Glib::Mutex::Lock
lm (playlists
->lock
);
3354 for (SessionPlaylists::List::iterator i
= playlists
->playlists
.begin(); i
!= playlists
->playlists
.end(); ++i
) {
3355 (*i
)->set_edit_mode (Config
->get_edit_mode ());
3358 } else if (p
== "use-video-sync") {
3360 waiting_for_sync_offset
= config
.get_use_video_sync();
3362 } else if (p
== "mmc-control") {
3364 //poke_midi_thread ();
3366 } else if (p
== "mmc-device-id" || p
== "mmc-receive-id") {
3368 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config
->get_mmc_receive_device_id());
3370 } else if (p
== "mmc-send-id") {
3372 MIDI::Manager::instance()->mmc()->set_send_device_id (Config
->get_mmc_send_device_id());
3374 } else if (p
== "midi-control") {
3376 //poke_midi_thread ();
3378 } else if (p
== "raid-path") {
3380 setup_raid_path (config
.get_raid_path());
3382 } else if (p
== "timecode-format") {
3386 } else if (p
== "video-pullup") {
3390 } else if (p
== "seamless-loop") {
3392 if (play_loop
&& transport_rolling()) {
3393 // to reset diskstreams etc
3394 request_play_loop (true);
3397 } else if (p
== "rf-speed") {
3399 cumulative_rf_motion
= 0;
3402 } else if (p
== "click-sound") {
3404 setup_click_sounds (1);
3406 } else if (p
== "click-emphasis-sound") {
3408 setup_click_sounds (-1);
3410 } else if (p
== "clicking") {
3412 if (Config
->get_clicking()) {
3413 if (_click_io
&& click_data
) { // don't require emphasis data
3420 } else if (p
== "send-mtc") {
3422 if (Config
->get_send_mtc ()) {
3423 /* mark us ready to send */
3424 next_quarter_frame_to_send
= 0;
3427 } else if (p
== "send-mmc") {
3429 MIDI::Manager::instance()->mmc()->enable_send (Config
->get_send_mmc ());
3431 } else if (p
== "midi-feedback") {
3433 session_midi_feedback
= Config
->get_midi_feedback();
3435 } else if (p
== "jack-time-master") {
3437 engine().reset_timebase ();
3439 } else if (p
== "native-file-header-format") {
3441 if (!first_file_header_format_reset
) {
3442 reset_native_file_format ();
3445 first_file_header_format_reset
= false;
3447 } else if (p
== "native-file-data-format") {
3449 if (!first_file_data_format_reset
) {
3450 reset_native_file_format ();
3453 first_file_data_format_reset
= false;
3455 } else if (p
== "external-sync") {
3456 if (!config
.get_external_sync()) {
3457 drop_sync_source ();
3459 switch_to_sync_source (config
.get_sync_source());
3461 } else if (p
== "remote-model") {
3462 set_remote_control_ids ();
3463 } else if (p
== "denormal-model") {
3465 } else if (p
== "history-depth") {
3466 set_history_depth (Config
->get_history_depth());
3467 } else if (p
== "sync-all-route-ordering") {
3468 sync_order_keys ("session");
3469 } else if (p
== "initial-program-change") {
3471 if (MIDI::Manager::instance()->mmc()->output_port() && Config
->get_initial_program_change() >= 0) {
3474 buf
[0] = MIDI::program
; // channel zero by default
3475 buf
[1] = (Config
->get_initial_program_change() & 0x7f);
3477 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf
, sizeof (buf
), 0);
3479 } else if (p
== "solo-mute-override") {
3480 // catch_up_on_solo_mute_override ();
3481 } else if (p
== "listen-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;
3493 Session::set_history_depth (uint32_t d
)
3495 _history
.set_depth (d
);
3499 Session::load_diskstreams_2X (XMLNode
const & node
, int)
3502 XMLNodeConstIterator citer
;
3504 clist
= node
.children();
3506 for (citer
= clist
.begin(); citer
!= clist
.end(); ++citer
) {
3509 /* diskstreams added automatically by DiskstreamCreated handler */
3510 if ((*citer
)->name() == "AudioDiskstream" || (*citer
)->name() == "DiskStream") {
3511 boost::shared_ptr
<AudioDiskstream
> dsp (new AudioDiskstream (*this, **citer
));
3512 _diskstreams_2X
.push_back (dsp
);
3514 error
<< _("Session: unknown diskstream type in XML") << endmsg
;
3518 catch (failed_constructor
& err
) {
3519 error
<< _("Session: could not load diskstream via XML state") << endmsg
;
3527 /** Connect things to the MMC object */
3529 Session::setup_midi_machine_control ()
3531 MIDI::MachineControl
* mmc
= MIDI::Manager::instance()->mmc ();
3533 mmc
->Play
.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play
, this, _1
));
3534 mmc
->DeferredPlay
.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play
, this, _1
));
3535 mmc
->Stop
.connect_same_thread (*this, boost::bind (&Session::mmc_stop
, this, _1
));
3536 mmc
->FastForward
.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward
, this, _1
));
3537 mmc
->Rewind
.connect_same_thread (*this, boost::bind (&Session::mmc_rewind
, this, _1
));
3538 mmc
->Pause
.connect_same_thread (*this, boost::bind (&Session::mmc_pause
, this, _1
));
3539 mmc
->RecordPause
.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause
, this, _1
));
3540 mmc
->RecordStrobe
.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe
, this, _1
));
3541 mmc
->RecordExit
.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit
, this, _1
));
3542 mmc
->Locate
.connect_same_thread (*this, boost::bind (&Session::mmc_locate
, this, _1
, _2
));
3543 mmc
->Step
.connect_same_thread (*this, boost::bind (&Session::mmc_step
, this, _1
, _2
));
3544 mmc
->Shuttle
.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle
, this, _1
, _2
, _3
));
3545 mmc
->TrackRecordStatusChange
.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable
, this, _1
, _2
, _3
));
3547 /* also handle MIDI SPP because its so common */
3549 mmc
->SPPStart
.connect_same_thread (*this, boost::bind (&Session::spp_start
, this, _1
, _2
));
3550 mmc
->SPPContinue
.connect_same_thread (*this, boost::bind (&Session::spp_continue
, this, _1
, _2
));
3551 mmc
->SPPStop
.connect_same_thread (*this, boost::bind (&Session::spp_stop
, this, _1
, _2
));
3554 boost::shared_ptr
<Controllable
>
3555 Session::solo_cut_control() const
3557 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3558 controls in Ardour that currently get presented to the user in the GUI that require
3559 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3561 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3562 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3566 return _solo_cut_control
;