22 #include "libardour-config.h"
44 #include <sys/param.h>
45 #include <sys/mount.h>
48 #ifdef HAVE_SYS_STATVFS_H
49 #include <sys/statvfs.h>
53 #include <glib/gstdio.h>
56 #include <glibmm/threads.h>
57 #include <glibmm/fileutils.h>
59 #include <boost/algorithm/string.hpp>
61 #include "midi++/mmc.h"
62 #include "midi++/port.h"
122 #include "control_protocol/control_protocol.h"
132 Session::pre_engine_init (
string fullpath)
134 if (fullpath.empty()) {
145 _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
151 timerclear (&last_mmc_step);
152 g_atomic_int_set (&processing_prohibited, 0);
153 g_atomic_int_set (&_record_status, Disabled);
154 g_atomic_int_set (&_playback_load, 100);
155 g_atomic_int_set (&_capture_load, 100);
157 _all_route_group->set_active (
true,
this);
158 interpolation.add_channel_to (0, 0);
160 if (config.get_use_video_sync()) {
161 waiting_for_sync_offset =
true;
163 waiting_for_sync_offset =
false;
166 last_rr_session_dir = session_dirs.begin();
168 set_history_depth (
Config->get_history_depth());
172 _speakers->setup_default_speakers (2);
175 boost::bind (&RCConfiguration::set_solo_mute_gain,
Config, _1),
176 boost::bind (&RCConfiguration::get_solo_mute_gain,
Config)));
177 add_controllable (_solo_cut_control);
181 SourceFactory::SourceCreated.connect_same_thread (*
this, boost::bind (&Session::add_source,
this, _1));
182 PlaylistFactory::PlaylistCreated.connect_same_thread (*
this, boost::bind (&Session::add_playlist,
this, _1, _2));
183 AutomationList::AutomationListCreated.connect_same_thread (*
this, boost::bind (&Session::add_automation_list,
this, _1));
184 Controllable::Destroyed.connect_same_thread (*
this, boost::bind (&Session::remove_controllable,
this, _1));
185 IO::PortCountChanged.connect_same_thread (*
this, boost::bind (&Session::ensure_buffers,
this, _1));
189 Delivery::disable_panners ();
190 IO::disable_connecting ();
192 AudioFileSource::set_peak_dir (_session_dir->peak_path());
196 Session::post_engine_init ()
200 set_block_size (_engine.samples_per_cycle());
201 set_frame_rate (_engine.sample_rate());
213 boost::function<framecnt_t(void)> timer_func (boost::bind (&Session::audible_frame,
this));
216 setup_midi_machine_control ();
218 if (_butler->start_thread()) {
222 if (start_midi_thread ()) {
226 setup_click_sounds (0);
227 setup_midi_control ();
229 _engine.Halted.connect_same_thread (*
this, boost::bind (&Session::engine_halted,
this));
230 _engine.Xrun.connect_same_thread (*
this, boost::bind (&Session::xrun_recovery,
this));
236 _tempo_map =
new TempoMap (_current_frame_rate);
237 _tempo_map->PropertyChanged.connect_same_thread (*
this, boost::bind (&Session::tempo_map_changed,
this, _1));
242 midi_clock->set_session (
this);
246 SndFileSource::setup_standard_crossfades (*
this, frame_rate());
247 _engine.GraphReordered.connect_same_thread (*
this, boost::bind (&Session::graph_reordered,
this));
249 AudioDiskstream::allocate_working_buffers();
250 refresh_disk_space ();
257 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
263 setup_raid_path (_path);
268 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed,
this, _1,
false));
269 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed,
this, _1,
true));
272 config.map_parameters (ft);
276 Delivery::reset_panners ();
283 ControlProtocolManager::instance().set_session (
this);
302 ControlProtocolManager::instance().midi_connectivity_established ();
306 auto_connect_master_bus ();
309 _state_of_the_state =
StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
313 initialize_latencies ();
315 _locations->added.connect_same_thread (*
this, boost::bind (&Session::location_added,
this, _1));
316 _locations->removed.connect_same_thread (*
this, boost::bind (&Session::location_removed,
this, _1));
317 _locations->changed.connect_same_thread (*
this, boost::bind (&Session::locations_changed,
this));
330 _engine.transport_locate (0);
332 send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
333 send_immediate_mmc (MIDI::MachineControlCommand (Timecode::Time ()));
340 _state_of_the_state = Clean;
342 Port::set_connecting_blocked (
false);
348 }
else if (state_was_pending) {
350 remove_pending_capture_state ();
351 state_was_pending =
false;
358 Session::raid_path ()
const
362 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
363 raid_search_path += (*i).path;
370 Session::setup_raid_path (
string path)
379 session_dirs.clear ();
385 for (Searchpath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
388 session_dirs.push_back (sp);
397 last_rr_session_dir = session_dirs.begin();
401 Session::path_is_within_session (
const std::string& path)
403 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
412 Session::ensure_subdirs ()
416 dir = session_directory().peak_path();
418 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
423 dir = session_directory().sound_path();
425 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
430 dir = session_directory().midi_path();
432 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
437 dir = session_directory().dead_path();
439 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
444 dir = session_directory().export_path();
446 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
451 dir = analysis_dir ();
453 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
458 dir = plugins_dir ();
460 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
465 dir = externals_dir ();
467 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
479 Session::create (
const string& session_template,
BusProfile* bus_profile)
481 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
486 if (ensure_subdirs ()) {
492 if (!session_template.empty()) {
495 ifstream in(in_path.c_str());
501 string out_path = Glib::build_filename (_session_dir->root_path(), _name +
statefile_suffix);
503 ofstream out(out_path.c_str());
510 std::string template_plugins = Glib::build_filename (session_template,
X_(
"plugins"));
531 _state_of_the_state = Clean;
545 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
550 r->
input()->ensure_io (count,
false,
this);
551 r->
output()->ensure_io (count,
false,
this);
562 add_routes (rl,
false,
false,
false);
577 if (
Config->get_use_monitor_bus() && bus_profile) {
578 add_monitor_section ();
585 Session::maybe_write_autosave()
587 if (dirty() && record_status() != Recording) {
588 save_state(
"",
true);
593 Session::remove_pending_capture_state ()
595 std::string pending_state_file_path(_session_dir->root_path());
599 if (!Glib::file_test (pending_state_file_path, Glib::FILE_TEST_EXISTS))
return;
601 if (g_remove (pending_state_file_path.c_str()) != 0) {
603 pending_state_file_path, g_strerror (errno)) <<
endmsg;
612 Session::rename_state (
string old_name,
string new_name)
614 if (old_name == _current_snapshot_name || old_name == _name) {
622 const std::string old_xml_path(Glib::build_filename (_session_dir->root_path(), old_xml_filename));
623 const std::string new_xml_path(Glib::build_filename (_session_dir->root_path(), new_xml_filename));
625 if (::g_rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
627 old_name, new_name, g_strerror(errno)) <<
endmsg;
635 Session::remove_state (
string snapshot_name)
637 if (!_writable || snapshot_name == _current_snapshot_name || snapshot_name == _name) {
642 std::string xml_path(_session_dir->root_path());
653 if (g_remove (xml_path.c_str()) != 0) {
655 xml_path, g_strerror (errno)) <<
endmsg;
661 Session::save_state (
string snapshot_name,
bool pending,
bool switch_to_snapshot,
bool template_only)
664 std::string xml_path(_session_dir->root_path());
670 if (!_writable || (_state_of_the_state & CannotSave)) {
674 if (g_atomic_int_get(&_suspend_save)) {
678 _save_queued =
false;
680 if (!_engine.connected ()) {
681 error <<
string_compose (
_(
"the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
689 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
691 i->second->session_saved();
697 SessionSaveUnderway ();
705 if (snapshot_name.empty()) {
706 snapshot_name = _current_snapshot_name;
707 }
else if (switch_to_snapshot) {
708 _current_snapshot_name = snapshot_name;
719 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && !
create_backup_file (xml_path)) {
730 std::string tmp_path(_session_dir->root_path());
733 cerr <<
"actually writing state to " << tmp_path << endl;
735 if (!tree.
write (tmp_path)) {
737 if (g_remove (tmp_path.c_str()) != 0) {
739 tmp_path, g_strerror (errno)) <<
endmsg;
745 cerr <<
"renaming state to " << xml_path << endl;
747 if (::g_rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
749 tmp_path, xml_path, g_strerror(errno)) <<
endmsg;
750 if (g_remove (tmp_path.c_str()) != 0) {
752 tmp_path, g_strerror (errno)) <<
endmsg;
760 save_history (snapshot_name);
762 bool was_dirty = dirty();
770 StateSaved (snapshot_name);
777 Session::restore_state (
string snapshot_name)
779 if (load_state (snapshot_name) == 0) {
780 set_state (*state_tree->root(), Stateful::loading_state_version);
787 Session::load_state (
string snapshot_name)
792 state_was_pending =
false;
796 std::string xmlpath(_session_dir->root_path());
799 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
803 boost::optional<int> r = AskAboutPendingState();
804 if (r.get_value_or (1)) {
805 state_was_pending =
true;
809 if (!state_was_pending) {
810 xmlpath = Glib::build_filename (_session_dir->root_path(), snapshot_name);
813 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
815 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
827 if (!state_tree->read (xmlpath)) {
834 XMLNode& root (*state_tree->root());
836 if (root.name() !=
X_(
"Session")) {
845 if ((prop = root.property (
"version")) == 0) {
847 Stateful::loading_state_version = 1000;
849 if (prop->
value().find (
'.') != string::npos) {
851 if (prop->
value()[0] ==
'2') {
852 Stateful::loading_state_version = 2000;
854 Stateful::loading_state_version = 3000;
857 Stateful::loading_state_version =
atoi (prop->
value());
861 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION && _writable) {
863 std::string backup_path(_session_dir->root_path());
865 backup_path = Glib::build_filename (backup_path, backup_filename);
869 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
871 VersionMismatch (xmlpath, backup_path);
873 if (!
copy_file (xmlpath, backup_path)) {;
886 config.set_variables (node);
891 Session::save_default_options ()
893 return config.save_state();
903 Session::get_template()
910 disable_record (
false);
916 Session::state (
bool full_state)
922 snprintf(buf,
sizeof(buf),
"%d", CURRENT_SESSION_FILE_VERSION);
930 snprintf (buf,
sizeof (buf),
"%" PRId64, _nominal_frame_rate);
933 if (session_dirs.size() > 1) {
937 vector<space_and_path>::iterator i = session_dirs.begin();
938 vector<space_and_path>::iterator next;
944 while (i != session_dirs.end()) {
948 if (next != session_dirs.end()) {
949 p += G_SEARCHPATH_SEPARATOR;
965 snprintf (buf,
sizeof (buf),
"%" PRIu64, ID::counter());
975 list<XMLNode*> midi_port_nodes = _midi_ports->get_midi_port_states();
976 if (!midi_port_nodes.empty()) {
978 for (list<XMLNode*>::const_iterator n = midi_port_nodes.begin(); n != midi_port_nodes.end(); ++n) {
993 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1002 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1020 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1024 if (boost::dynamic_pointer_cast<AudioRegion>(r)) {
1025 child->
add_child_nocopy ((boost::dynamic_pointer_cast<AudioRegion>(r))->get_basic_state ());
1034 if (!cassocs.empty()) {
1037 for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1040 i->first->id().print (buf,
sizeof (buf));
1042 i->second->id().print (buf,
sizeof (buf));
1055 Location* range =
new Location (*
this, 0, 0,
_(
"session"), Location::IsSessionRange);
1064 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1078 public_order.sort (cmp);
1083 assert (_monitor_out == public_order.front());
1086 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1087 if (!(*i)->is_auditioner()) {
1097 playlists->add_state (node, full_state);
1099 child = node->
add_child (
"RouteGroups");
1100 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1132 Session::get_control_protocol_state ()
1139 Session::set_state (
const XMLNode& node,
int version)
1146 _state_of_the_state =
StateOfTheState (_state_of_the_state|CannotSave);
1148 if (node.
name() !=
X_(
"Session")) {
1149 fatal <<
_(
"programming error: Session: incorrect XML node sent to set_state()") <<
endmsg;
1153 if ((prop = node.
property (
"name")) != 0) {
1154 _name = prop->
value ();
1157 if ((prop = node.
property (
X_(
"sample-rate"))) != 0) {
1159 _nominal_frame_rate =
atoi (prop->
value());
1161 if (_nominal_frame_rate != _current_frame_rate) {
1162 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1163 if (r.get_value_or (0)) {
1169 setup_raid_path(_session_dir->root_path());
1171 if ((prop = node.
property (
X_(
"id-counter"))) != 0) {
1173 sscanf (prop->
value().c_str(),
"%" PRIu64, &x);
1174 ID::init_counter (x);
1182 ID::init_counter (now);
1185 if ((prop = node.
property (
X_(
"event-counter"))) != 0) {
1191 _midi_ports->set_midi_port_states (child->
children());
1194 IO::disable_connecting ();
1196 Stateful::save_extra_xml (node);
1199 load_options (*child);
1201 load_options (*child);
1203 error <<
_(
"Session: XML state has no options section") <<
endmsg;
1206 if (version >= 3000) {
1208 warning <<
_(
"Session: XML state has no metadata section") <<
endmsg;
1215 _speakers->set_state (*child, version);
1219 error <<
_(
"Session: XML state has no sources section") <<
endmsg;
1221 }
else if (load_sources (*child)) {
1226 error <<
_(
"Session: XML state has no Tempo Map section") <<
endmsg;
1228 }
else if (_tempo_map->set_state (*child, version)) {
1233 error <<
_(
"Session: XML state has no locations section") <<
endmsg;
1235 }
else if (_locations->set_state (*child, version)) {
1239 locations_changed ();
1241 if (_session_range_location) {
1242 AudioFileSource::set_header_position_offset (_session_range_location->start());
1246 error <<
_(
"Session: XML state has no Regions section") <<
endmsg;
1248 }
else if (load_regions (*child)) {
1253 error <<
_(
"Session: XML state has no playlists section") <<
endmsg;
1255 }
else if (playlists->load (*
this, *child)) {
1261 }
else if (playlists->load_unused (*
this, *child)) {
1266 if (load_compounds (*child)) {
1271 if (version >= 3000) {
1273 warning <<
_(
"Session: XML state has no bundles section") <<
endmsg;
1279 _bundle_xml_node =
new XMLNode (*child);
1283 if (version < 3000) {
1285 error <<
_(
"Session: XML state has no diskstreams section") <<
endmsg;
1287 }
else if (load_diskstreams_2X (*child, version)) {
1293 error <<
_(
"Session: XML state has no routes section") <<
endmsg;
1295 }
else if (load_routes (*child, version)) {
1300 _diskstreams_2X.clear ();
1302 if (version >= 3000) {
1305 error <<
_(
"Session: XML state has no route groups section") <<
endmsg;
1307 }
else if (load_route_groups (*child, version)) {
1311 }
else if (version < 3000) {
1314 error <<
_(
"Session: XML state has no edit groups section") <<
endmsg;
1316 }
else if (load_route_groups (*child, version)) {
1321 error <<
_(
"Session: XML state has no mix groups section") <<
endmsg;
1323 }
else if (load_route_groups (*child, version)) {
1329 warning <<
_(
"Session: XML state has no click section") <<
endmsg;
1330 }
else if (_click_io) {
1331 setup_click_state (&node);
1335 ControlProtocolManager::instance().set_state (*child, version);
1338 update_have_rec_enabled_track ();
1355 Session::load_routes (
const XMLNode& node,
int version)
1365 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1368 if (version < 3000) {
1369 route = XMLRouteFactory_2X (**niter, version);
1371 route = XMLRouteFactory (**niter, version);
1375 error <<
_(
"Session: cannot create Route from XML description.") <<
endmsg;
1381 new_routes.push_back (route);
1384 BootMessage (
_(
"Tracks/busses loaded; Adding to Session"));
1386 add_routes (new_routes,
false,
false,
false);
1394 Session::XMLRouteFactory (
const XMLNode& node,
int version)
1398 if (node.
name() !=
"Route") {
1411 assert (type != DataType::NIL);
1417 if (type == DataType::AUDIO) {
1423 if (track->
init()) {
1431 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1446 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1457 Session::XMLRouteFactory_2X (
const XMLNode& node,
int version)
1461 if (node.
name() !=
"Route") {
1477 assert (type != DataType::NIL);
1481 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1482 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->
value()) {
1486 if (i == _diskstreams_2X.end()) {
1487 error <<
_(
"Could not find diskstream for route") <<
endmsg;
1493 if (type == DataType::AUDIO) {
1499 if (track->
init()) {
1509 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1524 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1545 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1546 if ((region = XMLRegionFactory (**niter,
false)) == 0) {
1547 error <<
_(
"Session: cannot create Region from XML description.");
1568 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1573 if ((caprop = ca->
property (
X_(
"original"))) == 0) {
1576 orig_id = caprop->
value();
1578 if ((caprop = ca->
property (
X_(
"copy"))) == 0) {
1581 copy_id = caprop->
value();
1586 if (!orig || !copy) {
1593 RegionFactory::add_compound_association (orig, copy);
1600 Session::load_nested_sources (
const XMLNode& node)
1607 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1608 if ((*niter)->name() ==
"Source") {
1615 error <<
_(
"Nested source has no ID info in session file! (ignored)") <<
endmsg;
1621 if (!source_by_id (source_id)) {
1624 SourceFactory::create (*
this, **niter,
true);
1635 Session::XMLRegionFactory (
const XMLNode& node,
bool full)
1645 if (child->
name() ==
"NestedSource") {
1646 load_nested_sources (*child);
1650 if (!type || type->
value() ==
"audio") {
1652 }
else if (type->
value() ==
"midi") {
1664 Session::XMLAudioRegionFactory (
const XMLNode& node,
bool )
1671 uint32_t nchans = 1;
1674 if (node.
name() !=
X_(
"Region")) {
1678 if ((prop = node.
property (
X_(
"channels"))) != 0) {
1682 if ((prop = node.
property (
"name")) == 0) {
1683 cerr <<
"no name for this region\n";
1687 if ((prop = node.
property (
X_(
"source-0"))) == 0) {
1688 if ((prop = node.
property (
"source")) == 0) {
1689 error <<
_(
"Session: XMLNode describing a AudioRegion is incomplete (no source)") <<
endmsg;
1696 if ((source = source_by_id (s_id)) == 0) {
1703 error <<
string_compose(
_(
"Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) <<
endmsg;
1707 sources.push_back (as);
1711 for (uint32_t n=1; n < nchans; ++n) {
1712 snprintf (buf,
sizeof(buf),
X_(
"source-%d"), n);
1713 if ((prop = node.
property (buf)) != 0) {
1717 if ((source = source_by_id (id2)) == 0) {
1727 sources.push_back (as);
1731 for (uint32_t n = 0; n < nchans; ++n) {
1732 snprintf (buf,
sizeof(buf),
X_(
"master-source-%d"), n);
1733 if ((prop = node.
property (buf)) != 0) {
1737 if ((source = source_by_id (id2)) == 0) {
1747 master_sources.push_back (as);
1757 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1765 if (!master_sources.empty()) {
1766 if (master_sources.size() != nchans) {
1767 error <<
_(
"Session: XMLNode describing an AudioRegion is missing some master sources; ignored") <<
endmsg;
1783 Session::XMLMidiRegionFactory (
const XMLNode& node,
bool )
1790 if (node.
name() !=
X_(
"Region")) {
1794 if ((prop = node.
property (
"name")) == 0) {
1795 cerr <<
"no name for this region\n";
1799 if ((prop = node.
property (
X_(
"source-0"))) == 0) {
1800 if ((prop = node.
property (
"source")) == 0) {
1801 error <<
_(
"Session: XMLNode describing a MidiRegion is incomplete (no source)") <<
endmsg;
1808 if ((source = source_by_id (s_id)) == 0) {
1819 sources.push_back (ms);
1826 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1843 Session::get_sources_as_xml ()
1849 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1857 Session::reset_write_sources (
bool mark_write_complete,
bool force)
1860 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1865 _state_of_the_state =
StateOfTheState (_state_of_the_state|InCleanup);
1867 _state_of_the_state =
StateOfTheState (_state_of_the_state & ~InCleanup);
1886 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1889 if ((source = XMLSourceFactory (**niter)) == 0) {
1890 error <<
_(
"Session: cannot create Source from XML description.") <<
endmsg;
1897 if (err.
type == DataType::MIDI && Glib::path_is_absolute (err.
path)) {
1898 error <<
string_compose (
_(
"A external MIDI file is missing. %1 cannot currently recover from missing external MIDI files"),
1903 if (!no_questions_about_missing_files) {
1904 user_choice = MissingFile (
this, err.
path, err.
type).get_value_or (-1);
1909 switch (user_choice) {
1921 no_questions_about_missing_files =
true;
1925 no_questions_about_missing_files =
true;
1932 case DataType::AUDIO:
1933 source = SourceFactory::createSilent (*
this, **niter,
max_framecnt, _current_frame_rate);
1936 case DataType::MIDI:
1943 if (!Glib::path_is_absolute (err.
path)) {
1944 fullpath = Glib::build_filename (source_search_path (DataType::MIDI).front(), err.
path);
1952 source = SourceFactory::createWritable (DataType::MIDI, *
this, fullpath,
false, _current_frame_rate,
false,
false);
1954 source->
set_id (**niter);
1956 SourceFactory::SourceCreated (source);
1970 if (node.
name() !=
"Source") {
1976 return SourceFactory::create (*
this, node,
true);
1980 error <<
string_compose (
_(
"Found a sound file that cannot be used by %1. Talk to the programmers."), PROGRAM_NAME) <<
endmsg;
1986 Session::save_template (
string template_name)
1990 if (_state_of_the_state & CannotSave) {
1996 if (g_mkdir_with_parents (user_template_dir.c_str(), 0755) != 0) {
1998 user_template_dir, g_strerror (errno)) <<
endmsg;
2004 std::string template_dir_path(user_template_dir);
2007 template_dir_path = Glib::build_filename (template_dir_path, template_name);
2009 if (Glib::file_test (template_dir_path, Glib::FILE_TEST_EXISTS)) {
2011 template_dir_path) <<
endmsg;
2015 if (g_mkdir_with_parents (template_dir_path.c_str(), 0755) != 0) {
2017 template_dir_path, g_strerror (errno)) <<
endmsg;
2022 std::string template_file_path(template_dir_path);
2023 template_file_path = Glib::build_filename (template_file_path, template_name +
template_suffix);
2025 if (!tree.
write (template_file_path)) {
2032 std::string template_plugin_state_path(template_dir_path);
2033 template_plugin_state_path = Glib::build_filename (template_plugin_state_path,
X_(
"plugins"));
2035 if (g_mkdir_with_parents (template_plugin_state_path.c_str(), 0755) != 0) {
2036 error <<
string_compose(
_(
"Could not create directory for Session template plugin state\"%1\" (%2)"),
2037 template_plugin_state_path, g_strerror (errno)) <<
endmsg;
2041 copy_recurse (plugins_dir(), template_plugin_state_path);
2047 Session::refresh_disk_space ()
2049 #if __APPLE__ || (HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H)
2055 _total_free_4k_blocks = 0;
2056 _total_free_4k_blocks_uncertain =
false;
2058 for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2060 struct statfs statfsbuf;
2061 statfs (i->path.c_str(), &statfsbuf);
2063 double const scale = statfsbuf.f_bsize / 4096.0;
2066 struct statvfs statvfsbuf;
2067 statvfs (i->path.c_str(), &statvfsbuf);
2073 if (statfsbuf.f_bavail == 0) {
2076 i->blocks_unknown =
true;
2077 }
else if (statvfsbuf.f_flag & ST_RDONLY) {
2080 i->blocks_unknown =
false;
2083 i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2084 i->blocks_unknown =
false;
2087 _total_free_4k_blocks += i->blocks;
2088 if (i->blocks_unknown) {
2089 _total_free_4k_blocks_uncertain =
true;
2092 #elif defined PLATFORM_WINDOWS
2093 vector<string> scanned_volumes;
2094 vector<string>::iterator j;
2095 vector<space_and_path>::iterator i;
2096 DWORD nSectorsPerCluster, nBytesPerSector,
2097 nFreeClusters, nTotalClusters;
2101 _total_free_4k_blocks = 0;
2103 for (i = session_dirs.begin(); i != session_dirs.end(); i++) {
2104 strncpy (disk_drive, (*i).path.c_str(), 3);
2108 volume_found =
false;
2109 if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters)))
2111 int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster;
2112 int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters;
2113 i->blocks = (uint32_t)(nFreeBytes / 4096);
2115 for (j = scanned_volumes.begin(); j != scanned_volumes.end(); j++) {
2116 if (0 == j->compare(disk_drive)) {
2117 volume_found =
true;
2122 if (!volume_found) {
2123 scanned_volumes.push_back(disk_drive);
2124 _total_free_4k_blocks += i->blocks;
2129 if (0 == _total_free_4k_blocks) {
2130 strncpy (disk_drive, path().c_str(), 3);
2133 if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters)))
2135 int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster;
2136 int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters;
2137 _total_free_4k_blocks = (uint32_t)(nFreeBytes / 4096);
2144 Session::get_best_session_directory_for_new_audio ()
2146 vector<space_and_path>::iterator i;
2147 string result = _session_dir->root_path();
2151 if (session_dirs.size() == 1) {
2183 refresh_disk_space ();
2185 int free_enough = 0;
2187 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2188 if ((*i).blocks * 4096 >=
Config->get_disk_choice_space_threshold()) {
2193 if (free_enough >= 2) {
2198 i = last_rr_session_dir;
2201 if (++i == session_dirs.end()) {
2202 i = session_dirs.begin();
2205 if ((*i).blocks * 4096 >=
Config->get_disk_choice_space_threshold()) {
2209 last_rr_session_dir = i;
2214 }
while (i != last_rr_session_dir);
2222 vector<space_and_path> sorted;
2225 sorted = session_dirs;
2226 sort (sorted.begin(), sorted.end(), cmp);
2228 for (i = sorted.begin(); i != sorted.end(); ++i) {
2232 last_rr_session_dir = i;
2242 Session::automation_dir ()
const
2244 return Glib::build_filename (_path,
"automation");
2248 Session::analysis_dir ()
const
2250 return Glib::build_filename (_path,
"analysis");
2254 Session::plugins_dir ()
const
2256 return Glib::build_filename (_path,
"plugins");
2260 Session::externals_dir ()
const
2262 return Glib::build_filename (_path,
"externals");
2273 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2274 if ((*niter)->name() ==
"InputBundle") {
2276 }
else if ((*niter)->name() ==
"OutputBundle") {
2288 Session::load_route_groups (
const XMLNode& node,
int version)
2295 if (version >= 3000) {
2297 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2298 if ((*niter)->name() ==
"RouteGroup") {
2300 add_route_group (rg);
2305 }
else if (version < 3000) {
2307 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2308 if ((*niter)->name() ==
"EditGroup" || (*niter)->name() ==
"MixGroup") {
2310 add_route_group (rg);
2329 string statename(state);
2331 string::size_type
start,end;
2332 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2333 statename = statename.substr (start+1);
2337 end = statename.length();
2340 return string(statename.substr (0, end));
2344 Session::possible_states (
string path)
2346 vector<string> states;
2349 transform(states.begin(), states.end(), states.begin(),
remove_end);
2351 sort (states.begin(), states.end());
2357 Session::possible_states ()
const
2359 return possible_states(_path);
2365 _route_groups.push_back (g);
2366 route_group_added (g);
2368 g->
RouteAdded.connect_same_thread (*
this, boost::bind (&Session::route_added_to_route_group,
this, _1, _2));
2369 g->
RouteRemoved.connect_same_thread (*
this, boost::bind (&Session::route_removed_from_route_group,
this, _1, _2));
2370 g->
PropertyChanged.connect_same_thread (*
this, boost::bind (&Session::route_group_property_changed,
this, g));
2378 list<RouteGroup*>::iterator i;
2380 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2381 _route_groups.erase (i);
2384 route_group_removed ();
2392 Session::reorder_route_groups (list<RouteGroup*> groups)
2394 _route_groups = groups;
2396 route_groups_reordered ();
2402 Session::route_group_by_name (
string name)
2404 list<RouteGroup *>::iterator i;
2406 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2407 if ((*i)->name() ==
name) {
2415 Session::all_route_group()
const
2417 return *_all_route_group;
2421 Session::add_commands (vector<Command*>
const & cmds)
2423 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2429 Session::begin_reversible_command (
const string&
name)
2431 begin_reversible_command (g_quark_from_string (name.c_str ()));
2439 Session::begin_reversible_command (GQuark q)
2446 if (_current_trans == 0) {
2448 assert (_current_trans_quarks.empty ());
2450 _current_trans->set_name (g_quark_to_string (q));
2453 _current_trans_quarks.push_front (q);
2457 Session::abort_reversible_command ()
2459 if (_current_trans != 0) {
2460 _current_trans->clear();
2461 delete _current_trans;
2463 _current_trans_quarks.clear();
2470 assert (_current_trans);
2471 assert (!_current_trans_quarks.empty ());
2476 _current_trans->add_command (cmd);
2479 _current_trans_quarks.pop_front ();
2481 if (!_current_trans_quarks.empty ()) {
2486 if (_current_trans->empty()) {
2488 delete _current_trans;
2493 gettimeofday (&now, 0);
2494 _current_trans->set_timestamp (now);
2496 _history.add (_current_trans);
2503 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2507 if (!AudioFileSource::safe_audio_file_extension (path)) {
2517 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2521 return ((path.length() > 4 && path.find (
".mid") != (path.length() - 4)) ||
2522 (path.length() > 4 && path.find (
".smf") != (path.length() - 4)) ||
2523 (path.length() > 5 && path.find (
".midi") != (path.length() - 5)));
2529 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2534 if (path.length() >= statefile_ext.length()) {
2535 return (0 == path.compare (path.length() - statefile_ext.length(), statefile_ext.length(), statefile_ext));
2542 Session::find_all_sources (
string path, set<string>& result)
2547 if (!tree.
read (path)) {
2562 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2566 if ((prop = (*niter)->property (
X_(
"type"))) == 0) {
2572 if ((prop = (*niter)->property (
X_(
"name"))) == 0) {
2576 if (Glib::path_is_absolute (prop->
value())) {
2585 if (FileSource::find (*
this, type, prop->
value(),
true, is_new, chan, found_path)) {
2586 result.insert (found_path);
2594 Session::find_all_sources_across_snapshots (set<string>& result,
bool exclude_this_snapshot)
2596 vector<string> state_files;
2598 string this_snapshot_path;
2604 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2605 ripped = ripped.substr (0, ripped.length() - 1);
2610 if (state_files.empty()) {
2615 this_snapshot_path = _path;
2619 for (vector<string>::iterator i = state_files.begin(); i != state_files.end(); ++i) {
2621 if (exclude_this_snapshot && *i == this_snapshot_path) {
2625 if (find_all_sources (*i, result) < 0) {
2645 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2646 return r.get_value_or (1);
2650 Session::cleanup_regions ()
2652 bool removed =
false;
2655 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2657 uint32_t used = playlists->region_use_count (i->second);
2659 if (used == 0 && !i->second->automatic ()) {
2661 RegionFactory::map_remove (i->second);
2667 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2668 if (!(i->second->whole_file() && i->second->max_source_level() > 0)) {
2671 assert(boost::dynamic_pointer_cast<PlaylistSource>(i->second->source (0)) != 0);
2672 if (0 == playlists->region_use_count (i->second)) {
2673 RegionFactory::map_remove (i->second);
2689 vector<boost::shared_ptr<Source> > dead_sources;
2692 vector<string> candidates;
2693 vector<string> unused;
2694 set<string> all_sources;
2703 _state_of_the_state = (
StateOfTheState) (_state_of_the_state | InCleanup);
2707 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2715 playlists->sync_all_regions_with_regions ();
2722 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2724 SourceMap::iterator tmp;
2733 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2734 dead_sources.push_back (i->second);
2735 i->second->drop_references ();
2743 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2752 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2766 find_all_sources_across_snapshots (all_sources,
true);
2771 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2773 SourceMap::iterator tmp = i;
2776 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2780 if (playlists->source_use_count (fs) != 0) {
2781 all_sources.insert (fs->
path());
2790 RegionFactory::remove_regions_using_source (i->second);
2795 for (set<string>::iterator j = all_sources.begin(); j != all_sources.end(); ++j) {
2796 spath = Glib::path_get_basename (*j);
2797 if ( spath == i->second->name () ) {
2798 all_sources.erase (j);
2809 for (vector<string>::iterator x = candidates.begin(); x != candidates.end(); ++x) {
2814 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2819 if (tmppath1 == tmppath2) {
2826 unused.push_back (spath);
2832 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2833 struct stat statbuf;
2842 if ((*x).find (
"/sounds/") != string::npos) {
2846 newpath = Glib::path_get_dirname (*x);
2847 newpath = Glib::path_get_dirname (newpath);
2853 newpath = Glib::path_get_dirname (*x);
2854 newpath = Glib::path_get_dirname (newpath);
2855 newpath = Glib::path_get_dirname (newpath);
2856 newpath = Glib::path_get_dirname (newpath);
2861 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2866 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2868 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2876 snprintf (buf,
sizeof (buf),
"%s.%d", newpath.c_str(), version);
2879 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2880 snprintf (buf,
sizeof (buf),
"%s.%d", newpath.c_str(), ++version);
2884 if (version == 999) {
2885 error <<
string_compose (
_(
"there are already 1000 files with names like %1; versioning discontinued"),
2889 newpath = newpath_v;
2898 stat ((*x).c_str(), &statbuf);
2900 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2902 (*x), newpath, strerror (errno))
2915 string peakpath = peak_path (base);
2917 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2918 if (::g_unlink (peakpath.c_str()) != 0) {
2920 peakpath, _path, strerror (errno))
2923 ::rename (newpath.c_str(), _path.c_str());
2928 rep.
paths.push_back (*x);
2929 rep.
space += statbuf.st_size;
2944 _state_of_the_state = (
StateOfTheState) (_state_of_the_state & ~InCleanup);
2954 vector<space_and_path>::iterator i;
2960 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2971 Session::set_dirty ()
2975 if (_state_of_the_state & Loading) {
2979 bool was_dirty = dirty();
2991 Session::set_clean ()
2993 bool was_dirty = dirty();
2995 _state_of_the_state = Clean;
3004 Session::set_deletion_in_progress ()
3006 _state_of_the_state =
StateOfTheState (_state_of_the_state | Deletion);
3010 Session::clear_deletion_in_progress ()
3012 _state_of_the_state =
StateOfTheState (_state_of_the_state & (~Deletion));
3025 controllables.insert (c);
3033 if (_state_of_the_state & Deletion) {
3041 if (x != controllables.end()) {
3042 controllables.erase (x);
3051 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3052 if ((*i)->id() == id) {
3067 case ControllableDescriptor::NamedRoute:
3070 if (str ==
"Master" || str ==
"master") {
3072 }
else if (str ==
"control" || str ==
"listen") {
3080 case ControllableDescriptor::RemoteControlID:
3081 r = route_by_remote_id (desc.
rid());
3090 case ControllableDescriptor::Gain:
3095 c = r->
trim()->gain_control ();
3102 case ControllableDescriptor::Mute:
3106 case ControllableDescriptor::Recenable:
3116 case ControllableDescriptor::PanDirection:
3118 c = r->
pannable()->pan_azimuth_control;
3122 case ControllableDescriptor::PanWidth:
3124 c = r->
pannable()->pan_width_control;
3128 case ControllableDescriptor::PanElevation:
3130 c = r->
pannable()->pan_elevation_control;
3134 case ControllableDescriptor::Balance:
3138 case ControllableDescriptor::PluginParameter:
3140 uint32_t plugin = desc.
target (0);
3141 uint32_t parameter_index = desc.
target (1);
3149 if (parameter_index > 0) {
3162 case ControllableDescriptor::SendGain:
3164 uint32_t send = desc.
target (0);
3179 c = s->
amp()->gain_control();
3194 Session::add_instant_xml (
XMLNode& node,
bool write_to_config)
3197 Stateful::add_instant_xml (node, _path);
3200 if (write_to_config) {
3206 Session::instant_xml (
const string& node_name)
3208 return Stateful::instant_xml (node_name, _path);
3212 Session::save_history (
string snapshot_name)
3220 if (!
Config->get_save_history() ||
Config->get_saved_history_depth() < 0 ||
3221 (_history.undo_depth() == 0 && _history.redo_depth() == 0)) {
3225 if (snapshot_name.empty()) {
3226 snapshot_name = _current_snapshot_name;
3230 const string backup_filename = history_filename +
backup_suffix;
3231 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3232 const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3234 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3235 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3236 error <<
_(
"could not backup old history file, current history not saved") <<
endmsg;
3241 tree.
set_root (&_history.get_state (
Config->get_saved_history_depth()));
3243 if (!tree.
write (xml_path))
3247 if (g_remove (xml_path.c_str()) != 0) {
3249 xml_path, g_strerror (errno)) <<
endmsg;
3251 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3253 backup_path, g_strerror (errno)) <<
endmsg;
3263 Session::restore_history (
string snapshot_name)
3267 if (snapshot_name.empty()) {
3268 snapshot_name = _current_snapshot_name;
3272 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3274 info <<
"Loading history from " << xml_path <<
endmsg;
3276 if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3278 _name, xml_path) <<
endmsg;
3282 if (!tree.
read (xml_path)) {
3305 child_it != t->
children().end(); child_it++)
3310 if (n->
name() ==
"MementoCommand" ||
3311 n->
name() ==
"MementoUndoCommand" ||
3312 n->
name() ==
"MementoRedoCommand") {
3314 if ((c = memento_command_factory(n))) {
3318 }
else if (n->
name() ==
"NoteDiffCommand") {
3325 error <<
_(
"Failed to downcast MidiSource for NoteDiffCommand") <<
endmsg;
3328 }
else if (n->
name() ==
"SysExDiffCommand") {
3336 error <<
_(
"Failed to downcast MidiSource for SysExDiffCommand") <<
endmsg;
3339 }
else if (n->
name() ==
"PatchChangeDiffCommand") {
3347 error <<
_(
"Failed to downcast MidiSource for PatchChangeDiffCommand") <<
endmsg;
3350 }
else if (n->
name() ==
"StatefulDiffCommand") {
3351 if ((c = stateful_diff_command_factory (n))) {
3366 Session::config_changed (std::string p,
bool ours)
3372 if (p ==
"seamless-loop") {
3374 }
else if (p ==
"rf-speed") {
3376 }
else if (p ==
"auto-loop") {
3378 }
else if (p ==
"auto-input") {
3382 set_track_monitor_input_status (!config.get_auto_input());
3385 }
else if (p ==
"punch-in") {
3389 if ((location = _locations->auto_punch_location()) != 0) {
3391 if (config.get_punch_in ()) {
3392 replace_event (SessionEvent::PunchIn, location->
start());
3394 remove_event (location->
start(), SessionEvent::PunchIn);
3398 }
else if (p ==
"punch-out") {
3402 if ((location = _locations->auto_punch_location()) != 0) {
3404 if (config.get_punch_out()) {
3405 replace_event (SessionEvent::PunchOut, location->
end());
3407 clear_events (SessionEvent::PunchOut);
3411 }
else if (p ==
"edit-mode") {
3415 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3416 (*i)->set_edit_mode (
Config->get_edit_mode ());
3419 }
else if (p ==
"use-video-sync") {
3421 waiting_for_sync_offset = config.get_use_video_sync();
3423 }
else if (p ==
"mmc-control") {
3427 }
else if (p ==
"mmc-device-id" || p ==
"mmc-receive-id" || p ==
"mmc-receive-device-id") {
3429 _mmc->set_receive_device_id (
Config->get_mmc_receive_device_id());
3431 }
else if (p ==
"mmc-send-id" || p ==
"mmc-send-device-id") {
3433 _mmc->set_send_device_id (
Config->get_mmc_send_device_id());
3435 }
else if (p ==
"midi-control") {
3439 }
else if (p ==
"raid-path") {
3441 setup_raid_path (config.get_raid_path());
3443 }
else if (p ==
"timecode-format") {
3447 }
else if (p ==
"video-pullup") {
3451 }
else if (p ==
"seamless-loop") {
3453 if (play_loop && transport_rolling()) {
3455 request_play_loop (
true);
3458 }
else if (p ==
"rf-speed") {
3460 cumulative_rf_motion = 0;
3463 }
else if (p ==
"click-sound") {
3465 setup_click_sounds (1);
3467 }
else if (p ==
"click-emphasis-sound") {
3469 setup_click_sounds (-1);
3471 }
else if (p ==
"clicking") {
3473 if (
Config->get_clicking()) {
3474 if (_click_io && click_data) {
3481 }
else if (p ==
"click-gain") {
3484 _click_gain->set_gain (
Config->get_click_gain(),
this);
3487 }
else if (p ==
"send-mtc") {
3489 if (
Config->get_send_mtc ()) {
3491 next_quarter_frame_to_send = 0;
3494 }
else if (p ==
"send-mmc") {
3496 _mmc->enable_send (
Config->get_send_mmc ());
3498 }
else if (p ==
"midi-feedback") {
3500 session_midi_feedback =
Config->get_midi_feedback();
3502 }
else if (p ==
"jack-time-master") {
3504 engine().reset_timebase ();
3506 }
else if (p ==
"native-file-header-format") {
3508 if (!first_file_header_format_reset) {
3509 reset_native_file_format ();
3512 first_file_header_format_reset =
false;
3514 }
else if (p ==
"native-file-data-format") {
3516 if (!first_file_data_format_reset) {
3517 reset_native_file_format ();
3520 first_file_data_format_reset =
false;
3522 }
else if (p ==
"external-sync") {
3523 if (!config.get_external_sync()) {
3524 drop_sync_source ();
3526 switch_to_sync_source (
Config->get_sync_source());
3528 }
else if (p ==
"denormal-model") {
3530 }
else if (p ==
"history-depth") {
3531 set_history_depth (
Config->get_history_depth());
3532 }
else if (p ==
"remote-model") {
3536 }
else if (p ==
"initial-program-change") {
3538 if (_mmc->output_port() &&
Config->get_initial_program_change() >= 0) {
3541 buf[0] = MIDI::program;
3542 buf[1] = (
Config->get_initial_program_change() & 0x7f);
3544 _mmc->output_port()->midimsg (buf,
sizeof (buf), 0);
3546 }
else if (p ==
"solo-mute-override") {
3548 }
else if (p ==
"listen-position" || p ==
"pfl-position") {
3549 listen_position_changed ();
3550 }
else if (p ==
"solo-control-is-listen-control") {
3551 solo_control_mode_changed ();
3552 }
else if (p ==
"solo-mute-gain") {
3553 _solo_cut_control->Changed();
3554 }
else if (p ==
"timecode-offset" || p ==
"timecode-offset-negative") {
3555 last_timecode_valid =
false;
3556 }
else if (p ==
"playback-buffer-seconds") {
3557 AudioSource::allocate_working_buffers (frame_rate());
3558 }
else if (p ==
"ltc-source-port") {
3559 reconnect_ltc_input ();
3560 }
else if (p ==
"ltc-sink-port") {
3561 reconnect_ltc_output ();
3562 }
else if (p ==
"timecode-generator-offset") {
3563 ltc_tx_parse_offset();
3570 Session::set_history_depth (uint32_t d)
3572 _history.set_depth (d);
3576 Session::load_diskstreams_2X (
XMLNode const & node,
int)
3583 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3587 if ((*citer)->name() ==
"AudioDiskstream" || (*citer)->name() ==
"DiskStream") {
3589 _diskstreams_2X.push_back (dsp);
3591 error <<
_(
"Session: unknown diskstream type in XML") <<
endmsg;
3596 error <<
_(
"Session: could not load diskstream via XML state") <<
endmsg;
3606 Session::setup_midi_machine_control ()
3608 _mmc =
new MIDI::MachineControl;
3609 _mmc->set_ports (_midi_ports->mmc_input_port(), _midi_ports->mmc_output_port());
3611 _mmc->Play.connect_same_thread (*
this, boost::bind (&Session::mmc_deferred_play,
this, _1));
3612 _mmc->DeferredPlay.connect_same_thread (*
this, boost::bind (&Session::mmc_deferred_play,
this, _1));
3613 _mmc->Stop.connect_same_thread (*
this, boost::bind (&Session::mmc_stop,
this, _1));
3614 _mmc->FastForward.connect_same_thread (*
this, boost::bind (&Session::mmc_fast_forward,
this, _1));
3615 _mmc->Rewind.connect_same_thread (*
this, boost::bind (&Session::mmc_rewind,
this, _1));
3616 _mmc->Pause.connect_same_thread (*
this, boost::bind (&Session::mmc_pause,
this, _1));
3617 _mmc->RecordPause.connect_same_thread (*
this, boost::bind (&Session::mmc_record_pause,
this, _1));
3618 _mmc->RecordStrobe.connect_same_thread (*
this, boost::bind (&Session::mmc_record_strobe,
this, _1));
3619 _mmc->RecordExit.connect_same_thread (*
this, boost::bind (&Session::mmc_record_exit,
this, _1));
3620 _mmc->Locate.connect_same_thread (*
this, boost::bind (&Session::mmc_locate,
this, _1, _2));
3621 _mmc->Step.connect_same_thread (*
this, boost::bind (&Session::mmc_step,
this, _1, _2));
3622 _mmc->Shuttle.connect_same_thread (*
this, boost::bind (&Session::mmc_shuttle,
this, _1, _2, _3));
3623 _mmc->TrackRecordStatusChange.connect_same_thread (*
this, boost::bind (&Session::mmc_record_enable,
this, _1, _2, _3));
3627 _mmc->SPPStart.connect_same_thread (*
this, boost::bind (&Session::spp_start,
this));
3628 _mmc->SPPContinue.connect_same_thread (*
this, boost::bind (&Session::spp_continue,
this));
3629 _mmc->SPPStop.connect_same_thread (*
this, boost::bind (&Session::spp_stop,
this));
3633 Session::solo_cut_control()
const
3644 return _solo_cut_control;
3648 Session::rename (
const std::string& new_name)
3656 string const old_sources_root = _session_dir->sources_root();
3658 if (!_writable || (_state_of_the_state & CannotSave)) {
3659 error <<
_(
"Cannot rename read-only session.") <<
endmsg;
3662 if (record_status() == Recording) {
3663 error <<
_(
"Cannot rename session while recording") <<
endmsg;
3683 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3692 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3693 oldstr = oldstr.substr (0, oldstr.length() - 1);
3696 string base = Glib::path_get_dirname (oldstr);
3698 newstr = Glib::build_filename (base, legal_name);
3700 cerr <<
"Looking for " << newstr << endl;
3702 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3703 cerr <<
" exists\n";
3712 for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3723 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3724 oldstr = oldstr.substr (0, oldstr.length() - 1);
3727 string base = Glib::path_get_dirname (oldstr);
3728 newstr = Glib::build_filename (base, legal_name);
3730 cerr <<
"for " << oldstr <<
" new dir = " << newstr << endl;
3732 cerr <<
"Rename " << oldstr <<
" => " << newstr << endl;
3733 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3734 cerr <<
string_compose (
_(
"renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
3747 (*_session_dir) = newstr;
3754 string old_interchange_dir;
3755 string new_interchange_dir;
3761 v.push_back (newstr);
3763 v.push_back (Glib::path_get_basename (oldstr));
3765 old_interchange_dir = Glib::build_filename (v);
3768 v.push_back (newstr);
3770 v.push_back (legal_name);
3772 new_interchange_dir = Glib::build_filename (v);
3774 cerr <<
"Rename " << old_interchange_dir <<
" => " << new_interchange_dir << endl;
3776 if (::g_rename (old_interchange_dir.c_str(), new_interchange_dir.c_str()) != 0) {
3778 old_interchange_dir, new_interchange_dir,
3782 old_interchange_dir, new_interchange_dir,
3791 oldstr = Glib::build_filename (new_path, _current_snapshot_name +
statefile_suffix);
3794 cerr <<
"Rename " << oldstr <<
" => " << newstr << endl;
3796 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3797 cerr <<
string_compose (
_(
"renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
3804 oldstr = Glib::build_filename (new_path, _current_snapshot_name) +
history_suffix;
3806 if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS)) {
3807 newstr = Glib::build_filename (new_path, legal_name) +
history_suffix;
3809 cerr <<
"Rename " << oldstr <<
" => " << newstr << endl;
3811 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
3812 cerr <<
string_compose (
_(
"renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
3824 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3827 string p = fs->
path ();
3830 SourceFactory::setup_peakfile(i->second,
true);
3834 _current_snapshot_name = new_name;
3841 save_state (_current_snapshot_name);
3851 Session::get_session_info_from_path (
XMLTree& tree,
const string& xmlpath)
3853 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
3857 if (!tree.
read (xmlpath)) {
3865 Session::get_info_from_path (
const string& xmlpath,
float& sample_rate,
SampleFormat& data_format)
3868 bool found_sr =
false;
3869 bool found_data_format =
false;
3871 if (get_session_info_from_path (tree, xmlpath)) {
3884 for (XMLNodeList::const_iterator c = children.begin(); c != children.end(); ++c) {
3886 if (child->
name() ==
"Config") {
3888 for (XMLNodeList::const_iterator oc = options.begin(); oc != options.end(); ++oc) {
3896 if (name->
value() ==
"native-file-data-format") {
3901 found_data_format =
true;
3907 if (found_data_format) {
3912 return !(found_sr && found_data_format);
3919 Session::bring_all_sources_into_session (boost::function<
void(uint32_t,uint32_t,
string)> callback)
3923 SourcePathMap source_path_map;
3932 cerr <<
" total sources = " << sources.size();
3934 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
3945 if (source_path_map.find (fs->
path()) != source_path_map.end()) {
3946 source_path_map[fs->
path()].push_back (fs);
3948 SeveralFileSources v;
3950 source_path_map.insert (make_pair (fs->
path(), v));
3956 cerr <<
" fsources = " << total << endl;
3958 for (SourcePathMap::iterator i = source_path_map.begin(); i != source_path_map.end(); ++i) {
3962 string old_path = i->first;
3964 callback (n, total, old_path);
3966 cerr << old_path << endl;
3970 switch (i->second.front()->type()) {
3971 case DataType::AUDIO:
3972 new_path = new_audio_source_path_for_embedded (old_path);
3975 case DataType::MIDI:
3980 if (new_path.empty()) {
3984 cerr <<
"Move " << old_path <<
" => " << new_path << endl;
3987 cerr <<
"failed !\n";
3995 remove_dir_from_search_path (Glib::path_get_dirname (old_path), i->second.front()->type());
3997 for (SeveralFileSources::iterator
f = i->second.begin();
f != i->second.end(); ++
f) {
3998 (*f)->set_path (new_path);
4003 save_state (
"",
false,
false);
4015 Session::save_as_bring_callback (uint32_t,uint32_t,
string)
4026 string typedir = Glib::path_get_basename (Glib::path_get_dirname (old_path));
4028 v.push_back (new_session_folder);
4030 v.push_back (new_session_path);
4031 v.push_back (typedir);
4032 v.push_back (Glib::path_get_basename (old_path));
4034 return Glib::build_filename (v);
4040 vector<string> files;
4041 string current_folder = Glib::path_get_dirname (_path);
4044 int64_t total_bytes = 0;
4048 int32_t internal_file_cnt = 0;
4050 vector<string> do_not_copy_extensions;
4059 for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
4069 all += files.size();
4071 for (vector<string>::iterator i = files.begin(); i != files.end(); ++i) {
4073 g_stat ((*i).c_str(), &gsb);
4074 total_bytes += gsb.st_size;
4080 string old_path = _path;
4081 string old_name = _name;
4082 string old_snapshot = _current_snapshot_name;
4083 string old_sd = _session_dir->root_path();
4084 vector<string> old_search_path[DataType::num_types];
4085 string old_config_search_path[DataType::num_types];
4087 old_search_path[DataType::AUDIO] = source_search_path (DataType::AUDIO);
4088 old_search_path[DataType::MIDI] = source_search_path (DataType::MIDI);
4089 old_config_search_path[DataType::AUDIO] = config.get_audio_search_path ();
4090 old_config_search_path[DataType::MIDI] = config.get_midi_search_path ();
4094 (*_session_dir) = to_dir;
4098 if (!_session_dir->create()) {
4109 for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
4117 const size_t prefix_len = (*sd).path.size();
4129 for (vector<string>::iterator i = files.begin(); i != files.end(); ++i) {
4131 std::string from = *i;
4142 throw Glib::FileError (Glib::FileError::IO_ERROR,
"copy failed");
4148 internal_file_cnt++;
4155 bool do_copy =
true;
4157 for (vector<string>::iterator v = do_not_copy_extensions.begin(); v != do_not_copy_extensions.end(); ++v) {
4158 if (((*i).length() > (*v).length()) && ((*i).find (*v) == (*i).length() - (*v).length())) {
4166 string to = Glib::build_filename (to_dir, (*i).substr (prefix_len));
4168 if (g_mkdir_with_parents (Glib::path_get_dirname (to).c_str(), 0755)) {
4169 throw Glib::FileError (Glib::FileError::IO_ERROR,
"cannot create required directory");
4173 throw Glib::FileError (Glib::FileError::IO_ERROR,
"copy failed");
4184 g_stat ((*i).c_str(), &gsb);
4185 copied += gsb.st_size;
4188 double fraction = (double) copied / total_bytes;
4192 boost::optional<bool> res = saveas.
Progress (fraction, cnt, all);
4193 bool keep_going =
true;
4200 throw Glib::FileError (Glib::FileError::FAILED,
"copy cancelled");
4208 string old = plugins_dir ();
4209 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4210 string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4214 old = externals_dir ();
4215 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4216 string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4220 old = automation_dir ();
4221 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4222 string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4234 old = analysis_dir ();
4235 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4236 string newdir = Glib::build_filename (to_dir,
"analysis");
4244 _current_snapshot_name = saveas.
new_name;
4253 if (internal_file_cnt) {
4254 for (vector<string>::iterator s = old_search_path[DataType::AUDIO].begin(); s != old_search_path[DataType::AUDIO].end(); ++s) {
4255 ensure_search_path_includes (*s, DataType::AUDIO);
4258 for (vector<string>::iterator s = old_search_path[DataType::MIDI].begin(); s != old_search_path[DataType::MIDI].end(); ++s) {
4259 ensure_search_path_includes (*s, DataType::MIDI);
4264 bool was_dirty = dirty ();
4267 save_default_options ();
4270 if (bring_all_sources_into_session (boost::bind (&Session::save_as_bring_callback,
this, _1, _2, _3))) {
4271 throw Glib::FileError (Glib::FileError::NO_SPACE_LEFT,
"consolidate failed");
4283 _current_snapshot_name = old_snapshot;
4285 (*_session_dir) = old_sd;
4291 if (internal_file_cnt) {
4293 config.set_audio_search_path (old_config_search_path[DataType::AUDIO]);
4294 config.set_midi_search_path (old_config_search_path[DataType::MIDI]);
4304 session_dirs.clear ();
4305 session_dirs.push_back (sp);
4306 refresh_disk_space ();
4310 reset_write_sources (
true,
true);
4316 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
4330 }
catch (Glib::FileError& e) {
std::map< PBD::ID, boost::shared_ptr< Region > > RegionMap
static bool accept_all_midi_files(const string &path, void *)
static bool accept_all_audio_files(const string &path, void *)
LIBPBD_API Transmitter fatal
int atoi(const string &s)
LIBARDOUR_API const char *const pending_suffix
std::map< std::string, SeveralFileSources > SourcePathMap
LIBARDOUR_API int remove_recent_sessions(const std::string &path)
LIBARDOUR_API void setup_fpu()
const std::string & value() const
PBD::Signal1< void, const PropertyChange & > PropertyChanged
LIBEVORAL_API event_id_t event_id_counter()
int set_state(const XMLNode &, int version)
void set_input_port(MIDI::Port *)
virtual int set_state(const XMLNode &, int version)
const std::string & top_level_name() const
LIBARDOUR_API std::string legalize_for_path(const std::string &str)
AutoConnectOption output_ac
std::map< boost::shared_ptr< Region >, boost::shared_ptr< Region > > CompoundAssociations
void remove_directory(const std::string &dir)
bool path_is_within(std::string const &haystack, std::string needle)
shared_ptr< T > dynamic_pointer_cast(shared_ptr< U > const &r)
const std::string & name() const
boost::shared_ptr< Pannable > pannable() const
LIBARDOUR_API int store_recent_sessions(std::string name, std::string path)
void reset_write_sources(bool, bool force=false)
boost::shared_ptr< Control > control(const Parameter &id, bool create_if_missing=false)
void set_session(ARDOUR::Session *)
boost::shared_ptr< AutomationControl > gain_control() const
static bool accept_all_state_files(const string &path, void *)
XMLNode * add_child_copy(const XMLNode &)
LIBPBD_API Transmitter error
LIBPBD_API Transmitter warning
const XMLNodeList & children(const std::string &str=std::string()) const
LIBEVORAL_API void init_event_id_counter(event_id_t n)
XMLNode & get_state(void)
PBD::Signal2< void, RouteGroup *, boost::weak_ptr< ARDOUR::Route > > RouteRemoved
LIBARDOUR_API bool create_backup_file(const std::string &file_path)
std::ostream & endmsg(std::ostream &ostr)
virtual bool empty() const =0
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > start
PBD::Signal3< bool, float, int64_t, int64_t > Progress
XMLNode * add_child(const char *)
LIBARDOUR_API std::string session_template_dir_to_file(std::string const &)
boost::shared_ptr< AutomationControl > rec_enable_control()
LIBPBD_API int replace_all(std::string &str, const std::string &target, const std::string &replacement)
void operator()(void const *) const
int clear_directory(const string &dir, size_t *size, vector< string > *paths)
uint32_t blocks
4kB blocks
boost::shared_ptr< Processor > nth_send(uint32_t n)
bool within_session() const
LIBARDOUR_API uint64_t TempoMap
std::list< XMLNode * > XMLNodeList
boost::shared_ptr< Amp > trim() const
void set_timestamp(struct timeval &t)
void set_length(framecnt_t len)
void copy_recurse(const std::string &from_path, const std::string &to_dir)
LIBARDOUR_API bool no_auto_connect()
static const char * state_node_name
bool copy_file(const std::string &from_path, const std::string &to_path)
void set_master_sources(const SourceList &)
XMLProperty * property(const char *)
LIBARDOUR_API RCConfiguration * Config
int set(framepos_t start, framepos_t end, bool allow_bbt_recompute=true)
#define string_2_enum(str, e)
XMLNode * set_root(XMLNode *n)
LIBARDOUR_API uint64_t Solo
LIBARDOUR_API std::string user_template_directory()
std::string new_parent_folder
bool set_id(const XMLNode &)
void add_command(Command *const)
boost::shared_ptr< Processor > nth_plugin(uint32_t n)
AutoConnectOption input_ac
LIBARDOUR_API const char *const backup_suffix
bool exists_and_writable(const std::string &p)
boost::shared_ptr< Region > region
void set_output_port(boost::shared_ptr< MidiPort >)
std::map< PBD::ID, boost::shared_ptr< AudioSource > > AudioSourceList
const std::string sound_path() const
LIBARDOUR_API XMLNode * find_named_node(const XMLNode &node, std::string name)
LIBARDOUR_API PBD::PropertyDescriptor< bool > regions
static bool state_file_filter(const string &str, void *)
std::string file_name() const
LIBPBD_API Transmitter info
void copy_files(const std::string &from_path, const std::string &to_dir)
LIBARDOUR_API const char *const statefile_suffix
LIBARDOUR_API const char *const template_suffix
void map_parameters(boost::function< void(std::string)> &)
XMLProperty * add_property(const char *name, const std::string &value)
void add(Location *, bool make_current=false)
LIBPBD_API Glib::ustring basename_nosuffix(Glib::ustring)
const std::string & path() const
static string make_new_media_path(string old_path, string new_session_folder, string new_session_path)
LIBARDOUR_API const char *const interchange_dir_name
void add_child_nocopy(XMLNode &)
virtual int set_state(const XMLNode &, int version)
XMLNode & get_state(void)
std::string final_session_folder_name
boost::shared_ptr< Amp > amp() const
boost::shared_ptr< SoloControllable > solo_control() const
XMLNode * add_content(const std::string &s=std::string())
std::vector< boost::shared_ptr< FileSource > > SeveralFileSources
TopLevelType top_level_type() const
static bool accept_all_files(string const &, void *)
LIBARDOUR_API PBD::Signal1< void, std::string > BootMessage
LIBPBD_TEMPLATE_MEMBER_API const std::string to_string() const
const std::string midi_path() const
PBD::Signal2< void, RouteGroup *, boost::weak_ptr< ARDOUR::Route > > RouteAdded
boost::shared_ptr< MuteControllable > mute_control() const
boost::shared_ptr< IO > input() const
LIBARDOUR_API const char *const temp_suffix
uint32_t target(uint32_t n) const
uint32_t master_out_channels
virtual void set_path(const std::string &)
const char * what() const
framecnt_t length() const
static const framepos_t max_framepos
boost::shared_ptr< IO > output() const
static string remove_end(string state)
static const framecnt_t max_framecnt
void find_files_matching_filter(vector< string > &result, const Searchpath &paths, bool(*filter)(const string &, void *), void *arg, bool pass_fullpath, bool return_fullpath, bool recurse)
virtual void set_diskstream(boost::shared_ptr< Diskstream >)
void add_instant_xml(XMLNode &)
LIBARDOUR_API const char *const history_suffix
std::list< boost::shared_ptr< Route > > RouteList
XMLNodeList::const_iterator XMLNodeConstIterator
AudioSourceList::iterator iter
static MidiPatchManager & instance()
std::vector< boost::shared_ptr< Source > > SourceList
std::vector< std::string > paths
std::string string_compose(const std::string &fmt, const T1 &o1)
boost::shared_ptr< ARDOUR::Playlist > playlist() const
void set_name(const std::string &str)
LIBARDOUR_API const char *const dead_dir_name
LIBPBD_API std::string canonical_path(const std::string &path)
std::string failure_message